home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8707 / 64 / arcadd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  11.1 KB  |  291 lines

  1. static char *RCSid = "$Header: arcadd.c,v 1.2 86/07/15 07:52:37 turner Exp $";
  2.  
  3. /*
  4.  * $Log:    arcadd.c,v $
  5.  * Hack-attack 1.3  86/12/20  01:23:45  wilhite@usceast.uucp
  6.  *     Bludgeoned into submission for VAX 11/780 BSD4.2
  7.  *    (ugly code, but fewer core dumps)
  8.  *
  9.  * Revision 1.2  86/07/15  07:52:37  turner
  10.  * 
  11.  * Revision 1.1  86/06/26  14:59:37  turner
  12.  * initial version
  13.  * 
  14.  */
  15.  
  16. /*  ARC - Archive utility - ARCADD
  17.  
  18. $define(tag,$$segment(@1,$$index(@1,=)+1))#
  19. $define(version,Version $tag(
  20. TED_VERSION DB =3.39), created on $tag(
  21. TED_DATE DB =02/05/86) at $tag(
  22. TED_TIME DB =22:21:53))#
  23. $undefine(tag)#
  24.     $version
  25.  
  26. (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  27.  
  28.     By:  Thom Henderson
  29.  
  30.     Description:
  31.          This file contains the routines used to add files to an archive.
  32.  
  33.     Language:
  34.          Computer Innovations Optimizing C86
  35. */
  36. #include <stdio.h>
  37. #include "arc.h"
  38.  
  39. INT addarc(num,arg,move,update,fresh)      /* add files to archive */
  40. INT num;                               /* number of arguments */
  41. char *arg[];                           /* pointers to arguments */
  42. INT move;                              /* true if moving file */
  43. INT update;                            /* true if updating */
  44. INT fresh;                             /* true if freshening */
  45. {
  46.     char *d, *dir();                   /* directory junk */
  47.     char *NameList;    /* Any pointer.  Used to pass file names around */
  48.     char buf[STRLEN];                 /* pathname buffer */
  49.     char **path = NULL;                /* pointer to pointers to paths */
  50.     char **name = NULL;                /* pointer to pointers to names */
  51.  INT nfiles = 0;                    /* number of files in lists */
  52.  INT notemp;                        /* true until a template works */
  53.  INT nowork = 1;                    /* true until files are added */
  54.     char *i, *rindex();                /* string indexing junk */
  55.     char *malloc(), *realloc();         /* memory allocators */
  56.  INT m, n;                          /* indices */
  57.     unsigned INT coreleft();           /* remaining memory reporter */
  58.     INT addbunch();
  59.  
  60.     if(num<1)                          /* if no files named */
  61.     {    num = 1;                      /* then fake one */
  62.          arg[0] = "*.*";               /* add everything */
  63.     }
  64.  
  65.     for(n=0; n<num; n++)               /* for each template supplied */
  66.     {
  67.          strcpy(buf,arg[n]);           /* get ready to fix path */
  68.          if(!(i=rindex(buf,'\\')))
  69.               if(!(i=rindex(buf,'/')))
  70.                    if(!(i=rindex(buf,':')))
  71.                         i = buf-1;
  72.          i++;                          /* pointer to where name goes */
  73.  
  74.          notemp = 1;                   /* reset files flag */
  75.          NameList = (char *) malloc(sizeof(char *));
  76.          for(d=dir(arg[n],0,NameList); d; d=dir(NULL,0,NameList))
  77.          {    notemp = 0;              /* template is giving results */
  78.               nfiles++;                /* add each matching file */
  79.               path = (char **)realloc(path,nfiles*sizeof(char **));
  80.               name = (char **)realloc(name,nfiles*sizeof(char **));
  81.               strcpy(i,d);             /* put name in path */
  82.               path[nfiles-1] = malloc(strlen(buf)+1);
  83.               strcpy(path[nfiles-1],buf);
  84.               name[nfiles-1] = d;      /* save name */
  85.  
  86. #if MSDOS
  87.               if(coreleft()<5120)
  88.               {    nfiles = addbunch(nfiles,path,name,move,update,fresh);
  89.                    nowork = nowork && !nfiles;
  90.                    while(nfiles)
  91.                    {    free(path[--nfiles]);
  92.                         free(name[nfiles]);
  93.                    }
  94.                    free(path); free(name);
  95.                    path = name = NULL;
  96.               }
  97. #endif
  98.          }
  99.          if(notemp && warn)
  100.               printf("No files match: %s\n",arg[n]);
  101.     }
  102.  
  103.     if(nfiles)
  104.     {    nfiles = addbunch(nfiles,path,name,move,update,fresh);
  105.          nowork = nowork && !nfiles;
  106.          while(nfiles)
  107.          {    free(path[--nfiles]);
  108.               free(name[nfiles]);
  109.          }
  110.          free(path); free(name);
  111.     }
  112.  
  113.     if(nowork && warn)
  114.          printf("No files were added.\n");
  115. }
  116.  
  117. INT addbunch(nfiles,path,name,move,update,fresh) /* add a bunch of files */
  118. INT nfiles;                            /* number of files to add */
  119. char **path;                           /* pointers to pathnames */
  120. char **name;                           /* pointers to filenames */
  121. INT move;                              /* true if moving file */
  122. INT update;                            /* true if updating */
  123. INT fresh;                             /* true if freshening */
  124. {
  125.     char buf[STRLEN];                 /* pathname buffer */
  126.  INT m, n;                          /* indices */
  127.     char *d;                           /* swap pointer */
  128.     struct heads hdr;                  /* file header data storage */
  129.     INT addfile();
  130.     INT izadir();           /* used to weed-out directories */
  131.  
  132.     for(n=0; n<nfiles-1; n++)          /* sort the list of names */
  133.     {    for(m=n+1; m<nfiles; m++)
  134.          {    if(strcmp(name[n],name[m])>0)
  135.               {    d = path[n];
  136.                    path[n] = path[m];
  137.                    path[m] = d;
  138.                    d = name[n];
  139.                    name[n] = name[m];
  140.                    name[m] = d;
  141.               }
  142.          }
  143.     }
  144.  
  145.     for(n=0; n<nfiles-1; )             /* consolidate the list of names */
  146.     {    if(!strcmp(path[n],path[n+1]) /* if duplicate names */
  147.          || !strcmp(path[n],arcname)   /* or this archive */
  148.          || izadir(path[n])            /* or directory */
  149.          || !strcmp(path[n],newname)   /* or the new version */
  150.          || !strcmp(path[n],bakname))  /* or its backup */
  151.          {    free(path[n]);           /* then forget the file */
  152.               free(name[n]);
  153.               for(m=n; m<nfiles-1; m++)
  154.               {    path[m] = path[m+1];
  155.                    name[m] = name[m+1];
  156.               }
  157.               nfiles--;
  158.          }
  159.          else n++;                     /* else test the next one */
  160.     }
  161.  
  162.     if(!strcmp(path[n],arcname)        /* special check for last file */
  163.     || !strcmp(path[n],newname)        /* courtesy of Rick Moore */
  164.     || izadir(path[n])
  165.     || !strcmp(path[n],bakname))
  166.     {    free(path[n]);
  167.          free(name[n]);
  168.          nfiles--;
  169.     }
  170.  
  171.     if(!nfiles)                        /* make sure we got some */
  172.          return 0;
  173.  
  174.     for(n=0; n<nfiles-1; n++)          /* watch out for duplicate names */
  175.          if(!strcmp(name[n],name[n+1]))
  176.               abort("Duplicate filenames:\n  %s\n  %s",path[n],path[n+1]);
  177.  
  178.     openarc(1);                        /* open archive for changes */
  179.  
  180.     for(n=0; n<nfiles; n++)            /* add each file in the list */
  181.          addfile(path[n],name[n],update,fresh);
  182.  
  183.     /* now we must copy over all files that follow our additions */
  184.  
  185.     while(readhdr(&hdr,arc))           /* while more entries to copy */
  186.     {    writehdr(&hdr,new);
  187.          filecopy(arc,new,hdr.size);
  188.     }
  189.     hdrver = 0;                        /* archive EOF type */
  190.     writehdr(&hdr,new);                /* write out our end marker */
  191.     closearc(1);                       /* close archive after changes */
  192.  
  193.     if(move)                           /* if this was a move */
  194.     {    for(n=0; n<nfiles; n++)       /* then delete each file added */
  195.          {    if(unlink(path[n]) && warn)
  196.               {    printf("Cannot unsave %s\n",path[n]);
  197.                    nerrs++;
  198.               }
  199.          }
  200.     }
  201.  
  202.     return nfiles;                     /* say how many were added */
  203. }
  204.  
  205. static INT addfile(path,name,update,fresh) /* add named file to archive */
  206. char *path;                            /* path name of file to add */
  207. char *name;                            /* name of file to add */
  208. INT update;                            /* true if updating */
  209. INT fresh;                             /* true if freshening */
  210. {
  211.     struct heads nhdr;                 /* data regarding the new file */
  212.     struct heads ohdr;                 /* data regarding an old file */
  213.     FILE *f, *fopen();                 /* file to add, opener */
  214.     long starts, ftell();              /* file locations */
  215.  INT c;                             /* one char of file */
  216.  INT upd = 0;                       /* true if replacing an entry */
  217.  
  218.     if(!(f=fopen(path,"r")))
  219.     {    if(warn)
  220.          {    printf("Cannot read file: %s\n",path);
  221.               nerrs++;
  222.          }
  223.          return;
  224.     }
  225.  
  226.     strcpy(nhdr.name,name);            /* save name */
  227.     nhdr.size = 0;                     /* clear out size storage */
  228.     nhdr.crc = 0;                      /* clear out CRC check storage */
  229.     getstamp(f,&nhdr.date,&nhdr.time);
  230.  
  231.     /* position archive to spot for new file */
  232.  
  233.     if(arc)                            /* if adding to existing archive */
  234.     {    starts = ftell(arc);          /* where are we? */
  235.          while(readhdr(&ohdr,arc))     /* while more files to check */
  236.          {    if(!strcmp(ohdr.name,nhdr.name))
  237.               {    upd = 1;            /* replace existing entry */
  238.                    if(update || fresh) /* if updating or freshening */
  239.                    {    if(nhdr.date<ohdr.date
  240.                         || (nhdr.date==ohdr.date && nhdr.time<=ohdr.time))
  241.                         {    fseek(arc,starts,0);
  242.                              fclose(f);
  243.                              return;   /* skip if not newer */
  244.                         }
  245.                    }
  246.               }
  247.  
  248.               if(strcmp(ohdr.name,nhdr.name)>=0)
  249.                    break;              /* found our spot */
  250.  
  251.               writehdr(&ohdr,new);     /* entry preceeds update; keep it */
  252.               filecopy(arc,new,ohdr.size);
  253.               starts = ftell(arc);     /* now where are we? */
  254.          }
  255.  
  256.          if(upd)                       /* if an update */
  257.          {    if(note)
  258.                  { printf("Updating file: %-12s  ",name); fflush(stdout);}
  259.               fseek(arc,ohdr.size,1);
  260.          }
  261.          else if(fresh)                /* else if freshening */
  262.          {    fseek(arc,starts,0);     /* then do not add files */
  263.               fclose(f);
  264.               return;
  265.          }
  266.          else                          /* else adding a new file */
  267.          {    if(note)
  268.                  { printf("Adding file:   %-12s  ",name); fflush(stdout);}
  269.               fseek(arc,starts,0);     /* reset for next time */
  270.          }
  271.     }
  272.  
  273.     else                               /* no existing archive */
  274.     {    if(fresh)                     /* cannot freshen nothing */
  275.          {    fclose(f);
  276.               return;
  277.          }
  278.          else if(note)                 /* else adding a file */
  279.             { printf("Adding file:   %-12s  ",name); fflush(stdout);}
  280.     }
  281.  
  282.     starts = ftell(new);               /* note where header goes */
  283.     hdrver = ARCVER;                  /* anything but end marker */
  284.     writehdr(&nhdr,new);               /* write out header skeleton */
  285.     pack(f,new,&nhdr);                 /* pack file into archive */
  286.     fseek(new,starts,0);               /* move back to header skeleton */
  287.     writehdr(&nhdr,new);               /* write out real header */
  288.     fseek(new,nhdr.size,1);            /* skip over data to next header */
  289.     fclose(f);                         /* all done with the file */
  290. }
  291.