home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / OS2ARC_S.ZIP / ARCADD.C < prev    next >
Text File  |  1987-10-15  |  11KB  |  271 lines

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