home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / arc_lbr / arcdmp1.arc / ARCDMP.C next >
Text File  |  1988-01-01  |  6KB  |  303 lines

  1. /*
  2.  *    arcdmp.c
  3.  *
  4.  *    V 1.1
  5.  *    Original August 1987, Jim Kyle
  6.  *    Modified January 1988, S. Sampson
  7.  *
  8.  *    This program splits big ARC files into floppy-sized chunks
  9.  *
  10.  *    Define ECO for ECO-C88 Compiler, Default is MSC V4.0
  11.  */
  12.  
  13. /* Includes */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #ifdef ECO
  18. #include <ctype.h>
  19. #include <malloc.h>
  20. #else
  21. #include <dos.h>
  22. #include <search.h>
  23. #include <stdlib.h>
  24. #endif
  25.  
  26. /* Defines */
  27.  
  28. #define WORKSPACE        16384
  29. #ifndef ECO
  30. #define    tempname        argv[1]
  31. #endif
  32.  
  33. /* Globals */
  34.  
  35. struct {
  36.     char    key;        /* always 26        */
  37.     char    type;        /* 0 for EOF        */
  38.     char    name[13];    /* filename.ext+NULL    */
  39.     long    asiz;        /* size of ARC member    */
  40.     int    date;        /* date in FCB format    */
  41.     int    time;        /* time in FCB format    */
  42.     int    CRC;        /* CRC value for entry    */
  43.     long    osiz;        /* original file size    */
  44. } header;            /* ARC element header    */
  45.  
  46. struct    list  {
  47.     long    size;        /* index to ARC file    */
  48.     long    loc;
  49. } f1[500], f2[500];
  50.  
  51. FILE    *infl,
  52.     *otfl;
  53.  
  54. long    avl;
  55.  
  56. int    f1c,
  57.     f2c,
  58.     outctr = 0;
  59.  
  60. char    outbas[16],
  61.     outnam[16],
  62.     *outbfr;
  63.  
  64. /* Prototypes, Forward declarations */
  65.  
  66. void    doarc(void);
  67. void    bldtbl(void);
  68. void    post(long);
  69. void    dump(struct list *, int);
  70. int    cmpsiz(struct list *, struct list *);
  71. int    cmploc(struct list *, struct list *);
  72. long    fill(void);
  73. void    copy(struct list *, struct list *);
  74. void    pack(struct list *);
  75.  
  76.  
  77. /* Program */
  78.  
  79. void main(argc, argv)
  80. int    argc;
  81. char    *argv[];
  82. {
  83.     register char    *p;
  84. #ifdef ECO
  85.     char    tempname[64];
  86. #endif
  87.  
  88.     /* provide help */
  89.  
  90.     if (argc < 2)  {
  91.         fprintf(stderr, "Usage: arcdmp archive[.ARC] prefix\n");
  92.         exit(1);
  93.     }
  94.  
  95.     /* convert the archive filename to uppercase */
  96.  
  97.     for (p = argv[1]; *p; p++)
  98.         *p = (char)toupper(*p);
  99.  
  100. #ifdef ECO
  101.     /* parse the many possibilities */
  102.  
  103.     if ((p = strrchr(argv[1], '.')) == (char *)NULL)
  104.         goto add;
  105.     else if (strcmp(p, ".ARC") == NULL)
  106.         strcpy(tempname, argv[1]);
  107.     else if (*(p+1) == '/' || *(p+1) == '\\')  {
  108. add:        strcpy(tempname, argv[1]);
  109.         strcat(tempname, ".ARC");
  110.     } else  {
  111.         fprintf(stderr, "File '%s' not an archive\n", argv[1]);
  112.         exit(1);
  113.     }
  114. #endif
  115.  
  116.     /* open up the archive */
  117.  
  118.     if ((infl = fopen(tempname, "rb")) == (FILE *)NULL)  {
  119.         fprintf(stderr, "Can't open '%s' archive\n", tempname);
  120.         exit(1);
  121.     }
  122.  
  123.     /* build the new filename with a given prefix or TMP */
  124.  
  125.     if (argc < 3)
  126.         strcpy (outbas, "TMP");
  127.     else if (strchr(argv[2], ':') == NULL)
  128.         sprintf(outbas, "%.5s", argv[2]);
  129.     else
  130.         sprintf(outbas, "%.7s", argv[2]); /* 5 char plus drive spec */
  131.  
  132.     /* reserve some memory space */
  133.  
  134.     if ((outbfr = calloc(WORKSPACE, sizeof(char))) == NULL)  {
  135.         fprintf(stderr, "Not enough memory\n");
  136.         exit(1);
  137.     }
  138.  
  139.     doarc();
  140.  
  141.     /* were done, so cleanup and leave */
  142.  
  143.     free(outbfr);
  144.     fclose(infl);
  145.     exit(0);
  146. }
  147.  
  148.  
  149. void doarc()
  150. {
  151.     int    cmploc(), cmpsiz();
  152.  
  153.     bldtbl();
  154.     qsort((char *)&f1[0], (unsigned)f1c, sizeof f1[0], cmpsiz);
  155.  
  156.     while ( f1c )  {
  157.         printf("  Floppy = %lu bytes (%s):\n", fill(), outnam);
  158.         qsort((char *)&f2[0], (unsigned)f2c, sizeof f2[0], cmploc);
  159.         dump(f2, f2c);
  160.     }
  161. }
  162.  
  163.  
  164. void bldtbl()
  165. {
  166.     long    curloc;
  167.  
  168.     curloc = 0L;
  169.     while (fread((char *)&header, 1, sizeof header, infl) > 2)  {
  170.         if (header.type)
  171.             post(curloc);
  172.  
  173.         if (fseek(infl, header.asiz, 1))  {
  174.             fprintf(stderr, "Seek error\n");
  175.             exit(1);
  176.         }
  177.  
  178.         curloc = ftell(infl);
  179.     }
  180. }
  181.  
  182.  
  183. /* post size and location in table */
  184.  
  185. void post(posn)
  186. long    posn;
  187. {
  188.     f1[f1c].size  = header.asiz + sizeof header;
  189.     f1[f1c++].loc = posn;
  190.     f1[f1c].loc   = posn + header.asiz + sizeof header;
  191.     f1[f1c].size  = 0L;
  192. }
  193.  
  194.  
  195. void dump(f, n)
  196. struct    list *f;
  197. int    n;
  198. {
  199.     if ((otfl = fopen(outnam, "wb")) == (FILE *)NULL)  {
  200.         fprintf(stderr, "Can't produce '%s'\n", outnam);
  201.         exit(1);
  202.     }
  203.  
  204.     while (n--)  {
  205.         if (fseek(infl, f->loc, 0))  {  /* position to member */
  206.             fprintf(stderr, "Positioning error\n");
  207.             exit(1);
  208.         }
  209.  
  210.         fread((char *)&header, 1, sizeof header, infl);
  211.         printf("%-14s%9lu%9lu\n", header.name, f->size, f->loc);
  212.         fwrite((char *)&header, 1, sizeof header, otfl);
  213.  
  214.         while (header.asiz > 0L)  {
  215.             int x;
  216.  
  217.             x = header.asiz > (long)WORKSPACE ? WORKSPACE : (int)header.asiz;
  218.             x = fread( outbfr, 1, x, infl);     /* read a chunk */
  219.  
  220.             if (x != fwrite( outbfr, 1, x, otfl))  {
  221.                 fprintf(stderr, "Output write error\n");
  222.                 exit(1);
  223.             }
  224.  
  225.             header.asiz -= (long)x;
  226.         }
  227.  
  228.         f++;
  229.     }
  230.  
  231.     printf("%-14s%9lu%9lu\n", "  Final-->", f->size, f->loc);
  232.     fputc(26, otfl);
  233.     fputc(0, otfl);
  234.  
  235.     fclose(otfl);
  236. }
  237.  
  238.  
  239. int cmpsiz(a1, a2)
  240. struct list *a1, *a2; /* sort biggest ones first */
  241. {
  242.     return(a1->size > a2->size ? -1 : a1->size < a2->size);
  243. }
  244.  
  245.  
  246. int cmploc(a1, a2)
  247. struct list *a1, *a2; /* restore to alpha sequence */
  248. {
  249.     return(a1->loc < a2->loc ? -1 : a1->loc > a2->loc);
  250. }
  251.  
  252.  
  253. long fill()                             /* fill up a small ARC table */
  254. {
  255.     int    c;
  256.     long    tmp;
  257.  
  258.     sprintf(outnam, "%s%03d.ARC", outbas, ++outctr);
  259.  
  260.     avl = 1024L * 354L - 3L;    /* 360K floppy size */
  261.     f2c = c = 0;
  262.     copy(&f1[c], &f2[f2c++]);    /* always take first one */
  263.     tmp = f1[c].size;
  264.     f2[f2c].size  = 0L;
  265.     pack(&f1[c]);            /* and remove from list */
  266.  
  267.     while ( c < f1c )  {
  268.         while (( f1[c].size < avl ) && f1[c].size )  {
  269.             copy(&f1[c], &f2[f2c++]);
  270.             tmp += f1[c].size;
  271.             f2[f2c].size  = 0L;
  272.             pack(&f1[c]);
  273.         }
  274.  
  275.         ++c;
  276.     }
  277.  
  278.     return tmp;
  279. }
  280.  
  281.  
  282. void copy(a1, a2)
  283. struct list *a1, *a2;
  284. {
  285.     a2->size = a1->size;
  286.     a2->loc  = a1->loc;
  287. }
  288.  
  289.  
  290. void pack(a1)
  291. struct list *a1;
  292. {
  293.     avl -= a1->size;
  294.     while (a1->size)  {
  295.         copy (a1+1, a1);
  296.         ++a1;
  297.     }
  298.  
  299.     --f1c;
  300. }
  301.  
  302. /* EOF */
  303.