pgpfiletype.c
来自「著名的加密软件的应用于电子邮件中」· C语言 代码 · 共 210 行
C
210 行
/*
* pgpFileType.c -- Figure out the type of a file.
*
* Copyright (C) 1993-1997 Pretty Good Privacy, Inc. All rights reserved.
*
* Written by Colin Plumb.
*
* $Id: pgpFileType.c,v 1.1.2.1 1997/06/07 09:51:41 mhw Exp $
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h> /* For strcmp */
#include "pgpFileType.h"
#include "pgpPktByte.h"
#define FILETYPELEN 8 /* # of characters needed */
struct FileTypeInternal {
unsigned char const pattern[FILETYPELEN]; /* First char is length */
struct PgpFileType type;
};
/* A character that does not appear in any pattern */
#define ANY (unsigned char)255
static struct 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 struct PgpFileType PGPFile = {"PGP", ".pgp", 0};
/* \250 3 P G P */
static unsigned char const PGPPattern[] = { 5, 168, 3, 80, 71, 80 };
static int
fileTypeMatch (byte const *bytes, byte 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 the file is a recognized type */
struct PgpFileType const *
pgpFileType (byte 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 &PGPFile;
return (struct PgpFileType *)0;
}
/*
* 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 (byte const *prefix, unsigned len)
{
if (!len)
return 0;
/* _All_ PGP messages start with a character 10xxxxxx */
if (!IS_OLD_PKTBYTE (*prefix))
return 0;
/* Check for a new-style PGP file, using the PGP file header */
if (fileTypeMatch (PGPPattern, prefix, len))
return 1;
/*
* Check for old-style PGP file, checking the middle bits for
* known packet types. This needs to match lib/pipe/file/pgpHeader.c
*/
switch (OLD_PKTBYTE_TYPE (*prefix)) {
case PKTBYTE_ESK:
case PKTBYTE_SIG:
case PKTBYTE_CONVESK:
case PKTBYTE_SECKEY:
case PKTBYTE_PUBKEY:
case PKTBYTE_SECSUBKEY:
case PKTBYTE_PUBSUBKEY:
case PKTBYTE_COMPRESSED:
case PKTBYTE_CONVENTIONAL:
case PKTBYTE_LITERAL:
/* These are the known packet types */
return 1;
default:
/* Its not known -- perhaps something else? */
return 0;
}
/* NOTREACHED */
return 0;
}
/*
* 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.
*/
int
pgpFileTypeBinary(char const *lang, byte const *buf, unsigned len)
{
unsigned highlimit;
char 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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?