home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / WHICHARC.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  9KB  |  252 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. /* --------------------------------------------------------------------
  5.    Module:     WHICHARC.C
  6.    Subject:    tries to determine the archiver used to compress files
  7.    Author:     Heinz Ozwirk & David Gersic
  8.                modified for SNIPPETS by Bob Stout
  9.    Status:     public domain
  10.    Started:    28.09.1991   13:35:57
  11.    Modified:   13.10.1991   14:15:57
  12.    Modified:   5 January, 1992 11:50am by David Gersic
  13.                    Added return codes for self extracting archive files.
  14.    Modified:   16 January, 1992, 4:15pm by David Gersic
  15.                    Added Pak and ARC ver. 6 with information from Richard
  16.                    Vanhouten @1:272/38. I'm not sure that this code works
  17.                    perfectly for those formats, as his message seems to
  18.                    indicate that the entire archive has to be scanned for
  19.                    headers to check before the type can be perfectly
  20.                    determined. It seems to work for test archives produced
  21.                    here, but may not work for all archives.
  22.    --------------------------------------------------------------------
  23.    Prototype:  int WhichArc(char *pName)
  24.       pName    address of full path name of file to examine
  25.       Result   -1:      file not found
  26.                UNKNOWN: unknown packer
  27.                ARC:     ARC or PKARC
  28.                ARJ:     ARJ
  29.                LHA:     LHARC or LHA
  30.                ZIP:     PKZIP
  31.                ZOO:     Zoo
  32.                PAK:     Pak
  33.                ARC7:    ARC later than ver. 6.02
  34.                SFXARC:  Self Extracting PKARC
  35.                SFXARJ:  Self Extracting ARJ
  36.                SFXLHARC:Self Extracting LHARC
  37.                SFXLHA:  Self Extracting LHA
  38.                SFXZIP:  Self Extracting ZIP
  39.                SFXPAK:  Self Extracting Pak
  40.                SFXARC6: Self Extracting ARC later than ver. 6.02
  41.                EXE:     MS DOS executable of unknown type
  42.  
  43.    LHARC/LHA
  44.       No archive header. WhichArc examines the checksum of the first
  45.       file header. If the checksum is valid and if the string -lh?-
  46.       is found, LHA or LHARC is assumed.
  47.  
  48.    ARJ
  49.       If a file starts with 0x60, 0xEA, ARJ is assumed.
  50.  
  51.    ZIP
  52.       If the file begins with "PK", PKZIP is assumed.
  53.  
  54.    ZOO
  55.       Zoo'ed archives always start with "ZOO x.xx Archive". WhichArc
  56.       only looks for "ZOO".
  57.  
  58.    ARC
  59.       No header. Files starting with 0x1A are assumed to be ARCed.
  60.  
  61.    PAK
  62.       Similar to ARC files, but if the second byte of the header is 0x0a or
  63.       0x0b, it was created by Pak.
  64.  
  65.    ARC7
  66.       Similar to ARC, but if the second byte of the header is 0x14 or
  67.       higher, it was created by an Arc version later than 6.02.
  68.  
  69.    SFX*
  70.       All of the SFX files start with a small decompressor. Seek past
  71.       the decompressor and repeat the above checks. 
  72.    -------------------------------------------------------------------- */
  73.  
  74.  
  75. typedef unsigned char BYTE;
  76.  
  77. enum ArcType { ArcERR=-1, UNKNOWN, ARC, ZOO, ARJ, LHARC, LHA, ZIP, PAK, ARC7,
  78.                SFXARC, SFXARJ, SFXLHARC, SFXLHA, SFXZIP, SFXARC7, SFXPAK, EXE
  79.              };
  80.  
  81. enum ArcType WhichArc(char *pName)
  82. {
  83.       FILE  *fp;
  84.       BYTE  header[128];
  85.       int   c, i, n;
  86.       enum  ArcType retval = ArcERR;
  87.  
  88.       memset(header, 0, sizeof(header));
  89.       fp = fopen(pName, "rb");
  90.       if (fp == NULL)
  91.             goto EXIT;                                /* error opening file */
  92.       n = fread(header, sizeof(BYTE), sizeof(header) - sizeof(BYTE), fp);
  93.  
  94.       if (n <= 0)                               /* error reading from file  */
  95.             goto EXIT;
  96.  
  97.       if (n >= 7 && n >= header[0] + 2)
  98.       {
  99.             for (c = 0, i = header[0]; i--; c += (header+2)[i])
  100.                   ;
  101.             if (((BYTE)(c & 0x00FF)) == header[1] 
  102.                   && header[2] == '-' 
  103.                   && header[3] == 'l' 
  104.                   && header[4] == 'h' 
  105.                   && header[6] == '-')
  106.             {
  107.                   retval = (header[5] > '1') ? LHA : LHARC;
  108.                   goto EXIT;
  109.             }
  110.       }
  111.  
  112.       if (n >= 2)
  113.       {
  114.             if (header[0] == 0x60 && header[1] == 0xEA)
  115.             {
  116.                   retval = ARJ;
  117.                   goto EXIT;
  118.             }
  119.             if (header[0] == 'P'  && header[1] == 'K')
  120.             {
  121.                   retval = ZIP;
  122.                   goto EXIT;
  123.             }
  124.       }
  125.  
  126.       if (n >= 3 && header[0] == 'Z' && header[1] == 'O' && header[2] == 'O')
  127.       {
  128.             retval = ZOO;
  129.             goto EXIT;
  130.       }
  131.  
  132.       if (n >= 25 && header[0] == 0x1A)
  133.       {
  134.             if (header[1]>0x14)
  135.                   retval = ARC7;
  136.             else if (header[1]==0x0a || header[1]==0x0b)
  137.                   retval = PAK;
  138.             else  retval = ARC;
  139.             goto EXIT;
  140.       }
  141.  
  142.       if (0 == strncmp(header, "MZ", 2))        /* some sort of .EXE file   */
  143.       {
  144.             /* test for SFX ARJ file */
  145.  
  146.             memset(header, 0, sizeof(header));
  147.             fseek(fp, 0x39ba, SEEK_SET);
  148.             n = fread(header, sizeof(BYTE),
  149.                   sizeof(header) - sizeof(BYTE), fp);
  150.             if (n > 1 && header[0] == 0x60 && header[1] == 0xea)
  151.             {
  152.                   retval = SFXARJ;
  153.                   goto EXIT;
  154.             }
  155.  
  156.             /* test for SFX LHARC file */
  157.  
  158.             memset(header, 0, sizeof(header));
  159.             fseek(fp, 0x653, SEEK_SET);
  160.             n = fread(header, sizeof(BYTE),
  161.                   sizeof(header) - sizeof(BYTE), fp);
  162.             for (c = 0, i = header[0]; i--; c += (header+2)[i])
  163.                   ;
  164.             if (n >= 7 && n >= header[0] + 2)
  165.             {
  166.                   if (((BYTE)(c & 0x00FF)) == header[1] 
  167.                         && header[2] == '-' 
  168.                         && header[3] == 'l' 
  169.                         && header[4] == 'h' 
  170.                         && header[6] == '-')
  171.                   {
  172.                         retval = SFXLHARC;
  173.                         goto EXIT;
  174.                   }
  175.             }
  176.  
  177.             /* test for SFX LHA file */
  178.  
  179.             memset(header, 0, sizeof(header));
  180.             fseek(fp, 0x799, SEEK_SET);
  181.             n = fread(header, sizeof(BYTE),
  182.                   sizeof(header) - sizeof(BYTE), fp);
  183.             for (c = 0, i = header[0]; i--; c += (header+2)[i])
  184.                   ;
  185.             if (n >= 7 && n >= header[0] + 2)
  186.             {
  187.                   if (((BYTE)(c & 0x00FF)) == header[1] 
  188.                         && header[2] == '-' 
  189.                         && header[3] == 'l' 
  190.                         && header[4] == 'h' 
  191.                         && header[6] == '-')
  192.                   {
  193.                         retval = SFXLHA;
  194.                         goto EXIT;
  195.                   }
  196.             }
  197.  
  198.             /* test for SFX ZIP file */
  199.  
  200.             memset(header, 0, sizeof(header));
  201.             fseek(fp, 0x31f0, SEEK_SET);
  202.             n = fread(header, sizeof(BYTE),
  203.                   sizeof(header) - sizeof(BYTE), fp);
  204.             if (n > 1 && header[0] == 'P'  && header[1] == 'K')
  205.             {
  206.                   retval = SFXZIP;
  207.                   goto EXIT;
  208.             }
  209.  
  210.             /* test for SFX PKARC file */
  211.  
  212.             memset(header, 0, sizeof(header));
  213.             fseek(fp,0x261e,SEEK_SET);
  214.             n = fread(header, sizeof(BYTE),
  215.                   sizeof(header) - sizeof(BYTE), fp);
  216.             if (n > 1 && header[0] == 0x1a)
  217.             {
  218.                   if (header[1]>0x14)
  219.                         retval = SFXARC7;
  220.                   else if (header[1]==0x0a || header[1]==0x0b)
  221.                         retval = SFXPAK;
  222.                   else  retval = SFXARC;
  223.             }
  224.             else  retval = EXE;
  225.       }
  226.       retval = UNKNOWN;
  227. EXIT: fclose(fp);
  228.       return retval;
  229. }
  230.  
  231. #ifdef TEST
  232.  
  233. int main(int argc,char *argv[])
  234. {
  235.       char *arc_types[]={"UNKNOWN", "ARC", "ZOO", "ARJ", "LHARC", "LHA",
  236.                          "ZIP", "PAK", "PAK", "ARC7", "SFXARC", "SFXARJ",
  237.                          "SFXLHARC", "SFXLHA", "SFXZIP", "SFXARC7", "SFXPAK",
  238.                          "EXE"};
  239.  
  240.       while (--argc)
  241.       {
  242.             enum ArcType which;
  243.  
  244.             if (ArcERR == (which = WhichArc(*++argv)))
  245.                   printf("File error accessing %s\n", *argv);
  246.             else  printf("%s archive type is %s\n", *argv, arc_types[which]);
  247.       }
  248.       return(0);
  249. }
  250.  
  251. #endif
  252.