os9@cbosgd.att.com (01/30/88)
OS-9 Discussions Friday, January 29th 1988 Volume 4 : Issue 4 Today's Topics: Shar09.shar [MODERATOR'S NOTE: From reader's requests I generally will not distribute sources as part of the digest unless they are reasonably wide usability. I do save any submitted sources and make them available by e-mail (and as long as we don't abuse our privileges of using other people's computers). This seemed of use to all 6809 OS9 users. - JDD] -------------------------------------------------------------------------- From: jimomura@lsuc.UUCP (Jim Omura) Date: Wed, 27-Jan-88 14:22:23 EST Subject: Shar09.shar Summary: 2nd posting -- working Yesterday, I posted 'shar' for 6809 to Usenet in 'comp.sys.m6809'. That version was essentially half working. It was not properly creating Sharfiles, but it was unpacking them fairly well. Today, after a bit more head banging, I finally got it to create Sharfile. I have not tested the minor options, but I'm not really concerned with them. This ends my work porting this program for the time being. As such, I'm sending this version through 'comp.os.os9'. Cheers! -- Jim O. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Shar.doc # Makefile # shar.h # subs.h # shar.c # sh.arch.c # sh.getpat.c # sh.index.c # sh.shar.c # This archive created: # By: Jim Omura () cat << \SHAR_EOF > Shar.doc Revision History: 88/01/27 Ported to OS-9 6809 by Jim Omura. This is a *partially* tested version of Shar. It will create a sharfile and unpack a "shar"files created by itself, the 68K version, and many other Sharfiles, but not all the options have been confirmed. I have noticed that many "variables" have been declared in "constant" form by Wecker, and I've converted some of them. This may be where some problem lies. Look first to converting the declarations in 'shar.h'. Compiler Usage: If you do not have 'make' you will have to add #define OS9 to the top of 'shar.h'. If your 'make' utility defaults to defining OS9, you should remove the '-dOS9' from the CFLAGS variable in the 'makefile'. 87/05/22 Patch by Dieter Stoll to fix 'mkdir' error report. General: This is an early version of Wecker's Shar.c with "first stage" porting to OS-9 68K completed. Use the Unix instructions for now. The code should be redone in some areas for cleaner logic, but has been tested and will create a 'shar' file. Furthermore, it will unpack many types of shar files. The only problem I've uncovered is that it will overwrite existing files without giving an error. Many thanks to Gary Kendall without whom I would have abandonned the effort. Cheers! -- Jim Omura The following are all the instructions I received: Creating a shar file: AMIGA: shar >foo.shar -a makefile *.h *.c VMS: create a batch job that executes: $ shar -a makefile *.h *.c edit the batch .LOG file (which is your shar file) U**X: shar -a makefile *.h *.c >foo.shar (P.S. the -a switch means do all options) Extracting from a shar file: AMIGA: shar -u foo.shar VMS: shar -u foo.shar U**X: shar -u foo.shar or sh foo.shar Installation: NOTE: The following will no longer work because I have broken the program down into smaller source modules. I have included these installation instructions to help in the creation of the necessary 'makefile's. -- Jim O. AMIGA: cc -DAMIGA shar.c ln -o shar shar.o -lc VMS: cc/DEFINE=VMS shar.c link shar,sys$library:vaxcrtl/lib shar :== $dev:[dir]shar U**X: cc -O -DULTRIX -o shar shar.c -lc Just typing "shar" will yield a usage line. (Doc: thanks for the code to base this off of). SHAR_EOF cat << \SHAR_EOF > Makefile # makefile for OS-9 6809 version of 'shar' # # 'sh.index.c' is not used by OS-9 versions CFLAGS = -dOS9 -r CFILES = shar.c sh.arch.c sh.getpat.c sh.shar.c HFILES = /dd/defs/stdio.h /dd/defs/ctype.h /dd/defs/modes.h /dd/defs/time.h RFILES = shar.r sh.arch.r sh.getpat.r sh.shar.r shar: $(RFILES) cc1 $(RFILES) -f=shar -m=1k del c.com $(RFILES): $(HFILES) cc1 $*.c $(CFLAGS) shar.r: shar.c shar.h cc1 shar.c $(CFLAGS) sh.arch.r: sh.arch.c subs.h cc1 sh.arch.c $(CFLAGS) sh.getpat.r: sh.getpat.c subs.h cc1 sh.getpat.c $(CFLAGS) sh.shar.r: sh.shar.c subs.h cc1 sh.shar.c $(CFLAGS) SHAR_EOF cat << \SHAR_EOF > shar.h #include <stdio.h> #ifdef AMIGA #include <exec/types.h> extern char *getenv(),*scdir(),*malloc(),*index(); #endif #ifdef OSK #include <ctype.h> #include <time.h> #include <modes.h> #define void int #define fputc putc extern char *getenv(),*scdir(),*malloc(),*index(); struct sgtbuf timebuf, *tpntr; char datestr[9]; #endif #ifdef OS9 #include <ctype.h> #include <time.h> #include <modes.h> #define void int #define fputc putc extern char *getenv(), *scdir(), *malloc(), *index(); struct sgtbuf timebuf, *tpntr; char datestr[9]; #endif #ifdef ULTRIX #include <sys/types.h> extern char *getenv(),*scdir(),*malloc(),*index(); #endif #ifdef VMS #include <types.h> extern char *getenv(),*scdir(),*malloc(); #endif /* Common Definitions: */ #define BADCH ((int)'?') #define EMSG "" #define rescanopts() (optind = 1) #define SED "sed 's/^%s//'" /* used to remove prefix from lines */ #define USAGE "[-u archive] [[-a] [-p prefix] [-d delim] [-bcv] files > archive]" #define OPTSTRING "u:ap:d:bcv" SHAR_EOF cat << \SHAR_EOF > subs.h /* Subs.h */ /* Note: This file is *not* the same as 'shar.h', but * similar. */ #include <stdio.h> #ifdef AMIGA #include <exec/types.h> extern char *getenv(),*scdir(),*malloc(),*index(); #endif #ifdef OSK #include <ctype.h> #include <time.h> #include <modes.h> #define void int #define fputc putc extern char *getenv(),*scdir(),*malloc(),*index(); struct sgtbuf timebuf, *tpntr; char datestr[9]; #endif #ifdef OS9 #include <ctype.h> #include <time.h> #include <modes.h> #define void int #define fputc putc extern char *getenv(), *scdir(), *malloc(), *index(); extern struct sgtbuf timebuf, *tpntr; extern char datestr[9]; #endif #ifdef ULTRIX #include <sys/types.h> extern char *getenv(),*scdir(),*malloc(),*index(); #endif #ifdef VMS #include <types.h> extern char *getenv(),*scdir(),*malloc(); #endif /* Common Definitions: */ #define BADCH ((int)'?') #define EMSG "" #define rescanopts() (optind = 1) extern int optind, /* index into parent argv vector */ optopt; /* character checked for validity */ extern long fsize; /* length of file */ extern char *optarg; /* argument associated with option */ extern char *sav[100]; /* saved file names */ extern int savind; /* save index */ /* OPTIONS */ extern int Verbose; /* provide append/extract feedback */ extern int Basename; /* extract into basenames */ extern int Count; /* count characters to check transfer */ extern char *Prefix; /* line prefix to avoid funny chars */ extern int UnShar; /* do we unshar an input file? */ #define SED "sed 's/^%s//'" /* used to remove prefix from lines */ #define USAGE "[-u archive] [[-a] [-p prefix] [-d delim] [-bcv] files > archive]" #define OPTSTRING "u:ap:d:bcv" SHAR_EOF cat << \SHAR_EOF > shar.c /* Shar puts readable text files together in a package from which they are easy to extract. v 880127 Jim Omura, BIX First OS-9 6809 port. v 870421 Jim Omura, BIX First OS-9 68K port. v 860712 D. Wecker for ULTRIX and the AMIGA - stripped down.. does patterns but no directories - added a -u (unshar) switch */ #include "shar.h" /* Declare Globals: */ int optind = 1, /* index into parent argv vector */ optopt; /* character checked for validity */ long fsize; /* length of file */ char *optarg; /* argument associated with option */ char *sav[100]; /* saved file names */ int savind; /* save index */ /* OPTIONS */ int Verbose = 0; /* provide append/extract feedback */ int Basename = 0; /* extract into basenames */ int Count = 0; /* count characters to check transfer */ char *Delim; /* put after each file */ char Filter[100]; /* used to extract archived files */ char *Prefix = NULL; /* line prefix to avoid funny chars */ int UnShar = 0; /* do we unshar an input file? */ int main(argc, argv) int argc; char **argv; { /* Declare Local Constants: */ char *def_delim = "SHAR_EOF\0"; /* Default Delim string */ char *def_filt = "cat\0"; /* Default Filter string */ /* Declare Local Variables: */ auto char *ppchFiles[256]; register int C; register char **ppchList; register int errflg; /* Reference the Globals: */ extern char Filter[100]; extern char *Delim; /* Initialize Variables: */ strncpy(Filter,def_filt,4); Delim = def_delim; errflg = 0; **ppchList = ppchFiles; /* This may be wrong -- Jim O. */ while(EOF != (C = getopt(argc, argv, OPTSTRING))) { switch(C) { case 'v': Verbose++; break; case 'c': Count++; break; case 'b': Basename++; break; case 'd': Delim = optarg; break; case 'a': /* all the options */ optarg = "XX"; Verbose++; Count++; Basename++; /* fall through to set prefix */ case 'p': (void) sprintf(Filter, SED, Prefix = optarg); break; case 'u': UnShar++; dounshar(optarg); break; default: errflg++; } } if (UnShar) exit(0); C = getarg(argc, argv); if (errflg || EOF == C) { if (EOF == C) fprintf(stderr, "shar: No input files\n"); fprintf(stderr, "usage: shar %s\n", USAGE); exit(1); } savind = 0; do { if (getpat(optarg)) exit(2); } while (EOF != (C = getarg(argc, argv))); sav[savind] = 0; header(sav); for (ppchList = sav; *ppchList; ++ppchList) shar(*ppchList); puts("#\tEnd of shell archive"); puts("exit 0"); exit(0); } /* * get option letter from argument vector */ int getopt(nargc, nargv, ostr) int nargc; char **nargv, *ostr; { register char *oli; /* option letter list index */ static char *place = EMSG; /* option letter processing */ if(!*place) { /* update scanning pointer */ if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF); if (*place == '-') { /* found "--" */ ++optind; return EOF; } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) { if(!*place) ++optind; tell(*nargv,": illegal option -- "); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) { /* no white space */ optarg = place; } else if (nargc <= ++optind) { /* no arg */ place = EMSG; tell(*nargv,": option requires an argument -- "); } else { optarg = nargv[optind]; /* white space */ } place = EMSG; ++optind; } return optopt; /* dump back option letter */ } /* End of getopt() */ int getarg(nargc, nargv) int nargc; char **nargv; { if (nargc <= optind) { optarg = (char *) 0; return EOF; } else { optarg = nargv[optind++]; return 0; } } /* End of getarg() */ dounshar(ArcNam) char *ArcNam; { register int i,j; register FILE *inptr,*outptr; auto char line[BUFSIZ]; int DirNum = -1; int Prefix = 0; char Dirs[5][40],FilNam[128],Delim[40],ScrStr[128]; char *ptr; if (!(inptr = fopen(ArcNam,"r"))) { fprintf(stderr,"shar: Can't open archive '%s'\n", ArcNam); return; } while (fgets(line,BUFSIZ,inptr)) { if (strncmp(line,"sed ",4) == 0) { Prefix = 0; if (!(ptr = index(line,'/'))) goto getfil; if (*++ptr == '^') ++ptr; while (*ptr++ != '/') Prefix++; goto getfil; } else if (strncmp(line,"cat ",4) == 0) { Prefix = 0; ; getfil: #ifdef VMS strcpy(FilNam,"["); #else FilNam[0] = 0; #endif for (i = 0; i <= DirNum; i++) { #ifdef VMS strcat(FilNam,"."); strcat(FilNam,Dirs[i]); #else strcat(FilNam,Dirs[i]); strcat(FilNam,"/"); #endif } #ifdef VMS strcat(FilNam,"]"); #endif getshpar(line, ">", ScrStr); strcat(FilNam,ScrStr); getshpar(line,"<<",Delim); fprintf(stderr,"Creating %s ...",FilNam); outptr = fopen(FilNam,"w"); while (fgets(line,BUFSIZ,inptr)) { if (strncmp(line,Delim,strlen(Delim)) == 0) break; if (outptr) fputs(&line[Prefix],outptr); } if (outptr) { fclose(outptr); fprintf(stderr,"...done\n"); } else fprintf(stderr,"...error in creating file\n"); } else if (strncmp(line,"mkdir ",6) == 0) { fprintf(stderr,"Need to make directory: %s\n",&line[6]); } else if (strncmp(line,"chdir ",6) == 0) { if (line[6] == '.' && line[7] == '.') DirNum--; else strcpy(Dirs[++DirNum],&line[6]); if (DirNum < -1) DirNum = -1; } else if (strncmp(line,"cd ",3) == 0) { if (line[3] == '.' && line[4] == '.') DirNum--; else strcpy(Dirs[++DirNum],&line[3]); if (DirNum < -1) DirNum = -1; } } fclose(inptr); } /* End of dounshar() */ getshpar(line,sea,par) char *line,*sea,*par; { register int i,j,k; register char *scr1,*scr2; while (*line) { scr1 = line; scr2 = sea; while (*scr1 && *scr2 && *scr1 == *scr2) { scr1++; scr2++; } if (*scr2 == 0) { if (*scr1 == 0) { *par = 0; return; } while ( *scr1 == ' ' || *scr1 == '\t' || *scr1 == '\\' || *scr1 == '\'' || *scr1 == '"') scr1++; while ( *scr1 != 0 && *scr1 != ' ' && *scr1 != '\t' && *scr1 != '\\' && *scr1 != '\'' && *scr1 != '"' && *scr1 != '\n' && *scr1 != '\r') *par++ = *scr1++; *par = 0; return; } line++; } *par = 0; } /* End of getshpar() */ /* tell() */ int tell(nargv,s) char *nargv; char *s; { fputs(nargv,stderr); fputs((s),stderr); fputc(optopt,stderr); fputc('\n',stderr); return(BADCH); } /* End of tell() */ /* ctime() */ /* #ifdef OSK char *ctime() { struct timestruct { char cyear, cmonth, cday, chour, cmin, csec; }; /* Do something */ /* timestruct.t_year,timestruct.t_month,timestruct.t_day */ /* return(*datestr); } /* #endif /* End of Shar.c */ SHAR_EOF cat << \SHAR_EOF > sh.arch.c /* sh.arch.c */ #include "subs.h" /* header() */ int header(ppchFiles) char *ppchFiles[]; { extern char *ctime(); register int i; auto long clock; register int problems = 0; register char **ppchList; register char *pchOrg = ""; /* getenv("ORGANIZATION"); */ register char *pchName = "Jim Omura"; /* getenv("NAME"); */ puts("#\tThis is a shell archive."); puts("#\tRemove everything above and including the cut line."); puts("#\tThen run the rest of the file through sh."); puts("#----cut here-----cut here-----cut here-----cut here----#"); puts("#!/bin/sh"); puts("# shar: Shell Archiver"); puts("#\tRun the following text with /bin/sh to create:"); for (ppchList = ppchFiles; *ppchList; ++ppchList) printf("#\t%s\n", *ppchList); #ifdef OSK getime(&timebuf); /* Finish this later--Jim O. */ /* printf("# This archive created: %s\n",ctime()); /* No Ctime() */ #endif #ifdef OS9 printf("# This archive created: \n"); /* No time yet */ #endif #ifdef AMIGA (void) time(& clock); printf("# This archive created: %s", ctime(&clock)); #endif if (pchName) printf("# By:\t%s (%s)\n", pchName, pchOrg ? pchOrg : "JO"); return(0); } /* End of header() */ /* archive() */ int archive(input, output) char *input, *output; { extern char Filter[100]; extern char *Delim; auto char line[BUFSIZ]; register FILE *ioptr; ioptr = fopen(input, "r"); if (ioptr != 0) { printf("%s << \\%s > %s\n", Filter, Delim, input); while(fgets(line, BUFSIZ, ioptr)) { if (Prefix) { fputs(Prefix, stdout); } fputs(line, stdout); if (Count) { fsize += strlen(line); } } /* End while */ fputs(Delim, stdout); fputc('\n', stdout); fclose(ioptr); return(0); } else { fprintf(stderr, "shar: Can't open '%s'\n", input); return(1); } } /* End of archive() */ SHAR_EOF cat << \SHAR_EOF > sh.getpat.c /* sh.getpat.c */ #include "subs.h" getpat(pattern) char *pattern; { register char *ptr; #ifdef AMIGA while (ptr = scdir(pattern)) { #else ptr = pattern; { #endif sav[savind] = malloc(strlen(ptr)+1); strcpy(sav[savind++],ptr); #ifdef OSK if (access(ptr,S_IOREAD) || access(ptr,S_IREAD)) { /* The logic here is mucked up. Change it later.--Jim O. */ } else { #endif #ifdef OS9 if ((access(ptr,S_IOREAD)==0) || (access(ptr,S_IREAD)==0)) { /* do continue */ } else { #endif #ifdef AMIGA /* *** This option for everything *except OS-9 versions -- Jim O. */ if (access(ptr,4)) { #endif printf("No read access for file: %s\n",ptr); return(-1); } } return(0); } /* End of getpat() */ SHAR_EOF cat << \SHAR_EOF > sh.index.c /* sh.index.c */ /* Part of Shar.c * * Only for VMS version */ #ifdef VMS char *index(s,c) char *s; char c; { while (*s != 0 && *s != c) s++; if (*s == 0 && *s != c) s = 0; return(s); } /* end of index() */ #endif SHAR_EOF cat << \SHAR_EOF > sh.shar.c /* sh.shar.c */ #include "subs.h" void shar(file) char *file; { register char *basefile; *basefile = file; /* This looks wrong?? -- Jim O */ if (!strcmp(file, ".")) { return; } fsize = 0; if (Basename) { while(*basefile) { basefile++; /* go to end of name */ } while(basefile > file && *(basefile-1) != '/') { basefile--; } } if (Verbose) { printf("echo shar: extracting %s\n", basefile); } if (archive(file, basefile)) { exit(66); } if (Count) { printf("if test %ld -ne \"`wc -c %s`\"\n",fsize,basefile); printf("then\necho shar: error transmitting %s ",basefile); printf("'(should have been %ld characters)'\nfi\n",fsize); } } /* end of shar() */ /* End of sh.shar.c */ SHAR_EOF # End of shell archive exit 0 -- Jim Omura, 2A King George's Drive, Toronto, (416) 652-3880 ihnp4!utzoo!lsuc!jimomura Byte Information eXchange: jimomura ------------------------------------- The views expressed in OS-9 Discussions are those of the individual authors only. Copies of digests are available by mail request. ------ Moderator: John Daleske cbosgd!cbdkc1!daleske daleske@cbdkc1.ATT.COM Submissions should go to: cbosgd!os9 os9@cbosgd.ATT.COM Comments to the moderator cbosgd!os9-request os9-request@cbosgd.ATT.COM ********************* End of OS-9 Discussions *********************