📄 pgpfiletype.c
字号:
/*
* Figure out the type of a file.
*
* Written by Colin Plumb.
*
* $Id: pgpFileType.c,v 1.10 1998/06/03 20:12:06 hal Exp $
*/
#include "pgpConfig.h"
#include <string.h> /* For strcmp */
#include "pgpFileType.h"
#include "pgpPktByte.h"
#define FILETYPELEN 8 /* # of characters needed */
/* A character that does not appear in any pattern */
#define ANY (unsigned char)255
static unsigned char const PGPPattern[] = { 5, 168, 3, 80, 71, 80 };
static int
fileTypeMatch (PGPByte const *bytes, PGPByte const *prefix, unsigned len)
{
unsigned l = *bytes++;
unsigned i;
if (l > len)
return 0;
for (i = 0; i < l; i++)
if (bytes[i] != prefix[i] && bytes[i] != ANY)
return 0;
return 1; /* Success */
}
/*
* Figure out if a file is a binary PGP file.
* Returns 1 if it is a PGP file, 0 if it is not.
*/
int
pgpFileTypePGP (PGPByte const *prefix, unsigned len)
{
PGPUInt32 type;
if (!len)
return 0;
/* Check first byte */
if (!IS_OLD_PKTBYTE (*prefix) && !IS_NEW_PKTBYTE(*prefix))
return 0;
/* Check for a new-style PGP file, using the PGP file header */
if (fileTypeMatch (PGPPattern, prefix, len))
return 1;
/*
* Check PGP packet type, checking the tag bits for
* known packet types. This needs to match pgpPktByte.h
*/
type = PKTBYTE_TYPE (*prefix);
if (type > 0 && type <= PKTBYTE_MAXIMUM)
return 1;
return 0;
}
#if 0 /* KEEP [ */
struct PGPFileTypeStruct {
char const * typeName; /* Noun/adjective to modify "file" */
char const * ext; /* .zip, .lha, .gz, etc. */
PGPBoolean compressible;/* Can it be further compressed (.tar) */
};
typedef struct PGPFileTypeStruct PGPFileTypeStruct;
typedef struct FileTypeInternal {
unsigned char const pattern[FILETYPELEN]; /* First char is length */
PGPFileTypeStruct type;
} FileTypeInternal;
static FileTypeInternal patterns[] =
{
{ { 2, 26, 11 }, { "PAK", ".pak", 0 } },
{ { 2, 31, 139 }, { "gzip", ".gz", 0 } },
{ { 2, 31, 157 }, { "compressed",".Z", 0 } },
{ { 2, 234, 96 }, { "Arj", ".arj", 0 } },
/* ^Z H P % */
{ { 4, 26, 72, 80, 37 }, { "Hyper", ".hyp", 0 } },
/* G I F 8 */
{ { 4, 71, 73, 70, 56 }, { "GIF", ".gif", 0 } },
/* HPAK */
{ { 4, 72, 80, 65, 75 }, { "Hpack", ".hpk", 0 } },
/* P K ^C ^D */
{ { 4, 80, 75, 3, 4 }, { "Zip", ".zip", 0 } },
/* Z O O */
{ { 4, 90, 79, 79, 32 }, { "Zoo", ".zoo", 0 } },
/* ? ? - l h a 0 - -lha1- -lha2- and -lha3- */
{ { 7, ANY, ANY, 45, 108, 104, 48, 45 }, { "LHArc", ".lzh", 0 } },
{ { 7, ANY, ANY, 45, 108, 104, 49, 45 }, { "LHArc", ".lzh", 0 } },
{ { 7, ANY, ANY, 45, 108, 104, 50, 45 }, { "LHArc", ".lzh", 0 } },
{ { 7, ANY, ANY, 45, 108, 104, 51, 45 }, { "LHArc", ".lzh", 0 } },
/* ? ? - l h a ? - */
{ { 7, ANY, ANY, 45, 108, 104, ANY, 45 }, { "LHArc", ".lha", 0 } }
};
static PGPFileTypeStruct sPGPFile = {"PGP", ".pgp", 0};
/* \250 3 P G P */
/* Figure out if the file is a recognized type */
static PGPFileTypeStruct const *
pgpFileType (PGPByte const *prefix, unsigned len)
{
unsigned i;
for (i = 0; i < sizeof(patterns)/sizeof(*patterns); i++) {
if (fileTypeMatch(patterns[i].pattern, prefix, len))
return &patterns[i].type;
}
if (pgpFileTypePGP (prefix, len))
return &sPGPFile;
return NULL;
}
/*
* Figure out if a file is human-readable or not.
* Returns 0 if text, 1 if binary.
*
* A file is considered binary if it contains any illegal control characters
* or "too many" characters with the 8th bit set. If you're using Latin-1,
* you might have some such characters, but a binary file probably averages
* about half odd characters. This test assumes a file is binary if the
* number of bytes with the high bit set exceeds a quarter of the buffer.
* EXCEPTION: If working in Russian, Cyrillic is usually placed in the high
* half, so ignore this test in that case.
*
* The legal control characters are:
* 0 NU null (nul) ILLEGAL
* 1 SH start of heading (soh) ILLEGAL
* 2 SX start of text (stx) ILLEGAL
* 3 EX end of text (etx) ILLEGAL
* 4 ET end of transmission (eot) ILLEGAL
* 5 EQ enquiry (enq) ILLEGAL
* 5 EQ enquiry (enq) ILLEGAL
* 6 AK acknowledge (ack) ILLEGAL
* 7 BL bell (bel) legal '\a'
* 8 BS backspace (bs) legal '\b'
* 9 HT character tabulation (ht) legal '\t'
* 10 LF line feed (lf) legal '\n'
* 11 VT line tabulation (vt) legal '\v'
* 12 FF form feed (ff) legal '\f'
* 13 CR carriage return (cr) legal '\r'
* 14 SO shift out (so) ILLEGAL
* 15 SI shift in (si) ILLEGAL
* 16 DL datalink escape (dle) ILLEGAL
* 17 D1 device control one (dc1) ILLEGAL
* 18 D2 device control two (dc2) ILLEGAL
* 19 D3 device control three (dc3) ILLEGAL
* 20 D4 device control four (dc4) ILLEGAL
* 21 NK negative acknowledge (nak) ILLEGAL
* 22 SY syncronous idle (syn) ILLEGAL
* 23 EB end of transmission block (etb) ILLEGAL
* 24 CN cancel (can) ILLEGAL
* 25 EM end of medium (em) ILLEGAL
* 26 SB substitute (sub) legal (CP/M & MS-DOS EOF)
* 27 EC escape (esc) ILLEGAL
* 28 FS file separator (is4) ILLEGAL
* 29 GS group separator (is3) ILLEGAL
* 30 RS record separator (is2) ILLEGAL
* 31 US unit separator (is1) ILLEGAL
*
* TODO: Worry about EBCDIC
* TODO: Use the charset rather than the language to decide.
* TODO: Worry about shift-JIS and other heavy top-8-bit uses.
*/
/* this appears to not be called. KEEP (as static) for now */
static int
pgpFileTypeBinary(char const *lang, PGPByte const *buf, unsigned len)
{
unsigned highlimit;
PGPByte c;
if (!len)
return 1; /* empty file or error, not a text file */
if (pgpFileType(buf, len))
return 1;
/* Limit on number of 8th-bit-set characters allowed */
highlimit = len/4;
if (lang && strcmp(lang, "ru") == 0)
highlimit = len;
do {
c = *buf++;
if (c < ' ' && (c < '\a' || c > '\r') && c != 26)
return 1; /* Illegal control char */
if ((c & 0x80) && highlimit-- == 0)
return 1; /* Too many 8th bits set */
} while (--len);
return 0;
}
#endif /* ] KEEP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -