summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/whicharc.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/whicharc.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/whicharc.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/whicharc.c b/reference/C/CONTRIB/SNIP/whicharc.c
new file mode 100755
index 0000000..8ca8ce8
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/whicharc.c
@@ -0,0 +1,251 @@
+#include <stdio.h>
+#include <string.h>
+
+/* --------------------------------------------------------------------
+ Module: WHICHARC.C
+ Subject: tries to determine the archiver used to compress files
+ Author: Heinz Ozwirk & David Gersic
+ modified for SNIPPETS by Bob Stout
+ Status: public domain
+ Started: 28.09.1991 13:35:57
+ Modified: 13.10.1991 14:15:57
+ Modified: 5 January, 1992 11:50am by David Gersic
+ Added return codes for self extracting archive files.
+ Modified: 16 January, 1992, 4:15pm by David Gersic
+ Added Pak and ARC ver. 6 with information from Richard
+ Vanhouten @1:272/38. I'm not sure that this code works
+ perfectly for those formats, as his message seems to
+ indicate that the entire archive has to be scanned for
+ headers to check before the type can be perfectly
+ determined. It seems to work for test archives produced
+ here, but may not work for all archives.
+ --------------------------------------------------------------------
+ Prototype: int WhichArc(char *pName)
+ pName address of full path name of file to examine
+ Result -1: file not found
+ UNKNOWN: unknown packer
+ ARC: ARC or PKARC
+ ARJ: ARJ
+ LHA: LHARC or LHA
+ ZIP: PKZIP
+ ZOO: Zoo
+ PAK: Pak
+ ARC7: ARC later than ver. 6.02
+ SFXARC: Self Extracting PKARC
+ SFXARJ: Self Extracting ARJ
+ SFXLHARC:Self Extracting LHARC
+ SFXLHA: Self Extracting LHA
+ SFXZIP: Self Extracting ZIP
+ SFXPAK: Self Extracting Pak
+ SFXARC6: Self Extracting ARC later than ver. 6.02
+ EXE: MS DOS executable of unknown type
+
+ LHARC/LHA
+ No archive header. WhichArc examines the checksum of the first
+ file header. If the checksum is valid and if the string -lh?-
+ is found, LHA or LHARC is assumed.
+
+ ARJ
+ If a file starts with 0x60, 0xEA, ARJ is assumed.
+
+ ZIP
+ If the file begins with "PK", PKZIP is assumed.
+
+ ZOO
+ Zoo'ed archives always start with "ZOO x.xx Archive". WhichArc
+ only looks for "ZOO".
+
+ ARC
+ No header. Files starting with 0x1A are assumed to be ARCed.
+
+ PAK
+ Similar to ARC files, but if the second byte of the header is 0x0a or
+ 0x0b, it was created by Pak.
+
+ ARC7
+ Similar to ARC, but if the second byte of the header is 0x14 or
+ higher, it was created by an Arc version later than 6.02.
+
+ SFX*
+ All of the SFX files start with a small decompressor. Seek past
+ the decompressor and repeat the above checks.
+ -------------------------------------------------------------------- */
+
+
+typedef unsigned char BYTE;
+
+enum ArcType { ArcERR=-1, UNKNOWN, ARC, ZOO, ARJ, LHARC, LHA, ZIP, PAK, ARC7,
+ SFXARC, SFXARJ, SFXLHARC, SFXLHA, SFXZIP, SFXARC7, SFXPAK, EXE
+ };
+
+enum ArcType WhichArc(char *pName)
+{
+ FILE *fp;
+ BYTE header[128];
+ int c, i, n;
+ enum ArcType retval = ArcERR;
+
+ memset(header, 0, sizeof(header));
+ fp = fopen(pName, "rb");
+ if (fp == NULL)
+ goto EXIT; /* error opening file */
+ n = fread(header, sizeof(BYTE), sizeof(header) - sizeof(BYTE), fp);
+
+ if (n <= 0) /* error reading from file */
+ goto EXIT;
+
+ if (n >= 7 && n >= header[0] + 2)
+ {
+ for (c = 0, i = header[0]; i--; c += (header+2)[i])
+ ;
+ if (((BYTE)(c & 0x00FF)) == header[1]
+ && header[2] == '-'
+ && header[3] == 'l'
+ && header[4] == 'h'
+ && header[6] == '-')
+ {
+ retval = (header[5] > '1') ? LHA : LHARC;
+ goto EXIT;
+ }
+ }
+
+ if (n >= 2)
+ {
+ if (header[0] == 0x60 && header[1] == 0xEA)
+ {
+ retval = ARJ;
+ goto EXIT;
+ }
+ if (header[0] == 'P' && header[1] == 'K')
+ {
+ retval = ZIP;
+ goto EXIT;
+ }
+ }
+
+ if (n >= 3 && header[0] == 'Z' && header[1] == 'O' && header[2] == 'O')
+ {
+ retval = ZOO;
+ goto EXIT;
+ }
+
+ if (n >= 25 && header[0] == 0x1A)
+ {
+ if (header[1]>0x14)
+ retval = ARC7;
+ else if (header[1]==0x0a || header[1]==0x0b)
+ retval = PAK;
+ else retval = ARC;
+ goto EXIT;
+ }
+
+ if (0 == strncmp(header, "MZ", 2)) /* some sort of .EXE file */
+ {
+ /* test for SFX ARJ file */
+
+ memset(header, 0, sizeof(header));
+ fseek(fp, 0x39ba, SEEK_SET);
+ n = fread(header, sizeof(BYTE),
+ sizeof(header) - sizeof(BYTE), fp);
+ if (n > 1 && header[0] == 0x60 && header[1] == 0xea)
+ {
+ retval = SFXARJ;
+ goto EXIT;
+ }
+
+ /* test for SFX LHARC file */
+
+ memset(header, 0, sizeof(header));
+ fseek(fp, 0x653, SEEK_SET);
+ n = fread(header, sizeof(BYTE),
+ sizeof(header) - sizeof(BYTE), fp);
+ for (c = 0, i = header[0]; i--; c += (header+2)[i])
+ ;
+ if (n >= 7 && n >= header[0] + 2)
+ {
+ if (((BYTE)(c & 0x00FF)) == header[1]
+ && header[2] == '-'
+ && header[3] == 'l'
+ && header[4] == 'h'
+ && header[6] == '-')
+ {
+ retval = SFXLHARC;
+ goto EXIT;
+ }
+ }
+
+ /* test for SFX LHA file */
+
+ memset(header, 0, sizeof(header));
+ fseek(fp, 0x799, SEEK_SET);
+ n = fread(header, sizeof(BYTE),
+ sizeof(header) - sizeof(BYTE), fp);
+ for (c = 0, i = header[0]; i--; c += (header+2)[i])
+ ;
+ if (n >= 7 && n >= header[0] + 2)
+ {
+ if (((BYTE)(c & 0x00FF)) == header[1]
+ && header[2] == '-'
+ && header[3] == 'l'
+ && header[4] == 'h'
+ && header[6] == '-')
+ {
+ retval = SFXLHA;
+ goto EXIT;
+ }
+ }
+
+ /* test for SFX ZIP file */
+
+ memset(header, 0, sizeof(header));
+ fseek(fp, 0x31f0, SEEK_SET);
+ n = fread(header, sizeof(BYTE),
+ sizeof(header) - sizeof(BYTE), fp);
+ if (n > 1 && header[0] == 'P' && header[1] == 'K')
+ {
+ retval = SFXZIP;
+ goto EXIT;
+ }
+
+ /* test for SFX PKARC file */
+
+ memset(header, 0, sizeof(header));
+ fseek(fp,0x261e,SEEK_SET);
+ n = fread(header, sizeof(BYTE),
+ sizeof(header) - sizeof(BYTE), fp);
+ if (n > 1 && header[0] == 0x1a)
+ {
+ if (header[1]>0x14)
+ retval = SFXARC7;
+ else if (header[1]==0x0a || header[1]==0x0b)
+ retval = SFXPAK;
+ else retval = SFXARC;
+ }
+ else retval = EXE;
+ }
+ retval = UNKNOWN;
+EXIT: fclose(fp);
+ return retval;
+}
+
+#ifdef TEST
+
+int main(int argc,char *argv[])
+{
+ char *arc_types[]={"UNKNOWN", "ARC", "ZOO", "ARJ", "LHARC", "LHA",
+ "ZIP", "PAK", "PAK", "ARC7", "SFXARC", "SFXARJ",
+ "SFXLHARC", "SFXLHA", "SFXZIP", "SFXARC7", "SFXPAK",
+ "EXE"};
+
+ while (--argc)
+ {
+ enum ArcType which;
+
+ if (ArcERR == (which = WhichArc(*++argv)))
+ printf("File error accessing %s\n", *argv);
+ else printf("%s archive type is %s\n", *argv, arc_types[which]);
+ }
+ return(0);
+}
+
+#endif