From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP  2-SEP-1988 09:31
To:	ARISIA::EVERHART
Subj:	ARC mods 2/7


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu,  1 SEP 88 06:28:20 PDT
Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Thu, 1 Sep 88 06:04:56 PDT
Received: from UKACRL.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 7780; Thu, 01 Sep 88 09:01:14 EDT
Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 3194; Thu,
 01 Sep 88 13:58:36 BST
Received: from RL.IB by UK.AC.RL.IB (Mailer X1.25) with BSMTP id 3184; Thu, 01
          Sep 88 13:58:34 BS
Via:      UK.AC.KCL.CC.OAK;  1 SEP 88 13:57:14 BST
Date:     1-SEP-1988 13:57:58 GMT
From:     UDAA055%OAK.CC.KCL.AC.UK@CUNYVM.CUNY.EDU
To:       info-vax@KL.SRI.COM
Subject:  ARC mods 2/7
Sender:   Andy Harper, Kings College London <A.Harper%OAK.CC.KCL.AC.UK@CUNYVM.CUNY.EDU>

+-+-+-+ Beginning of part 2 +-+-+-+
X         cvtarc(num-3,&arg[3]);
X         break;
X
X    case 'R':                          /* Run */
X         runarc(num-3,&arg[3]);
X         break;
X
X    default:
X         abort("I don't know how to do %c yet!",opt);
X    
X#ifdef VAXC
X    printvmsstats();
X#endif VAXC
X#ifndef VAXC
X    return nerrs;
X#endif
X
$ GOSUB UNPACK_FILE
$ FILE_IS = "ARC.H"
$ CHECKSUM_IS = 1313831668
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X * $Header: arc.h,v 1.2 86/07/15 07:52:34 turner Exp $
X */
X
X/*
X * $Log:`009arc.h,v $
X * VAXC modifications       31-AUG-1988`009`009Andy Harper, KCL
X * Separated VAXC and BSD dependencies
X *
X * Hack-attack 1.3  86/12/20  01:23:45  wilhite@usceast.uucp
X * `009Bludgeoned into submission for VAX 11/780 BSD4.2
X *`009(ugly code, but fewer core dumps)
X *
X * Revision 1.2  86/07/15  07:52:34  turner
X *
X *
X * Revision 1.1  86/06/26  15:01:23  turner
X * initial version
X *
X *
X */
X
X#define`009ST`0090`009/* Atari 520ST or 1040 `009`009 */
X#define BSD`0090`009/* BSD4.2 on a vax`009`009 */
X#define MSDOS`0090`009/* MSDOS on an IBM PC or Wannabe */
X
X#if ST
X#define EXTERN
X#define INT short
X#endif
X
X#if BSD
X#include <ctype.h>`009/* for isupper etc.                  */
X#define EXTERN
X#define INT short
X#define envfind getenv
X#endif
X
X#if MSDOS
X#define EXTERN extern
X#define INT int
X#endif
X
X#ifdef VAXC
X#include <ctype.h>
X#define EXTERN
X#define INT short
X#define envfind getenv
X#define abort vabort
X#define unlink(x) delete(x)
X#endif
X
X/*
X * added macro def's in C format 6/26/86 jmt
X */
X#include "arcm.h"
X
X/*  ARC - Archive utility - ARC Header
X
X    Version 2.14, created on 02/03/86 at 22:48:29
X
X(C) COPYRIGHT 1985 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#include "arcs.h"
X
XEXTERN INT keepbak;             /* true if saving the old archive */
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 kludge;              /* kludge flag */
XEXTERN char arctemp[STRLEN];       /* arc temp file prefix */
XEXTERN char *password;          /* encryption password pointer */
XEXTERN INT nerrs;               /* number of errors encountered */
X
XEXTERN char hdrver;                      /* header version */
X
XEXTERN FILE *arc;                        /* the old archive */
XEXTERN FILE *new;                        /* the new archive */
X
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 INT arcdate;    /* archive date stamp */
XEXTERN unsigned INT arctime;    /* archive time stamp */
XEXTERN int dosquash;
X
X#ifdef VAXC
XEXTERN int vmsstats;`009`009/* Flag for VMS statistics */
X#endif VAXC
$ GOSUB UNPACK_FILE
$ FILE_IS = "ARC.HLP"
$ CHECKSUM_IS = 708345932
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X
X! HELP file for the ARC file archiver utility
X!     Author:   Andy Harper, Kings College London for ARC 5.12
X!
X1 ARC
X
XThe ARC utility is an implementation of the 'ar' utility found on most
Xunix systems. It provides the ability to copy a whole series of files
Xinto a single large file known as an 'archive' (Hence the names 'ar' and
X'ARC'). ARC can al;so encrypt and compress the stored files.
X
XSyntax:
X
X     $ ARC options archivefilename [filespecs]
X2 Archivefilename
X
XThis is the name of the archive file, in which all the files are stored.
XThe default filetype extension is  ".ARC"
X
X2 Examples
X
X     ARC A TEST.ARC *.H
X         Create (if necessary) an archive file called "TEST.ARC"; then
X         add to it all files matching the filespec  "*.H".  If the
X         archive file already exists, files are added to the existing
X         one; if a file being added already exists in the archive, then
X         it is replaced by the new one.
X
X     ARC ABS% TEST.ARC *.H
X         As above but also: retain backup (B), suppress compression (S),
X         and print VMS statistics (%).
X
X     ARC L TEST.ARC
X         List all the files in the archive called "TEST.ARC"
X
X     ARC X  TEST.ARC  FRED.H
X         Extract the file "FRED.H" from the archive "TEST.ARC" and
X         create a new file with the same name.
X
X2 Filespecs
X
XThese are the names of the files to be stored in or retrieved from the
Xarchive. Normal VMS wildcards may be used.  Where an option is selected
Xwhich requires a filespec, a default of *.* is assumed.
X
X2 Options
X
XThe option parameter to ARC determines what is to be done to the
Xarchive. Each option is a single letter.
X
X3 Actions
X
XAction options control the basic operation of the archive run, as
Xfollows:
X
X   A   Add files to the archive
X   M   Move files to the archive
X   U   Update files in the archive
X   F   Freshen files in the archive
X   D   Delete files from the archive
X   X,E Extract files from the archive
X   R   Run files from the archive
X   P   Print files from the archive
X   L   List names of files in the archive, plus basic info.
X   V   List names of files in the archive, plus all info
X   T   Test integrity of archive
X   C   Convert archi9ve entry to new packing method
X3 Controls
X
XControl options modify the basic action of the selected action option:
X
X   B    Retain the backup archive copy (normally deleted)
X   S    Suppress compression of file
X   W    Suppress warning messages
X   N    Suppress notes and comments
X   %    Print VMS statistics on completion.
X   Q    Use 'squash' rather than 'crunch' compression
X3 Encryption
X
XEncryption options control the encryption/decryption of files
Xadded to/extracted from the archive:
X
X   G<password>  Encrypt/decrypt file using a password of <password>
$ GOSUB UNPACK_FILE
$ FILE_IS = "ARCADD.C"
$ CHECKSUM_IS = 877191898
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
Xstatic char *RCSid = "$Header: arcadd.c,v 1.2 86/07/15 07:52:37 turner Exp $";
X
X/*
X * Modified 1-sep-1988  Andy Harper, Kings College london
X * Get around bug caused by filenames longer than the FNLEN constant. A
X * proper fix requires a new archive header that allows very long
X * filenames (At least as long as STRLEN).
X *
X *
X * $Log:`009arcadd.c,v $
X * Hack-attack 1.3  86/12/20  01:23:45  wilhite@usceast.uucp
X * `009Bludgeoned into submission for VAX 11/780 BSD4.2
X *`009(ugly code, but fewer core dumps)
X *
X * Revision 1.2  86/07/15  07:52:37  turner
X *
X *
X * Revision 1.1  86/06/26  14:59:37  turner
X * initial version
X *
X *
X */
X
X/*  ARC - Archive utility - ARCADD
X
X$define(tag,$$segment(@1,$$index(@1,=)+1))#
X$define(version,Version $tag(
XTED_VERSION DB =3.39), created on $tag(
XTED_DATE DB =02/05/86) at $tag(
XTED_TIME DB =22:21:53))#
X$undefine(tag)#
X    $version
X
X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
X
X    By:  Thom Henderson
X
X    Description:
X         This file contains the routines used to add files to an archive.
X
X    Language:
X         Computer Innovations Optimizing C86
X*/
X#include <stdio.h>
X#include "arc.h"
X#ifdef VAXC
X#include "dir.h"
X#endif VAXC
X
XINT addarc(num,arg,move,update,fresh)      /* add files to archive */
XINT num;                               /* number of arguments */
Xchar *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 *NameList;`009/* Any pointer.  Used to pass file names around */
X    char buf[STRLEN];                 /* pathname buffer */
X    char **path = NULL;                /* pointer to pointers to paths */
X    char **name = NULL;                /* 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 m, n;                          /* indices */
X    unsigned INT coreleft();           /* remaining memory reporter */
X    INT addbunch();
X
X    if(num<1)                          /* if no files named */
X    $    num = 1;                      /* then fake one */
X         arg[0] = "*.*";               /* add everything */
X`009 printf("%%ARC-I-NOSPEC, File not specfied.  Defaulting to *.*\n");
X    
X
X    for(n=0; n<num; n++)               /* for each template supplied */
X    $
X#ifdef VAXC
X/* We do not plan on using this... Take a look at the code where we talk
X * about the VMS file spec for more info... (down a page or so)
X */
X         strcpy(buf,arg[n]);           /* get ready to fix path */
X`009 (void) parsedir(buf, 0, PARSE_NODE|PARSE_DEVICE|PARSE_DIRECTORY);
X`009 i = buf + strlen(buf);`009`009/* Point to null byte */
X#else
X         strcpy(buf,arg[n]);           /* get ready to fix path */
X         if(!(i=rindex(buf,'\\')))
X              if(!(i=rindex(buf,'/')))
X                   if(!(i=rindex(buf,':')))
X                        i = buf-1;
X         i++;                          /* pointer to where name goes */
X#endif VAXC
X         notemp = 1;                   /* reset files flag */
X         NameList = (char *) malloc(sizeof(char *));
X         for(d=dir(arg[n],0,NameList); d; d=dir(NULL,0,NameList))
X         $    notemp = 0;              /* template is giving results */
X              nfiles++;                /* add each matching file */
X#ifdef VAXC
X/* For VMS */
X`009      if (!path)
X`009      $
X`009`009path = (char **)malloc(sizeof(char **));
X`009`009name = (char **)malloc(sizeof(char **));
X`009      
X#endif VAXC
X              path = (char **)realloc(path,nfiles*sizeof(char **));
X              name = (char **)realloc(name,nfiles*sizeof(char **));
X#ifdef VAXC
X/*
X * For VMS, we are passing the whole filespec back from the directory
X * routines.  We do this as a person might specify [...]*.h which we
X * would need to have the directory of the filespec to do the open!
X * (node::device:[directory]filename.extension;version)
X */
X              strcpy(i,d);             /* put name in path */
X              path[nfiles-1] = malloc(strlen(buf)+1);
X              strcpy(path[nfiles-1],buf);
X/*
X * name[] is pointing at the WHOLE filespec, not the file name.
X * file parsing will have to be done later on to get the filename
X * and extension that are needed.
X */
X
X`009      (void) parsedir(d, 0, PARSE_NAME|PARSE_TYPE);
X`009      name[nfiles-1] = d;
X#else
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#endif VAXC
X
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); 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); free(name);
X    
X
X    if(nowork && warn)
X         printf("No files were added.\n");
X
X
XINT addbunch(nfiles,path,name,move,update,fresh) /* add a bunch of files */
XINT nfiles;                            /* number of files to add */
Xchar **path;                           /* pointers to pathnames */
Xchar **name;                           /* pointers to filenames */
XINT move;                              /* true if moving file */
XINT update;                            /* true if updating */
XINT fresh;                             /* true if freshening */
X$
X    char buf[STRLEN];                 /* pathname buffer */
X INT m, n;                          /* indices */
X    char *d;                           /* swap pointer */
X    struct heads hdr;                  /* file header data storage */
X    INT addfile();
X    INT izadir();`009`009   /* used to weed-out directories */
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         || izadir(path[n])            /* or directory */
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         
X         else 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    || izadir(path[n])
X    || !strcmp(path[n],bakname))
X    $    free(path[n]);
X         free(name[n]);
X         nfiles--;
X    
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 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
-+-+-+-+-+ End of part 2 +-+-+-+-+-

