home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c019 / 3.ddi / ARCVIEW / ARCVIEW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-06  |  13.9 KB  |  413 lines

  1.  
  2. /*--------------------------------------------------------------------------*/
  3. /* Another semi-useful utility by Doug Boone. Lists the contents of all the */
  4. /* archive programs I am currently aware of:                                */
  5. /*                                                                          */
  6. /*      ARC     Systems Enhancements Associates                             */
  7. /*      PAK     NoGate Consulting's PAK                                     */
  8. /*      ZOO     Rahul Dhesi                                                 */
  9. /*      DWC     Dean Cooper                                                 */
  10. /*                                                                          */
  11. /* Compiled with Turbo C 2.0, will work with either the Tiny or Small model */
  12. /* assuming you have the ARCVIEW.COM file, it was generated with:           */
  13. /*                                                                          */
  14. /*      tcc -a- -f- -G -K -lt -mt -Z arcview.c                              */
  15. /*                                                                          */
  16. /*      -a- Byte align characters                                           */
  17. /*      -f- No floating point numbers                                       */
  18. /*      -G  Optomize for speed                                              */
  19. /*      -K  Chars are unsigned                                              */
  20. /*      -lt Tell tlink to make it a COM file                                */
  21. /*      -mt Tiny memory model                                               */
  22. /*      -Z  Use register optomization                                       */
  23. /*                                                                          */
  24. /* If you find any problems, or are want to send a "thank you", or whatever */
  25. /* I can be reached at FidoNet 119/5, (916) 893-9019 24 hrs HST             */
  26. /* Copyright 1988.                                                          */
  27. /*                                                                          */
  28. /* "Don't rip me off."  - Tom Jennings, FidoNet's founder                   */
  29. /*--------------------------------------------------------------------------*/
  30.  
  31. #include    <stdio.h>
  32. #include    <string.h>
  33. #include    <ctype.h>
  34. #include    <time.h>
  35. #include    <signal.h>
  36. #include    <dos.h>
  37. #include    <dir.h>
  38. #include    <io.h>
  39. #include    <fcntl.h>
  40. #include    <dos.h>
  41. #include    <sys\types.h>
  42. #include    <sys\stat.h>
  43. #include    "archdr.h"
  44.  
  45.  
  46. char*   _Cdecl      memrstr(char *,char *,int);
  47. int     _Cdecl      read_dwc(char *);
  48.  
  49. main(int argc, char *argv[])
  50. {
  51.     int     i;
  52.     int     done;
  53.     struct  ffblk   ffblk;
  54.     char    name[80];
  55.     int     infile;        /* file handle */
  56.     char    *firstchar;
  57.     char    apath[80];
  58.     char    *result;
  59.     int     success;
  60.  
  61.     if (argc < 2) {
  62.         printf ("\nView the contents of ARC, PAK, ZOO, and DWC files\n\n");
  63.         exit(1);
  64.         }
  65.     firstchar = (char *) malloc(1);
  66.  
  67.     for (i=1; i<argc; i++) {
  68.         strcpy(apath,argv[i]);
  69.         result = strrchr(apath,'\\');
  70.         if (result != NULL)
  71.             *++result = '\0';
  72.         else {
  73.             result = strrchr(apath,':');
  74.             if (result !=NULL)
  75.                 *++result = '\0';
  76.             else
  77.                 apath[0] = '\0';
  78.             }
  79.         if (strncmp(argv[i],".",1)==0)
  80.             strcpy(argv[i],"*.*");
  81.         done = findfirst(argv[i],&ffblk,0);
  82.         while (done == 0) {
  83.             strcpy(name,apath);
  84.             strcat(name,ffblk.ff_name);
  85.             infile = open(name,O_RDONLY|O_BINARY);
  86.             if (infile > 0)
  87.                 success = read(infile,firstchar,1);
  88.             close(infile);
  89.             firstchar[0] = toupper(firstchar[0]);
  90.             if (firstchar[0] == 0x1a)
  91.                 success = lstarc(name);
  92.             else if (firstchar[0] == 'Z')
  93.                 success = do_zoo(name);
  94.             else success = read_dwc(name);
  95.             if (success<0)
  96.                 printf("\n%s Not an archive file\n\n",name);
  97.             done = findnext(&ffblk);
  98.             }        /* end of findfirst/findnext loop */
  99.         }        /* end of for loop */
  100.     free(firstchar);
  101.     exit(0);
  102. }
  103.  
  104. /* ====================================================================
  105.  * start a new screen full while listing the contents of an arc file
  106.  * ====================================================================
  107.  */
  108. arc_header(char *packer,char *name)
  109.  
  110. {
  111.     printf("\n %s  Contents of %s\n",packer,name);
  112.     printf("Filename        Length   Method     Size   Ratio    Date      Time    CRC\n");
  113.     printf("--------        ------   ------    ------  -----    ----      ----    ---\n");
  114.     return;
  115. }
  116.  
  117. /* ====================================================================
  118.  * start of list arc contents processing
  119.  * ====================================================================
  120.  */
  121. int lstarc(char *arcname)        /* list files in archive */
  122. {
  123.     struct     heads *hdr;        /* header data */
  124.     int     totmbrs;        /* total members in arc */
  125.     long    totlen;            /* total of file lengths */
  126.     long    totsize;        /* total of file sizes */
  127.     long    totsf;
  128.     int        ver;
  129.     long    new_pos;
  130.     register int done;        /* result */
  131.     FILE      *arc;            /* archive file */
  132.     char    date[9];
  133.     char    time[9];
  134.     char    method[11];
  135.  
  136.     totmbrs = totlen = totsize = 0L;    /* reset totals */
  137.  
  138.     hdr = (struct heads *) malloc(sizeof(struct heads));
  139.  
  140.     if((arc=fopen(arcname,"rb")) == NULL ) {
  141.         perror("  Cannot read archive: ");
  142.         return(-1);
  143.         }
  144.     done = fseek(arc,1L,SEEK_SET);
  145.     ver = fgetc(arc);
  146.     arc_header("ARC/PAK",arcname);
  147.     while (ver > 0 && ver < 11) {
  148.         done = fread(hdr,sizeof(struct heads),1,arc);
  149.         totlen += hdr->mbrlen;
  150.         totsize += hdr->mbrsize;
  151.         totmbrs++;
  152.         sprintf(date,"%02d-%02d-%02d",
  153.             ((hdr->mbrdate >> MONTH_SHIFT) & MONTH_MASK),
  154.                 (hdr->mbrdate & DAY_MASK),
  155.                     ((hdr->mbrdate >> YEAR_SHIFT) + DOS_EPOCH));
  156.  
  157.         sprintf(time,"%02d:%02d:%02d",((hdr->mbrtime >> 11) & 0x1f),
  158.             ((hdr->mbrtime >> 5) & 0x3f),(hdr->mbrtime &0x1f)*2);
  159.         switch(ver) {
  160.             case 1:    strcpy(method,"    --    ");    /* 1 - old, no compression */
  161.                     break;
  162.             case 2: strcpy(method,"  Stored  ");    /* 2 - new, no compression */
  163.                     break;
  164.             case 3: strcpy(method,"  Packed  ");    /* 3 - dle for repeat chars */
  165.                     break;
  166.             case 4: strcpy(method," Squeezed ");    /* 4 - huffman encodeing */
  167.                     break;
  168.             case 5: strcpy(method," Crunched ");    /* 5 - lz, no dle */
  169.                     break;
  170.             case 6: strcpy(method," Crunched ");    /* 6 - lz with dle */
  171.                     break;
  172.             case 7: strcpy(method," Crunched ");    /* 7 - lz with readjust */
  173.                     break;
  174.             case 8: strcpy(method," Crunched ");    /* 8 - lz with readjust and dle */
  175.                     break;
  176.             case 9: strcpy(method," Squashed ");    /* 9 - modified lzw, no dle */
  177.                     break;
  178.             case 10: strcpy(method,"  Crushed ");    /* PAK's new method */
  179.                         break;
  180.             default: strcpy(method," Unknown! ");/* future? */
  181.                     break;
  182.              }        /* End of version switch */
  183.         one_line(hdr->mbrname,hdr->mbrlen,hdr->mbrsize,method,date,time,hdr->mbrcrc);
  184.         done = fseek(arc,hdr->mbrsize+1L,SEEK_CUR);
  185.         ver = fgetc(arc);
  186.         };        /* End of while loop */
  187.     fclose(arc);        /* then close it */
  188.     totsf = 0L;
  189.     if(totlen>0L)
  190.         totsf = (int)(100L - ((100L*totsize)/totlen));
  191.     printf("----\t\t------\t\t   ------  -----\n");
  192.     printf("Total %6d  %8ld  ",totmbrs,totlen);
  193.     printf("\t %8ld   %3d%%\n",totsize,totsf);
  194.     free(hdr);
  195.     return(0);
  196. }
  197.  
  198. /* Handle a ZOO archive */
  199.  
  200. int do_zoo(char *filename)
  201. {
  202.     FILE    *fhandle;
  203.     struct    zoo_header    *main_head;
  204.     struct    direntry    *one_head;
  205.     int     result;
  206.     long        moving;
  207.     unsigned    totmbr=0;        /* number of members in Zoo */
  208.     long    totlen=0L;        /* total of all file sizes */
  209.     long    totsize = 0L;
  210.     int     totsf;
  211.     char    method[11];
  212.     char    time[9];
  213.     char    date[9];
  214.  
  215.     main_head = (struct zoo_header *) malloc(sizeof(struct zoo_header));
  216.     one_head = (struct direntry *) malloc(sizeof(struct direntry));
  217.  
  218.     fhandle = fopen(filename,"rb");
  219.     result = fread(main_head,sizeof(struct zoo_header),1,fhandle);
  220.     if ((strnicmp(main_head->text,"ZOO",3)) != 0) {
  221.         printf("  Not a Zoo archive!  ");
  222.         fclose(fhandle);
  223.         return(-1);
  224.         }
  225.     arc_header("ZOO",filename);
  226.     moving = fseek(fhandle,main_head->zoo_start,SEEK_SET);
  227.     result = fread(one_head,sizeof(struct direntry),1,fhandle);
  228.     do {
  229.         if (result == 1) {
  230.             totmbr++;
  231.             totsize += one_head->org_size;
  232.             totlen += one_head->size_now;
  233.             switch(one_head->packing_method) {
  234.                 case 0:
  235.                             strcpy(method,"  Stored  ");
  236.                             break;
  237.                 case 1:
  238.                             strcpy(method," Norm LZW ");
  239.                             break;
  240.                 default:
  241.                             strcpy(method,"  Unknown ");
  242.                             break;
  243.                 }
  244.             sprintf(date,"%02d-%02d-%02d",
  245.                 ((one_head->date >> MONTH_SHIFT) & MONTH_MASK),
  246.                     (one_head->date & DAY_MASK),
  247.                         ((one_head->date >> YEAR_SHIFT) + DOS_EPOCH));
  248.  
  249.             sprintf(time,"%02d:%02d:%02d",((one_head->time >> 11) & 0x1f),
  250.                 ((one_head->time >> 5) & 0x3f),(one_head->time &0x1f)*2);
  251.  
  252.             one_line(one_head->fname,one_head->org_size,one_head->size_now,
  253.                 method,date,time,one_head->dir_crc);
  254.  
  255.             moving = fseek(fhandle,one_head->next,SEEK_SET);
  256.             }
  257.         result = fread(one_head,sizeof(struct direntry),1,fhandle);
  258.         } while ((one_head->offset != 0L) &&
  259.             (result == 1));
  260.     free(one_head);
  261.     free(main_head);
  262.     result = fclose(fhandle);
  263.     if (totlen>0)
  264.         totsf=(int)(100L - ((100L*totlen)/totsize));
  265.     else
  266.         totsf = 0;
  267.     printf("----\t\t------\t\t   ------  -----\n");
  268.     printf("Total %6d  %8ld  ",totmbr,totlen);
  269.     printf("\t %8ld   %3d%%\n",totsize,totsf);
  270.     return(0);
  271. }
  272.  
  273. /* Read a DWC archive. These are the hardest ones to get into. */
  274.  
  275. int read_dwc(char *name)
  276. {
  277.     long    size;
  278.     int        infile;
  279.     unsigned    int        result;
  280.     struct    dwc_entry    *one_entry;
  281.     struct    dwc_arc    *one_archive;
  282.     struct  tm *t;
  283.     char    junkbuffer[256];
  284.     char    *dwc;
  285.     unsigned int    junkoffset;
  286.     int        count;  /* total number of files in this archive */
  287.     long    totsize = 0L;
  288.     long    totlen = 0L;
  289.     int     totmbr = 0;
  290.     int     totsf;
  291.     char    date[9];
  292.     char    time[9];
  293.     char    method[11];
  294.  
  295.     if((infile = open(name,O_BINARY|O_RDONLY)) < 0) {
  296.         printf("Couldn't open file %s\n",name);
  297.         return(-1);
  298.         }
  299.     one_entry = (struct dwc_entry *) malloc(sizeof(struct dwc_entry));
  300.     one_archive = (struct dwc_arc *) malloc(sizeof(struct dwc_arc));
  301.     count = 0;
  302.     do {
  303.         totlen = (long) (++count * sizeof(junkbuffer));
  304.         size = lseek(infile,-totlen,SEEK_END);
  305.         if (size > 0L)
  306.             result = read(infile,junkbuffer,sizeof(junkbuffer));
  307.         else result = 0;
  308.         } while (result == sizeof(junkbuffer) &&
  309.             ((dwc = memrstr(junkbuffer,"DWC",result)) == NULL));
  310.  
  311.     if (result < sizeof(junkbuffer)) { /* Failed to find "DWC", not DWC file */
  312.         close (infile);
  313.         free(one_archive);
  314.         free(one_entry);
  315.         return(-1);
  316.         }
  317.     junkoffset = count * sizeof(junkbuffer)  /* start of this buffer block */
  318.         - (dwc-junkbuffer)  /* minus the offset to the "DWC" in the buffer */
  319.         + sizeof(struct dwc_arc) - 3;
  320.     size = lseek (infile,-(long)junkoffset,SEEK_END);
  321.     result = read(infile,one_archive,sizeof(struct dwc_arc));
  322.     if (one_archive->size != sizeof(struct dwc_arc)) {
  323.         close(infile);
  324.         free(one_archive);
  325.         free(one_entry);
  326.         return(-1);
  327.         }
  328.     arc_header("DWC",name);
  329.     count = (int) one_archive->entries;
  330.     totmbr = count;
  331.     totlen = 0L;
  332.     size = lseek(infile,-(long)(count*one_archive->ent_sz+junkoffset),SEEK_END);
  333.     while (count>0) {
  334.         result = read(infile,one_entry,sizeof(struct dwc_entry));
  335.         totsize += one_entry->size;
  336.         totlen += one_entry->new_size;
  337.         switch(one_entry->method) {
  338.             case 0:
  339.                         strcpy(method,"  Stored  ");
  340.                         break;
  341.             case 1:
  342.                         strcpy(method," Norm LZW ");
  343.                         break;
  344.             default:
  345.                         strcpy(method,"  Unknown ");
  346.                         break;
  347.             }
  348.         totsf = 0;
  349.         t = localtime(&one_entry->time);
  350.         sprintf(time,"%02d-%02d-%02d",
  351.             (t->tm_mon+1),t->tm_mday,t->tm_year);
  352.  
  353.         sprintf(date,"%02d:%02d:%02d",
  354.             t->tm_hour,t->tm_min,t->tm_sec);
  355.  
  356.         one_line(one_entry->name,one_entry->size,one_entry->new_size,
  357.             method,time,date,one_entry->crc);
  358.         count--;
  359.         };
  360.     close (infile);
  361.     free(one_archive);
  362.     free(one_entry);
  363.     if (totlen>0)
  364.         totsf=(int)(100L - ((100L*totlen)/totsize));
  365.     else
  366.         totsf = 0;
  367.     printf("----\t\t------\t\t   ------  -----\n");
  368.     printf("Total %6d  %8ld  ",totmbr,totlen);
  369.     printf("\t %8ld   %3d%%\n",totsize,totsf);
  370.     return(0);
  371. }
  372.  
  373. /* memrstr searches backwards through a chunk of memory called "buffer"     */
  374. /* that is "buflen" long, looking for a string "target". The search is from */
  375. /* the end of "buffer" forward. It returns a pointer to the start of the    */
  376. /* target string                                                            */
  377.  
  378. char *memrstr(char *buffer,char *target,int buflen)
  379. {
  380.  
  381.     char    c = ' ';
  382.     char    *ptr;
  383.     int        found = 1;
  384.  
  385.     c = target[strlen(target)-1];
  386.     ptr = buffer+buflen;
  387.     do {
  388.         if (c != *ptr)
  389.             ptr--;
  390.         else {
  391.             ptr -= strlen(target)-1;
  392.             found = strnicmp(target,ptr,sizeof(target));
  393.             if (found != 0)
  394.                 ptr += strlen(target) - 2;
  395.             }
  396.         if (ptr < buffer)
  397.             ptr = NULL;
  398.         } while (found !=0 && ptr != NULL);
  399.     return(ptr);
  400. }
  401.  
  402. one_line(char *name,long org_len,long new_len,char *pack,char *date,char *time,int crc)
  403. {
  404.     int     factor;
  405.  
  406.     if (new_len > 0)
  407.         factor = (100 * new_len)/org_len;
  408.  
  409.     printf("%-12s  %8ld %10s%8ld   %3d%%",name,org_len,pack,new_len,factor);
  410.     printf("  %8s  %8s  %04X\n",date,time,crc);
  411.     return;
  412. }
  413.