home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c019 / 1.ddi / ARC521_C / MARC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-01  |  8.8 KB  |  301 lines

  1. /*
  2.  * $Header: marc.c,v 1.2 88/06/06 01:05:02 hyc Locked $
  3.  */
  4.  
  5. /*  MARC - Archive merge utility
  6.  
  7.     Version 5.21, created on 04/22/87 at 15:05:10
  8.  
  9. (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  10.  
  11.     By:     Thom Henderson
  12.  
  13.     Description:
  14.      This program is used to "merge" archives.  That is, to move
  15.      files from one archive to another with no data conversion.
  16.      Please refer to the ARC source for a description of archives
  17.      and archive formats.
  18.  
  19.     Instructions:
  20.      Run this program with no arguments for complete instructions.
  21.  
  22.     Language:
  23.      Computer Innovations Optimizing C86
  24. */
  25. #include <stdio.h>
  26. #include "arc.h"
  27.  
  28. FILE *src;                   /* source archive */
  29. char srcname[STRLEN];               /* source archive name */
  30.  
  31. static char **lst;               /* files list */
  32. static int lnum;               /* length of files list */
  33.  
  34.  
  35. main(nargs,arg)                   /* system entry point */
  36. int nargs;                   /* number of arguments */
  37. char *arg[];                   /* pointers to arguments */
  38. {
  39.     char *makefnam();               /* filename fixup routine */
  40.     char *calloc();               /* memory manager */
  41.     char *envfind();
  42. #if    !MTS
  43.     char *arctemp2, *mktemp();        /* temp file stuff */
  44. #endif
  45. #if    GEMDOS
  46.     void exitpause();
  47. #endif
  48.     int n;                   /* index */
  49.  
  50.     if(nargs<3)
  51.     {     printf("MARC - Archive merger, Version 5.21, created on 04/22/87 at 15:05:10\n");
  52. /*     printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;");
  53.      printf(" ALL RIGHTS RESERVED\n\n");
  54.      printf("Please refer all inquiries to:\n\n");
  55.      printf("    System Enhancement Associates\n");
  56.      printf("    21 New Street, Wayne NJ 07470\n\n");
  57.      printf("You may copy and distribute this program freely,");
  58.      printf(" provided that:\n");
  59.      printf("    1)      No fee is charged for such copying and");
  60.      printf(" distribution, and\n");
  61.      printf("    2)      It is distributed ONLY in its original,");
  62.      printf(" unmodified state.\n\n");
  63.      printf("If you like this program, and find it of use, then your");
  64.      printf(" contribution will\n");
  65.      printf("be appreciated.  You may not use this product in a");
  66.      printf(" commercial environment\n");
  67.      printf("or a governmental organization without paying a license");
  68.      printf(" fee of $35.  Site\n");
  69.      printf("licenses and commercial distribution licenses are");
  70.      printf(" available.  A program\n");
  71.      printf("disk and printed documentation are available for $50.\n");
  72.      printf("\nIf you fail to abide by the terms of this license, ");
  73.      printf(" then your conscience\n");
  74.      printf("will haunt you for the rest of your life.\n\n");
  75. */
  76.      printf("Usage: MARC <tgtarc> <srcarc> [<filename> . . .]\n");
  77.      printf("Where: <tgtarc> is the archive to add files to,\n");
  78.      printf("    <srcarc> is the archive to get files from, and\n");
  79.      printf("    <filename> is zero or more file names to get.\n");
  80.      printf("\nAdapted from MSDOS by Howard Chu\n");
  81. #if    GEMDOS
  82.      exitpause();
  83. #endif
  84.      return 1;
  85.     }
  86.  
  87.     /* see where temp files go */
  88. #if    !MTS
  89.     arctemp = calloc(1, STRLEN);
  90.     if (!(arctemp2 = envfind("ARCTEMP")))
  91.         arctemp2 = envfind("TMPDIR");
  92.     if (arctemp2) {
  93.         strcpy(arctemp, arctemp2);
  94.         n = strlen(arctemp);
  95.         if (arctemp[n - 1] != CUTOFF)
  96.             arctemp[n] = CUTOFF;
  97.     }
  98. #if    !MSDOS
  99.     strcat(arctemp, mktemp("AXXXXXX"));
  100. #else
  101.     strcat(arctemp, "$ARCTEMP");
  102. #endif
  103. #else
  104.     guinfo("SHFSEP    ", gotinf);
  105.     sepchr[0] = gotinf[0];
  106.     guinfo("SCRFCHAR", gotinf);
  107.     tmpchr[0] = gotinf[0];
  108.     arctemp = "-$$$";
  109.     arctemp[0] = tmpchr[0];
  110. #endif
  111.  
  112.     makefnam(arg[1],".arc",arcname);   /* fix up archive names */
  113.     makefnam(arg[2],".arc",srcname);
  114. /*    makefnam(".$$$",arcname,newname);*/
  115.     sprintf(newname,"%s.arc",arctemp);
  116.  
  117. #if    !UNIX
  118.     upper(arcname); upper(srcname); upper(newname);
  119. #endif
  120.  
  121.     arc = fopen(arcname,"rb");           /* open the archives */
  122.     if(!(src=fopen(srcname,"rb")))
  123.      abort("Cannot read source archive %s",srcname);
  124.     if(!(new=fopen(newname,"wb")))
  125.      abort("Cannot create new archive %s",newname);
  126.  
  127.     if(!arc)
  128.      printf("Creating new archive %s\n",arcname);
  129.  
  130.     /* get the files list set up */
  131.  
  132.     lnum = nargs-3;               /* initial length of list */
  133.     if(lnum<1)                   /* phoney for default case */
  134.     {     lnum = 1;
  135.      lst = (char **) calloc(1,sizeof(char *));
  136.      lst[0] = "*.*";
  137.     }
  138.     else                   /* else use filenames given */
  139.     {     lst = (char **) calloc(lnum,sizeof(char *));
  140.      for(n=3; n<nargs; n++)
  141.           lst[n-3] = arg[n];
  142.  
  143.      for(n=0; n<lnum; )           /* expand indirect references */
  144.      {    if(*lst[n] == '@')
  145.            expandlst(n);
  146.           else n++;
  147.      }
  148.     }
  149.  
  150.     merge(lnum,lst);               /* merge desired files */
  151.  
  152.     if(arc) fclose(arc);           /* close the archives */
  153.     fclose(src);
  154.     fclose(new);
  155.  
  156.     if(arc)                   /* make the switch */
  157.      if(unlink(arcname))
  158.           abort("Unable to delete old copy of %s",arcname);
  159.     if(move(newname,arcname))
  160.      abort("Unable to rename %s to %s",newname,arcname);
  161.  
  162.     setstamp(arcname,arcdate,arctime);     /* new arc matches newest file */
  163.  
  164. #if    GEMDOS
  165.     exitpause();
  166. #endif
  167.     return nerrs;
  168. }
  169.  
  170. merge(nargs,arg)               /* merge two archives */
  171. int nargs;                   /* number of filename templates */
  172. char *arg[];                   /* pointers to names */
  173. {
  174.     struct heads srch;               /* source archive header */
  175.     struct heads arch;               /* target archive header */
  176.     int gotsrc, gotarc;               /* archive entry versions (0=end) */
  177.     int copy;                   /* true to copy file from source */
  178.     int n;                   /* index */
  179.  
  180.     gotsrc = gethdr(src,&srch);           /* get first source file */
  181.     gotarc = gethdr(arc,&arch);           /* get first target file */
  182.  
  183.     while(gotsrc || gotarc)           /* while more to merge */
  184.     {     if(strcmp(srch.name,arch.name)>0)
  185.      {    copyfile(arc,&arch,gotarc);
  186.           gotarc = gethdr(arc,&arch);
  187.      }
  188.  
  189.      else if(strcmp(srch.name,arch.name)<0)
  190.      {    copy = 0;
  191.           for(n=0; n<nargs; n++)
  192.           {       if(match(srch.name,arg[n]))
  193.            {    copy = 1;
  194.             break;
  195.            }
  196.           }
  197.           if(copy)               /* select source or target */
  198.           {       printf("Adding file:      %s\n",srch.name);
  199.            copyfile(src,&srch,gotsrc);
  200.           }
  201.           else fseek(src,srch.size,1);
  202.           gotsrc = gethdr(src,&srch);
  203.      }
  204.  
  205.      else                   /* duplicate names */
  206.      {    copy = 0;
  207.           {       if((srch.date>arch.date)
  208.            || (srch.date==arch.date && srch.time>arch.time))
  209.            {    for(n=0; n<nargs; n++)
  210.             {    if(match(srch.name,arg[n]))
  211.                  {      copy = 1;
  212.                   break;
  213.                  }
  214.             }
  215.            }
  216.           }
  217.           if(copy)               /* select source or target */
  218.           {       printf("Updating file: %s\n",srch.name);
  219.            copyfile(src,&srch,gotsrc);
  220.            gotsrc = gethdr(src,&srch);
  221.            if(gotarc)
  222.            {    fseek(arc,arch.size,1);
  223.             gotarc = gethdr(arc,&arch);
  224.            }
  225.           }
  226.           else
  227.           {       copyfile(arc,&arch,gotarc);
  228.            gotarc = gethdr(arc,&arch);
  229.            if(gotsrc)
  230.            {    fseek(src,srch.size,1);
  231.             gotsrc = gethdr(src,&srch);
  232.            }
  233.           }
  234.      }
  235.     }
  236.  
  237.     hdrver = 0;                   /* end of archive marker */
  238.     writehdr(&arch,new);           /* mark the end of the archive */
  239. }
  240.  
  241. int gethdr(f,hdr)               /* special read header for merge */
  242. FILE *f;                   /* file to read from */
  243. struct heads *hdr;               /* storage for header */
  244. {
  245.     char *i = hdr->name;           /* string index */
  246.     int n;                   /* index */
  247.  
  248.     for(n=0; n<FNLEN; n++)           /* fill name field */
  249.      *i++ = 0176;               /* impossible high value */
  250.     *--i = '\0';               /* properly end the name */
  251.  
  252.     hdrver = 0;                   /* reset header version */
  253.     if(readhdr(hdr,f))               /* use normal reading logic */
  254.      return hdrver;               /* return the version */
  255.     else return 0;               /* or fake end of archive */
  256. }
  257.  
  258. copyfile(f,hdr,ver)               /* copy a file from an archive */
  259. FILE *f;                   /* archive to copy from */
  260. struct heads *hdr;               /* header data for file */
  261. int ver;                   /* header version */
  262. {
  263.     hdrver = ver;               /* set header version */
  264.     writehdr(hdr,new);               /* write out the header */
  265.     filecopy(f,new,hdr->size);           /* copy over the data */
  266. }
  267.  
  268. static expandlst(n)               /* expand an indirect reference */
  269. int n;                       /* number of entry to expand */
  270. {
  271.     FILE *lf, *fopen();               /* list file, opener */
  272.     char *malloc(), *realloc();           /* memory managers */
  273.     char buf[100];               /* input buffer */
  274.     int x;                   /* index */
  275.     char *p = lst[n]+1;               /* filename pointer */
  276.  
  277.     if(*p)                   /* use name if one was given */
  278.     {     makefnam(p,".CMD",buf);
  279.      upper(buf);
  280.      if(!(lf=fopen(buf,"r")))
  281.           abort("Cannot read list of files in %s",buf);
  282.     }
  283.     else lf = stdin;               /* else use standard input */
  284.  
  285.     for(x=n+1; x<lnum; x++)           /* drop reference from the list */
  286.      lst[x-1] = lst[x];
  287.     lnum--;
  288.  
  289.     while(fscanf(lf,"%99s",buf)>0)     /* read in the list */
  290.     {     if(!(lst=(char **) realloc(lst,(lnum+1)*sizeof(char *))))
  291.           abort("too many file references");
  292.  
  293.      lst[lnum] = malloc(strlen(buf)+1);
  294.      strcpy(lst[lnum],buf);           /* save the name */
  295.      lnum++;
  296.     }
  297.  
  298.     if(lf!=stdin)               /* avoid closing standard input */
  299.      fclose(lf);
  300. }
  301.