/***********************************************
 * released under (E) licensing ...            *
 *        (E) RULES AND REGULATIONS            *
 * permission to use/rewrite/add     : granted *
 * permission to trojan/steal        : denied  *
 * permission to use illegally       : denied  *
 * permission to use on /dev/urandom : denied  *
 ***********************************************/
/* contact el8@press.co.jp for full license    */
/* code copyrighted by ~el8 -- don't infringe! */

/*
-+-+
cat <<'/*++--++*'> eldump.c # */

/**********************************************
 * released under (E) licensing ...           *
 *        (E) RULES AND REGULATIONS           *
 * permission to use/rewrite/add    : granted *
 * permission to trojan/steal       : denied  *
 * permission to use illegally      : denied  *
 * permission to use on dev/urandom : denied  *
 **********************************************/


/*******************************************
 * eldump.c for standard UNIX compilers    *
 * next version:                           *
 *                                         *
 *  +article extraction (ablility to       *(E)*
 *                specify article number)  *[~]*
 *  +code extract by article number        *[E]*
 *  +GUI interface for file viewing        *[L]*
 *             (most likely curses based)  *[8]*
 *  +ability to update code/articles via   *[`]*
 *               updates/correction posted *[9]*
 *               on ~el8 website           *[9]*
 *  +much cooler/faster/stronger/portable  *
 *  +Versions for DOS C/COBOL/Asm/Pascal   *
 *******************************************/

// Questions/Comments/Corrections @ el8@press.co.jp //
// el8.n3.net //


#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

/**************************************
* next version of eldump will have    *
* a lot more features, this is just   *
* a basic code extraction version.    *
*      - team ~el8                    *
*                                     *
* #define ISH_START        "[SOI] %s" *
* #define ARTICLE_START    "[BOW] %s" *
* #define ARTICLE_END         "[EOW]" *
* #define ISH_END             "[EOI]" *
**************************************/

/* for verbosity */
#define VERBOSE                0x01
#define VERY	              0x10
#define LOTS	              0x20
/* char array sizes */
#define LINELEN                  80
#define BUFLEN                  255

/* Issue Tag Defines */
#define CODE_START  "[CUT_HERE] %s"
#define CODE_START_ARGS          1
#define DIR_START  "[BEGIN_DIR] %s"
#define DIR_START_ARGS           1
#define DIR_END      "[END_DIR] %s"
#define DIR_END_ARGS             1
#define CODE_END     "[END_CUT] %s"
#define CODE_END_ARGS            1
#define loop(n)            for(;n;)

/* global vars */
FILE *TextFD;
char BaseDirectory[BUFLEN], buf[LINELEN], 
CodeDir[BUFLEN + BUFLEN], tmp[LINELEN];
int verbose = 0, linez = 0, codez = 0, dirz = 0;
const char *license = \
"/***********************************************\n"
" * released under (E) licensing ...            *\n"
" *        (E) RULES AND REGULATIONS            *\n"
" * permission to use/rewrite/add     : granted *\n"
" * permission to trojan/steal        : denied  *\n"
" * permission to use illegally       : denied  *\n"
" * permission to use on /dev/urandom : denied  *\n"
" ***********************************************/\n"
"/* contact el8@press.co.jp for full license    */\n"
"/* code copyrighted by ~el8 -- don't infringe! */\n\n";

/**********************
* int  article(char *);
* int    issue(char *);
**********************/

/* function prototypes */
int code (char *);
int extr (char *);

