home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / ARC521-2.ZIP / MARC.C < prev    next >
C/C++ Source or Header  |  1989-12-30  |  10KB  |  326 lines

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