Path: utzoo!utgpu!watmath!uunet!xanth!galaxia!lazlo!gizzmo!fthood!egray From: egray@fthood.UUCP Newsgroups: unix-pc.sources Subject: Arc v5.21 (3 of 6) Message-ID: <6800097@fthood> Date: 1 Jan 89 19:39:00 GMT Lines: 1843 Nf-ID: #N:fthood:6800097:000:48711 Nf-From: fthood.UUCP!egray Jan 1 13:39:00 1989 This is part 3 (of 6) to the Arc v5.21 distribution package. Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV Directorate of Engineering & Housing Environmental Management Office Fort Hood, TX 76544-5057 ------------------------------------------------------------------------------ #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # arcadd.c # arccode.c # arccvt.c # arcdata.c # arcdel.c # arcdos.c # arcext.c # arcio.c # arclst.c # This archive created: Sun Jan 1 12:48:17 1989 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'arcadd.c'" '(12955 characters)' if test -f 'arcadd.c' then echo shar: "will not over-write existing file 'arcadd.c'" else sed 's/^X//' << \SHAR_EOF > 'arcadd.c' X/* X * $Header: arcadd.c,v 1.10 88/11/16 17:43:25 hyc Exp $ X */ X X/* X * ARC - Archive utility - ARCADD X * X * Version 3.40, created on 06/18/86 at 13:10:18 X * X * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains the routines used to add files to an archive. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X#if MTS X#include X#endif X Xstatic int addfile(); Xchar *strcpy(); Xint strcmp(), strlen(), free(), readhdr(), unlink(); X#if UNIX Xint izadir(); X#endif Xvoid writehdr(), filecopy(), getstamp(); Xvoid pack(), closearc(), openarc(), abort(); X Xvoid Xaddarc(num, arg, move, update, fresh) /* add files to archive */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ Xint move; /* true if moving file */ Xint update; /* true if updating */ Xint fresh; /* true if freshening */ X{ X char *d, *dir(); /* directory junk */ X char buf[STRLEN]; /* pathname buffer */ X char **path; /* pointer to pointers to paths */ X char **name; /* pointer to pointers to names */ X int nfiles = 0; /* number of files in lists */ X int notemp; /* true until a template works */ X int nowork = 1; /* true until files are added */ X char *i, *rindex(); /* string indexing junk */ X char *malloc(), *realloc(); /* memory allocators */ X int n; /* index */ X#ifdef LOCAL X extern int unix_names; X#endif /* LOCAL */ X#if MSDOS X unsigned int coreleft(); /* remaining memory reporter */ X#endif X int addbunch(); X X if (num < 1) { /* if no files named */ X num = 1; /* then fake one */ X#if DOS X arg[0] = "*.*"; /* add everything */ X#endif X#if UNIX X arg[0] = "*"; X#endif X#if MTS X arg[0] = "?"; X#endif X } X path = (char **) malloc(sizeof(char **)); X name = (char **) malloc(sizeof(char **)); X X X for (n = 0; n < num; n++) { /* for each template supplied */ X strcpy(buf, arg[n]); /* get ready to fix path */ X#if !MTS X if (!(i = rindex(buf, '\\'))) X if (!(i = rindex(buf, '/'))) X if (!(i = rindex(buf, ':'))) X i = buf - 1; X#else X if (!(i = rindex(buf, sepchr[0]))) X if (buf[0] != tmpchr[0]) X i = buf - 1; X else X i = buf; X#endif X i++; /* pointer to where name goes */ X X notemp = 1; /* reset files flag */ X for (d = dir(arg[n]); d; d = dir(NULL)) { X notemp = 0; /* template is giving results */ X nfiles++; /* add each matching file */ X path = (char **) realloc(path, nfiles * sizeof(char **)); X name = (char **) realloc(name, nfiles * sizeof(char **)); X strcpy(i, d); /* put name in path */ X path[nfiles - 1] = malloc(strlen(buf) + 1); X strcpy(path[nfiles - 1], buf); X name[nfiles - 1] = d; /* save name */ X#if LOCAL X /* make it a MSDOS file name */ X if (!unix_names) { X if (legalize(path[nfiles-1], name[nfiles-1])) { X nfiles--; X continue; X } X } X#endif /* LOCAL */ X#if MSDOS X if (coreleft() < 5120) { X nfiles = addbunch(nfiles, path, name, move, update, fresh); X nowork = nowork && !nfiles; X while (nfiles) { X free(path[--nfiles]); X free(name[nfiles]); X } X free(path); X free(name); X path = name = NULL; X } X#endif X } X if (notemp && warn) X printf("No files match: %s\n", arg[n]); X } X X if (nfiles) { X nfiles = addbunch(nfiles, path, name, move, update, fresh); X nowork = nowork && !nfiles; X while (nfiles) { X free(path[--nfiles]); X free(name[nfiles]); X } X free(path); X free(name); X } X if (nowork && warn) X printf("No files were added.\n"); X} X Xint Xaddbunch(nfiles, path, name, move, update, fresh) /* add a bunch of files */ X int nfiles; /* number of files to add */ X char **path; /* pointers to pathnames */ X char **name; /* pointers to filenames */ X int move; /* true if moving file */ X int update; /* true if updating */ X int fresh; /* true if freshening */ X{ X int m, n; /* indices */ X char *d; /* swap pointer */ X struct heads hdr; /* file header data storage */ X X for (n = 0; n < nfiles - 1; n++) { /* sort the list of names */ X for (m = n + 1; m < nfiles; m++) { X if (strcmp(name[n], name[m]) > 0) { X d = path[n]; X path[n] = path[m]; X path[m] = d; X d = name[n]; X name[n] = name[m]; X name[m] = d; X } X } X } X X for (n = 0; n < nfiles - 1;) { /* consolidate the list of names */ X if (!strcmp(path[n], path[n + 1]) /* if duplicate names */ X ||!strcmp(path[n], arcname) /* or this archive */ X#if UNIX X ||izadir(path[n]) /* or a directory */ X#endif X ||!strcmp(path[n], newname) /* or the new version */ X ||!strcmp(path[n], bakname)) { /* or its backup */ X free(path[n]); /* then forget the file */ X free(name[n]); X for (m = n; m < nfiles - 1; m++) { X path[m] = path[m + 1]; X name[m] = name[m + 1]; X } X nfiles--; X } else X n++; /* else test the next one */ X } X X if (!strcmp(path[n], arcname) /* special check for last file */ X ||!strcmp(path[n], newname) /* courtesy of Rick Moore */ X#if UNIX X ||izadir(path[n]) X#endif X || !strcmp(path[n], bakname)) { X free(path[n]); X free(name[n]); X nfiles--; X } X if (!nfiles) /* make sure we got some */ X return 0; X X for (n = 0; n < nfiles - 1; n++) { /* watch out for duplicate X * names */ X#ifdef LOCAL X if (!strcmp(name[n], name[n + 1])) { X printf("Duplicate filenames: %s %s\n", path[n], path[n+1]); X printf("Skipping filename: %s\n", path[n+1]); X free(path[n+1]); X free(name[n+1]); X for (m = n+1; m < nfiles-1 ; m++) { X path[m] = path[m+1]; X name[m] = name[m+1]; X } X nfiles--; X } X#else /* LOCAL */ X if (!strcmp(name[n], name[n + 1])) X abort("Duplicate filenames:\n %s\n %s", path[n], path[n + 1]); X#endif /* LOCAL */ X } X openarc(1); /* open archive for changes */ X X for (n = 0; n < nfiles;) { /* add each file in the list */ X if (addfile(path[n], name[n], update, fresh) < 0) { X free(path[n]); /* remove this name if */ X free(name[n]); /* it wasn't added */ X for (m = n; m < nfiles-1 ; m++) { X path[m] = path[m+1]; X name[m] = name[m+1]; X } X nfiles--; X } else n++; X } X X /* now we must copy over all files that follow our additions */ X X while (readhdr(&hdr, arc)) { /* while more entries to copy */ X writehdr(&hdr, new); X filecopy(arc, new, hdr.size); X } X hdrver = 0; /* archive EOF type */ X writehdr(&hdr, new); /* write out our end marker */ X closearc(1); /* close archive after changes */ X X if (move) { /* if this was a move */ X for (n = 0; n < nfiles; n++) { /* then delete each file X * added */ X if (unlink(path[n]) && warn) { X printf("Cannot unsave %s\n", path[n]); X nerrs++; X } X } X } X return nfiles; /* say how many were added */ X} X Xstatic int Xaddfile(path, name, update, fresh) /* add named file to archive */ X char *path; /* path name of file to add */ X char *name; /* name of file to add */ X int update; /* true if updating */ X int fresh; /* true if freshening */ X{ X struct heads nhdr; /* data regarding the new file */ X struct heads ohdr; /* data regarding an old file */ X FILE *f, *fopen(); /* file to add, opener */ X long starts, ftell(); /* file locations */ X int upd = 0;/* true if replacing an entry */ X#ifdef LOCAL X void upper(); X#endif /* LOCAL */ X X#if !MTS X if (!(f = fopen(path, OPEN_R))) X#else X if (image) X f = fopen(path, "rb"); X else X f = fopen(path, "r"); X if (!f) X#endif X { X if (warn) { X printf("Cannot read file: %s\n", path); X nerrs++; X } X return(-1); X } X#if !DOS X if (strlen(name) >= FNLEN) { X if (warn) { X char buf[STRLEN]; X printf("WARNING: File %s name too long!\n", name); X name[FNLEN-1]='\0'; X while(1) { X printf(" Truncate to %s (y/n)? ", name); X fflush(stdout); X fgets(buf, STRLEN, stdin); X *buf = toupper(*buf); X if (*buf == 'Y' || *buf == 'N') X break; X } X if (*buf == 'N') { X printf("Skipping...\n"); X fclose(f); X return(-1); X } X } X else { X if (note) X printf("Skipping file: %s - name too long.\n", X name); X fclose(f); X return(-1); X } X } X#endif X#ifdef LOCAL X upper(name); X#endif /* LCOAL */ X strcpy(nhdr.name, name);/* save name */ X nhdr.size = 0; /* clear out size storage */ X nhdr.crc = 0; /* clear out CRC check storage */ X#if !MTS X getstamp(f, &nhdr.date, &nhdr.time); X#else X { X char *buffer, *malloc(); X int inlen; X struct GDDSECT *region; X X region=gdinfo(f->_fd._fdub); X inlen=region->GDINLEN; X buffer=malloc(inlen); /* maximum line length */ X setbuf(f,buffer); X f->_bufsiz=inlen; X f->_mods|=_NOIC; /* Don't do "$continue with" */ X f->_mods&=~_IC; /* turn it off, if set... */ X } X getstamp(path, &nhdr.date, &nhdr.time); X#endif X X /* position archive to spot for new file */ X X if (arc) { /* if adding to existing archive */ X starts = ftell(arc); /* where are we? */ X while (readhdr(&ohdr, arc)) { /* while more files to check */ X if (!strcmp(ohdr.name, nhdr.name)) { X upd = 1; /* replace existing entry */ X if (update || fresh) { /* if updating or X * freshening */ X if (nhdr.date < ohdr.date X || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) { X fseek(arc, starts, 0); X fclose(f); X return(0);/* skip if !newer */ X } X } X } X if (strcmp(ohdr.name, nhdr.name) >= 0) X break; /* found our spot */ X X writehdr(&ohdr, new); /* entry preceeds update; X * keep it */ X filecopy(arc, new, ohdr.size); X starts = ftell(arc); /* now where are we? */ X } X X if (upd) { /* if an update */ X if (note) { X printf("Updating file: %-12s ", name); X fflush(stdout); X } X fseek(arc, ohdr.size, 1); X } else if (fresh) { /* else if freshening */ X fseek(arc, starts, 0); /* then do not add files */ X fclose(f); X return(0); X } else { /* else adding a new file */ X if (note) { X printf("Adding file: %-12s ", name); X fflush(stdout); X } X fseek(arc, starts, 0); /* reset for next time */ X } X } else { /* no existing archive */ X if (fresh) { /* cannot freshen nothing */ X fclose(f); X return(0); X } else if (note) { /* else adding a file */ X printf("Adding file: %-12s ", name); X fflush(stdout); X } X } X X starts = ftell(new); /* note where header goes */ X hdrver = ARCVER; /* anything but end marker */ X writehdr(&nhdr, new); /* write out header skeleton */ X pack(f, new, &nhdr); /* pack file into archive */ X fseek(new, starts, 0); /* move back to header skeleton */ X writehdr(&nhdr, new); /* write out real header */ X fseek(new, nhdr.size, 1); /* skip over data to next header */ X fclose(f); /* all done with the file */ X return(0); X} X X#ifdef LOCAL X/* X * Convert a Unix filename to a legal MSDOS name. Returns a 1 if the file X * can't be found (or is not a regular file). Will truncate file and X * extension names, will substitute the letter 'X' for any illegal character X * in the name. X */ X X#include X#include X#include X Xint Xlegalize(path, name) Xchar *path, *name; X{ X static char *dev[8] = {"CON", "AUX", "COM1", "LPT1", "PRN", "LPT2", X "LPT3", "NUL"}; X char *s, *temp, *ext, *strcpy(), *strpbrk(), buf[256]; X int i, dot, modified, verbose; X struct stat stbuf; X X/* verbose = warn; */ X verbose = 0; X X if (stat(path, &stbuf) < 0) { X fprintf(stderr, "Can't find \"%s\"\n", path); X return(1); X } X if ((stbuf.st_mode & S_IFREG) != S_IFREG) { X if (verbose) X fprintf(stderr, "\"%s\" Is not a regular file\n", path); X return(1); X } X X strcpy(buf, name); X temp = buf; X X ext = ""; X dot = 0; X for (s = temp; *s; ++s) { X if (*s == '.' && !dot) { X dot = 1; X *s = '\0'; X ext = s + 1; X } X if (islower(*s)) X *s = toupper(*s); X } X if (*temp == '\0') { X temp = "X"; X if (verbose) X printf("\"%s\" Null name component, using \"%s.%s\"\n", name, temp, ext); X } X for (i=0; i<8; i++) { X if (!strcmp(temp, dev[i])) { X *temp = 'X'; X if (verbose) X printf("\"%s\" Is a device name, using \"%s.%s\"\n", name, temp, ext); X } X } X if (strlen(temp) > 8) { X *(temp+8) = '\0'; X if (verbose) X printf("\"%s\" Name too long, using, \"%s.%s\"\n", name, temp, ext); X } X if (strlen(ext) > 3) { X *(ext+3) = '\0'; X if (verbose) X printf("\"%s\" Extension too long, using \"%s.%s\"\n", name, temp, ext); X } X modified = 0; X while (s = strpbrk(temp, "^+=/[]:',?*\\<>|\". ")) { X modified++; X *s = 'X'; X } X while (s = strpbrk(ext, "^+=/[]:',?*\\<>|\". ")) { X modified++; X *s = 'X'; X } X if (modified && verbose) X printf("\"%s\" Contains illegal character(s), using \"%s.%s\"\n", name, temp, ext); X X if (*ext != '\0') X sprintf(name, "%s.%s", temp, ext); X else X strcpy(name, temp); X return(0); X} X X#ifdef BSD X Xchar * Xstrpbrk(p1, p2) Xchar *p1, *p2; X{ X char *p2start = p2; X X while (*p1) { X while (*p2) { X if (*p2 == *p1) X return p1; X p2++; X } X p2 = p2start; X p1++; X } X return NULL; X} X X#endif /* BSD */ X#endif /* LOCAL */ SHAR_EOF if test 12955 -ne "`wc -c < 'arcadd.c'`" then echo shar: "error transmitting 'arcadd.c'" '(should have been 12955 characters)' fi fi echo shar: "extracting 'arccode.c'" '(1192 characters)' if test -f 'arccode.c' then echo shar: "will not over-write existing file 'arccode.c'" else sed 's/^X//' << \SHAR_EOF > 'arccode.c' X/* X * $Header: arccode.c,v 1.1 88/06/01 15:15:58 hyc Locked $ X */ X X/* X * ARC - Archive utility - ARCCODE X * X * Version 1.02, created on 01/20/86 at 13:33:35 X * X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains the routines used to encrypt and decrypt data X * in an archive. The encryption method is nothing fancy, being just a X * routine XOR, but it is used on the packed data, and uses a variable length X * key. The end result is something that is in theory crackable, but I'd X * hate to try it. It should be more than sufficient for casual use. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X Xstatic char *p; /* password pointer */ X Xvoid Xsetcode() X{ /* get set for encoding/decoding */ X p = password; /* reset password pointer */ X} X Xint Xcode(c) /* encode some character */ Xint c; /* character to encode */ X{ X if (p) { /* if password is in use */ X if (!*p) /* if we reached the end */ X p = password; /* then wrap back to the start */ X return c ^ *p++;/* very simple here */ X } else X return c; /* else no encryption */ X} SHAR_EOF if test 1192 -ne "`wc -c < 'arccode.c'`" then echo shar: "error transmitting 'arccode.c'" '(should have been 1192 characters)' fi fi echo shar: "extracting 'arccvt.c'" '(3396 characters)' if test -f 'arccvt.c' then echo shar: "will not over-write existing file 'arccvt.c'" else sed 's/^X//' << \SHAR_EOF > 'arccvt.c' X/* X * $Header: arccvt.c,v 1.5 88/06/01 19:17:40 hyc Locked $ X */ X X/* X * ARC - Archive utility - ARCCVT X * X * Version 1.16, created on 02/03/86 at 22:53:02 X * X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains the routines used to convert archives to use X * newer file storage methods. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X Xvoid openarc(), rempath(), closearc(), abort(), pack(), writehdr(), filecopy(); Xint match(), readhdr(), unpack(), unlink(); X Xstatic char tempname[STRLEN]; /* temp file name */ X Xvoid Xcvtarc(num, arg) /* convert archive */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ X{ X struct heads hdr; /* file header */ X int cvt; /* true to convert current file */ X int did[MAXARG];/* true when argument was used */ X int n; /* index */ X char *makefnam(); /* filename fixer */ X FILE *fopen();/* file opener */ X void cvtfile(); X X if (arctemp) /* use temp area if specified */ X sprintf(tempname, "%s.CVT", arctemp); X else X makefnam("$ARCTEMP.CVT", arcname, tempname); X#if !DOS X image = 1; X#endif X X openarc(1); /* open archive for changes */ X X for (n = 0; n < num; n++) /* for each argument */ X did[n] = 0; /* reset usage flag */ X rempath(num, arg); /* strip off paths */ X X if (num) { /* if files were named */ X while (readhdr(&hdr, arc)) { /* while more files to check */ X cvt = 0;/* reset convert flag */ X for (n = 0; n < num; n++) { /* for each template X * given */ X if (match(hdr.name, arg[n])) { X cvt = 1; /* turn on convert flag */ X did[n] = 1; /* turn on usage flag */ X break; /* stop looking */ X } X } X X if (cvt)/* if converting this one */ X cvtfile(&hdr); /* then do it */ X else { /* else just copy it */ X writehdr(&hdr, new); X filecopy(arc, new, hdr.size); X } X } X } else X while (readhdr(&hdr, arc)) /* else convert all files */ X cvtfile(&hdr); X X hdrver = 0; /* archive EOF type */ X writehdr(&hdr, new); /* write out our end marker */ X closearc(1); /* close archive after changes */ X X if (note) { X for (n = 0; n < num; n++) { /* report unused args */ X if (!did[n]) { X printf("File not found: %s\n", arg[n]); X nerrs++; X } X } X } X} X Xvoid Xcvtfile(hdr) /* convert a file */ X struct heads *hdr; /* pointer to header data */ X{ X long starts, ftell(); /* where the file goes */ X FILE *tmp, *fopen(); /* temporary file */ X X if (!(tmp = fopen(tempname, "w+b"))) X abort("Unable to create temporary file %s", tempname); X X if (note) { X printf("Converting file: %-12s reading, ", hdr->name); X fflush(stdout); X } X unpack(arc, tmp, hdr); /* unpack the entry */ X fseek(tmp, 0L, 0); /* reset temp for reading */ X X starts = ftell(new); /* note where header goes */ X hdrver = ARCVER; /* anything but end marker */ X writehdr(hdr, new); /* write out header skeleton */ X pack(tmp, new, hdr); /* pack file into archive */ X fseek(new, starts, 0); /* move back to header skeleton */ X writehdr(hdr, new); /* write out real header */ X fseek(new, hdr->size, 1); /* skip over data to next header */ X fclose(tmp); /* all done with the file */ X if (unlink(tempname) && warn) { X printf("Cannot unsave %s\n", tempname); X nerrs++; X } X} SHAR_EOF if test 3396 -ne "`wc -c < 'arccvt.c'`" then echo shar: "error transmitting 'arccvt.c'" '(should have been 3396 characters)' fi fi echo shar: "extracting 'arcdata.c'" '(2067 characters)' if test -f 'arcdata.c' then echo shar: "will not over-write existing file 'arcdata.c'" else sed 's/^X//' << \SHAR_EOF > 'arcdata.c' X/* X * $Header: arcdata.c,v 1.7 88/07/31 18:47:22 hyc Exp $ X */ X X/* ARC - Archive utility - ARCDATA X X Version 2.17, created on 04/22/87 at 13:09:43 X X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This file defines the external data storage used by the ARC X archive utility. X X X Language: X Computer Innovations Optimizing C86 X*/ X#include X X#define DONT_DEFINE X#include "arc.h" X Xint keepbak = 0; /* true if saving the old archive */ X#if UNIX Xint image = 1; /* true to suppress CRLF/LF x-late */ X#endif X#if MTS Xint image = 0; /* true to suppress EBCDIC/ASCII x-late */ Xchar sepchr[2] = ":";/* Shared file separator */ Xchar tmpchr[2] = "-";/* Temporary file prefix */ X#endif X#if GEMDOS Xint hold = 0; /* true to pause before exit */ X#endif Xint warn = 1; /* true to print warnings */ Xint note = 1; /* true to print comments */ Xint bose = 0; /* true to be verbose */ Xint nocomp = 0; /* true to suppress compression */ Xint overlay = 0; /* true to overlay on extract */ Xint kludge = 0; /* kludge flag */ Xchar *arctemp = NULL; /* arc temp file prefix */ Xchar *password = NULL;/* encryption password pointer */ Xint nerrs = 0; /* number of errors encountered */ Xint changing = 0; /* true if archive being modified */ X Xchar hdrver; /* header version */ X XFILE *arc; /* the old archive */ XFILE *new; /* the new archive */ Xchar arcname[STRLEN]; /* storage for archive name */ Xchar bakname[STRLEN]; /* storage for backup copy name */ Xchar newname[STRLEN]; /* storage for new archive name */ Xunsigned short arcdate = 0; /* archive date stamp */ Xunsigned short arctime = 0; /* archive time stamp */ Xunsigned short olddate = 0; /* old archive date stamp */ Xunsigned short oldtime = 0; /* old archive time stamp */ Xint dosquash = 0; /* true to squash instead of crunch */ SHAR_EOF if test 2067 -ne "`wc -c < 'arcdata.c'`" then echo shar: "error transmitting 'arcdata.c'" '(should have been 2067 characters)' fi fi echo shar: "extracting 'arcdel.c'" '(2055 characters)' if test -f 'arcdel.c' then echo shar: "will not over-write existing file 'arcdel.c'" else sed 's/^X//' << \SHAR_EOF > 'arcdel.c' X/* X * $Header: arcdel.c,v 1.3 88/04/19 01:39:32 hyc Exp $ X */ X X/* X * ARC - Archive utility - ARCDEL X * X * Version 2.09, created on 02/03/86 at 22:53:27 X * X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains the routines used to delete entries in an X * archive. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X Xvoid abort(), rempath(), openarc(), closearc(), writehdr(), filecopy(); Xint match(), readhdr(); X Xvoid Xdelarc(num, arg) /* remove files from archive */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ X{ X struct heads hdr; /* header data */ X int del; /* true to delete a file */ X int did[MAXARG];/* true when argument used */ X int n; /* index */ X X if (!num) /* she must specify which */ X abort("You must tell me which files to delete!"); X X for (n = 0; n < num; n++) /* for each argument */ X did[n] = 0; /* reset usage flag */ X rempath(num, arg); /* strip off paths */ X X openarc(1); /* open archive for changes */ X X while (readhdr(&hdr, arc)) { /* while more entries in archive */ X del = 0; /* reset delete flag */ X for (n = 0; n < num; n++) { /* for each template given */ X if (match(hdr.name, arg[n])) { X del = 1; /* turn on delete flag */ X did[n] = 1; /* turn on usage flag */ X break; /* stop looking */ X } X } X X if (del) { /* skip over unwanted files */ X fseek(arc, hdr.size, 1); X if (note) X printf("Deleting file: %s\n", hdr.name); X } else { /* else copy over file data */ X writehdr(&hdr, new); /* write out header and file */ X filecopy(arc, new, hdr.size); X } X } X X hdrver = 0; /* special end of archive type */ X writehdr(&hdr, new); /* write out archive end marker */ X closearc(1); /* close archive after changes */ X X if (note) { X for (n = 0; n < num; n++) { /* report unused arguments */ X if (!did[n]) { X printf("File not found: %s\n", arg[n]); X nerrs++; X } X } X } X} SHAR_EOF if test 2055 -ne "`wc -c < 'arcdel.c'`" then echo shar: "error transmitting 'arcdel.c'" '(should have been 2055 characters)' fi fi echo shar: "extracting 'arcdos.c'" '(4684 characters)' if test -f 'arcdos.c' then echo shar: "will not over-write existing file 'arcdos.c'" else sed 's/^X//' << \SHAR_EOF > 'arcdos.c' X/* X * $Header: arcdos.c,v 1.8 88/08/01 15:07:15 hyc Exp $ X */ X X/* X * ARC - Archive utility - ARCDOS X * X * Version 1.44, created on 07/25/86 at 14:17:38 X * X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains certain DOS level routines that assist in X * doing fancy things with an archive, primarily reading and setting the date X * and time last modified. X * X * These are, by nature, system dependant functions. But they are also, by X * nature, very expendable. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X X#if MSDOS X#include "fileio2.h" /* needed for filehand */ X#endif X X#if UNIX X#include X#include X#include X Xstruct timeval { /* man page said , but it */ X long tv_sec; /* really seems to be in , */ X long tv_usec; /* but why bother... */ X}; X#endif X X#if GEMDOS X#include X#endif X Xchar *strcpy(), *strcat(), *malloc(); X Xvoid Xgetstamp(f, date, time) /* get a file's date/time stamp */ X#if !MTS X FILE *f; /* file to get stamp from */ X#else X char *f; /* filename "" "" */ X#endif X unsigned short *date, *time; /* storage for the stamp */ X{ X#if MSDOS X struct { X int ax, bx, cx, dx, si, di, ds, es; X } reg; X X reg.ax = 0x5700; /* get date/time */ X reg.bx = filehand(f); /* file handle */ X if (sysint21(®, ®) & 1) /* DOS call */ X printf("Get timestamp fail (%d)\n", reg.ax); X X *date = reg.dx; /* save date/time */ X *time = reg.cx; X#endif X#if GEMDOS X int fd, ret[2]; X X fd = fileno(f); X Fdatime(ret, fd, 0); X *date = ret[1]; X *time = ret[0]; X#endif X#if UNIX X struct stat buf; X struct tm *localtime(), *t; X X fstat(fileno(f), &buf); X t=localtime(&(buf.st_mtime)); X *date = (unsigned short) (((t->tm_year - 80) << 9) + X ((t->tm_mon + 1) << 5) + t->tm_mday); X *time = (unsigned short) ((t->tm_hour << 11) + X (t->tm_min << 5) + t->tm_sec / 2); X#endif X#if MTS X fortran timein(), X#if USEGFINFO X gfinfo(); X#else X fileinfo(); X#endif X int stclk[2]; X char name[24]; X struct bigtime { X int greg; X int year; X int mon; X int day; X int hour; X int min; X int sec; X int usec; X int week; X int toff; X int tzn1; X int tzn2; X } tvec; X#if USEGFINFO X static int gfflag = 0x0009, gfdummy[2] = { X 0, 0 X }; X int gfcinfo[18]; X#else X static int cattype = 2; X#endif X X strcpy(name, f); X strcat(name, " "); X#if USEGFINFO X gfcinfo[0] = 18; X gfinfo(name, name, &gfflag, gfcinfo, gfdummy, gfdummy); X timein("*IBM MICROSECONDS*", &gfcinfo[16], &tvec); X#else X fileinfo(name, &cattype, "CILCCT ", stclk); X timein("*IBM MICROSECONDS*", stclk, &tvec); X#endif X X *date = (unsigned short) (((tvec.year - 1980) << 9) + ((tvec.mon) << 5) + tvec.day); X *time = (unsigned short) ((tvec.hour << 11) + (tvec.min << 5) + tvec.sec / 2); X#endif X} X Xvoid Xsetstamp(f, date, time) /* set a file's date/time stamp */ X char *f; /* filename to stamp */ X unsigned short date, time; /* desired date, time */ X{ X#if MSDOS X FILE *ff; X struct { X int ax, bx, cx, dx, si, di, ds, es; X } reg; X X ff = fopen(f, "w+"); /* How else can I get a handle? */ X X reg.ax = 0x5701; /* set date/time */ X reg.bx = filehand(f); /* file handle */ X reg.cx = time; /* desired time */ X reg.dx = date; /* desired date */ X if (sysint21(®, ®) & 1) /* DOS call */ X printf("Set timestamp fail (%d)\n", reg.ax); X fclose(ff); X#endif X#if GEMDOS X int fd, set[2]; X X fd = Fopen(f, 0); X set[0] = time; X set[1] = date; X Fdatime(set, fd, 1); X Fclose(fd); X#endif X#if UNIX X struct tm tm; X struct timeval tvp[2]; X int utimes(); X long tmclock(); X tm.tm_sec = (time & 31) * 2; X tm.tm_min = (time >> 5) & 63; X tm.tm_hour = (time >> 11); X tm.tm_mday = date & 31; X tm.tm_mon = ((date >> 5) & 15) - 1; X tm.tm_year = (date >> 9) + 80; X tvp[0].tv_sec = tmclock(&tm); X tvp[1].tv_sec = tvp[0].tv_sec; X tvp[0].tv_usec = tvp[1].tv_usec = 0; X utimes(f, tvp); X#endif X} X X#if MSDOS Xint Xfilehand(stream) /* find handle on a file */ X struct bufstr *stream; /* file to grab onto */ X{ X return stream->bufhand; /* return DOS 2.0 file handle */ X} X#endif X X#if UNIX Xint Xizadir(filename) /* Is filename a directory? */ X char *filename; X{ X struct stat buf; X X if (stat(filename, &buf) != 0) X return (0); /* Ignore if stat fails since */ X else X return (buf.st_mode & S_IFDIR); /* bad files trapped later */ X} X#endif SHAR_EOF if test 4684 -ne "`wc -c < 'arcdos.c'`" then echo shar: "error transmitting 'arcdos.c'" '(should have been 4684 characters)' fi fi echo shar: "extracting 'arcext.c'" '(5041 characters)' if test -f 'arcext.c' then echo shar: "will not over-write existing file 'arcext.c'" else sed 's/^X//' << \SHAR_EOF > 'arcext.c' X/* X * $Header: arcext.c,v 1.5 88/06/01 19:26:31 hyc Locked $ X */ X X/* X * ARC - Archive utility - ARCEXT X * X * Version 2.19, created on 10/24/86 at 14:53:32 X * X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X * X * By: Thom Henderson X * X * Description: This file contains the routines used to extract files from an X * archive. X * X * Language: Computer Innovations Optimizing C86 X */ X#include X#include "arc.h" X#if !MSDOS X#include X#endif X Xvoid openarc(), closearc(), setstamp(); Xint free(), match(), readhdr(), unpack(); Xchar *strcpy(), *strcat(); X Xvoid Xextarc(num, arg, prt) /* extract files from archive */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ X int prt; /* true if printing */ X{ X struct heads hdr; /* file header */ X int save; /* true to save current file */ X int did[MAXARG];/* true when argument was used */ X char *i, *rindex(); /* string index */ X char **name, *malloc(); /* name pointer list, X * allocator */ X int n; /* index */ X void extfile(); X X name = (char **) malloc(num * sizeof(char *)); /* get storage for name X * pointers */ X X for (n = 0; n < num; n++) { /* for each argument */ X did[n] = 0; /* reset usage flag */ X#if !MTS X if (!(i = rindex(arg[n], '\\'))) /* find start of name */ X if (!(i = rindex(arg[n], '/'))) X if (!(i = rindex(arg[n], ':'))) X i = arg[n] - 1; X#else X if (!(i = rindex(arg[n], sepchr[0]))) X if (arg[n][0] != tmpchr[0]) X i = arg[n] - 1; X else X i = arg[n]; X#endif X name[n] = i + 1; X } X X X openarc(0); /* open archive for reading */ X X if (num) { /* if files were named */ X while (readhdr(&hdr, arc)) { /* while more files to check */ X save = 0; /* reset save flag */ X for (n = 0; n < num; n++) { /* for each template X * given */ X if (match(hdr.name, name[n])) { X save = 1; /* turn on save flag */ X did[n] = 1; /* turn on usage flag */ X break; /* stop looking */ X } X } X X if (save) /* extract if desired, else skip */ X extfile(&hdr, arg[n], prt); X else X fseek(arc, hdr.size, 1); X } X } else X while (readhdr(&hdr, arc)) /* else extract all files */ X extfile(&hdr, "", prt); X X closearc(0); /* close archive after reading */ X X if (note) { X for (n = 0; n < num; n++) { /* report unused args */ X if (!did[n]) { X printf("File not found: %s\n", arg[n]); X nerrs++; X } X } X } X free(name); X} X Xvoid Xextfile(hdr, path, prt) /* extract a file */ X struct heads *hdr; /* pointer to header data */ X char *path; /* pointer to path name */ X int prt; /* true if printing */ X{ X FILE *f, *fopen(); /* extracted file, opener */ X char buf[STRLEN]; /* input buffer */ X char fix[STRLEN]; /* fixed name buffer */ X char *i, *rindex(); /* string index */ X#ifdef LOCAL X extern int unix_names; X void lower(); X#endif /* LOCAL */ X X if (prt) { /* printing is much easier */ X unpack(arc, stdout, hdr); /* unpack file from archive */ X printf("\f"); /* eject the form */ X return; /* see? I told you! */ X } X strcpy(fix, path); /* note path name template */ X#if !MTS X if (*path) { X if (!(i = rindex(fix, '\\'))) /* find start of name */ X if (!(i = rindex(fix, '/'))) X if (!(i = rindex(fix, ':'))) X i = fix - 1; X } else i = fix -1; X#else X if (!(i = rindex(fix, sepchr[0]))) X if (fix[0] != tmpchr[0]) X i = fix - 1; X else X i = fix; X#endif X#ifdef LOCAL X if (!unix_names) X lower(hdr->name); X#endif /* LOCAL */ X strcpy(i + 1, hdr->name); /* replace template with name */ X X if (note) X printf("Extracting file: %s\n", fix); X X if (warn && !overlay) { X if (f = fopen(fix, "r")) { /* see if it exists */ X fclose(f); X printf("WARNING: File %s already exists!", fix); X fflush(stdout); X while (1) { X printf(" Overwrite it (y/n)? "); X fflush(stdout); X fgets(buf, STRLEN, stdin); X *buf = toupper(*buf); X if (*buf == 'Y' || *buf == 'N') X break; X } X if (*buf == 'N') { X printf("%s not extracted.\n", fix); X fseek(arc, hdr->size, 1); X return; X } X } X } X#if !MTS X if (!(f = fopen(fix, OPEN_W))) X#else X { X fortran create(); X void memset(); X char c_name[256]; X struct crsize { X short maxsize, cursize; X } c_size; X char c_vol[6]; X int c_type; X strcpy(c_name, fix); X strcat(c_name, " "); X c_size.maxsize = 0; X c_size.cursize = hdr->length / 4096 + 1; X memset(c_vol, 0, sizeof(c_vol)); X c_type = 0x100; X create(c_name, &c_size, c_vol, &c_type); X } X if (image) { X f = fopen(fix, "wb"); X } else X f = fopen(fix, "w"); X if (!f) X#endif X { X if (warn) { X printf("Cannot create %s\n", fix); X nerrs++; X } X fseek(arc, hdr->size, 1); X return; X } X /* now unpack the file */ X X unpack(arc, f, hdr); /* unpack file from archive */ X fclose(f); /* all done writing to file */ X#if !MTS X setstamp(fix, hdr->date, hdr->time); /* use filename for stamp */ X#endif X} SHAR_EOF if test 5041 -ne "`wc -c < 'arcext.c'`" then echo shar: "error transmitting 'arcext.c'" '(should have been 5041 characters)' fi fi echo shar: "extracting 'arcio.c'" '(7491 characters)' if test -f 'arcio.c' then echo shar: "will not over-write existing file 'arcio.c'" else sed 's/^X//' << \SHAR_EOF > 'arcio.c' X/* X * $Header: arcio.c,v 1.9 88/07/31 18:49:19 hyc Exp $ X */ X X/* ARC - Archive utility - ARCIO X X Version 2.50, created on 04/22/87 at 13:25:20 X X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This file contains the file I/O routines used to manipulate X an archive. X X Language: X Computer Innovations Optimizing C86 X*/ X#include X#include "arc.h" X#if MTS X#include X#endif X Xvoid abort(); Xint strlen(), free(); X Xint Xreadhdr(hdr, f) /* read a header from an archive */ X struct heads *hdr; /* storage for header */ X FILE *f; /* archive to read header from */ X{ X#if !MSDOS X unsigned char dummy[28]; X int i; X#endif X char name[FNLEN]; /* filename buffer */ X int try = 0;/* retry counter */ X static int first = 1; /* true only on first read */ X X if (!f) /* if archive didn't open */ X return 0; /* then pretend it's the end */ X if (feof(f)) /* if no more data */ X return 0; /* then signal end of archive */ X X if (fgetc(f) != ARCMARK) { /* check archive validity */ X if (warn) { X printf("An entry in %s has a bad header.", arcname); X nerrs++; X } X while (!feof(f)) { X try++; X if (fgetc(f) == ARCMARK) { X ungetc(hdrver = fgetc(f), f); X if (!(hdrver & 0x80) && hdrver <= ARCVER) X break; X } X } X X if (feof(f) && first) X abort("%s is not an archive", arcname); X X if (changing && warn) X abort("%s is corrupted -- changes disallowed", arcname); X X if (warn) X printf(" %d bytes skipped.\n", try); X X if (feof(f)) X return 0; X } X hdrver = fgetc(f); /* get header version */ X if (hdrver & 0x80) /* sign bit? negative? */ X abort("Invalid header in archive %s", arcname); X if (hdrver == 0) X return 0; /* note our end of archive marker */ X if (hdrver > ARCVER) { X fread(name, sizeof(char), FNLEN, f); X#if MTS X atoe(name, strlen(name)); X#endif X printf("I don't know how to handle file %s in archive %s\n", X name, arcname); X printf("I think you need a newer version of ARC.\n"); X exit(1); X } X /* amount to read depends on header type */ X X if (hdrver == 1) { /* old style is shorter */ X fread(hdr, sizeof(struct heads) - sizeof(long int), 1, f); X hdrver = 2; /* convert header to new format */ X hdr->length = hdr->size; /* size is same when not X * packed */ X } else X#if MSDOS X fread(hdr, sizeof(struct heads), 1, f); X#else X fread(dummy, 27, 1, f); X X for (i = 0; i < FNLEN; hdr->name[i] = dummy[i], i++); X#if MTS X (void) atoe(hdr->name, strlen(hdr->name)); X#endif X for (i = 0, hdr->size=0; i<4; hdr->size<<=8, hdr->size += dummy[16-i], i++); X hdr->date = (short) ((dummy[18] << 8) + dummy[17]); X hdr->time = (short) ((dummy[20] << 8) + dummy[19]); X hdr->crc = (short) ((dummy[22] << 8) + dummy[21]); X for (i = 0, hdr->length=0; i<4; hdr->length<<=8, hdr->length += dummy[26-i], i++); X#endif X X if (hdr->date > olddate X || (hdr->date == olddate && hdr->time > oldtime)) { X olddate = hdr->date; X oldtime = hdr->time; X } X first = 0; X return 1; /* we read something */ X} X Xvoid Xput_int(number, f) /* write a 2 byte integer */ X short number; X FILE *f; X{ X fputc((char) (number & 255), f); X fputc((char) (number >> 8), f); X} X Xvoid Xput_long(number, f) /* write a 4 byte integer */ X long number; X FILE *f; X{ X put_int((short) (number & 0xFFFF), f); X put_int((short) (number >> 16), f); X} X Xvoid Xwritehdr(hdr, f) /* write a header to an archive */ X struct heads *hdr; /* header to write */ X FILE *f; /* archive to write to */ X{ X fputc(ARCMARK, f); /* write out the mark of ARC */ X fputc(hdrver, f); /* write out the header version */ X if (!hdrver) /* if that's the end */ X return; /* then write no more */ X#if MSDOS X fwrite(hdr, sizeof(struct heads), 1, f); X#else X /* byte/word ordering hassles... */ X#if MTS X etoa(hdr->name, strlen(hdr->name)); X#endif X fwrite(hdr->name, 1, FNLEN, f); X put_long(hdr->size, f); X put_int(hdr->date, f); X put_int(hdr->time, f); X put_int(hdr->crc, f); X put_long(hdr->length, f); X#endif X X /* note the newest file for updating the archive timestamp */ X X if (hdr->date > arcdate X || (hdr->date == arcdate && hdr->time > arctime)) { X arcdate = hdr->date; X arctime = hdr->time; X } X} X Xvoid Xputc_tst(c, t) /* put a character, with tests */ X char c; /* character to output */ X FILE *t; /* file to write to */ X{ X c &= 0xff; X if (t) { X#if UNIX X fputc(c, t); X if (ferror(t)) X abort("Write failed"); X#else X if (fputc(c, t) == EOF) X abort("Write fail (disk full?)"); X#endif X } X} X X/* X * NOTE: The filecopy() function is used to move large numbers of bytes from X * one file to another. This particular version has been modified to improve X * performance in Computer Innovations C86 version 2.3 in the small memory X * model. It may not work as expected with other compilers or libraries, or X * indeed with different versions of the CI-C86 compiler and library, or with X * the same version in a different memory model. X * X * The following is a functional equivalent to the filecopy() routine that X * should work properly on any system using any compiler, albeit at the cost X * of reduced performance: X * X * filecopy(f,t,size) X * FILE *f, *t; long size; X * { X * while(size--) X * putc_tst(fgetc(f),t); X * } X */ X#if MSDOS X#include X Xfilecopy(f, t, size) /* bulk file copier */ X FILE *f, *t; /* files from and to */ X long size; /* bytes to copy */ X{ X char *buf; /* buffer pointer */ X char *alloc();/* buffer allocator */ X unsigned int bufl; /* buffer length */ X unsigned int coreleft(); /* space available reporter */ X unsigned int cpy; /* bytes being copied */ X long floc, tloc, fseek(); /* file pointers, setter */ X struct regval reg; /* registers for DOS calls */ X X if ((bufl = coreleft()) < 1000) /* see how much space we have */ X abort("Out of memory"); X bufl -= 1000; /* fudge factor for overhead */ X if (bufl > 60000) X bufl = 60000; /* avoid choking alloc() */ X if (bufl > size) X bufl = size; /* avoid wasting space */ X buf = alloc(bufl); /* allocate our buffer */ X X floc = fseek(f, 0L, 1); /* reset I/O system */ X tloc = fseek(t, 0L, 1); X X segread(®.si); /* set segment registers for DOS */ X X while (size > 0) { /* while more to copy */ X reg.ax = 0x3F00;/* read from handle */ X reg.bx = filehand(f); X reg.cx = bufl < size ? bufl : size; /* amount to read */ X reg.dx = buf; X if (sysint21(®, ®) & 1) X abort("Read fail"); X X cpy = reg.ax; /* amount actually read */ X reg.ax = 0x4000;/* write to handle */ X reg.bx = filehand(t); X reg.cx = cpy; X reg.dx = buf; X sysint21(®, ®); X X if (reg.ax != cpy) X abort("Write fail (disk full?)"); X X size -= (long) cpy; X } X X free(buf); /* all done with buffer */ X} X#else X Xvoid Xfilecopy(f, t, size) /* bulk file copier */ X FILE *f, *t; /* files from and to */ X long size; /* bytes to copy */ X{ X char *buf; /* buffer pointer */ X char *malloc(); /* buffer allocator */ X unsigned int bufl; /* buffer length */ X unsigned int cpy; /* bytes being copied */ X X bufl = 32760; X if (bufl > size) X bufl = size; /* don't waste space */ X X buf = malloc(bufl); X X while (size > 0) { X cpy = fread(buf, sizeof(char), X bufl < size ? bufl : (unsigned short) size, f); X if (fwrite(buf, sizeof(char), cpy, t) != cpy) X abort("Write fail (no space?)"); X size -= cpy; X } X X free(buf); X} X#endif SHAR_EOF if test 7491 -ne "`wc -c < 'arcio.c'`" then echo shar: "error transmitting 'arcio.c'" '(should have been 7491 characters)' fi fi echo shar: "extracting 'arclst.c'" '(4418 characters)' if test -f 'arclst.c' then echo shar: "will not over-write existing file 'arclst.c'" else sed 's/^X//' << \SHAR_EOF > 'arclst.c' X/* X * $Header: arclst.c,v 1.5 88/06/01 18:05:57 hyc Locked $ X */ X X/* ARC - Archive utility - ARCLST X X Version 2.39, created on 04/22/87 at 13:48:29 X X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This file contains the routines used to list the contents X of an archive. X X Language: X Computer Innovations Optimizing C86 X*/ X#include X#include "arc.h" X Xvoid rempath(), openarc(), closearc(); Xint readhdr(), match(); X Xvoid Xlstarc(num, arg) /* list files in archive */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ X{ X struct heads hdr; /* header data */ X int list; /* true to list a file */ X int did[MAXARG]; /* true when argument was used */ X long tnum, tlen, tsize; /* totals */ X int n; /* index */ X void lstfile(); X X tnum = tlen = tsize = 0;/* reset totals */ X X for (n = 0; n < num; n++) /* for each argument */ X did[n] = 0; /* reset usage flag */ X rempath(num, arg); /* strip off paths */ X X if (note && !kludge) { X printf("Name Length "); X if (bose) X printf(" Stowage SF Size now"); X printf(" Date "); X if (bose) X printf(" Time CRC"); X printf("\n"); X X printf("============ ========"); X if (bose) X printf(" ======== ==== ========"); X printf(" ========="); X if (bose) X printf(" ====== ===="); X printf("\n"); X } X openarc(0); /* open archive for reading */ X X if (num) { /* if files were named */ X while (readhdr(&hdr, arc)) { /* process all archive files */ X list = 0; /* reset list flag */ X for (n = 0; n < num; n++) { /* for each template X * given */ X if (match(hdr.name, arg[n])) { X list = 1; /* turn on list flag */ X did[n] = 1; /* turn on usage flag */ X break; /* stop looking */ X } X } X X if (list) { /* if this file is wanted */ X if (!kludge) X lstfile(&hdr); /* then tell about it */ X tnum++; /* update totals */ X tlen += hdr.length; X tsize += hdr.size; X } X fseek(arc, hdr.size, 1); /* move to next header */ X } X } else X while (readhdr(&hdr, arc)) { /* else report on all files */ X if (!kludge) X lstfile(&hdr); X tnum++; /* update totals */ X tlen += hdr.length; X tsize += hdr.size; X fseek(arc, hdr.size, 1); /* skip to next header */ X } X X closearc(0); /* close archive after reading */ X X if (note && !kludge) { X printf(" ==== ========"); X if (bose) X printf(" ==== ========"); X printf("\n"); X } X if (note) { X printf("Total %6ld %8ld", tnum, tlen); X if (bose) { X if (tlen) X printf(" %3ld%%", 100L - (100L * tsize) / tlen); X else X printf(" ---"); X printf(" %8ld", tsize); X } X printf("\n"); X X for (n = 0; n < num; n++) { /* report unused args */ X if (!did[n]) { X printf("File not found: %s\n", arg[n]); X nerrs++; X } X } X } X} X Xvoid Xlstfile(hdr) /* tell about a file */ X struct heads *hdr; /* pointer to header data */ X{ X int yr, mo, dy; /* parts of a date */ X int hh, mm; /* parts of a time */ X X static char *mon[] = /* month abbreviations */ X { X "Jan", "Feb", "Mar", "Apr", X "May", "Jun", "Jul", "Aug", X "Sep", "Oct", "Nov", "Dec" X }; X X if (!note) { /* no notes means short listing */ X printf("%s\n", hdr->name); X return; X } X X yr = (hdr->date >> 9) & 0x7f; /* dissect the date */ X mo = (hdr->date >> 5) & 0x0f; X dy = hdr->date & 0x1f; X X hh = (hdr->time >> 11) & 0x1f; /* dissect the time */ X mm = (hdr->time >> 5) & 0x3f; X/* ss = (hdr->time & 0x1f) * 2; seconds, not used. */ X X printf("%-12s %8ld ", hdr->name, hdr->length); X X if (bose) { X switch (hdrver) { X case 1: X case 2: X printf(" -- "); X break; X case 3: X printf(" Packed "); X break; X case 4: X printf("Squeezed"); X break; X case 5: X case 6: X case 7: X printf("crunched"); X break; X case 8: X printf("Crunched"); X break; X case 9: X printf("Squashed"); X break; X default: X printf("Unknown!"); X } X X if (hdr->length) X printf(" %3ld%%", 100L - (100L * hdr->size) / hdr->length); X else X printf(" ---"); X printf(" %8ld ", hdr->size); X } X printf("%2d %3s %02d", dy, mon[mo - 1], (yr + 80) % 100); X X if (bose) X printf(" %2d:%02d%c %04x", X (hh > 12 ? hh - 12 : hh), mm, (hh > 11 ? 'p' : 'a'), X hdr->crc & 0xffff); X X printf("\n"); X} SHAR_EOF if test 4418 -ne "`wc -c < 'arclst.c'`" then echo shar: "error transmitting 'arclst.c'" '(should have been 4418 characters)' fi fi exit 0 # End of shell archive