wht@n4hgf.Mt-Park.GA.US (Warren Tucker) (07/15/90)
Submitted-by: wht@n4hgf.Mt-Park.GA.US Archive-name: shar332/part02 #!/bin/sh # This is part 02 of shar332 # ============= unshar.c ============== echo "x - extracting unshar.c (Text)" sed 's/^X//' << 'SHAR_EOF' > unshar.c && Xchar *revision = "3.30"; X/**************************************************************** X * unshar.c: Unpackage one or more shell archive files X * X * Usage: unshar [-c] [-C exit_line] [ -d directory ] [ file ] ... X * X * Description: unshar is a filter which removes the front part X * of a file and passes the rest to the 'sh' command. X * It understands phrases like "cut here", and also X * knows about shell comment characters and the Unix X * commands "echo", "cat", and "sed". X * X * It can unshar shar files concatenated in one file, with the X * the "-c" command, which separates files by recognizing the X * "exit 0" string at the beginning of a line X * X * (The -C string option allows you to specify this string, thus X * -c is equivalent to -C "exit 0") X * X * The -d flag tells unshar to change directory before unsharing X * X * HISTORY X * 19-Apr-90 Colas Nahaboo (colas@mirsa.inria.fr) X * added -c and -C flags to read from concatenated archives X * 1-Feb-85 Guido van Rossum (guido@mcvax) at CWI, Amsterdam X * Added missing 'quit' routine; X * added -d flag to change to directory first; X * added filter mode (read stdin when no arguments); X * added 'getopt' to get flags (makes it self-contained). X * 29-Jan-85 Michael Mauldin (mlm) at Carnegie-Mellon University X * Created. X ****************************************************************/ X/*+:EDITS:*/ X/*:05-05-1990-01:37-relay.EU.net!rivm!a3-dont assume vax is running BSD */ X/*:04-19-1990-15:20-wht@n4hgf-fix so -d doesnt make argv files unreachable */ X/*:04-19-1990-15:06-wht@n4hgf-colas@mirsa patches had expanded tabs */ X/*:04-10-1990-22:02-wht@n4hgf-stdin failed sometimes-can not seek on pipe */ X X#include <stdio.h> X#define EOL '\n' X X#if (defined(pyr) || defined(sun) || defined(BSD42) || \ X defined(vax) || defined(sequent)) && !defined(SYS5) X#define strchr index X#undef USE_GETCWD Xchar *getwd(); X#else X#define USE_GETCWD Xchar *getcwd(); X#endif X Xchar *strchr(); X Xextern char *optarg; Xextern int optind; X Xint continue_reading = 0; Xchar *exit_string = "exit 0"; Xint exit_string_length; Xchar argvdir[1024]; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int i,ch; X FILE *in; X char s1024[1024]; X X setbuf(stdout,NULL); X setbuf(stderr,NULL); X X#ifdef USE_GETCWD X if(!getcwd(argvdir,sizeof(argvdir))) X { X perror("cannot get current directory name"); X exit(1); X } X#else X argvdir[0] = 0; X if(!getwd(argvdir)) X { X if(argvdir[0]) X fprintf(stderr,"%s\n",argvdir); X else X printf(stderr,"cannot get current directory name\n"); X exit(1); X } X#endif X X X /* Process options */ X X while((ch = getopt(argc,argv,"d:cC:")) != EOF) X { X switch(ch) X { X case 'd': X if(chdir(optarg) == -1) X { X fprintf(stderr,"unshar: cannot chdir to '%s'\n",optarg); X exit(2); X } X break; X case 'C': X exit_string = optarg; X case 'c': X continue_reading = 1; X exit_string_length = strlen(exit_string); X break; X default: X quit(2,"Usage: unshar [-d directory] [file] ...\n"); X } X } X X if(optind < argc) X { X for(i= optind; i < argc; ++i) X { X if(argv[i][0] == '/') { X strcpy(s1024,argv[i]); X } else { X strcpy(s1024,argvdir); X strcat(s1024,"/"); X strcat(s1024,argv[i]); X } X if(!(in = fopen(s1024,"r"))) X { X perror(s1024); X exit(1); X } X process(s1024,in); X fclose(in); X } X } X else X { X sprintf(s1024,"/tmp/unsh.%05d",getpid()); X unlink(s1024); X if(!(in = fopen(s1024,"w+"))) X { X fprintf(stderr,"cannot open temp file '%s'\n",s1024); X exit(1); X } X unlink(s1024); /* don't try this with MSDOS, sports fans */ X while(i = fread(s1024,1,sizeof(s1024),stdin)) X fwrite(s1024,i,1,in); X rewind(in); X process("standard input",in); X fclose(in); X } X X exit(0); X} X X Xprocess(name,in) Xchar *name; XFILE *in; X{ X char buffer[8196]; X char ch; X FILE *shpr,*popen(); X long current_position = 0; X char *more_to_read = 0; X X while(position(name,in,current_position)) X { X printf("%s:\n",name); X if(!(shpr = popen("sh","w"))) X quit(1,"unshar: cannot open 'sh' process\n"); X X if (!continue_reading) { X while((ch = fgetc(in)) != EOF) X fputc(ch,shpr); X pclose(shpr); X break; X } else { X while (more_to_read = fgets(buffer, 8196, in)) { X fputs(buffer, shpr); X if (!strncmp(exit_string, buffer, exit_string_length)) { X break; X } X } X pclose(shpr); X if (more_to_read) X current_position = ftell(in); X else { X break; X } X } X } X} X X/**************************************************************** X * position: position 'fil' at the start of the shell command X * portion of a shell archive file. X ****************************************************************/ X Xposition(fn,fil,start) Xchar *fn; XFILE *fil; Xlong start; /* scan file from position */ X{ X char buf[BUFSIZ]; X long pos,ftell(); X X /* Results from star matcher */ X static char res1[BUFSIZ],res2[BUFSIZ],res3[BUFSIZ],res4[BUFSIZ]; X static char *result[] = X { X res1,res2,res3,res4 }; X X fseek(fil, start, 0); X X while(1) X { /* Record position of the start of this line */ X pos = ftell(fil); X X /* Read next line, fail if no more and no previous process */ X if(!fgets(buf,BUFSIZ,fil)) X { X if(!start) X fprintf(stderr,"unshar: found no shell commands in %s\n",fn); X return(0); X } X X /* Bail out if we see C preprocessor commands or C comments */ X if(stlmatch(buf,"#include") || stlmatch(buf,"# include") || X stlmatch(buf,"#define") || stlmatch(buf,"# define") || X stlmatch(buf,"#ifdef") || stlmatch(buf,"# ifdef") || X stlmatch(buf,"#ifndef") || stlmatch(buf,"# ifndef") || X stlmatch(buf,"/*")) X { X fprintf(stderr, X "unshar: %s looks like raw C code, not a shell archive\n",fn); X return(0); X } X X /* Does this line start with a shell command or comment */ X if(stlmatch(buf,"#") || stlmatch(buf,":") || X stlmatch(buf,"echo ") || stlmatch(buf,"sed ") || X stlmatch(buf,"cat ") || stlmatch(buf,"if ")) X { X fseek(fil,pos,0); X return(1); X } X X /* Does this line say "Cut here" */ X if(smatch(buf,"*CUT*HERE*",result) || X smatch(buf,"*cut*here*",result) || X smatch(buf,"*TEAR*HERE*",result) || X smatch(buf,"*tear*here*",result) || X smatch(buf,"*CUT*CUT*",result) || X smatch(buf,"*cut*cut*",result)) X { X /* Read next line after "cut here", skipping blank lines */ X while(1) X { X pos = ftell(fil); X X if(!fgets(buf,BUFSIZ,fil)) X { X fprintf(stderr, X "unshar: found no shell commands after 'cut' in %s\n",fn); X return(0); X } X X if(*buf != '\n') break; X } X X /* Win if line starts with a comment character of lower case letter */ X if(*buf == '#' || *buf == ':' || (('a' <= *buf) && ('z' >= *buf))) X { X fseek(fil,pos,0); X return(1); X } X X /* Cut here message lied to us */ X fprintf(stderr,"unshar: %s is probably not a shell archive,\n",fn); X fprintf(stderr," the 'cut' line was followed by: %s",buf); X return(0); X } X } X} X X/***************************************************************** X * stlmatch -- match leftmost part of string X * X * Usage: i = stlmatch (big,small) X * int i; X * char *small, *big; X * X * Returns 1 iff initial characters of big match small exactly; X * else 0. X * X * HISTORY X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University X * Ripped out of CMU lib for Rog-O-Matic portability X * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University X * Rewritten for VAX from Ken Greer's routine. X * X * Originally from klg (Ken Greer) on IUS/SUS UNIX X *****************************************************************/ X Xint stlmatch(big,small) Xchar *small,*big; X{ X register char *s,*b; X s = small; X b = big; X do X { X if(*s == '\0') X return(1); X } while(*s++ == *b++); X return(0); X} X X/***************************************************************** X * smatch: Given a data string and a pattern containing one or X * more embedded stars (*) (which match any number of characters) X * return true if the match succeeds, and set res[i] to the X * characters matched by the 'i'th *. X *****************************************************************/ X Xsmatch(dat,pat,res) Xregister char *dat,*pat,**res; X{ X register char *star = 0,*starend,*resp; X int nres = 0; X X while(1) X { X if(*pat == '*') X { X star = ++pat; /* Pattern after * */ X starend = dat; /* Data after * match */ X resp = res[nres++]; /* Result string */ X *resp = '\0'; /* Initially null */ X } X else if(*dat == *pat) /* Characters match */ X { X if(*pat == '\0') /* Pattern matches */ X return(1); X pat++; /* Try next position */ X dat++; X } X else X { X if(*dat == '\0') /* Pattern fails - no more */ X return(0); /* data */ X if(star == 0) /* Pattern fails - no * to */ X return(0); /* adjust */ X pat = star; /* Restart pattern after * */ X *resp++ = *starend; /* Copy character to result */ X *resp = '\0'; /* null terminate */ X dat = ++starend; /* Rescan after copied char */ X } X } X} X X/***************************************************************** X * Addendum: quit subroutine (print a message and exit) X *****************************************************************/ X Xquit(status,message) Xint status; Xchar *message; X{ X fprintf(stderr,message); X exit(status); X} X X/***************************************************************** X * Public Domain getopt routine X *****************************************************************/ X X/* X * get option letter from argument vector X */ Xint opterr = 1; /* useless, never set or used */ Xint optind = 1; /* index into parent argv vector */ Xint optopt; /* character checked for validity */ Xchar *optarg; /* argument associated with option */ X X#define BADCH (int)'?' X#define EMSG "" X#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \ X fputc(optopt,stderr);fputc('\n',stderr);return(BADCH); X Xgetopt(nargc,nargv,ostr) Xint nargc; Xchar **nargv,*ostr; X{ X static char *place = EMSG; /* option letter processing */ X register char *oli; /* option letter list index */ X char *strchr(); X X if(!*place) X { /* update scanning pointer */ X if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) X return(EOF); X if(*place == '-') X { /* found "--" */ X ++optind; X return(EOF); X } X } /* option letter okay? */ X if((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) X { X if(!*place) ++optind; X tell(": illegal option -- "); X } X if(*++oli != ':') X { /* don't need argument */ X optarg = (char *)0; X if(!*place) ++optind; X } X else X { /* need an argument */ X if(*place) optarg = place; /* no white space */ X else if(nargc <= ++optind) X { /* no arg */ X place = EMSG; X tell(": option requires an argument -- "); X } X else optarg = nargv[optind]; /* white space */ X place = EMSG; X ++optind; X } X return(optopt); /* dump back option letter */ X} X/* vi: set tabstop=4 shiftwidth=4: */ SHAR_EOF # ============= uushar.c ============== echo "x - extracting uushar.c (Text)" sed 's/^X//' << 'SHAR_EOF' > uushar.c && X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X X/* ENC is the basic 1 character encoding function to make a char printing */ X#define ENC(c) ((((c) & 077) + ' ') | ((c & 077) == 0 ? 0100 : 0)) X Xencode (in, out) X FILE *in; X FILE *out; X{ X char buf[80]; X int i, n; X X for (;;) X { X /* 1 (up to) 45 character line */ X n = fr (in, buf, 45); X putc (ENC (n), out); X X for (i = 0; i < n; i += 3) X outdec (&buf[i], out); X X putc ('\n', out); X if (n <= 0) X break; X } X} X X/* X * output one group of 3 bytes, pointed at by p, on file f. X */ Xoutdec (p, f) X char *p; X FILE *f; X{ X int c1, c2, c3, c4; X X c1 = *p >> 2; X c2 = (*p << 4) & 060 | (p[1] >> 4) & 017; X c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03; X c4 = p[2] & 077; X putc (ENC (c1), f); X putc (ENC (c2), f); X putc (ENC (c3), f); X putc (ENC (c4), f); X} X X/* fr: like read but stdio */ Xint X fr (fp, buf, cnt) X FILE *fp; X char *buf; X int cnt; X{ X int c, i; X X for (i = 0; i < cnt; i++) X { X c = getc (fp); X if (c == EOF) X return (i); X buf[i] = c; X } X return (cnt); X} X/* vi: set tabstop=4 shiftwidth=4: */ SHAR_EOF # ============= who@where.c ============== echo "x - extracting who@where.c (Text)" sed 's/^X//' << 'SHAR_EOF' > who@where.c && X/*+------------------------------------------------------------------------- X who@where.c - find out who i am & where i am X ...!gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu) X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:04-03-1990-19:55-wht@n4hgf-get rid of complicated who_am_i */ X/*:04-01-1990-13:30-pat@rwing-use utsname.nodename instead of sysname */ X/*:04-02-1990-12:12-wht@n4hgf-sigh... some pwd.h dont declare functions */ X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */ X/*:03-28-1990-15:24-wht@n4hgf-creation */ X X#include <stdio.h> X#include <sys/types.h> X#include <pwd.h> X X/* assume system v unless otherwise fixed */ X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42) && !defined(SYS5) X#define BSD42 X#endif X#if defined(sun) /* this miscreant doesn't exactly fit BSD or SYSV */ X#undef BSD42 X#undef SYS5 X#endif X#if !defined(BSD42) && !defined(sun) && !defined(SYS5) X#define SYS5 X#endif X X#if defined(sun) || defined(BSD42) X#define strchr index X#define strrchr rindex X#endif X X#if !defined(SYS5) || defined(sun) X#include <sys/time.h> Xextern int errno; X#else X#include <sys/utsname.h> X#include <time.h> X#endif /* system dependencies */ X X/*+------------------------------------------------------------------------- X who_am_i() - get user name X--------------------------------------------------------------------------*/ Xchar * Xwho_am_i() X{ X struct passwd *getpwuid(); X struct passwd *passwd; X passwd = getpwuid(getuid()); X (void)endpwent(); X if(passwd == (struct passwd *)0) X return("???"); X return(passwd->pw_name); X X} /* end of who_am_i */ X X/*+------------------------------------------------------------------------- X where_am_i() - do uname, gethostname, or read file (/etc/systemid) X--------------------------------------------------------------------------*/ Xchar * Xwhere_am_i() X{ X#if defined(M_SYS5) /* SCO UNIX or XENIX */ XFILE *fpsid = fopen("/etc/systemid","r"); Xstatic char s20[20]; X if(!fpsid) X return("???"); X fgets(s20,sizeof(s20),fpsid); X fclose(fpsid); X s20[strlen(s20) - 1] = 0; X return(s20); X#else /* M_SYS5 */ X#if defined(SYS5) Xstatic struct utsname where_i_am; X uname(&where_i_am); X return(where_i_am.nodename); X#else /* SYS5 */ Xstatic char where_i_am[64]; X gethostname(where_i_am,sizeof(where_i_am)); X return(where_i_am); X#endif /* SYS5 */ X#endif /* M_SYS5 */ X} /* end of where_am_i */ X X/*+------------------------------------------------------------------------- X who_where(buf) X--------------------------------------------------------------------------*/ Xchar * Xwho_where(buf) Xchar *buf; X{ Xstatic char ww[64]; X X if(!buf) X buf = ww; X strcpy(buf,who_am_i()); X strcat(buf,"@"); X strcat(buf,where_am_i()); X} /* end of who_where */ X X/* vi: set tabstop=4 shiftwidth=4: */ X/* end of who@where.c */ SHAR_EOF exit 0 -------------------------------------------------------------------- Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US Sforzando (It., sfohr-tsahn'-doh). A direction to perform the tone or chord with special stress, or marked and sudden emphasis.