rsalz@uunet.uu.net (Rich Salz) (07/02/88)
Submitted-by: hyc@math.lsa.umich.edu Posting-number: Volume 15, Issue 79 Archive-name: arc5.21/part03 #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 hyc 11146 Jun 17 17:03 arc.c # -rw-r--r-- 1 hyc 3318 Jun 1 19:59 arc.h # -rw-r--r-- 1 hyc 9286 Jun 13 00:31 arcadd.c # -rw-r--r-- 1 hyc 1204 Jun 1 15:16 arccode.c # -rw-r--r-- 1 hyc 3396 Jun 1 19:18 arccvt.c # -rw-r--r-- 1 hyc 2070 Jun 13 04:26 arcdata.c # -rw-r--r-- 1 hyc 2055 Apr 19 01:39 arcdel.c # -rw-r--r-- 1 hyc 5008 Jun 13 14:08 arcdos.c # -rw-r--r-- 1 hyc 4898 Jun 13 14:06 arcext.c # -rw-r--r-- 1 hyc 7418 Jun 13 13:48 arcio.c # -rw-r--r-- 1 hyc 4418 Jun 1 18:06 arclst.c # echo 'x - arc.c' if test -f arc.c; then echo 'shar: not overwriting arc.c'; else sed 's/^X//' << '________This_Is_The_END________' > arc.c X/* X * $Header: arc.c,v 1.10 88/06/17 15:22:48 hyc Locked $ X */ X X/* ARC - Archive utility X X Version 5.21, created on 04/22/87 at 15:05:21 X X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This program is a general archive utility, and is used to maintain X an archive of files. An "archive" is a single file that combines X many files, reducing storage space and allowing multiple files to X be handled as one. X X Instructions: X Run this program with no arguments for complete instructions. X X Programming notes: X ARC Version 2 differs from version 1 in that archive entries X are automatically compressed when they are added to the archive, X making a separate compression step unecessary. The nature of the X compression is indicated by the header version number placed in X each archive entry, as follows: X X 1 = Old style, no compression X 2 = New style, no compression X 3 = Compression of repeated characters only X 4 = Compression of repeated characters plus Huffman SQueezing X 5 = Lempel-Zev packing of repeated strings (old style) X 6 = Lempel-Zev packing of repeated strings (new style) X 7 = Lempel-Zev Williams packing with improved hash function X 8 = Dynamic Lempel-Zev packing with adaptive reset X 9 = Dynamic Lempel-Zev packing, larger hash table X X Type 5, Lempel-Zev packing, was added as of version 4.0 X X Type 6 is Lempel-Zev packing where runs of repeated characters X have been collapsed, and was added as of version 4.1 X X Type 7 is a variation of Lempel-Zev using a different hash X function which yields speed improvements of 20-25%, and was X added as of version 4.6 X X Type 8 is a different implementation of Lempel-Zev, using a X variable code size and an adaptive block reset, and was added X as of version 5.0 X X Type 9 is a slight modification of type 8, first used by Phil X Katz in his PKARC utilites. The primary difference is the use X of a hash table twice as large as for type 8, and that this X algorithm called Squashing, doesn't perform run-length encoding X on the input data. X X Verion 4.3 introduced a temporary file for holding the result X of the first crunch pass, thus speeding up crunching. X X Version 4.4 introduced the ARCTEMP environment string, so that X the temporary crunch file may be placed on a ramdisk. Also X added was the distinction bewteen Adding a file in all cases, X and Updating a file only if the disk file is newer than the X corresponding archive entry. X X The compression method to use is determined when the file is X added, based on whichever method yields the smallest result. X X Language: X Computer Innovations Optimizing C86 X*/ X#include <stdio.h> X#include "arc.h" X Xint strlen(); Xvoid addarc(), delarc(), extarc(), lstarc(), tstarc(), cvtarc(), runarc(); Xvoid abort(); X#if MTS Xvoid etoa(); X#endif X#if GEMDOS Xlong _stksize = 24576; X#endif Xchar *strcpy(), *strcat(); X Xstatic char **lst; /* files list */ Xstatic int lnum; /* length of files list */ X Xmain(num, arg) /* system entry point */ X int num; /* number of arguments */ X char *arg[]; /* pointers to arguments */ X{ X char opt = 0;/* selected action */ X char *a; /* option pointer */ X char *makefnam(); /* filename fixup routine */ X void upper();/* case conversion routine */ X char *index();/* string index utility */ X char *envfind(); /* environment searcher */ X int n; /* index */ X char *arctemp2, *calloc(), *mktemp(); X#if GEMDOS X void exitpause(); X#endif X#if MTS X fortran void guinfo(); X char gotinf[4]; X#endif X X if (num < 3) { X printf("ARC - Archive utility, Version 5.21, created on 04/22/87 at 15:05:21\n"); X/* printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;"); X printf(" ALL RIGHTS RESERVED\n\n"); X printf("Please refer all inquiries to:\n\n"); X printf(" System Enhancement Associates\n"); X printf(" 21 New Street, Wayne NJ 07470\n\n"); X printf("You may copy and distribute this program freely,"); X printf(" provided that:\n"); X printf(" 1) No fee is charged for such copying and"); X printf(" distribution, and\n"); X printf(" 2) It is distributed ONLY in its original,"); X printf(" unmodified state.\n\n"); X printf("If you like this program, and find it of use, then your"); X printf(" contribution will\n"); X printf("be appreciated. You may not use this product in a"); X printf(" commercial environment\n"); X printf("or a governmental organization without paying a license"); X printf(" fee of $35. Site\n"); X printf("licenses and commercial distribution licenses are"); X printf(" available. A program\n"); X printf("disk and printed documentation are available for $50.\n"); X printf("\nIf you fail to abide by the terms of this license, "); X printf(" then your conscience\n"); X printf("will haunt you for the rest of your life.\n\n"); */ X#if MSDOS X printf("Usage: ARC {amufdxerplvtc}[bswnoq][g<password>]"); X#endif X#if GEMDOS X printf("Usage: ARC {amufdxerplvtc}[bhswnoq][g<password>]"); X#endif X#if UNIX X printf("Usage: arc {amufdxerplvtc}[biswnoq][g<password>]"); X#endif X#if MTS X printf("Parameters: {amufdxeplvtc}[biswnoq][g<password>]"); X#endif X printf(" <archive> [<filename> . . .]\n"); X printf("Where: a = add files to archive\n"); X printf(" m = move files to archive\n"); X printf(" u = update files in archive\n"); X printf(" f = freshen files in archive\n"); X printf(" d = delete files from archive\n"); X printf(" x,e = extract files from archive\n"); X#if !MTS X printf(" r = run files from archive\n"); X#endif X printf(" p = copy files from archive to"); X printf(" standard output\n"); X printf(" l = list files in archive\n"); X printf(" v = verbose listing of files in archive\n"); X printf(" t = test archive integrity\n"); X printf(" c = convert entry to new packing method\n"); X printf(" b = retain backup copy of archive\n"); X#if GEMDOS X printf(" h = hold screen after finishing\n"); X#endif X#if MTS X printf(" i = suppress ASCII/EBCDIC translation\n"); X#endif X#if UNIX X printf(" i = suppress image mode (translate EOL)\n"); X#endif X printf(" s = suppress compression (store only)\n"); X printf(" w = suppress warning messages\n"); X printf(" n = suppress notes and comments\n"); X printf(" o = overwrite existing files when"); X printf(" extracting\n"); X printf(" q = squash instead of crunching\n"); X printf(" g = Encrypt/decrypt archive entry\n"); X printf("\nAdapted from MSDOS by Howard Chu\n"); X /* X * printf("\nPlease refer to the program documentation for"); X * printf(" complete instructions.\n"); X */ X#if GEMDOS X exitpause(); X#endif X return 1; X } X /* see where temp files go */ X#if !MTS X arctemp = calloc(1, STRLEN); X if (!(arctemp2 = envfind("ARCTEMP"))) X arctemp2 = envfind("TMPDIR"); X if (arctemp2) { X strcpy(arctemp, arctemp2); X n = strlen(arctemp); X if (arctemp[n - 1] != CUTOFF) X arctemp[n] = CUTOFF; X } X#if !MSDOS X strcat(arctemp, mktemp("AXXXXXX")); X#else X strcat(arctemp, "$ARCTEMP"); X#endif X#else X guinfo("SHFSEP ", gotinf); X sepchr[0] = gotinf[0]; X guinfo("SCRFCHAR", gotinf); X tmpchr[0] = gotinf[0]; X arctemp = "-$$$"; X arctemp[0] = tmpchr[0]; X#endif X X#if !UNIX X /* avoid any case problems with arguments */ X X for (n = 1; n < num; n++) /* for each argument */ X upper(arg[n]); /* convert it to uppercase */ X#else X /* avoid case problems with command options */ X upper(arg[1]); /* convert to uppercase */ X#endif X X /* create archive names, supplying defaults */ X makefnam(arg[2], ".arc", arcname); X /* makefnam(".$$$",arcname,newname); */ X sprintf(newname, "%s.arc", arctemp); X makefnam(".BAK", arcname, bakname); X X /* now scan the command and see what we are to do */ X X for (a = arg[1]; *a; a++) { /* scan the option flags */ X#if !MTS X if (index("AMUFDXEPLVTCR", *a)) { /* if a known command */ X#else X if (index("AMUFDXEPLVTC", *a)) { X#endif X if (opt)/* do we have one yet? */ X abort("Cannot mix %c and %c", opt, *a); X opt = *a; /* else remember it */ X } else if (*a == 'B') /* retain backup copy */ X keepbak = 1; X X else if (*a == 'W') /* suppress warnings */ X warn = 0; X#if !DOS X else if (*a == 'I') /* image mode, no ASCII/EBCDIC x-late */ X image = !image; X#endif X#if GEMDOS X else if (*a == 'H') /* pause before exit */ X hold = 1; X#endif X X else if (*a == 'N') /* suppress notes and comments */ X note = 0; X X else if (*a == 'O') /* overwrite file on extract */ X overlay = 1; X X else if (*a == 'G') { /* garble */ X password = a + 1; X while (*a) X a++; X a--; X#if MTS X etoa(password, strlen(password)); X#endif X } else if (*a == 'S') /* storage kludge */ X nocomp = 1; X X else if (*a == 'K') /* special kludge */ X kludge = 1; X X else if (*a == 'Q') /* use squashing */ X dosquash = 1; X X else if (*a == '-' || *a == '/') /* UNIX and PC-DOS X * option markers */ X ; X X else X abort("%c is an unknown command", *a); X } X X if (!opt) X abort("I have nothing to do!"); X X /* get the files list set up */ X X lnum = num - 3; /* initial length of list */ X lst = (char **) calloc((lnum==0) ? 1:lnum, X sizeof(char *)); /* initial list */ X for (n = 3; n < num; n++) X lst[n - 3] = arg[n]; X X for (n = 0; n < lnum;) {/* expand indirect references */ X if (*lst[n] == '@') X expandlst(n); X else X n++; X } X X /* act on whatever action command was given */ X X switch (opt) { /* action depends on command */ X case 'A': /* Add */ X case 'M': /* Move */ X case 'U': /* Update */ X case 'F': /* Freshen */ X addarc(lnum, lst, (opt == 'M'), (opt == 'U'), (opt == 'F')); X break; X X case 'D': /* Delete */ X delarc(lnum, lst); X break; X X case 'E': /* Extract */ X case 'X': /* eXtract */ X case 'P': /* Print */ X extarc(lnum, lst, (opt == 'P')); X break; X X case 'V': /* Verbose list */ X bose = 1; X case 'L': /* List */ X lstarc(lnum, lst); X break; X X case 'T': /* Test */ X tstarc(); X break; X X case 'C': /* Convert */ X cvtarc(lnum, lst); X break; X#if !MTS X case 'R': /* Run */ X runarc(lnum, lst); X break; X#endif X default: X abort("I don't know how to do %c yet!", opt); X } X#if GEMDOS X if (hold) X exitpause(); X#endif X return nerrs; X} Xstatic Xexpandlst(n) /* expand an indirect reference */ X int n; /* number of entry to expand */ X{ X FILE *lf, *fopen(); /* list file, opener */ X char *malloc(), *realloc(); /* memory managers */ X char buf[100]; /* input buffer */ X int x; /* index */ X char *p = lst[n] + 1; /* filename pointer */ X X if (*p) { /* use name if one was given */ X makefnam(p, ".CMD", buf); X if (!(lf = fopen(buf, "r"))) X abort("Cannot read list of files in %s", buf); X } else X lf = stdin; /* else use standard input */ X X for (x = n + 1; x < lnum; x++) /* drop reference from the list */ X lst[x - 1] = lst[x]; X lnum--; X X while (fscanf(lf, "%99s", buf) > 0) { /* read in the list */ X if (!(lst =(char **)realloc(lst, (lnum + 1) * sizeof(char *)))) X abort("too many file references"); X X lst[lnum] = malloc(strlen(buf) + 1); X strcpy(lst[lnum], buf); /* save the name */ X lnum++; X } X X if (lf != stdin) /* avoid closing standard input */ X fclose(lf); X} ________This_Is_The_END________ if test `wc -c < arc.c` -ne 11146; then echo 'shar: arc.c was damaged during transit (should have been 11146 bytes)' fi fi ; : end of overwriting check echo 'x - arc.h' if test -f arc.h; then echo 'shar: not overwriting arc.h'; else sed 's/^X//' << '________This_Is_The_END________' > arc.h X/* X * $Header: arc.h,v 1.7 88/06/01 17:51:06 hyc Locked $ X */ X X#undef MSDOS X#undef GEMDOS /* This amusing garbage is to get all my */ X#undef DOS /* define's past some compilers, which */ X#undef BSD /* apparently define some of these themselves */ X#undef SYSV X#undef UNIX X#undef MTS X X#define MSDOS 0 /* MSDOS machine */ X#define GEMDOS 0 /* Atari, GEMDOS */ X#define BSD 1 /* BSD4.2 or 4.3 */ X#define SYSV 0 /* Also uses BSD */ X#define MTS 0 /* MTS or 370(?) */ X X/* X * Assumptions: X * char = 8 bits X * short = 16 bits X * long = 32 bits X * int >= 16 bits X */ X X#if MSDOS || GEMDOS X#define DOS 1 X#define CUTOFF '\\' X#endif X X#if !MSDOS X#define envfind getenv X#define setmem(a, b, c) memset(a, c, b) X#endif X X#if BSD || SYSV X#define UNIX 1 X#define CUTOFF '/' X#include <ctype.h> X#endif X X#if MTS X#define rindex strrchr X#define index strchr X#undef USEGFINFO /* define this to use GFINFO for directory */ X#define USECATSCAN /* scanning, else use CATSCAN/FILEINFO... */ X#define CUTOFF sepchr[0] X#endif X X/* ARC - Archive utility - ARC Header 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 is the header file for the ARC archive utility. It defines X global parameters and the references to the external data. X X X Language: X Computer Innovations Optimizing C86 X*/ X X#define ARCMARK 26 /* special archive marker */ X#define ARCVER 9 /* archive header version code */ X#define STRLEN 100 /* system standard string length */ X#define FNLEN 13 /* file name length */ X#define MAXARG 25 /* maximum number of arguments */ X X#ifndef DONT_DEFINE /* Defined by arcdata.c */ X#include "arcs.h" X Xextern int keepbak; /* true if saving the old archive */ X#if !DOS Xextern int image; /* true to suppress CRLF/LF x-late */ X#endif X#if MTS Xextern char sepchr[2]; /* Shared file separator, default = ':' */ Xextern char tmpchr[2]; /* Temporary file prefix, default = '-' */ X#endif X#if GEMDOS Xextern int hold; /* hold screen before exiting */ X#endif Xextern int warn; /* true to print warnings */ Xextern int note; /* true to print comments */ Xextern int bose; /* true to be verbose */ Xextern int nocomp; /* true to suppress compression */ Xextern int overlay; /* true to overlay on extract */ Xextern int kludge; /* kludge flag */ Xextern char *arctemp; /* arc temp file prefix */ Xextern char *password; /* encryption password pointer */ Xextern int nerrs; /* number of errors encountered */ Xextern int changing; /* true if archive being modified */ X Xextern char hdrver; /* header version */ X Xextern FILE *arc; /* the old archive */ Xextern FILE *new; /* the new archive */ Xextern char arcname[STRLEN];/* storage for archive name */ Xextern char bakname[STRLEN];/* storage for backup copy name */ Xextern char newname[STRLEN];/* storage for new archive name */ Xextern unsigned short arcdate; /* archive date stamp */ Xextern unsigned short arctime; /* archive time stamp */ Xextern unsigned short olddate; /* old archive date stamp */ Xextern unsigned short oldtime; /* old archive time stamp */ Xextern int dosquash; /* squash instead of crunch */ X#endif /* DONT_DEFINE */ ________This_Is_The_END________ if test `wc -c < arc.h` -ne 3318; then echo 'shar: arc.h was damaged during transit (should have been 3318 bytes)' fi fi ; : end of overwriting check echo 'x - arcadd.c' if test -f arcadd.c; then echo 'shar: not overwriting arcadd.c'; else sed 's/^X//' << '________This_Is_The_END________' > arcadd.c X/* X * $Header: arcadd.c,v 1.8 88/06/13 00:31:15 hyc Locked $ 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 <stdio.h> X#include "arc.h" X#if MTS X#include <mts.h> X#endif X Xstatic void 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#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 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 if (!strcmp(name[n], name[n + 1])) X abort("Duplicate filenames:\n %s\n %s", path[n], path[n + 1]); X } X openarc(1); /* open archive for changes */ X X for (n = 0; n < nfiles; n++) /* add each file in the list */ X addfile(path[n], name[n], update, fresh); 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 void 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 X#if !MTS X if (!(f = fopen(path, "rb"))) 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; X } 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); X inlen=region->GDINLEN; X buffer=malloc(inlen); /* maximum line length */ X setbuf(f,buffer); X f->_bufsiz=inlen; X f->_mods|=0x00040000; /* Don't do "$continue with" */ X f->_mods&=0xfff7ffff; /* 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; /* skip if not 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; 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; 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 strcpy(nhdr.name, name); 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} ________This_Is_The_END________ if test `wc -c < arcadd.c` -ne 9286; then echo 'shar: arcadd.c was damaged during transit (should have been 9286 bytes)' fi fi ; : end of overwriting check echo 'x - arccode.c' if test -f arccode.c; then echo 'shar: not overwriting arccode.c'; else sed 's/^X//' << '________This_Is_The_END________' > 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 <stdio.h> 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 Xunsigned char Xcode(c) /* encode some character */ X char 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} ________This_Is_The_END________ if test `wc -c < arccode.c` -ne 1204; then echo 'shar: arccode.c was damaged during transit (should have been 1204 bytes)' fi fi ; : end of overwriting check echo 'x - arccvt.c' if test -f arccvt.c; then echo 'shar: not overwriting arccvt.c'; else sed 's/^X//' << '________This_Is_The_END________' > 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 <stdio.h> 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} ________This_Is_The_END________ if test `wc -c < arccvt.c` -ne 3396; then echo 'shar: arccvt.c was damaged during transit (should have been 3396 bytes)' fi fi ; : end of overwriting check echo 'x - arcdata.c' if test -f arcdata.c; then echo 'shar: not overwriting arcdata.c'; else sed 's/^X//' << '________This_Is_The_END________' > arcdata.c X/* X * $Header: arcdata.c,v 1.6 88/06/01 19:17:58 hyc Locked $ 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 <stdio.h> 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 */ ________This_Is_The_END________ if test `wc -c < arcdata.c` -ne 2070; then echo 'shar: arcdata.c was damaged during transit (should have been 2070 bytes)' fi fi ; : end of overwriting check echo 'x - arcdel.c' if test -f arcdel.c; then echo 'shar: not overwriting arcdel.c'; else sed 's/^X//' << '________This_Is_The_END________' > 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 <stdio.h> 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} ________This_Is_The_END________ if test `wc -c < arcdel.c` -ne 2055; then echo 'shar: arcdel.c was damaged during transit (should have been 2055 bytes)' fi fi ; : end of overwriting check echo 'x - arcdos.c' if test -f arcdos.c; then echo 'shar: not overwriting arcdos.c'; else sed 's/^X//' << '________This_Is_The_END________' > arcdos.c X/* X * $Header: arcdos.c,v 1.5 88/06/13 00:40:49 hyc Locked $ 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 <stdio.h> X#include "arc.h" X X#if MSDOS X#include "fileio2.h" /* needed for filehand */ X#endif X X#if UNIX X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/time.h> X#include "tws.h" X#endif X X#if SYSV Xstruct timeval { X long tv_sec; X long tv_usec; X}; X#endif X X#if GEMDOS X#include <osbind.h> 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 char *ctime(); X struct stat *buf; X int day, hr, min, sec, yr, imon; X static char mon[4], *mons[12] = { X "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" X }; X X buf = (struct stat *) malloc(sizeof(struct stat)); X fstat(fileno(f), buf); X X sscanf(ctime(&(buf->st_mtime)), "%*4s%3s%d%d:%d:%d%d", mon, &day, &hr, &min, X &sec, &yr); X for (imon = 0; imon < 12 && strcmp(mon, mons[imon]); imon++); X X *date = (unsigned short) (((yr - 1980) << 9) + ((imon + 1) << 5) + day); X *time = (unsigned short) ((hr << 11) + (min << 5) + 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 tws tms; X struct timeval tvp[2]; X int utimes(); X twscopy(&tms, dtwstime()); X tms.tw_sec = (time & 31) * 2; X tms.tw_min = (time >> 5) & 63; X tms.tw_hour = (time >> 11); X tms.tw_mday = date & 31; X tms.tw_mon = ((date >> 5) & 15) - 1; X tms.tw_year = (date >> 9) + 80; X tms.tw_clock = 0L; X tms.tw_flags = TW_NULL; X tvp[0].tv_sec = twclock(&tms); 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 ________This_Is_The_END________ if test `wc -c < arcdos.c` -ne 5008; then echo 'shar: arcdos.c was damaged during transit (should have been 5008 bytes)' fi fi ; : end of overwriting check echo 'x - arcext.c' if test -f arcext.c; then echo 'shar: not overwriting arcext.c'; else sed 's/^X//' << '________This_Is_The_END________' > 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 <stdio.h> X#include "arc.h" X#if !MSDOS X#include <ctype.h> 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 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 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, "wb"))) 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} ________This_Is_The_END________ if test `wc -c < arcext.c` -ne 4898; then echo 'shar: arcext.c was damaged during transit (should have been 4898 bytes)' fi fi ; : end of overwriting check echo 'x - arcio.c' if test -f arcio.c; then echo 'shar: not overwriting arcio.c'; else sed 's/^X//' << '________This_Is_The_END________' > arcio.c X/* X * $Header: arcio.c,v 1.7 88/06/02 16:27:32 hyc Locked $ 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 <stdio.h> X#include "arc.h" X#if MTS X#include <ctype.h> 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; 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; 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#else X if (fputc(c, t) == EOF) X abort("Write fail (disk full?)"); X#endif 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 <fileio2.h> 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 ________This_Is_The_END________ if test `wc -c < arcio.c` -ne 7418; then echo 'shar: arcio.c was damaged during transit (should have been 7418 bytes)' fi fi ; : end of overwriting check echo 'x - arclst.c' if test -f arclst.c; then echo 'shar: not overwriting arclst.c'; else sed 's/^X//' << '________This_Is_The_END________' > 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 <stdio.h> 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} ________This_Is_The_END________ if test `wc -c < arclst.c` -ne 4418; then echo 'shar: arclst.c was damaged during transit (should have been 4418 bytes)' fi fi ; : end of overwriting check exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.