home *** CD-ROM | disk | FTP | other *** search
- /* ARC - Archive utility - ARCADD
-
- Version 3.40, created on 06/18/86 at 13:10:18
-
- (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
-
- By: Thom Henderson
-
- Description:
- This file contains the routines used to add files to an archive.
-
- Language:
- Computer Innovations Optimizing C86
- */
- #include <stdio.h>
- #include "arc.h"
-
- addarc(num,arg,move,update,fresh) /* add files to archive */
- int num; /* number of arguments */
- char *arg[]; /* pointers to arguments */
- int move; /* true if moving file */
- int update; /* true if updating */
- int fresh; /* true if freshening */
- {
- char *d, *dir(); /* directory junk */
- char buf[100]; /* pathname buffer */
- char **path = NULL; /* pointer to pointers to paths */
- char **name = NULL; /* pointer to pointers to names */
- int nfiles = 0; /* number of files in lists */
- int notemp; /* true until a template works */
- int nowork = 1; /* true until files are added */
- char *i, *rindex(); /* string indexing junk */
- char *alloc(), *realloc(); /* memory allocators */
- int m, n; /* indices */
- unsigned int coreleft(); /* remaining memory reporter */
-
- if(num<1) /* if no files named */
- { num = 1; /* then fake one */
- arg[0] = "*.*"; /* add everything */
- }
-
- for(n=0; n<num; n++) /* for each template supplied */
- { strcpy(buf,arg[n]); /* get ready to fix path */
- if(!(i=rindex(buf,'\\')))
- if(!(i=rindex(buf,'/')))
- if(!(i=rindex(buf,':')))
- i = buf-1;
- i++; /* pointer to where name goes */
-
- notemp = 1; /* reset files flag */
- for(d=dir(arg[n],0); *d; d=dir(NULL,0))
- { notemp = 0; /* template is giving results */
- nfiles++; /* add each matching file */
- path = (char **)realloc(path,nfiles*sizeof(char **));
- name = (char **)realloc(name,nfiles*sizeof(char **));
- strcpy(i,d); /* put name in path */
- path[nfiles-1] = alloc(strlen(buf)+1);
- strcpy(path[nfiles-1],buf);
- name[nfiles-1] = d; /* save name */
-
- if(coreleft()<5120)
- { nfiles = addbunch(nfiles,path,name,move,update,fresh);
- nowork = nowork && !nfiles;
- while(nfiles)
- { free(path[--nfiles]);
- free(name[nfiles]);
- }
- free(path); free(name);
- path = name = NULL;
- }
- }
- if(notemp && warn)
- printf("No files match: %s\n",arg[n]);
- }
-
- if(nfiles)
- { nfiles = addbunch(nfiles,path,name,move,update,fresh);
- nowork = nowork && !nfiles;
- while(nfiles)
- { free(path[--nfiles]);
- free(name[nfiles]);
- }
- free(path); free(name);
- }
-
- if(nowork && warn)
- printf("No files were added.\n");
- }
-
- int addbunch(nfiles,path,name,move,update,fresh) /* add a bunch of files */
- int nfiles; /* number of files to add */
- char **path; /* pointers to pathnames */
- char **name; /* pointers to filenames */
- int move; /* true if moving file */
- int update; /* true if updating */
- int fresh; /* true if freshening */
- {
- char buf[100]; /* pathname buffer */
- int m, n; /* indices */
- char *d; /* swap pointer */
- struct heads hdr; /* file header data storage */
-
- for(n=0; n<nfiles-1; n++) /* sort the list of names */
- { for(m=n+1; m<nfiles; m++)
- { if(strcmp(name[n],name[m])>0)
- { d = path[n];
- path[n] = path[m];
- path[m] = d;
- d = name[n];
- name[n] = name[m];
- name[m] = d;
- }
- }
- }
-
- for(n=0; n<nfiles-1; ) /* consolidate the list of names */
- { if(!strcmp(path[n],path[n+1]) /* if duplicate names */
- || !strcmp(path[n],arcname) /* or this archive */
- || !strcmp(path[n],newname) /* or the new version */
- || !strcmp(path[n],bakname)) /* or its backup */
- { free(path[n]); /* then forget the file */
- free(name[n]);
- for(m=n; m<nfiles-1; m++)
- { path[m] = path[m+1];
- name[m] = name[m+1];
- }
- nfiles--;
- }
- else n++; /* else test the next one */
- }
-
- if(!strcmp(path[n],arcname) /* special check for last file */
- || !strcmp(path[n],newname) /* courtesy of Rick Moore */
- || !strcmp(path[n],bakname))
- { free(path[n]);
- free(name[n]);
- nfiles--;
- }
-
- if(!nfiles) /* make sure we got some */
- return 0;
-
- for(n=0; n<nfiles-1; n++) /* watch out for duplicate names */
- if(!strcmp(name[n],name[n+1]))
- abort("Duplicate filenames:\n %s\n %s",path[n],path[n+1]);
-
- openarc(1); /* open archive for changes */
-
- for(n=0; n<nfiles; n++) /* add each file in the list */
- addfile(path[n],name[n],update,fresh);
-
- /* now we must copy over all files that follow our additions */
-
- while(readhdr(&hdr,arc)) /* while more entries to copy */
- { writehdr(&hdr,new);
- filecopy(arc,new,hdr.size);
- }
- hdrver = 0; /* archive EOF type */
- writehdr(&hdr,new); /* write out our end marker */
- closearc(1); /* close archive after changes */
-
- if(move) /* if this was a move */
- { for(n=0; n<nfiles; n++) /* then delete each file added */
- { if(unlink(path[n]) && warn)
- { printf("Cannot unsave %s\n",path[n]);
- nerrs++;
- }
- }
- }
-
- return nfiles; /* say how many were added */
- }
-
- static addfile(path,name,update,fresh) /* add named file to archive */
- char *path; /* path name of file to add */
- char *name; /* name of file to add */
- int update; /* true if updating */
- int fresh; /* true if freshening */
- {
- struct heads nhdr; /* data regarding the new file */
- struct heads ohdr; /* data regarding an old file */
- FILE *f, *fopen(); /* file to add, opener */
- long starts, ftell(); /* file locations */
- int c; /* one char of file */
- int upd = 0; /* true if replacing an entry */
-
- if(!(f=fopen(path,"rb")))
- { if(warn)
- { printf("Cannot read file: %s\n",path);
- nerrs++;
- }
- return;
- }
-
- strcpy(nhdr.name,name); /* save name */
- nhdr.size = 0; /* clear out size storage */
- nhdr.crc = 0; /* clear out CRC check storage */
- getstamp(f,&nhdr.date,&nhdr.time);
-
- /* position archive to spot for new file */
-
- if(arc) /* if adding to existing archive */
- { starts = ftell(arc); /* where are we? */
- while(readhdr(&ohdr,arc)) /* while more files to check */
- { if(!strcmp(ohdr.name,nhdr.name))
- { upd = 1; /* replace existing entry */
- if(update || fresh) /* if updating or freshening */
- { if(nhdr.date<ohdr.date
- || (nhdr.date==ohdr.date && nhdr.time<=ohdr.time))
- { fseek(arc,starts,0);
- fclose(f);
- return; /* skip if not newer */
- }
- }
- }
-
- if(strcmp(ohdr.name,nhdr.name)>=0)
- break; /* found our spot */
-
- writehdr(&ohdr,new); /* entry preceeds update; keep it */
- filecopy(arc,new,ohdr.size);
- starts = ftell(arc); /* now where are we? */
- }
-
- if(upd) /* if an update */
- { if(note)
- printf("Updating file: %-12s ",name);
- fseek(arc,ohdr.size,1);
- }
- else if(fresh) /* else if freshening */
- { fseek(arc,starts,0); /* then do not add files */
- fclose(f);
- return;
- }
- else /* else adding a new file */
- { if(note)
- printf("Adding file: %-12s ",name);
- fseek(arc,starts,0); /* reset for next time */
- }
- }
-
- else /* no existing archive */
- { if(fresh) /* cannot freshen nothing */
- { fclose(f);
- return;
- }
- else if(note) /* else adding a file */
- printf("Adding file: %-12s ",name);
- }
-
- starts = ftell(new); /* note where header goes */
- hdrver = 8; /* anything but end marker */
- writehdr(&nhdr,new); /* write out header skeleton */
- pack(f,new,&nhdr); /* pack file into archive */
- fseek(new,starts,0); /* move back to header skeleton */
- writehdr(&nhdr,new); /* write out real header */
- fseek(new,nhdr.size,1); /* skip over data to next header */
- fclose(f); /* all done with the file */
- }
-