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

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