home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / OS2MNX1.ZIP / UNSHAR2.C < prev    next >
Text File  |  1989-12-08  |  9KB  |  305 lines

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