From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/whicharc.c | 251 ++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/whicharc.c (limited to 'reference/C/CONTRIB/SNIP/whicharc.c') 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 +#include + +/* -------------------------------------------------------------------- + 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 -- cgit v1.2.3-54-g00ecf