int
main (int argc, char *argv[])
{
  int NumberOfFiles; // For multiple files
  getcwd (BaseDirectory, BUFLEN);	// error checking is for pussiez

  setvbuf (stderr, (char *) NULL, _IONBF, 0); 
  if (argc < 2) // no options specified
    {
      fprintf (stderr,
	       "\033[0;36m"
".---------------------------------------.\n"
"|\033[1;36m  /\\/|    _  ___              _       \033[0;36m |\n"
"|\033[1;36m |/\\/ ___| |( _ )   _____  _| |_ _ __  \033[0;36m|\n"
"|\033[1;36m     / _ \\ |/ _ \\  / _ \\ \\/ / __| '__| \033[0;36m|\n"
"|\033[1;36m    |  __/ | (_) ||  __/>  <| |_| |    \033[0;36m|\n"
"|\033[1;36m     \\___|_|\\___/  \\___/_/\\_\\\\__|_|    \033[0;36m|\n"
"`---usage-------------------------------'\n"
    "\033[m\n"
   "\033[7m %s [file1 file2 file3 ...] <option>\t\033[m\n"
      "\033[0;32m\n"
     ".---options-----------------------------.\n"
     "|+\033[1;32m   [-v]: verbose     \033[0;32m                 |\n"
     "|+\033[1;32m  [-vv]: very verbose\033[0;32m                 |\n"
     "|+\033[1;32m [-vvv]: very very verbose \033[0;32m           |\n"
     "`---------------------------------------'\n"
     "\033[m",
      argv[0]);
      exit (-1);
    }

  verbose -= verbose; // zero verbose
  if (!strncmp (argv[argc - 1], "-v", 2)) // if the last option was a "-v"
    {
      verbose = VERBOSE;
      argc--;
    }
  else if (!strncmp (argv[argc - 1], "-vv", 3)) // "-vv"
    {
      verbose = (VERY + VERBOSE);
      argc--;
    }
  else if (!strncmp (argv[argc - 1], "-vvv", 4)) // "-vvv"
    {
      verbose = (LOTS + VERBOSE + LOTS);
      argc--;
    }

  if (argc < 2)
    {
      fprintf (stderr, "need files...\n");
      exit (-1);
    }

  for (NumberOfFiles = 1; NumberOfFiles < argc; NumberOfFiles++)
    {
      if (verbose >= LOTS)
	{
	  fprintf (stderr, "eldumping code from %s\n", argv[NumberOfFiles]);
	  if (extr (argv[NumberOfFiles]) == 0)
	    {
	      fprintf (stderr, "[#%i] code eldump of %s: success!\n",
		       NumberOfFiles, argv[NumberOfFiles]);
	    }
	  else
	    {
	      fprintf (stderr, "[#%i] code eldump of %s: failed.\n",
		       NumberOfFiles, argv[NumberOfFiles]);
	    }
	}
      else
	{
	  extr (argv[NumberOfFiles]);
	}
    }

  if (verbose >= VERBOSE)
    {
      fprintf (stderr, "\t%i texts\n\t%i dirs\n\t%i codes\n\t\%i lines\n",
	       NumberOfFiles - 1, dirz, codez, linez);
    }
  exit (0);
}

int
extr (char *TextFileName)

{
  char arg[LINELEN];
  if ((TextFD = fopen (TextFileName, "r")) == NULL)
    {
      fprintf (stderr, "opening text %s: %s\n", TextFileName, strerror (errno));
      return (-1);
    }
  loop (!feof (TextFD))
  {
    fgets (buf, LINELEN, TextFD);

    if (sscanf (buf, DIR_START, arg) == DIR_START_ARGS)
      {
	snprintf (CodeDir, sizeof CodeDir, "%s/%s", BaseDirectory, arg);
	if (verbose >= VERBOSE)
	  {
	    fprintf (stderr, "creating %s/\n", CodeDir);
	    dirz++;
	  }

	if ((mkdir (CodeDir, 0700) == -1) && (errno != EEXIST))
	  {
	    perror (CodeDir);
	    fclose (TextFD);
	    return (-1);
	  }
	if (chdir (CodeDir) == -1)
	  {
	    fprintf (stderr, "changing to code dir %s: %s\n", CodeDir, 
strerror (errno));
	    fclose (TextFD);
	    return (-1);
	  }
	else if (verbose >= LOTS)
	  fprintf (stderr, "changing to %s\n", CodeDir);
      }
    else if (sscanf (buf, CODE_START, arg) == CODE_START_ARGS)
      {
	if (verbose >= VERY)
	  fprintf (stderr, "eldumping %s\n", arg);
	if (code (arg) == -1)
	  {
	    fclose (TextFD);
	    return (-1);
	  }
      }

    else if (sscanf (buf, DIR_END, tmp) == DIR_END_ARGS)
      {
	if (verbose >= LOTS)
	  fprintf (stderr, "changing to ..\n");

	chdir ((!strcmp (arg, ".")) ? "." : "..");
      }
  }
  fclose (TextFD);
  return (0);
}

int
code (char *CodeFileName)
{
  FILE *CodeFile;
  char codebuff[BUFLEN];

  chdir ((CodeDir != NULL) ? CodeDir : ".");

  if ((CodeFile = fopen (CodeFileName, "w+")) == NULL)
    {
      fprintf (stderr, "opening code %s: %s\n", CodeFileName, strerror (errno));
      return (-1);
    }
  if (verbose >= VERBOSE)
    codez++;
  if (CodeFileName[strlen(CodeFileName)-1] == 'c' 
&& CodeFileName[strlen(CodeFileName)-2] == '.')
  fputs (license, CodeFile);
  loop (!feof (TextFD))
  {
    fgets (codebuff, LINELEN, TextFD);

    if (sscanf (codebuff, CODE_END, tmp) == CODE_END_ARGS)
      {
	if (verbose >= LOTS)
	  fprintf (stderr, "end of %s\n", CodeFileName);

	fclose (CodeFile);
	break;
      }
    else
      {
	fputs (codebuff, CodeFile);
	if (verbose >= VERBOSE)
	  linez++;

      }
  }
  return 0;
}

// [CUT_HERE] <NAME> then [END_CUT] <NAME>  //
// [BEGIN_DIR] <NAME> then [END_DIR] <NAME> //


/*++--++*
   cat <<'[EOI]'> /dev/null
*/



syntax highlighted by Code2HTML, v. 0.9.1