#include #include #include #include #include #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. * * Feb 1990--Fred C. Smith--Added make_subdir() which * handles shar files which require extracted files to * be inserted into a non-existent sub directory. * * Feb 1990--Fred C. Smith--Added APPEND mode in which unshar * checks for existence of a file before unsharing, and if * already exists it appends to it. Also outputs a message * for each file indicating whether it is creating or * appending (message is output in all modes). * * Jan 2017--Ken Lorber--Minimal changes for modern C and POSIX. */ /* 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 NULL */ 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 */ { static 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(NULL); 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 to skip: ", file); gets (line); if (line[0] != '\0') { zout = fopen (line, openmode); if (zout==NULL) { 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(method) /* Unshar brutally! */ int method; { 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; int fw; /* bugfix: if using cat(1), don't strip leading 'X' (keni) */ switch(fw=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",file); if (verbose) printf(" stopping at %s\n",word); extract(fw==CAT?NOX:YESX,file,word,x,method); } } else printf("%s\n",file); break; default: break; } } } void usage() { fprintf(stderr,"Usage: unshar [-t] [-b] [-v] [-xfile] [file(s)]\n"); exit(0); } int 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= APPEND; /* default used to be BRUTAL */ table= 0; /* Don't generate a table */ verbose=0; /* Nor be very verbose */ numext= 0; /* Initially no files to extract */ while ((c=getopt(argc,argv,"x:tbav"))!=EOF) switch(c) { case 't' : table=1; /* Get the various options */ break; case 'a' : method= APPEND; 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