ewilts%Ins.MRC.AdhocNet.CA%Stasis.MRC.AdhocNet.CA%UNCAEDU.@CORNELLC.CCS.CORNELL.EDU.BITNET (Ed Wilts) (06/24/88)
$Part02:
$ File_is="ARCADD.C"
$ Check_Sum_is=775976552
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
Xstatic char *RCSid = "$Header: arcadd.c,v 1.2 86/07/15 07:52:37 turner Exp $";
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
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 added */
X { if(unlink(path[n]) && warn)
X { printf("Cannot unsave %s\n",path[n]);
X nerrs++;
X }
X }
X }
X
X return nfiles; /* say how many were added */
X}
X
Xstatic INT addfile(path,name,update,fresh) /* add named file to archive */
Xchar *path; /* path name of file to add */
Xchar *name; /* name of file to add */
XINT update; /* true if updating */
XINT 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 c; /* one char of file */
X INT upd = 0; /* true if replacing an entry */
X
X if(!(f=fopen(path,"r")))
X { if(warn)
X { printf("Cannot read file: %s\n",path);
X nerrs++;
X }
X return;
X }
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 getstamp(f,&nhdr.date,&nhdr.time);
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 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
X if(strcmp(ohdr.name,nhdr.name)>=0)
X break; /* found our spot */
X
X writehdr(&ohdr,new); /* entry preceeds update; 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); fflush(stdout);}
X fseek(arc,ohdr.size,1);
X }
X else if(fresh) /* else if freshening */
X { fseek(arc,starts,0); /* then do not add files */
X fclose(f);
X return;
X }
X else /* else adding a new file */
X { if(note)
X { printf("Adding file: %-12s ",name); fflush(stdout);}
X fseek(arc,starts,0); /* reset for next time */
X }
X }
X
X else /* no existing archive */
X { if(fresh) /* cannot freshen nothing */
X { fclose(f);
X return;
X }
X else if(note) /* else adding a file */
X { printf("Adding file: %-12s ",name); fflush(stdout);}
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}
X
$ GoSub Convert_File
$ File_is="ARCCODE.C"
$ Check_Sum_is=1750696541
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
Xstatic char *RCSid = "$Header: arccode.c,v 1.1 86/06/26 14:59:53 turner Exp $";
X
X/*
X * $Log:`009arccode.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.1 86/06/26 14:59:53 turner
X * initial version
X *
X *
X */
X
X/* ARC - Archive utility - ARCCODE
X
X$define(tag,$$segment(@1,$$index(@1,=)+1))#
X$define(version,Version $tag(
XTED_VERSION DB =1.02), created on $tag(
XTED_DATE DB =01/20/86) at $tag(
XTED_TIME DB =13:33:35))#
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 encrypt and decrypt
X data in an archive. The encryption method is nothing fancy,
X being just a routine XOR, but it is used on the packed data,
X and uses a variable length key. The end result is something
X that is in theory crackable, but I'd hate to try it. It should
X be more than sufficient for casual use.
X
X Language:
X Computer Innovations Optimizing C86
X*/
X#include <stdio.h>
X#include "arc.h"
X
Xstatic char *p; /* password pointer */
X
XINT setcode() /* get set for encoding/decoding */
X{
X p = password; /* reset password pointer */
X}
X
XINT code(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 }
X else return c; /* else no encryption */
X}
X
$ GoSub Convert_File
$ Goto Part03