home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / unshar.zoo / unshar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-21  |  6.3 KB  |  277 lines

  1. #include <stdio.h>
  2. #include "unshar.h"
  3.  
  4. /*
  5.  * Unshar - extract files from shell archive
  6.  *
  7.  * Written by Warren Toomey. Nov, 1989.
  8.  * You may freely copy or give away this source as
  9.  * long as this notice remains intact.
  10.  *
  11.  */
  12.  
  13. /* Global variables */
  14.  
  15. int table;            /* Generate a table, or extract */
  16. int verbose;            /* Unshar verbosely - debugging */
  17. int numext;            /* Number of files to extract */
  18. char *exfile[100];        /* Files to extract */
  19.  
  20.  
  21. #define getline(x,y)    fgetline(stdin,x,y)
  22.  
  23. int fgetline(zin,how,buf)    /* Get a line from a file */
  24.  FILE *zin;
  25.  int how;            /* Ignore leading whitespace if */
  26.  char *buf;            /* how == NOWHITE */
  27.  {
  28.   int ch=NULL;
  29.  
  30.   *buf=NULL;            /* Null the buffer */
  31.   if (how==NOWHITE)        /* If skip any whitespace */
  32.     {
  33.      while (((ch=fgetc(zin))==' ') || (ch=='\t'));
  34.      if (ch==EOF)  return(EOF);    /* Returning EOF or NULL */
  35.      if (ch=='\n') return(NULL);
  36.      *buf++ =ch;        /* Put char in buffer */
  37.     }
  38.  
  39.   while ((ch=fgetc(zin))!='\n')    /* Now get the line */
  40.    {
  41.     if (ch==EOF) { *buf=NULL; return(EOF); }
  42.     *buf++ = ch;
  43.    }
  44.   
  45.   *buf=NULL;            /* Finally null-terminate the buffer */
  46.   return(NULL);            /* and return */
  47.  }
  48.  
  49.  
  50.  
  51. char *getstring(buf)        /* Get the next string from the buffer */
  52.  char *buf;            /* ignoring any quotes */
  53.  {
  54.   char out[BUFSIZE];
  55.   char *temp=out;
  56.   while ((*buf==' ') || (*buf=='\t')) buf++;    /* Skip whitespace */
  57.  
  58.   switch(*buf)            /* Now check first char */
  59.    {
  60.     case '\'' : buf++;
  61.         while (*buf!='\'') *temp++ = *buf++;
  62.         *temp=NULL;
  63.         return(out);
  64.     case '\"' : buf++;
  65.         while (*buf!='\"') *temp++ = *buf++;
  66.         *temp=NULL;
  67.         return(out);
  68.     case NULL : return(NULL);
  69.     default   : while ((*buf!=' ') && (*buf!='\t'))
  70.            if (*buf!='\\') *temp++ = *buf++;
  71.            else buf++;
  72.         *temp=NULL;
  73.         return(out);
  74.    }
  75.  }
  76.  
  77.  
  78. int firstword(buf)        /* Return token value of first word */
  79.  char *buf;            /* in the buffer. Assume no leading */
  80.  {                /* whitespace in the buffer */
  81.   int i;
  82.  
  83.   for (i=1;i<NUMTOKS;i++)
  84.      if (strncmp(buf,token[i],strlen(token[i]))==0)
  85.     return(i);
  86.  
  87.   return(UNKNOWN);
  88.  }
  89.  
  90.  
  91. int mustget(s1)            /* Return 1 if s1 is in the list of  */
  92.  char *s1;            /* files to extract. Return 0 if not */
  93.  {                
  94.   int i;
  95.  
  96.   if (numext==0) return(0);
  97.   for (i=0;i<numext;i++)
  98.    if (!strcmp(s1,exfile[i])) return(1);
  99.   return(0);
  100.  }
  101.  
  102.  
  103. void extract(how,file,end,lead)    /* Extract file, up until end word */
  104.  int how;            /* If how==YESX, then ignore lead   */
  105.  char *file;            /* character on every line */
  106.  char *end;
  107.  int lead;
  108.  {
  109.   FILE *zout;
  110.   char line[BUFSIZE];
  111.   char *temp;
  112.   int ch;
  113.  
  114.   zout=fopen(file,"w");        /* Open output file */
  115.   if (zout==NULL)
  116.     { perror("unshar");
  117.       return;
  118.     }
  119.  
  120.   while(1)
  121.    {
  122.     ch=getline(WHITE,line);    /* Get a line of file */
  123.     temp=line;
  124.     if (ch==EOF)
  125.       { fprintf(zout,"%s\n",line);
  126.     fclose(zout);
  127.     return;
  128.       }
  129.  
  130.     if (strncmp(line,end,strlen(end))==0)    /* If end word */
  131.       { fclose(zout);                /* close the file */
  132.     return;
  133.       }
  134.  
  135.      if ((how==YESX) && (*temp==lead)) temp++;    /* Skip any lead */
  136.      fprintf(zout,"%s\n",temp);
  137.     }
  138.  }
  139.  
  140.  
  141. void getnames(buf,file,word)    /* Get the file & end word */
  142.  char *buf, *file, *word;    /* from the buffer */
  143.  {
  144.   char *temp;
  145.  
  146.   temp=buf;
  147.   if (verbose) printf("Getnames: buf is %s\n",buf);
  148.  
  149.   while (*temp!=NULL)        /* Scan along buffer */
  150.    {
  151.     switch(*temp)        /* Get file or end word */
  152.      {
  153.       case '>' : strcpy(file,getstring(++temp)); /* Get the file name */
  154.           break;
  155.       case '<' : if (*(++temp)=='<') ++temp;    /* Skip 2nd < */
  156.          strcpy(word,getstring(temp));    /* Get next word */
  157.          break;
  158.       default  : temp++;
  159.      }
  160.    }
  161.  }
  162.  
  163.  
  164.  
  165. void disembowel()        /* Unshar brutally! */
  166.  {
  167.   char buf[BUFSIZE];        /* Line buffer */
  168.   char file[BUFSIZE];        /* File name */
  169.   char word[BUFSIZE];        /* Word buffer */
  170.   int ch,x;
  171.  
  172.   if (verbose) printf("Entering disembowel\n");
  173.   x='X';            /* Leading X character */
  174.   while(1)
  175.    {
  176.     ch=getline(NOWHITE,buf);    /* Get a line from file */
  177.     if (ch==EOF) 
  178.     return;
  179.  
  180.     switch(firstword(buf))    /* Extract, depending on first word */
  181.      {
  182.       case CAT:
  183.       case GRES:
  184.       case SED:  if (verbose) printf("About to do getnames\n");
  185.          getnames(buf,file,word);
  186.          if (table==0)
  187.           {
  188.            if ((numext==0) || (mustget(file)))
  189.             {
  190.              printf("unshar: Extracting  %s\n",file);
  191.              if (verbose) 
  192.             printf("        stopping at %s\n",word);
  193.              extract(YESX,file,word,x);
  194.             }
  195.           }
  196.          else printf("%s\n",file);
  197.          break;
  198.       default:   break;
  199.      }
  200.    }
  201.  }
  202.   
  203.  
  204.  
  205. usage()
  206.  {
  207.   fprintf(stderr,"Usage: unshar [-t] [-b] [-v] [-xfile] [file(s)]\n");
  208.   exit(0);
  209.  }
  210.  
  211.  
  212. main(argc,argv)
  213.  int argc;
  214.  char *argv[];
  215.  {
  216.   extern int optind;
  217.   extern char *optarg;
  218.   int i,c,first;
  219.  
  220.   FILE *zin;            /* Dummy file descriptor */
  221.   int method;            /* Method of unsharing */
  222.  
  223.   method= BRUTAL;        /* Only BRUTAL currently available */
  224.   table=  0;            /* Don't generate a table */
  225.   verbose=0;            /* Nor be very verbose */
  226.   numext= 0;            /* Initially no files to extract */
  227.  
  228.  
  229.   while ((c=getopt(argc,argv,"x:tbv"))!=EOF)
  230.     switch(c)
  231.      {
  232.       case 't' : table=1;    /* Get the various options */
  233.          break;
  234.       case 'b' : method= BRUTAL;
  235.          break;
  236.       case 'v' : verbose=1;
  237.          break;
  238.       case 'x' : exfile[numext]= (char *)malloc(strlen(optarg)+1);
  239.          strcpy(exfile[numext++],optarg);
  240.          break;
  241.       default  : usage();
  242.      }
  243.  
  244.   if (argc==1) first=argc;        /* Find first file argument */
  245.   else for (first=1;first<argc;first++)
  246.     if (argv[first][0]!='-') break;
  247.  
  248.   if (first==argc)            /* If no file argument */
  249.    {                    /* use stdin only */
  250.     switch(method)
  251.      {
  252.       case BRUTAL: disembowel();    /* Unshar brutally! */
  253.            break;
  254.       default:       fprintf(stderr,"unshar: Unknown method of unsharing\n");
  255.            exit(1);
  256.       }
  257.    }
  258.   else
  259.    for (i=first;i<argc;i++)    /* open stdio with every file */
  260.    {
  261.     fclose(stdin);
  262.     if ((zin=fopen(argv[i],"r"))==NULL)
  263.       { perror("unshar");
  264.         exit(1);
  265.       }
  266.  
  267.     switch(method)
  268.      {
  269.       case BRUTAL: disembowel();    /* Unshar brutally! */
  270.            break;
  271.       default:       fprintf(stderr,"unshar: Unknown method of unsharing\n");
  272.            exit(1);
  273.       }
  274.    }
  275.   exit(0);
  276.  }
  277.