home *** CD-ROM | disk | FTP | other *** search
- /* $Header: d:/rcs/D:/RCS/RCS/unshar.c 1.2 89/12/08 10:47:50 RCA Exp $
- * $Log: unshar.c $
- * Revision 1.2 89/12/08 10:47:50 RCA
- * Added usage box.
- *
- * Revision 1.1 89/12/08 10:31:58 RCA
- * Initial revision
- *
- */
-
- #include <stdio.h>
- #include "unshar.h"
-
- /*
- * Unshar - extract files from shell archive
- *
- * Written by Warren Toomey. Nov, 1989.
- * You may freely copy or give away this source as
- * long as this notice remains intact.
- *
- */
-
- /* Global variables */
-
- int table; /* Generate a table, or extract */
- int verbose; /* Unshar verbosely - debugging */
- int numext; /* Number of files to extract */
- char *exfile[100]; /* Files to extract */
-
-
- #define getline(x,y) fgetline(stdin,x,y)
-
- int fgetline(zin,how,buf) /* Get a line from a file */
- FILE *zin;
- int how; /* Ignore leading whitespace if */
- char *buf; /* how == NOWHITE */
- {
- int ch=0;
-
- *buf=0; /* Null the buffer */
- if (how==NOWHITE) /* If skip any whitespace */
- {
- while (((ch=fgetc(zin))==' ') || (ch=='\t'));
- if (ch==EOF) return(EOF); /* Returning EOF or 0 */
- if (ch=='\n') return(0);
- *buf++ =ch; /* Put char in buffer */
- }
-
- while ((ch=fgetc(zin))!='\n') /* Now get the line */
- {
- if (ch==EOF) { *buf=0; return(EOF); }
- *buf++ = ch;
- }
-
- *buf=0; /* Finally null-terminate the buffer */
- return(0); /* and return */
- }
-
-
-
- char *getstring(buf) /* Get the next string from the buffer */
- char *buf; /* ignoring any quotes */
- {
- char out[BUFSIZE];
- char *temp=out;
- while ((*buf==' ') || (*buf=='\t')) buf++; /* Skip whitespace */
-
- switch(*buf) /* Now check first char */
- {
- case '\'' : buf++;
- while (*buf!='\'') *temp++ = *buf++;
- *temp=0;
- return(out);
- case '\"' : buf++;
- while (*buf!='\"') *temp++ = *buf++;
- *temp=0;
- return(out);
- case 0 : return(0);
- default : while ((*buf!=' ') && (*buf!='\t'))
- if (*buf!='\\') *temp++ = *buf++;
- else buf++;
- *temp=0;
- return(out);
- }
- }
-
-
- int firstword(buf) /* Return token value of first word */
- char *buf; /* in the buffer. Assume no leading */
- { /* whitespace in the buffer */
- int i;
-
- for (i=1;i<NUMTOKS;i++)
- if (strncmp(buf,token[i],strlen(token[i]))==0)
- return(i);
-
- return(UNKNOWN);
- }
-
-
- int mustget(s1) /* Return 1 if s1 is in the list of */
- char *s1; /* files to extract. Return 0 if not */
- {
- int i;
-
- if (numext==0) return(0);
- for (i=0;i<numext;i++)
- if (!strcmp(s1,exfile[i])) return(1);
- return(0);
- }
-
-
- void extract(how,file,end,lead) /* Extract file, up until end word */
- int how; /* If how==YESX, then ignore lead */
- char *file; /* character on every line */
- char *end;
- int lead;
- {
- FILE *zout;
- char line[BUFSIZE];
- char *temp;
- int ch;
-
- zout=fopen(file,"w"); /* Open output file */
- if (zout==0)
- { perror("unshar");
- return;
- }
-
- while(1)
- {
- ch=getline(WHITE,line); /* Get a line of file */
- temp=line;
- if (ch==EOF)
- { fprintf(zout,"%s\n",line);
- fclose(zout);
- return;
- }
-
- if (strncmp(line,end,strlen(end))==0) /* If end word */
- { fclose(zout); /* close the file */
- return;
- }
-
- if ((how==YESX) && (*temp==lead)) temp++; /* Skip any lead */
- fprintf(zout,"%s\n",temp);
- }
- }
-
-
- void getnames(buf,file,word) /* Get the file & end word */
- char *buf, *file, *word; /* from the buffer */
- {
- char *temp;
-
- temp=buf;
- if (verbose) printf("Getnames: buf is %s\n",buf);
-
- while (*temp!=0) /* Scan along buffer */
- {
- switch(*temp) /* Get file or end word */
- {
- case '>' : strcpy(file,getstring(++temp)); /* Get the file name */
- break;
- case '<' : if (*(++temp)=='<') ++temp; /* Skip 2nd < */
- strcpy(word,getstring(temp)); /* Get next word */
- break;
- default : temp++;
- }
- }
- }
-
-
-
- void disembowel() /* Unshar brutally! */
- {
- char buf[BUFSIZE]; /* Line buffer */
- char file[BUFSIZE]; /* File name */
- char word[BUFSIZE]; /* Word buffer */
- int ch,x;
-
- if (verbose) printf("Entering disembowel\n");
- x='X'; /* Leading X character */
- while(1)
- {
- ch=getline(NOWHITE,buf); /* Get a line from file */
- if (ch==EOF)
- return;
-
- switch(firstword(buf)) /* Extract, depending on first word */
- {
- case CAT:
- case GRES:
- case SED: if (verbose) printf("About to do getnames\n");
- getnames(buf,file,word);
- if (table==0)
- {
- if ((numext==0) || (mustget(file)))
- {
- printf("unshar: Extracting %s\n",file);
- if (verbose)
- printf(" stopping at %s\n",word);
- extract(YESX,file,word,x);
- }
- }
- else printf("%s\n",file);
- break;
- default: break;
- }
- }
- }
-
-
-
- usage()
- {
- printf(" █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ \n");
- printf(" █ Unshar (Un-SHell ARchive UNIX files) $Author: RCA $ █ \n");
- printf(" █ $Date: 89/12/08 10:47:50 $ $Revision: 1.2 $ █ \n");
- printf(" █ Usage: unshar [-t] [-b] [-v] [-xfile] [files(s) █ \n");
- printf(" █ -t Do not extract files, just list the files in █ \n");
- printf(" █ the archive(s). █ \n");
- printf(" █ -b Extract files from the archive(s) brutally, █ \n");
- printf(" █ with no regard at all to things such as █ \n");
- printf(" █ testing if the file exists, etc. Currently █ \n");
- printf(" █ this is the only method supported, but other █ \n");
- printf(" █ methods would be easy to add. █ \n");
- printf(" █ -v Be verbose. Used only for debugging purposes. █ \n");
- printf(" █ -xfile Extract the named file from the shell █ \n");
- printf(" █ archive. If the -x flag is used, only those █ \n");
- printf(" █ files specified will be extracted. █ \n");
- printf(" █ OS: DOS or OS/2 █ \n");
- printf(" █ Credits: Code by Warren Toomey █ \n");
- printf(" █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ \n");
- exit(0);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- extern int optind;
- extern char *optarg;
- int i,c,first;
-
- FILE *zin; /* Dummy file descriptor */
- int method; /* Method of unsharing */
-
- method= BRUTAL; /* Only BRUTAL currently available */
- table= 0; /* Don't generate a table */
- verbose=0; /* Nor be very verbose */
- numext= 0; /* Initially no files to extract */
-
-
- if (argc==1) usage();
- while ((c=getopt(argc,argv,"x:tbv"))!=EOF)
- switch(c)
- {
- case 't' : table=1; /* Get the various options */
- break;
- case 'b' : method= BRUTAL;
- break;
- case 'v' : verbose=1;
- break;
- case 'x' : exfile[numext]= (char *)malloc(strlen(optarg)+1);
- strcpy(exfile[numext++],optarg);
- break;
- default : usage();
- }
-
- if (argc==1) first=argc; /* Find first file argument */
- else for (first=1;first<argc;first++)
- if (argv[first][0]!='-') break;
-
- if (first==argc) /* If no file argument */
- { /* use stdin only */
- switch(method)
- {
- case BRUTAL: disembowel(); /* Unshar brutally! */
- break;
- default: printf("unshar: Unknown method of unsharing\n");
- exit(1);
- }
- }
- else
- for (i=first;i<argc;i++) /* open stdio with every file */
- {
- fclose(stdin);
- if ((zin=fopen(argv[i],"r"))==0)
- { perror("unshar");
- exit(1);
- }
-
- switch(method)
- {
- case BRUTAL: disembowel(); /* Unshar brutally! */
- break;
- default: printf("unshar: Unknown method of unsharing\n");
- exit(1);
- }
- }
- exit(0);
- }
-