1bd389b36SDavid du Colombier #include <u.h> 2bd389b36SDavid du Colombier #include <libc.h> 3bd389b36SDavid du Colombier #include <bio.h> 4bd389b36SDavid du Colombier #include <ctype.h> 5bd389b36SDavid du Colombier #include <mach.h> 63e12c5d1SDavid du Colombier 73e12c5d1SDavid du Colombier /* 83e12c5d1SDavid du Colombier * file - determine type of file 93e12c5d1SDavid du Colombier */ 103e12c5d1SDavid du Colombier #define LENDIAN(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)) 113e12c5d1SDavid du Colombier 129a747e4fSDavid du Colombier uchar buf[6001]; 133e12c5d1SDavid du Colombier short cfreq[140]; 143e12c5d1SDavid du Colombier short wfreq[50]; 153e12c5d1SDavid du Colombier int nbuf; 169a747e4fSDavid du Colombier Dir* mbuf; 173e12c5d1SDavid du Colombier int fd; 183e12c5d1SDavid du Colombier char *fname; 193e12c5d1SDavid du Colombier char *slash; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier enum 223e12c5d1SDavid du Colombier { 233e12c5d1SDavid du Colombier Cword, 243e12c5d1SDavid du Colombier Fword, 253e12c5d1SDavid du Colombier Aword, 26219b2ee8SDavid du Colombier Alword, 277dd7cddfSDavid du Colombier Lword, 283e12c5d1SDavid du Colombier I1, 293e12c5d1SDavid du Colombier I2, 303e12c5d1SDavid du Colombier I3, 313e12c5d1SDavid du Colombier Clatin = 128, 323e12c5d1SDavid du Colombier Cbinary, 333e12c5d1SDavid du Colombier Cnull, 343e12c5d1SDavid du Colombier Ceascii, 353e12c5d1SDavid du Colombier Cutf, 363e12c5d1SDavid du Colombier }; 373e12c5d1SDavid du Colombier struct 383e12c5d1SDavid du Colombier { 393e12c5d1SDavid du Colombier char* word; 403e12c5d1SDavid du Colombier int class; 413e12c5d1SDavid du Colombier } dict[] = 423e12c5d1SDavid du Colombier { 437dd7cddfSDavid du Colombier "PATH", Lword, 44219b2ee8SDavid du Colombier "TEXT", Aword, 45219b2ee8SDavid du Colombier "adt", Alword, 46219b2ee8SDavid du Colombier "aggr", Alword, 47219b2ee8SDavid du Colombier "alef", Alword, 487dd7cddfSDavid du Colombier "array", Lword, 49219b2ee8SDavid du Colombier "block", Fword, 50219b2ee8SDavid du Colombier "chan", Alword, 51219b2ee8SDavid du Colombier "char", Cword, 52219b2ee8SDavid du Colombier "common", Fword, 537dd7cddfSDavid du Colombier "con", Lword, 54219b2ee8SDavid du Colombier "data", Fword, 55219b2ee8SDavid du Colombier "dimension", Fword, 56219b2ee8SDavid du Colombier "double", Cword, 57219b2ee8SDavid du Colombier "extern", Cword, 58219b2ee8SDavid du Colombier "bio", I2, 59219b2ee8SDavid du Colombier "float", Cword, 607dd7cddfSDavid du Colombier "fn", Lword, 61219b2ee8SDavid du Colombier "function", Fword, 62219b2ee8SDavid du Colombier "h", I3, 637dd7cddfSDavid du Colombier "implement", Lword, 647dd7cddfSDavid du Colombier "import", Lword, 65219b2ee8SDavid du Colombier "include", I1, 66219b2ee8SDavid du Colombier "int", Cword, 67219b2ee8SDavid du Colombier "integer", Fword, 687dd7cddfSDavid du Colombier "iota", Lword, 69219b2ee8SDavid du Colombier "libc", I2, 70219b2ee8SDavid du Colombier "long", Cword, 717dd7cddfSDavid du Colombier "module", Lword, 72219b2ee8SDavid du Colombier "real", Fword, 737dd7cddfSDavid du Colombier "ref", Lword, 74219b2ee8SDavid du Colombier "register", Cword, 757dd7cddfSDavid du Colombier "self", Lword, 76219b2ee8SDavid du Colombier "short", Cword, 77219b2ee8SDavid du Colombier "static", Cword, 78219b2ee8SDavid du Colombier "stdio", I2, 79219b2ee8SDavid du Colombier "struct", Cword, 80219b2ee8SDavid du Colombier "subroutine", Fword, 81219b2ee8SDavid du Colombier "u", I2, 82219b2ee8SDavid du Colombier "void", Cword, 83219b2ee8SDavid du Colombier }; 84219b2ee8SDavid du Colombier 85219b2ee8SDavid du Colombier /* codes for 'mode' field in language structure */ 86219b2ee8SDavid du Colombier enum { 87219b2ee8SDavid du Colombier Normal = 0, 88219b2ee8SDavid du Colombier First, /* first entry for language spanning several ranges */ 89219b2ee8SDavid du Colombier Multi, /* later entries " " " ... */ 90219b2ee8SDavid du Colombier Shared, /* codes used in several languages */ 913e12c5d1SDavid du Colombier }; 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier struct 943e12c5d1SDavid du Colombier { 95219b2ee8SDavid du Colombier int mode; /* see enum above */ 963e12c5d1SDavid du Colombier int count; 973e12c5d1SDavid du Colombier int low; 983e12c5d1SDavid du Colombier int high; 993e12c5d1SDavid du Colombier char *name; 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier } language[] = 1023e12c5d1SDavid du Colombier { 103219b2ee8SDavid du Colombier Normal, 0, 0x0080, 0x0080, "Extended Latin", 104219b2ee8SDavid du Colombier Normal, 0, 0x0100, 0x01FF, "Extended Latin", 105219b2ee8SDavid du Colombier Normal, 0, 0x0370, 0x03FF, "Greek", 106219b2ee8SDavid du Colombier Normal, 0, 0x0400, 0x04FF, "Cyrillic", 107219b2ee8SDavid du Colombier Normal, 0, 0x0530, 0x058F, "Armenian", 108219b2ee8SDavid du Colombier Normal, 0, 0x0590, 0x05FF, "Hebrew", 109219b2ee8SDavid du Colombier Normal, 0, 0x0600, 0x06FF, "Arabic", 110219b2ee8SDavid du Colombier Normal, 0, 0x0900, 0x097F, "Devanagari", 111219b2ee8SDavid du Colombier Normal, 0, 0x0980, 0x09FF, "Bengali", 112219b2ee8SDavid du Colombier Normal, 0, 0x0A00, 0x0A7F, "Gurmukhi", 113219b2ee8SDavid du Colombier Normal, 0, 0x0A80, 0x0AFF, "Gujarati", 114219b2ee8SDavid du Colombier Normal, 0, 0x0B00, 0x0B7F, "Oriya", 115219b2ee8SDavid du Colombier Normal, 0, 0x0B80, 0x0BFF, "Tamil", 116219b2ee8SDavid du Colombier Normal, 0, 0x0C00, 0x0C7F, "Telugu", 117219b2ee8SDavid du Colombier Normal, 0, 0x0C80, 0x0CFF, "Kannada", 118219b2ee8SDavid du Colombier Normal, 0, 0x0D00, 0x0D7F, "Malayalam", 119219b2ee8SDavid du Colombier Normal, 0, 0x0E00, 0x0E7F, "Thai", 120219b2ee8SDavid du Colombier Normal, 0, 0x0E80, 0x0EFF, "Lao", 121219b2ee8SDavid du Colombier Normal, 0, 0x1000, 0x105F, "Tibetan", 122219b2ee8SDavid du Colombier Normal, 0, 0x10A0, 0x10FF, "Georgian", 123219b2ee8SDavid du Colombier Normal, 0, 0x3040, 0x30FF, "Japanese", 124219b2ee8SDavid du Colombier Normal, 0, 0x3100, 0x312F, "Chinese", 125219b2ee8SDavid du Colombier First, 0, 0x3130, 0x318F, "Korean", 126219b2ee8SDavid du Colombier Multi, 0, 0x3400, 0x3D2F, "Korean", 127219b2ee8SDavid du Colombier Shared, 0, 0x4e00, 0x9fff, "CJK", 128219b2ee8SDavid du Colombier Normal, 0, 0, 0, 0, /* terminal entry */ 1293e12c5d1SDavid du Colombier }; 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier 1323e12c5d1SDavid du Colombier enum 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier Fascii, /* printable ascii */ 1353e12c5d1SDavid du Colombier Flatin, /* latin 1*/ 1363e12c5d1SDavid du Colombier Futf, /* UTf character set */ 1373e12c5d1SDavid du Colombier Fbinary, /* binary */ 1383e12c5d1SDavid du Colombier Feascii, /* ASCII with control chars */ 1393e12c5d1SDavid du Colombier Fnull, /* NULL in file */ 1403e12c5d1SDavid du Colombier } guess; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier void bump_utf_count(Rune); 1437dd7cddfSDavid du Colombier int cistrncmp(char*, char*, int); 1443e12c5d1SDavid du Colombier void filetype(int); 1453e12c5d1SDavid du Colombier int getfontnum(uchar*, uchar**); 1463e12c5d1SDavid du Colombier int isas(void); 1473e12c5d1SDavid du Colombier int isc(void); 1483e12c5d1SDavid du Colombier int iscint(void); 1493e12c5d1SDavid du Colombier int isenglish(void); 1507dd7cddfSDavid du Colombier int ishp(void); 1517dd7cddfSDavid du Colombier int ishtml(void); 1529a747e4fSDavid du Colombier int isrfc822(void); 153d9306527SDavid du Colombier int ismbox(void); 1547dd7cddfSDavid du Colombier int islimbo(void); 1553e12c5d1SDavid du Colombier int ismung(void); 1563e12c5d1SDavid du Colombier int isp9bit(void); 1573e12c5d1SDavid du Colombier int isp9font(void); 158fb7f0c93SDavid du Colombier int isrtf(void); 159f2e8132aSDavid du Colombier int ismsdos(void); 160b7327ca2SDavid du Colombier int iself(void); 1613e12c5d1SDavid du Colombier int istring(void); 162ddb951e3SDavid du Colombier int iff(void); 1633e12c5d1SDavid du Colombier int long0(void); 1644b30ca09SDavid du Colombier int istar(void); 1653e12c5d1SDavid du Colombier int p9bitnum(uchar*); 1663e12c5d1SDavid du Colombier int p9subfont(uchar*); 1673e12c5d1SDavid du Colombier void print_utf(void); 1683e12c5d1SDavid du Colombier void type(char*, int); 1693e12c5d1SDavid du Colombier int utf_count(void); 1703e12c5d1SDavid du Colombier void wordfreq(void); 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier int (*call[])(void) = 1733e12c5d1SDavid du Colombier { 1743e12c5d1SDavid du Colombier long0, /* recognizable by first 4 bytes */ 1753e12c5d1SDavid du Colombier istring, /* recognizable by first string */ 176ddb951e3SDavid du Colombier iff, /* interchange file format (strings) */ 1779a747e4fSDavid du Colombier isrfc822, /* email file */ 178d9306527SDavid du Colombier ismbox, /* mail box */ 1794b30ca09SDavid du Colombier istar, /* recognizable by tar checksum */ 180643074abSDavid du Colombier ishtml, /* html keywords */ 181219b2ee8SDavid du Colombier iscint, /* compiler/assembler intermediate */ 1827dd7cddfSDavid du Colombier islimbo, /* limbo source */ 183219b2ee8SDavid du Colombier isc, /* c & alef compiler key words */ 1843e12c5d1SDavid du Colombier isas, /* assembler key words */ 1853e12c5d1SDavid du Colombier ismung, /* entropy compressed/encrypted */ 1863e12c5d1SDavid du Colombier isp9font, /* plan 9 font */ 1877dd7cddfSDavid du Colombier isp9bit, /* plan 9 image (as from /dev/window) */ 1887dd7cddfSDavid du Colombier isenglish, /* char frequency English */ 189fb7f0c93SDavid du Colombier isrtf, /* rich text format */ 190f2e8132aSDavid du Colombier ismsdos, /* msdos exe (virus file attachement) */ 191b7327ca2SDavid du Colombier iself, /* ELF (foreign) executable */ 1923e12c5d1SDavid du Colombier 0 1933e12c5d1SDavid du Colombier }; 1943e12c5d1SDavid du Colombier 1957dd7cddfSDavid du Colombier int mime; 1967dd7cddfSDavid du Colombier 1977dd7cddfSDavid du Colombier #define OCTET "application/octet-stream\n" 1987dd7cddfSDavid du Colombier #define PLAIN "text/plain\n" 1997dd7cddfSDavid du Colombier 2003e12c5d1SDavid du Colombier void 2013e12c5d1SDavid du Colombier main(int argc, char *argv[]) 2023e12c5d1SDavid du Colombier { 2033e12c5d1SDavid du Colombier int i, j, maxlen; 2043e12c5d1SDavid du Colombier char *cp; 2053e12c5d1SDavid du Colombier Rune r; 2063e12c5d1SDavid du Colombier 2077dd7cddfSDavid du Colombier ARGBEGIN{ 2087dd7cddfSDavid du Colombier case 'm': 2097dd7cddfSDavid du Colombier mime = 1; 2107dd7cddfSDavid du Colombier break; 2117dd7cddfSDavid du Colombier default: 2127dd7cddfSDavid du Colombier fprint(2, "usage: file [-m] [file...]\n"); 2137dd7cddfSDavid du Colombier exits("usage"); 2147dd7cddfSDavid du Colombier }ARGEND; 2157dd7cddfSDavid du Colombier 2163e12c5d1SDavid du Colombier maxlen = 0; 2177dd7cddfSDavid du Colombier if(mime == 0 || argc > 1){ 2187dd7cddfSDavid du Colombier for(i = 0; i < argc; i++) { 2193e12c5d1SDavid du Colombier for (j = 0, cp = argv[i]; *cp; j++, cp += chartorune(&r, cp)) 2203e12c5d1SDavid du Colombier ; 2213e12c5d1SDavid du Colombier if(j > maxlen) 2223e12c5d1SDavid du Colombier maxlen = j; 2233e12c5d1SDavid du Colombier } 2247dd7cddfSDavid du Colombier } 2257dd7cddfSDavid du Colombier if (argc <= 0) { 2267dd7cddfSDavid du Colombier if(!mime) 2273e12c5d1SDavid du Colombier print ("stdin: "); 2283e12c5d1SDavid du Colombier filetype(0); 2293e12c5d1SDavid du Colombier } 2303e12c5d1SDavid du Colombier else { 2317dd7cddfSDavid du Colombier for(i = 0; i < argc; i++) 2323e12c5d1SDavid du Colombier type(argv[i], maxlen); 2333e12c5d1SDavid du Colombier } 2343e12c5d1SDavid du Colombier exits(0); 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier void 2383e12c5d1SDavid du Colombier type(char *file, int nlen) 2393e12c5d1SDavid du Colombier { 2403e12c5d1SDavid du Colombier Rune r; 2413e12c5d1SDavid du Colombier int i; 2423e12c5d1SDavid du Colombier char *p; 2433e12c5d1SDavid du Colombier 2447dd7cddfSDavid du Colombier if(nlen > 0){ 2453e12c5d1SDavid du Colombier slash = 0; 2463e12c5d1SDavid du Colombier for (i = 0, p = file; *p; i++) { 2473e12c5d1SDavid du Colombier if (*p == '/') /* find rightmost slash */ 2483e12c5d1SDavid du Colombier slash = p; 2493e12c5d1SDavid du Colombier p += chartorune(&r, p); /* count runes */ 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier print("%s:%*s",file, nlen-i+1, ""); 2527dd7cddfSDavid du Colombier } 2533e12c5d1SDavid du Colombier fname = file; 2543e12c5d1SDavid du Colombier if ((fd = open(file, OREAD)) < 0) { 2553e12c5d1SDavid du Colombier print("cannot open\n"); 2563e12c5d1SDavid du Colombier return; 2573e12c5d1SDavid du Colombier } 2583e12c5d1SDavid du Colombier filetype(fd); 2593e12c5d1SDavid du Colombier close(fd); 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier 2623e12c5d1SDavid du Colombier void 2633e12c5d1SDavid du Colombier filetype(int fd) 2643e12c5d1SDavid du Colombier { 2653e12c5d1SDavid du Colombier Rune r; 266219b2ee8SDavid du Colombier int i, f, n; 267219b2ee8SDavid du Colombier char *p, *eob; 2683e12c5d1SDavid du Colombier 2699a747e4fSDavid du Colombier free(mbuf); 2709a747e4fSDavid du Colombier mbuf = dirfstat(fd); 2719a747e4fSDavid du Colombier if(mbuf == nil){ 2729a747e4fSDavid du Colombier print("cannot stat: %r\n"); 2733e12c5d1SDavid du Colombier return; 2743e12c5d1SDavid du Colombier } 2759a747e4fSDavid du Colombier if(mbuf->mode & DMDIR) { 2767dd7cddfSDavid du Colombier print(mime ? "text/directory\n" : "directory\n"); 2773e12c5d1SDavid du Colombier return; 2783e12c5d1SDavid du Colombier } 2799a747e4fSDavid du Colombier if(mbuf->type != 'M' && mbuf->type != '|') { 2807dd7cddfSDavid du Colombier print(mime ? OCTET : "special file #%c/%s\n", 2819a747e4fSDavid du Colombier mbuf->type, mbuf->name); 2823e12c5d1SDavid du Colombier return; 2833e12c5d1SDavid du Colombier } 2849a747e4fSDavid du Colombier nbuf = read(fd, buf, sizeof(buf)-1); 2853e12c5d1SDavid du Colombier 2863e12c5d1SDavid du Colombier if(nbuf < 0) { 2873e12c5d1SDavid du Colombier print("cannot read\n"); 2883e12c5d1SDavid du Colombier return; 2893e12c5d1SDavid du Colombier } 2903e12c5d1SDavid du Colombier if(nbuf == 0) { 2917dd7cddfSDavid du Colombier print(mime ? PLAIN : "empty file\n"); 2923e12c5d1SDavid du Colombier return; 2933e12c5d1SDavid du Colombier } 2949a747e4fSDavid du Colombier buf[nbuf] = 0; 2953e12c5d1SDavid du Colombier 2963e12c5d1SDavid du Colombier /* 2973e12c5d1SDavid du Colombier * build histogram table 2983e12c5d1SDavid du Colombier */ 2993e12c5d1SDavid du Colombier memset(cfreq, 0, sizeof(cfreq)); 3003e12c5d1SDavid du Colombier for (i = 0; language[i].name; i++) 3013e12c5d1SDavid du Colombier language[i].count = 0; 302219b2ee8SDavid du Colombier eob = (char *)buf+nbuf; 303219b2ee8SDavid du Colombier for(n = 0, p = (char *)buf; p < eob; n++) { 304219b2ee8SDavid du Colombier if (!fullrune(p, eob-p) && eob-p < UTFmax) 305219b2ee8SDavid du Colombier break; 3063e12c5d1SDavid du Colombier p += chartorune(&r, p); 3073e12c5d1SDavid du Colombier if (r == 0) 3083e12c5d1SDavid du Colombier f = Cnull; 3093e12c5d1SDavid du Colombier else if (r <= 0x7f) { 3103e12c5d1SDavid du Colombier if (!isprint(r) && !isspace(r)) 3113e12c5d1SDavid du Colombier f = Ceascii; /* ASCII control char */ 3123e12c5d1SDavid du Colombier else f = r; 313219b2ee8SDavid du Colombier } else if (r == 0x080) { 314219b2ee8SDavid du Colombier bump_utf_count(r); 315219b2ee8SDavid du Colombier f = Cutf; 3163e12c5d1SDavid du Colombier } else if (r < 0xA0) 3173e12c5d1SDavid du Colombier f = Cbinary; /* Invalid Runes */ 3183e12c5d1SDavid du Colombier else if (r <= 0xff) 3193e12c5d1SDavid du Colombier f = Clatin; /* Latin 1 */ 3203e12c5d1SDavid du Colombier else { 3213e12c5d1SDavid du Colombier bump_utf_count(r); 3223e12c5d1SDavid du Colombier f = Cutf; /* UTF extension */ 3233e12c5d1SDavid du Colombier } 3243e12c5d1SDavid du Colombier cfreq[f]++; /* ASCII chars peg directly */ 3253e12c5d1SDavid du Colombier } 3263e12c5d1SDavid du Colombier /* 3273e12c5d1SDavid du Colombier * gross classify 3283e12c5d1SDavid du Colombier */ 3293e12c5d1SDavid du Colombier if (cfreq[Cbinary]) 3303e12c5d1SDavid du Colombier guess = Fbinary; 3313e12c5d1SDavid du Colombier else if (cfreq[Cutf]) 3323e12c5d1SDavid du Colombier guess = Futf; 3333e12c5d1SDavid du Colombier else if (cfreq[Clatin]) 3343e12c5d1SDavid du Colombier guess = Flatin; 3353e12c5d1SDavid du Colombier else if (cfreq[Ceascii]) 3363e12c5d1SDavid du Colombier guess = Feascii; 337219b2ee8SDavid du Colombier else if (cfreq[Cnull] == n) { 33859cc4ca5SDavid du Colombier print(mime ? OCTET : "first block all null bytes\n"); 3393e12c5d1SDavid du Colombier return; 3403e12c5d1SDavid du Colombier } 3413e12c5d1SDavid du Colombier else guess = Fascii; 3423e12c5d1SDavid du Colombier /* 3433e12c5d1SDavid du Colombier * lookup dictionary words 3443e12c5d1SDavid du Colombier */ 345219b2ee8SDavid du Colombier memset(wfreq, 0, sizeof(wfreq)); 3467dd7cddfSDavid du Colombier if(guess == Fascii || guess == Flatin || guess == Futf) 3473e12c5d1SDavid du Colombier wordfreq(); 3483e12c5d1SDavid du Colombier /* 3493e12c5d1SDavid du Colombier * call individual classify routines 3503e12c5d1SDavid du Colombier */ 3513e12c5d1SDavid du Colombier for(i=0; call[i]; i++) 3523e12c5d1SDavid du Colombier if((*call[i])()) 3533e12c5d1SDavid du Colombier return; 3543e12c5d1SDavid du Colombier 3553e12c5d1SDavid du Colombier /* 3563e12c5d1SDavid du Colombier * if all else fails, 3573e12c5d1SDavid du Colombier * print out gross classification 3583e12c5d1SDavid du Colombier */ 35980ee5cbfSDavid du Colombier if (nbuf < 100 && !mime) 3607dd7cddfSDavid du Colombier print(mime ? PLAIN : "short "); 3613e12c5d1SDavid du Colombier if (guess == Fascii) 3627dd7cddfSDavid du Colombier print(mime ? PLAIN : "Ascii\n"); 3633e12c5d1SDavid du Colombier else if (guess == Feascii) 3647dd7cddfSDavid du Colombier print(mime ? PLAIN : "extended ascii\n"); 3653e12c5d1SDavid du Colombier else if (guess == Flatin) 3667dd7cddfSDavid du Colombier print(mime ? PLAIN : "latin ascii\n"); 3673e12c5d1SDavid du Colombier else if (guess == Futf && utf_count() < 4) 3683e12c5d1SDavid du Colombier print_utf(); 3697dd7cddfSDavid du Colombier else print(mime ? OCTET : "binary\n"); 3703e12c5d1SDavid du Colombier } 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier void 3733e12c5d1SDavid du Colombier bump_utf_count(Rune r) 3743e12c5d1SDavid du Colombier { 3753e12c5d1SDavid du Colombier int low, high, mid; 3763e12c5d1SDavid du Colombier 3773e12c5d1SDavid du Colombier high = sizeof(language)/sizeof(language[0])-1; 3783e12c5d1SDavid du Colombier for (low = 0; low < high;) { 3793e12c5d1SDavid du Colombier mid = (low+high)/2; 3803e12c5d1SDavid du Colombier if (r >=language[mid].low) { 3813e12c5d1SDavid du Colombier if (r <= language[mid].high) { 3823e12c5d1SDavid du Colombier language[mid].count++; 3833e12c5d1SDavid du Colombier break; 3843e12c5d1SDavid du Colombier } else low = mid+1; 3853e12c5d1SDavid du Colombier } else high = mid; 3863e12c5d1SDavid du Colombier } 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier 3893e12c5d1SDavid du Colombier int 3903e12c5d1SDavid du Colombier utf_count(void) 3913e12c5d1SDavid du Colombier { 3923e12c5d1SDavid du Colombier int i, count; 3933e12c5d1SDavid du Colombier 394219b2ee8SDavid du Colombier count = 0; 395219b2ee8SDavid du Colombier for (i = 0; language[i].name; i++) 3963e12c5d1SDavid du Colombier if (language[i].count > 0) 397219b2ee8SDavid du Colombier switch (language[i].mode) { 398219b2ee8SDavid du Colombier case Normal: 399219b2ee8SDavid du Colombier case First: 4003e12c5d1SDavid du Colombier count++; 401219b2ee8SDavid du Colombier break; 402219b2ee8SDavid du Colombier default: 403219b2ee8SDavid du Colombier break; 404219b2ee8SDavid du Colombier } 4053e12c5d1SDavid du Colombier return count; 4063e12c5d1SDavid du Colombier } 4073e12c5d1SDavid du Colombier 408219b2ee8SDavid du Colombier int 409219b2ee8SDavid du Colombier chkascii(void) 410219b2ee8SDavid du Colombier { 411219b2ee8SDavid du Colombier int i; 412219b2ee8SDavid du Colombier 413219b2ee8SDavid du Colombier for (i = 'a'; i < 'z'; i++) 414219b2ee8SDavid du Colombier if (cfreq[i]) 415219b2ee8SDavid du Colombier return 1; 416219b2ee8SDavid du Colombier for (i = 'A'; i < 'Z'; i++) 417219b2ee8SDavid du Colombier if (cfreq[i]) 418219b2ee8SDavid du Colombier return 1; 419219b2ee8SDavid du Colombier return 0; 420219b2ee8SDavid du Colombier } 421219b2ee8SDavid du Colombier 422219b2ee8SDavid du Colombier int 423219b2ee8SDavid du Colombier find_first(char *name) 424219b2ee8SDavid du Colombier { 425219b2ee8SDavid du Colombier int i; 426219b2ee8SDavid du Colombier 427219b2ee8SDavid du Colombier for (i = 0; language[i].name != 0; i++) 428219b2ee8SDavid du Colombier if (language[i].mode == First 429219b2ee8SDavid du Colombier && strcmp(language[i].name, name) == 0) 430219b2ee8SDavid du Colombier return i; 431219b2ee8SDavid du Colombier return -1; 432219b2ee8SDavid du Colombier } 433219b2ee8SDavid du Colombier 4343e12c5d1SDavid du Colombier void 4353e12c5d1SDavid du Colombier print_utf(void) 4363e12c5d1SDavid du Colombier { 437219b2ee8SDavid du Colombier int i, printed, j; 4383e12c5d1SDavid du Colombier 4397dd7cddfSDavid du Colombier if(mime){ 4407dd7cddfSDavid du Colombier print(PLAIN); 4417dd7cddfSDavid du Colombier return; 4427dd7cddfSDavid du Colombier } 443219b2ee8SDavid du Colombier if (chkascii()) { 444219b2ee8SDavid du Colombier printed = 1; 445219b2ee8SDavid du Colombier print("Ascii"); 446219b2ee8SDavid du Colombier } else 447219b2ee8SDavid du Colombier printed = 0; 448219b2ee8SDavid du Colombier for (i = 0; language[i].name; i++) 4493e12c5d1SDavid du Colombier if (language[i].count) { 450219b2ee8SDavid du Colombier switch(language[i].mode) { 451219b2ee8SDavid du Colombier case Multi: 452219b2ee8SDavid du Colombier j = find_first(language[i].name); 453219b2ee8SDavid du Colombier if (j < 0) 454219b2ee8SDavid du Colombier break; 455219b2ee8SDavid du Colombier if (language[j].count > 0) 456219b2ee8SDavid du Colombier break; 457219b2ee8SDavid du Colombier /* Fall through */ 458219b2ee8SDavid du Colombier case Normal: 459219b2ee8SDavid du Colombier case First: 4603e12c5d1SDavid du Colombier if (printed) 4613e12c5d1SDavid du Colombier print(" & "); 4623e12c5d1SDavid du Colombier else printed = 1; 4633e12c5d1SDavid du Colombier print("%s", language[i].name); 464219b2ee8SDavid du Colombier break; 465219b2ee8SDavid du Colombier case Shared: 466219b2ee8SDavid du Colombier default: 467219b2ee8SDavid du Colombier break; 468219b2ee8SDavid du Colombier } 4693e12c5d1SDavid du Colombier } 4703e12c5d1SDavid du Colombier if(!printed) 4713e12c5d1SDavid du Colombier print("UTF"); 4723e12c5d1SDavid du Colombier print(" text\n"); 4733e12c5d1SDavid du Colombier } 4743e12c5d1SDavid du Colombier 4753e12c5d1SDavid du Colombier void 4763e12c5d1SDavid du Colombier wordfreq(void) 4773e12c5d1SDavid du Colombier { 478219b2ee8SDavid du Colombier int low, high, mid, r; 479219b2ee8SDavid du Colombier uchar *p, *p2, c; 4803e12c5d1SDavid du Colombier 481219b2ee8SDavid du Colombier p = buf; 482219b2ee8SDavid du Colombier for(;;) { 483219b2ee8SDavid du Colombier while (p < buf+nbuf && !isalpha(*p)) 484219b2ee8SDavid du Colombier p++; 485219b2ee8SDavid du Colombier if (p >= buf+nbuf) 486219b2ee8SDavid du Colombier return; 487219b2ee8SDavid du Colombier p2 = p; 488219b2ee8SDavid du Colombier while(p < buf+nbuf && isalpha(*p)) 489219b2ee8SDavid du Colombier p++; 490219b2ee8SDavid du Colombier c = *p; 491219b2ee8SDavid du Colombier *p = 0; 4923e12c5d1SDavid du Colombier high = sizeof(dict)/sizeof(dict[0]); 4933e12c5d1SDavid du Colombier for(low = 0;low < high;) { 4943e12c5d1SDavid du Colombier mid = (low+high)/2; 495219b2ee8SDavid du Colombier r = strcmp(dict[mid].word, (char*)p2); 496219b2ee8SDavid du Colombier if(r == 0) { 4973e12c5d1SDavid du Colombier wfreq[dict[mid].class]++; 4983e12c5d1SDavid du Colombier break; 4993e12c5d1SDavid du Colombier } 500219b2ee8SDavid du Colombier if(r < 0) 5013e12c5d1SDavid du Colombier low = mid+1; 5023e12c5d1SDavid du Colombier else 5033e12c5d1SDavid du Colombier high = mid; 5043e12c5d1SDavid du Colombier } 505219b2ee8SDavid du Colombier *p++ = c; 5063e12c5d1SDavid du Colombier } 5073e12c5d1SDavid du Colombier } 5083e12c5d1SDavid du Colombier 5099a747e4fSDavid du Colombier typedef struct Filemagic Filemagic; 5109a747e4fSDavid du Colombier struct Filemagic { 5119a747e4fSDavid du Colombier ulong x; 5129a747e4fSDavid du Colombier ulong mask; 5139a747e4fSDavid du Colombier char *desc; 5149a747e4fSDavid du Colombier char *mime; 5159a747e4fSDavid du Colombier }; 5169a747e4fSDavid du Colombier 5179a747e4fSDavid du Colombier Filemagic long0tab[] = { 5189a747e4fSDavid du Colombier 0xF16DF16D, 0xFFFFFFFF, "pac1 audio file\n", OCTET, 5199a747e4fSDavid du Colombier 0x31636170, 0xFFFFFFFF, "pac3 audio file\n", OCTET, 5209a747e4fSDavid du Colombier 0x32636170, 0xFFFF00FF, "pac4 audio file\n", OCTET, 5219a747e4fSDavid du Colombier 0xBA010000, 0xFFFFFFFF, "mpeg system stream\n", OCTET, 5229a747e4fSDavid du Colombier 0x30800CC0, 0xFFFFFFFF, "inferno .dis executable\n", OCTET, 523fb7f0c93SDavid du Colombier 0x04034B50, 0xFFFFFFFF, "zip archive\n", "application/zip", 5249a747e4fSDavid du Colombier 070707, 0xFFFF, "cpio archive\n", OCTET, 525fb7f0c93SDavid du Colombier 0x2F7, 0xFFFF, "tex dvi\n", "application/dvi", 5269552e201SDavid du Colombier 0xfaff, 0xfeff, "mp3 audio\n", "audio/mpeg", 5279a747e4fSDavid du Colombier }; 5289a747e4fSDavid du Colombier 5299a747e4fSDavid du Colombier int 5309a747e4fSDavid du Colombier filemagic(Filemagic *tab, int ntab, ulong x) 5319a747e4fSDavid du Colombier { 5329a747e4fSDavid du Colombier int i; 5339a747e4fSDavid du Colombier 5349a747e4fSDavid du Colombier for(i=0; i<ntab; i++) 5359a747e4fSDavid du Colombier if((x&tab[i].mask) == tab[i].x){ 5369a747e4fSDavid du Colombier print(mime ? tab[i].mime : tab[i].desc); 5379a747e4fSDavid du Colombier return 1; 5389a747e4fSDavid du Colombier } 5399a747e4fSDavid du Colombier return 0; 5409a747e4fSDavid du Colombier } 5419a747e4fSDavid du Colombier 5423e12c5d1SDavid du Colombier int 5433e12c5d1SDavid du Colombier long0(void) 5443e12c5d1SDavid du Colombier { 5453e12c5d1SDavid du Colombier Fhdr f; 5467dd7cddfSDavid du Colombier long x; 5473e12c5d1SDavid du Colombier 5483e12c5d1SDavid du Colombier seek(fd, 0, 0); /* reposition to start of file */ 5493e12c5d1SDavid du Colombier if(crackhdr(fd, &f)) { 5507dd7cddfSDavid du Colombier print(mime ? OCTET : "%s\n", f.name); 5513e12c5d1SDavid du Colombier return 1; 5523e12c5d1SDavid du Colombier } 5537dd7cddfSDavid du Colombier x = LENDIAN(buf); 5549a747e4fSDavid du Colombier if(filemagic(long0tab, nelem(long0tab), x)) 555219b2ee8SDavid du Colombier return 1; 5567dd7cddfSDavid du Colombier return 0; 5577dd7cddfSDavid du Colombier } 5583e12c5d1SDavid du Colombier 5594b30ca09SDavid du Colombier /* from tar.c */ 5604b30ca09SDavid du Colombier enum { NAMSIZ = 100, TBLOCK = 512 }; 5614b30ca09SDavid du Colombier 5624b30ca09SDavid du Colombier union hblock 5634b30ca09SDavid du Colombier { 5644b30ca09SDavid du Colombier char dummy[TBLOCK]; 5654b30ca09SDavid du Colombier struct header 5664b30ca09SDavid du Colombier { 5674b30ca09SDavid du Colombier char name[NAMSIZ]; 5684b30ca09SDavid du Colombier char mode[8]; 5694b30ca09SDavid du Colombier char uid[8]; 5704b30ca09SDavid du Colombier char gid[8]; 5714b30ca09SDavid du Colombier char size[12]; 5724b30ca09SDavid du Colombier char mtime[12]; 5734b30ca09SDavid du Colombier char chksum[8]; 5744b30ca09SDavid du Colombier char linkflag; 5754b30ca09SDavid du Colombier char linkname[NAMSIZ]; 5764b30ca09SDavid du Colombier /* rest are defined by POSIX's ustar format; see p1003.2b */ 5774b30ca09SDavid du Colombier char magic[6]; /* "ustar" */ 5784b30ca09SDavid du Colombier char version[2]; 5794b30ca09SDavid du Colombier char uname[32]; 5804b30ca09SDavid du Colombier char gname[32]; 5814b30ca09SDavid du Colombier char devmajor[8]; 5824b30ca09SDavid du Colombier char devminor[8]; 5834b30ca09SDavid du Colombier char prefix[155]; /* if non-null, path = prefix "/" name */ 5844b30ca09SDavid du Colombier } dbuf; 5854b30ca09SDavid du Colombier }; 5864b30ca09SDavid du Colombier 5874b30ca09SDavid du Colombier int 5884b30ca09SDavid du Colombier checksum(union hblock *hp) 5894b30ca09SDavid du Colombier { 5904b30ca09SDavid du Colombier int i; 5914b30ca09SDavid du Colombier char *cp; 5924b30ca09SDavid du Colombier struct header *hdr = &hp->dbuf; 5934b30ca09SDavid du Colombier 5944b30ca09SDavid du Colombier for (cp = hdr->chksum; cp < &hdr->chksum[sizeof hdr->chksum]; cp++) 5954b30ca09SDavid du Colombier *cp = ' '; 5964b30ca09SDavid du Colombier i = 0; 5974b30ca09SDavid du Colombier for (cp = hp->dummy; cp < &hp->dummy[TBLOCK]; cp++) 5984b30ca09SDavid du Colombier i += *cp & 0xff; 5994b30ca09SDavid du Colombier return i; 6004b30ca09SDavid du Colombier } 6014b30ca09SDavid du Colombier 6024b30ca09SDavid du Colombier int 6034b30ca09SDavid du Colombier istar(void) 6044b30ca09SDavid du Colombier { 6054b30ca09SDavid du Colombier int chksum; 6064b30ca09SDavid du Colombier char tblock[TBLOCK]; 6074b30ca09SDavid du Colombier union hblock *hp = (union hblock *)tblock; 6084b30ca09SDavid du Colombier struct header *hdr = &hp->dbuf; 6094b30ca09SDavid du Colombier 6104b30ca09SDavid du Colombier seek(fd, 0, 0); /* reposition to start of file */ 6114b30ca09SDavid du Colombier if (readn(fd, tblock, sizeof tblock) != sizeof tblock) 6124b30ca09SDavid du Colombier return 0; 6134b30ca09SDavid du Colombier chksum = strtol(hdr->chksum, 0, 8); 6144b30ca09SDavid du Colombier if (hdr->name[0] != '\0' && checksum(hp) == chksum) { 6154b30ca09SDavid du Colombier if (strcmp(hdr->magic, "ustar") == 0) 6164b30ca09SDavid du Colombier print(mime? "application/x-ustar\n": 6174b30ca09SDavid du Colombier "posix tar archive\n"); 6184b30ca09SDavid du Colombier else 6194b30ca09SDavid du Colombier print(mime? "application/x-tar\n": "tar archive\n"); 6204b30ca09SDavid du Colombier return 1; 6214b30ca09SDavid du Colombier } 6224b30ca09SDavid du Colombier return 0; 6234b30ca09SDavid du Colombier } 6244b30ca09SDavid du Colombier 6253e12c5d1SDavid du Colombier /* 6263e12c5d1SDavid du Colombier * initial words to classify file 6273e12c5d1SDavid du Colombier */ 628219b2ee8SDavid du Colombier struct FILE_STRING 629219b2ee8SDavid du Colombier { 6303e12c5d1SDavid du Colombier char *key; 6313e12c5d1SDavid du Colombier char *filetype; 6323e12c5d1SDavid du Colombier int length; 6337dd7cddfSDavid du Colombier char *mime; 6343e12c5d1SDavid du Colombier } file_string[] = 6353e12c5d1SDavid du Colombier { 6367dd7cddfSDavid du Colombier "!<arch>\n__.SYMDEF", "archive random library", 16, "application/octet-stream", 6377dd7cddfSDavid du Colombier "!<arch>\n", "archive", 8, "application/octet-stream", 6387dd7cddfSDavid du Colombier "070707", "cpio archive - ascii header", 6, "application/octet-stream", 6397dd7cddfSDavid du Colombier "#!/bin/rc", "rc executable file", 9, "text/plain", 6407dd7cddfSDavid du Colombier "#!/bin/sh", "sh executable file", 9, "text/plain", 6417dd7cddfSDavid du Colombier "%!", "postscript", 2, "application/postscript", 6427dd7cddfSDavid du Colombier "\004%!", "postscript", 3, "application/postscript", 6437dd7cddfSDavid du Colombier "x T post", "troff output for post", 8, "application/troff", 6447dd7cddfSDavid du Colombier "x T Latin1", "troff output for Latin1", 10, "application/troff", 6457dd7cddfSDavid du Colombier "x T utf", "troff output for UTF", 7, "application/troff", 6467dd7cddfSDavid du Colombier "x T 202", "troff output for 202", 7, "application/troff", 6477dd7cddfSDavid du Colombier "x T aps", "troff output for aps", 7, "application/troff", 6487dd7cddfSDavid du Colombier "GIF", "GIF image", 3, "image/gif", 6497dd7cddfSDavid du Colombier "\0PC Research, Inc\0", "ghostscript fax file", 18, "application/ghostscript", 65059cc4ca5SDavid du Colombier "%PDF", "PDF", 4, "application/pdf", 6517dd7cddfSDavid du Colombier "<html>\n", "HTML file", 7, "text/html", 6527dd7cddfSDavid du Colombier "<HTML>\n", "HTML file", 7, "text/html", 6537dd7cddfSDavid du Colombier "compressed\n", "Compressed image or subfont", 11, "application/octet-stream", 6547dd7cddfSDavid du Colombier "\111\111\052\000", "tiff", 4, "image/tiff", 6557dd7cddfSDavid du Colombier "\115\115\000\052", "tiff", 4, "image/tiff", 6567dd7cddfSDavid du Colombier "\377\330\377\340", "jpeg", 4, "image/jpeg", 6577dd7cddfSDavid du Colombier "\377\330\377\341", "jpeg", 4, "image/jpeg", 6587dd7cddfSDavid du Colombier "\377\330\377\333", "jpeg", 4, "image/jpeg", 659da51d93aSDavid du Colombier "BM", "bmp", 2, "image/bmp", 6607dd7cddfSDavid du Colombier "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", "microsoft office document", 8, "application/octet-stream", 661fb7f0c93SDavid du Colombier "<MakerFile ", "FrameMaker file", 11, "application/framemaker", 662fb7f0c93SDavid du Colombier "\033%-12345X", "HPJCL file", 9, "application/hpjcl", 663ddb951e3SDavid du Colombier "ID3", "mp3 audio with id3", 3, "audio/mpeg", 6647989f6fbSDavid du Colombier "\211PNG", "PNG image", 4, "image/png", 6657dd7cddfSDavid du Colombier 0,0,0,0 6663e12c5d1SDavid du Colombier }; 6673e12c5d1SDavid du Colombier 6683e12c5d1SDavid du Colombier int 6693e12c5d1SDavid du Colombier istring(void) 6703e12c5d1SDavid du Colombier { 6713e12c5d1SDavid du Colombier int i; 6723e12c5d1SDavid du Colombier struct FILE_STRING *p; 6733e12c5d1SDavid du Colombier 6743e12c5d1SDavid du Colombier for(p = file_string; p->key; p++) { 675219b2ee8SDavid du Colombier if(nbuf >= p->length && !memcmp(buf, p->key, p->length)) { 6767dd7cddfSDavid du Colombier if(mime) 6777dd7cddfSDavid du Colombier print("%s\n", p->mime); 6787dd7cddfSDavid du Colombier else 6793e12c5d1SDavid du Colombier print("%s\n", p->filetype); 6803e12c5d1SDavid du Colombier return 1; 6813e12c5d1SDavid du Colombier } 6823e12c5d1SDavid du Colombier } 6833e12c5d1SDavid du Colombier if(strncmp((char*)buf, "TYPE=", 5) == 0) { /* td */ 6843e12c5d1SDavid du Colombier for(i = 5; i < nbuf; i++) 6853e12c5d1SDavid du Colombier if(buf[i] == '\n') 6863e12c5d1SDavid du Colombier break; 6877dd7cddfSDavid du Colombier if(mime) 6887dd7cddfSDavid du Colombier print(OCTET); 6897dd7cddfSDavid du Colombier else 69059cc4ca5SDavid du Colombier print("%.*s picture\n", utfnlen((char*)buf+5, i-5), (char*)buf+5); 6913e12c5d1SDavid du Colombier return 1; 6923e12c5d1SDavid du Colombier } 6933e12c5d1SDavid du Colombier return 0; 6943e12c5d1SDavid du Colombier } 6953e12c5d1SDavid du Colombier 696ddb951e3SDavid du Colombier int 697ddb951e3SDavid du Colombier iff(void) 698ddb951e3SDavid du Colombier { 699ddb951e3SDavid du Colombier if (strncmp((char*)buf, "FORM", 4) == 0 && 700ddb951e3SDavid du Colombier strncmp((char*)buf+8, "AIFF", 4) == 0) { 701ddb951e3SDavid du Colombier print("%s\n", mime? "audio/x-aiff": "aiff audio"); 702ddb951e3SDavid du Colombier return 1; 703ddb951e3SDavid du Colombier } 704ddb951e3SDavid du Colombier return 0; 705ddb951e3SDavid du Colombier } 706ddb951e3SDavid du Colombier 7077dd7cddfSDavid du Colombier char* html_string[] = 7087dd7cddfSDavid du Colombier { 7097dd7cddfSDavid du Colombier "title", 7107dd7cddfSDavid du Colombier "body", 7117dd7cddfSDavid du Colombier "head", 7127dd7cddfSDavid du Colombier "strong", 7137dd7cddfSDavid du Colombier "h1", 7147dd7cddfSDavid du Colombier "h2", 7157dd7cddfSDavid du Colombier "h3", 7167dd7cddfSDavid du Colombier "h4", 7177dd7cddfSDavid du Colombier "h5", 7187dd7cddfSDavid du Colombier "h6", 7197dd7cddfSDavid du Colombier "ul", 7207dd7cddfSDavid du Colombier "li", 7217dd7cddfSDavid du Colombier "dl", 7227dd7cddfSDavid du Colombier "br", 7237dd7cddfSDavid du Colombier "em", 7247dd7cddfSDavid du Colombier 0, 7257dd7cddfSDavid du Colombier }; 7267dd7cddfSDavid du Colombier 7277dd7cddfSDavid du Colombier int 7287dd7cddfSDavid du Colombier ishtml(void) 7297dd7cddfSDavid du Colombier { 7307dd7cddfSDavid du Colombier uchar *p, *q; 7317dd7cddfSDavid du Colombier int i, count; 7327dd7cddfSDavid du Colombier 7337dd7cddfSDavid du Colombier /* compare strings between '<' and '>' to html table */ 7347dd7cddfSDavid du Colombier count = 0; 7357dd7cddfSDavid du Colombier p = buf; 7367dd7cddfSDavid du Colombier for(;;) { 7377dd7cddfSDavid du Colombier while (p < buf+nbuf && *p != '<') 7387dd7cddfSDavid du Colombier p++; 7397dd7cddfSDavid du Colombier p++; 7407dd7cddfSDavid du Colombier if (p >= buf+nbuf) 7417dd7cddfSDavid du Colombier break; 7427dd7cddfSDavid du Colombier if(*p == '/') 7437dd7cddfSDavid du Colombier p++; 7447dd7cddfSDavid du Colombier q = p; 7457dd7cddfSDavid du Colombier while(p < buf+nbuf && *p != '>') 7467dd7cddfSDavid du Colombier p++; 7477dd7cddfSDavid du Colombier if (p >= buf+nbuf) 7487dd7cddfSDavid du Colombier break; 7497dd7cddfSDavid du Colombier for(i = 0; html_string[i]; i++) { 7507dd7cddfSDavid du Colombier if(cistrncmp(html_string[i], (char*)q, p-q) == 0) { 7517dd7cddfSDavid du Colombier if(count++ > 4) { 7527dd7cddfSDavid du Colombier print(mime ? "text/html\n" : "HTML file\n"); 7537dd7cddfSDavid du Colombier return 1; 7547dd7cddfSDavid du Colombier } 7557dd7cddfSDavid du Colombier break; 7567dd7cddfSDavid du Colombier } 7577dd7cddfSDavid du Colombier } 7587dd7cddfSDavid du Colombier p++; 7597dd7cddfSDavid du Colombier } 7607dd7cddfSDavid du Colombier return 0; 7617dd7cddfSDavid du Colombier } 7627dd7cddfSDavid du Colombier 7639a747e4fSDavid du Colombier char* rfc822_string[] = 7647dd7cddfSDavid du Colombier { 7659a747e4fSDavid du Colombier "from:", 7669a747e4fSDavid du Colombier "date:", 7679a747e4fSDavid du Colombier "to:", 7689a747e4fSDavid du Colombier "subject:", 7699a747e4fSDavid du Colombier "received:", 770d9306527SDavid du Colombier "reply to:", 771d9306527SDavid du Colombier "sender:", 7729a747e4fSDavid du Colombier 0, 7739a747e4fSDavid du Colombier }; 7747dd7cddfSDavid du Colombier 7759a747e4fSDavid du Colombier int 7769a747e4fSDavid du Colombier isrfc822(void) 7779a747e4fSDavid du Colombier { 7789a747e4fSDavid du Colombier 7799a747e4fSDavid du Colombier char *p, *q, *r; 7809a747e4fSDavid du Colombier int i, count; 7819a747e4fSDavid du Colombier 7829a747e4fSDavid du Colombier count = 0; 7839a747e4fSDavid du Colombier p = (char*)buf; 7849a747e4fSDavid du Colombier for(;;) { 7859a747e4fSDavid du Colombier q = strchr(p, '\n'); 7869a747e4fSDavid du Colombier if(q == nil) 7877dd7cddfSDavid du Colombier break; 788d9306527SDavid du Colombier *q = 0; 789d9306527SDavid du Colombier if(p == (char*)buf && strncmp(p, "From ", 5) == 0 && strstr(p, " remote from ")){ 790d9306527SDavid du Colombier count++; 791d9306527SDavid du Colombier *q = '\n'; 792d9306527SDavid du Colombier p = q+1; 793d9306527SDavid du Colombier continue; 794d9306527SDavid du Colombier } 795d9306527SDavid du Colombier *q = '\n'; 7969a747e4fSDavid du Colombier if(*p != '\t' && *p != ' '){ 7979a747e4fSDavid du Colombier r = strchr(p, ':'); 7989a747e4fSDavid du Colombier if(r == 0 || r > q) 7999a747e4fSDavid du Colombier break; 8009a747e4fSDavid du Colombier for(i = 0; rfc822_string[i]; i++) { 8019a747e4fSDavid du Colombier if(cistrncmp(p, rfc822_string[i], strlen(rfc822_string[i])) == 0){ 8029a747e4fSDavid du Colombier count++; 8039a747e4fSDavid du Colombier break; 8047dd7cddfSDavid du Colombier } 8059a747e4fSDavid du Colombier } 8069a747e4fSDavid du Colombier } 8079a747e4fSDavid du Colombier p = q+1; 8089a747e4fSDavid du Colombier } 8099a747e4fSDavid du Colombier if(count >= 3){ 8109a747e4fSDavid du Colombier print(mime ? "message/rfc822\n" : "email file\n"); 8117dd7cddfSDavid du Colombier return 1; 8127dd7cddfSDavid du Colombier } 8139a747e4fSDavid du Colombier return 0; 8149a747e4fSDavid du Colombier } 8157dd7cddfSDavid du Colombier 8163e12c5d1SDavid du Colombier int 817d9306527SDavid du Colombier ismbox(void) 818d9306527SDavid du Colombier { 819d9306527SDavid du Colombier char *p, *q; 820d9306527SDavid du Colombier 821d9306527SDavid du Colombier p = (char*)buf; 822d9306527SDavid du Colombier q = strchr(p, '\n'); 823d9306527SDavid du Colombier if(q == nil) 824d9306527SDavid du Colombier return 0; 825d9306527SDavid du Colombier *q = 0; 826d9306527SDavid du Colombier if(strncmp(p, "From ", 5) == 0 && strstr(p, " remote from ") == nil){ 827d9306527SDavid du Colombier print(mime ? "text/plain\n" : "mail box\n"); 828d9306527SDavid du Colombier return 1; 829d9306527SDavid du Colombier } 830d9306527SDavid du Colombier *q = '\n'; 831d9306527SDavid du Colombier return 0; 832d9306527SDavid du Colombier } 833d9306527SDavid du Colombier 834d9306527SDavid du Colombier int 8353e12c5d1SDavid du Colombier iscint(void) 8363e12c5d1SDavid du Colombier { 837219b2ee8SDavid du Colombier int type; 838219b2ee8SDavid du Colombier char *name; 839219b2ee8SDavid du Colombier Biobuf b; 8403e12c5d1SDavid du Colombier 841219b2ee8SDavid du Colombier if(Binit(&b, fd, OREAD) == Beof) 8423e12c5d1SDavid du Colombier return 0; 843219b2ee8SDavid du Colombier seek(fd, 0, 0); 844219b2ee8SDavid du Colombier type = objtype(&b, &name); 845219b2ee8SDavid du Colombier if(type < 0) 846219b2ee8SDavid du Colombier return 0; 8477dd7cddfSDavid du Colombier if(mime) 8487dd7cddfSDavid du Colombier print(OCTET); 8497dd7cddfSDavid du Colombier else 850219b2ee8SDavid du Colombier print("%s intermediate\n", name); 851219b2ee8SDavid du Colombier return 1; 8523e12c5d1SDavid du Colombier } 8533e12c5d1SDavid du Colombier 8543e12c5d1SDavid du Colombier int 8553e12c5d1SDavid du Colombier isc(void) 8563e12c5d1SDavid du Colombier { 8573e12c5d1SDavid du Colombier int n; 8583e12c5d1SDavid du Colombier 8593e12c5d1SDavid du Colombier n = wfreq[I1]; 8603e12c5d1SDavid du Colombier /* 8613e12c5d1SDavid du Colombier * includes 8623e12c5d1SDavid du Colombier */ 8633e12c5d1SDavid du Colombier if(n >= 2 && wfreq[I2] >= n && wfreq[I3] >= n && cfreq['.'] >= n) 8643e12c5d1SDavid du Colombier goto yes; 865219b2ee8SDavid du Colombier if(n >= 1 && wfreq[Alword] >= n && wfreq[I3] >= n && cfreq['.'] >= n) 866219b2ee8SDavid du Colombier goto yes; 8673e12c5d1SDavid du Colombier /* 8683e12c5d1SDavid du Colombier * declarations 8693e12c5d1SDavid du Colombier */ 8703e12c5d1SDavid du Colombier if(wfreq[Cword] >= 5 && cfreq[';'] >= 5) 8713e12c5d1SDavid du Colombier goto yes; 8723e12c5d1SDavid du Colombier /* 8733e12c5d1SDavid du Colombier * assignments 8743e12c5d1SDavid du Colombier */ 8753e12c5d1SDavid du Colombier if(cfreq[';'] >= 10 && cfreq['='] >= 10 && wfreq[Cword] >= 1) 8763e12c5d1SDavid du Colombier goto yes; 8773e12c5d1SDavid du Colombier return 0; 8783e12c5d1SDavid du Colombier 8793e12c5d1SDavid du Colombier yes: 8807dd7cddfSDavid du Colombier if(mime){ 8817dd7cddfSDavid du Colombier print(PLAIN); 8827dd7cddfSDavid du Colombier return 1; 8837dd7cddfSDavid du Colombier } 884219b2ee8SDavid du Colombier if(wfreq[Alword] > 0) 885219b2ee8SDavid du Colombier print("alef program\n"); 886219b2ee8SDavid du Colombier else 8873e12c5d1SDavid du Colombier print("c program\n"); 8883e12c5d1SDavid du Colombier return 1; 8893e12c5d1SDavid du Colombier } 8903e12c5d1SDavid du Colombier 8913e12c5d1SDavid du Colombier int 8927dd7cddfSDavid du Colombier islimbo(void) 8937dd7cddfSDavid du Colombier { 8947dd7cddfSDavid du Colombier 8957dd7cddfSDavid du Colombier /* 8967dd7cddfSDavid du Colombier * includes 8977dd7cddfSDavid du Colombier */ 8987dd7cddfSDavid du Colombier if(wfreq[Lword] < 4) 8997dd7cddfSDavid du Colombier return 0; 9007dd7cddfSDavid du Colombier print(mime ? PLAIN : "limbo program\n"); 9017dd7cddfSDavid du Colombier return 1; 9027dd7cddfSDavid du Colombier } 9037dd7cddfSDavid du Colombier 9047dd7cddfSDavid du Colombier int 9053e12c5d1SDavid du Colombier isas(void) 9063e12c5d1SDavid du Colombier { 9073e12c5d1SDavid du Colombier 9083e12c5d1SDavid du Colombier /* 9093e12c5d1SDavid du Colombier * includes 9103e12c5d1SDavid du Colombier */ 9113e12c5d1SDavid du Colombier if(wfreq[Aword] < 2) 9123e12c5d1SDavid du Colombier return 0; 9137dd7cddfSDavid du Colombier print(mime ? PLAIN : "as program\n"); 9143e12c5d1SDavid du Colombier return 1; 9153e12c5d1SDavid du Colombier } 9163e12c5d1SDavid du Colombier 9173e12c5d1SDavid du Colombier /* 9183e12c5d1SDavid du Colombier * low entropy means encrypted 9193e12c5d1SDavid du Colombier */ 9203e12c5d1SDavid du Colombier int 9213e12c5d1SDavid du Colombier ismung(void) 9223e12c5d1SDavid du Colombier { 9233e12c5d1SDavid du Colombier int i, bucket[8]; 9243e12c5d1SDavid du Colombier float cs; 9253e12c5d1SDavid du Colombier 9263e12c5d1SDavid du Colombier if(nbuf < 64) 9273e12c5d1SDavid du Colombier return 0; 9283e12c5d1SDavid du Colombier memset(bucket, 0, sizeof(bucket)); 9293e12c5d1SDavid du Colombier for(i=0; i<64; i++) 9303e12c5d1SDavid du Colombier bucket[(buf[i]>>5)&07] += 1; 9313e12c5d1SDavid du Colombier 9323e12c5d1SDavid du Colombier cs = 0.; 9333e12c5d1SDavid du Colombier for(i=0; i<8; i++) 9343e12c5d1SDavid du Colombier cs += (bucket[i]-8)*(bucket[i]-8); 9353e12c5d1SDavid du Colombier cs /= 8.; 9363e12c5d1SDavid du Colombier if(cs <= 24.322) { 9377dd7cddfSDavid du Colombier if(buf[0]==0x1f && (buf[1]==0x8b || buf[1]==0x9d)) 9387dd7cddfSDavid du Colombier print(mime ? OCTET : "compressed\n"); 9393e12c5d1SDavid du Colombier else 9407dd7cddfSDavid du Colombier print(mime ? OCTET : "encrypted\n"); 9413e12c5d1SDavid du Colombier return 1; 9423e12c5d1SDavid du Colombier } 9433e12c5d1SDavid du Colombier return 0; 9443e12c5d1SDavid du Colombier } 9453e12c5d1SDavid du Colombier 9463e12c5d1SDavid du Colombier /* 9473e12c5d1SDavid du Colombier * english by punctuation and frequencies 9483e12c5d1SDavid du Colombier */ 9493e12c5d1SDavid du Colombier int 9503e12c5d1SDavid du Colombier isenglish(void) 9513e12c5d1SDavid du Colombier { 9523e12c5d1SDavid du Colombier int vow, comm, rare, badpun, punct; 9533e12c5d1SDavid du Colombier char *p; 9543e12c5d1SDavid du Colombier 9553e12c5d1SDavid du Colombier if(guess != Fascii && guess != Feascii) 9563e12c5d1SDavid du Colombier return 0; 9573e12c5d1SDavid du Colombier badpun = 0; 9583e12c5d1SDavid du Colombier punct = 0; 9593e12c5d1SDavid du Colombier for(p = (char *)buf; p < (char *)buf+nbuf-1; p++) 9603e12c5d1SDavid du Colombier switch(*p) { 9613e12c5d1SDavid du Colombier case '.': 9623e12c5d1SDavid du Colombier case ',': 9633e12c5d1SDavid du Colombier case ')': 9643e12c5d1SDavid du Colombier case '%': 9653e12c5d1SDavid du Colombier case ';': 9663e12c5d1SDavid du Colombier case ':': 9673e12c5d1SDavid du Colombier case '?': 9683e12c5d1SDavid du Colombier punct++; 9693e12c5d1SDavid du Colombier if(p[1] != ' ' && p[1] != '\n') 9703e12c5d1SDavid du Colombier badpun++; 9713e12c5d1SDavid du Colombier } 9723e12c5d1SDavid du Colombier if(badpun*5 > punct) 9733e12c5d1SDavid du Colombier return 0; 9743e12c5d1SDavid du Colombier if(cfreq['>']+cfreq['<']+cfreq['/'] > cfreq['e']) /* shell file test */ 9753e12c5d1SDavid du Colombier return 0; 9763e12c5d1SDavid du Colombier if(2*cfreq[';'] > cfreq['e']) 9773e12c5d1SDavid du Colombier return 0; 9783e12c5d1SDavid du Colombier 9793e12c5d1SDavid du Colombier vow = 0; 9803e12c5d1SDavid du Colombier for(p="AEIOU"; *p; p++) { 9813e12c5d1SDavid du Colombier vow += cfreq[*p]; 9823e12c5d1SDavid du Colombier vow += cfreq[tolower(*p)]; 9833e12c5d1SDavid du Colombier } 9843e12c5d1SDavid du Colombier comm = 0; 9853e12c5d1SDavid du Colombier for(p="ETAION"; *p; p++) { 9863e12c5d1SDavid du Colombier comm += cfreq[*p]; 9873e12c5d1SDavid du Colombier comm += cfreq[tolower(*p)]; 9883e12c5d1SDavid du Colombier } 9893e12c5d1SDavid du Colombier rare = 0; 9903e12c5d1SDavid du Colombier for(p="VJKQXZ"; *p; p++) { 9913e12c5d1SDavid du Colombier rare += cfreq[*p]; 9923e12c5d1SDavid du Colombier rare += cfreq[tolower(*p)]; 9933e12c5d1SDavid du Colombier } 9943e12c5d1SDavid du Colombier if(vow*5 >= nbuf-cfreq[' '] && comm >= 10*rare) { 9957dd7cddfSDavid du Colombier print(mime ? PLAIN : "English text\n"); 9963e12c5d1SDavid du Colombier return 1; 9973e12c5d1SDavid du Colombier } 9983e12c5d1SDavid du Colombier return 0; 9993e12c5d1SDavid du Colombier } 10003e12c5d1SDavid du Colombier 10013e12c5d1SDavid du Colombier /* 10023e12c5d1SDavid du Colombier * pick up a number with 10033e12c5d1SDavid du Colombier * syntax _*[0-9]+_ 10043e12c5d1SDavid du Colombier */ 10053e12c5d1SDavid du Colombier #define P9BITLEN 12 10063e12c5d1SDavid du Colombier int 10073e12c5d1SDavid du Colombier p9bitnum(uchar *bp) 10083e12c5d1SDavid du Colombier { 10093e12c5d1SDavid du Colombier int n, c, len; 10103e12c5d1SDavid du Colombier 10113e12c5d1SDavid du Colombier len = P9BITLEN; 10123e12c5d1SDavid du Colombier while(*bp == ' ') { 10133e12c5d1SDavid du Colombier bp++; 10143e12c5d1SDavid du Colombier len--; 10153e12c5d1SDavid du Colombier if(len <= 0) 10163e12c5d1SDavid du Colombier return -1; 10173e12c5d1SDavid du Colombier } 10183e12c5d1SDavid du Colombier n = 0; 10193e12c5d1SDavid du Colombier while(len > 1) { 10203e12c5d1SDavid du Colombier c = *bp++; 10213e12c5d1SDavid du Colombier if(!isdigit(c)) 10223e12c5d1SDavid du Colombier return -1; 10233e12c5d1SDavid du Colombier n = n*10 + c-'0'; 10243e12c5d1SDavid du Colombier len--; 10253e12c5d1SDavid du Colombier } 10263e12c5d1SDavid du Colombier if(*bp != ' ') 10273e12c5d1SDavid du Colombier return -1; 10283e12c5d1SDavid du Colombier return n; 10293e12c5d1SDavid du Colombier } 10303e12c5d1SDavid du Colombier 10313e12c5d1SDavid du Colombier int 10327dd7cddfSDavid du Colombier depthof(char *s, int *newp) 10337dd7cddfSDavid du Colombier { 10347dd7cddfSDavid du Colombier char *es; 10357dd7cddfSDavid du Colombier int d; 10367dd7cddfSDavid du Colombier 10377dd7cddfSDavid du Colombier *newp = 0; 10387dd7cddfSDavid du Colombier es = s+12; 10397dd7cddfSDavid du Colombier while(s<es && *s==' ') 10407dd7cddfSDavid du Colombier s++; 10417dd7cddfSDavid du Colombier if(s == es) 10427dd7cddfSDavid du Colombier return -1; 10437dd7cddfSDavid du Colombier if('0'<=*s && *s<='9') 1044*16941224SDavid du Colombier return 1<<strtol(s, 0, 0); 10457dd7cddfSDavid du Colombier 10467dd7cddfSDavid du Colombier *newp = 1; 10477dd7cddfSDavid du Colombier d = 0; 10487dd7cddfSDavid du Colombier while(s<es && *s!=' '){ 10497dd7cddfSDavid du Colombier s++; /* skip letter */ 10507dd7cddfSDavid du Colombier d += strtoul(s, &s, 10); 10517dd7cddfSDavid du Colombier } 10527dd7cddfSDavid du Colombier 10537dd7cddfSDavid du Colombier switch(d){ 10547dd7cddfSDavid du Colombier case 32: 10557dd7cddfSDavid du Colombier case 24: 10567dd7cddfSDavid du Colombier case 16: 10577dd7cddfSDavid du Colombier case 8: 10587dd7cddfSDavid du Colombier return d; 10597dd7cddfSDavid du Colombier } 10607dd7cddfSDavid du Colombier return -1; 10617dd7cddfSDavid du Colombier } 10627dd7cddfSDavid du Colombier 10637dd7cddfSDavid du Colombier int 10643e12c5d1SDavid du Colombier isp9bit(void) 10653e12c5d1SDavid du Colombier { 10667dd7cddfSDavid du Colombier int dep, lox, loy, hix, hiy, px, new; 1067219b2ee8SDavid du Colombier ulong t; 10683e12c5d1SDavid du Colombier long len; 10697dd7cddfSDavid du Colombier char *newlabel; 10703e12c5d1SDavid du Colombier 10717dd7cddfSDavid du Colombier newlabel = "old "; 10727dd7cddfSDavid du Colombier 10737dd7cddfSDavid du Colombier dep = depthof((char*)buf + 0*P9BITLEN, &new); 10747dd7cddfSDavid du Colombier if(new) 10757dd7cddfSDavid du Colombier newlabel = ""; 10763e12c5d1SDavid du Colombier lox = p9bitnum(buf + 1*P9BITLEN); 10773e12c5d1SDavid du Colombier loy = p9bitnum(buf + 2*P9BITLEN); 10783e12c5d1SDavid du Colombier hix = p9bitnum(buf + 3*P9BITLEN); 10793e12c5d1SDavid du Colombier hiy = p9bitnum(buf + 4*P9BITLEN); 10807dd7cddfSDavid du Colombier if(dep < 0 || lox < 0 || loy < 0 || hix < 0 || hiy < 0) 10813e12c5d1SDavid du Colombier return 0; 10823e12c5d1SDavid du Colombier 10837dd7cddfSDavid du Colombier if(dep < 8){ 10847dd7cddfSDavid du Colombier px = 8/dep; /* pixels per byte */ 1085219b2ee8SDavid du Colombier /* set l to number of bytes of data per scan line */ 1086219b2ee8SDavid du Colombier if(lox >= 0) 1087219b2ee8SDavid du Colombier len = (hix+px-1)/px - lox/px; 1088219b2ee8SDavid du Colombier else{ /* make positive before divide */ 1089219b2ee8SDavid du Colombier t = (-lox)+px-1; 1090219b2ee8SDavid du Colombier t = (t/px)*px; 1091219b2ee8SDavid du Colombier len = (t+hix+px-1)/px; 1092219b2ee8SDavid du Colombier } 10937dd7cddfSDavid du Colombier }else 10947dd7cddfSDavid du Colombier len = (hix-lox)*dep/8; 10953e12c5d1SDavid du Colombier len *= (hiy-loy); /* col length */ 10963e12c5d1SDavid du Colombier len += 5*P9BITLEN; /* size of initial ascii */ 10973e12c5d1SDavid du Colombier 10983e12c5d1SDavid du Colombier /* 10997dd7cddfSDavid du Colombier * for image file, length is non-zero and must match calculation above 11003e12c5d1SDavid du Colombier * for /dev/window and /dev/screen the length is always zero 11013e12c5d1SDavid du Colombier * for subfont, the subfont header should follow immediately. 11023e12c5d1SDavid du Colombier */ 11039a747e4fSDavid du Colombier if (len != 0 && mbuf->length == 0) { 11047dd7cddfSDavid du Colombier print("%splan 9 image\n", newlabel); 11057dd7cddfSDavid du Colombier return 1; 11067dd7cddfSDavid du Colombier } 11079a747e4fSDavid du Colombier if (mbuf->length == len) { 11087dd7cddfSDavid du Colombier print("%splan 9 image\n", newlabel); 11097dd7cddfSDavid du Colombier return 1; 11107dd7cddfSDavid du Colombier } 11117dd7cddfSDavid du Colombier /* Ghostscript sometimes produces a little extra on the end */ 11129a747e4fSDavid du Colombier if (mbuf->length < len+P9BITLEN) { 11137dd7cddfSDavid du Colombier print("%splan 9 image\n", newlabel); 11143e12c5d1SDavid du Colombier return 1; 11153e12c5d1SDavid du Colombier } 11163e12c5d1SDavid du Colombier if (p9subfont(buf+len)) { 11177dd7cddfSDavid du Colombier print("%ssubfont file\n", newlabel); 11183e12c5d1SDavid du Colombier return 1; 11193e12c5d1SDavid du Colombier } 11203e12c5d1SDavid du Colombier return 0; 11213e12c5d1SDavid du Colombier } 11223e12c5d1SDavid du Colombier 11233e12c5d1SDavid du Colombier int 11243e12c5d1SDavid du Colombier p9subfont(uchar *p) 11253e12c5d1SDavid du Colombier { 11263e12c5d1SDavid du Colombier int n, h, a; 11273e12c5d1SDavid du Colombier 11287dd7cddfSDavid du Colombier /* if image too big, assume it's a subfont */ 11293e12c5d1SDavid du Colombier if (p+3*P9BITLEN > buf+sizeof(buf)) 11303e12c5d1SDavid du Colombier return 1; 11313e12c5d1SDavid du Colombier 11323e12c5d1SDavid du Colombier n = p9bitnum(p + 0*P9BITLEN); /* char count */ 11333e12c5d1SDavid du Colombier if (n < 0) 11343e12c5d1SDavid du Colombier return 0; 11353e12c5d1SDavid du Colombier h = p9bitnum(p + 1*P9BITLEN); /* height */ 11363e12c5d1SDavid du Colombier if (h < 0) 11373e12c5d1SDavid du Colombier return 0; 11383e12c5d1SDavid du Colombier a = p9bitnum(p + 2*P9BITLEN); /* ascent */ 11393e12c5d1SDavid du Colombier if (a < 0) 11403e12c5d1SDavid du Colombier return 0; 11413e12c5d1SDavid du Colombier return 1; 11423e12c5d1SDavid du Colombier } 11433e12c5d1SDavid du Colombier 11443e12c5d1SDavid du Colombier #define WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') 11453e12c5d1SDavid du Colombier 11463e12c5d1SDavid du Colombier int 11473e12c5d1SDavid du Colombier isp9font(void) 11483e12c5d1SDavid du Colombier { 11493e12c5d1SDavid du Colombier uchar *cp, *p; 11503e12c5d1SDavid du Colombier int i, n; 11513e12c5d1SDavid du Colombier char pathname[1024]; 11523e12c5d1SDavid du Colombier 11533e12c5d1SDavid du Colombier cp = buf; 11543e12c5d1SDavid du Colombier if (!getfontnum(cp, &cp)) /* height */ 11553e12c5d1SDavid du Colombier return 0; 11563e12c5d1SDavid du Colombier if (!getfontnum(cp, &cp)) /* ascent */ 11573e12c5d1SDavid du Colombier return 0; 11583e12c5d1SDavid du Colombier for (i = 0; 1; i++) { 11593e12c5d1SDavid du Colombier if (!getfontnum(cp, &cp)) /* min */ 11603e12c5d1SDavid du Colombier break; 11613e12c5d1SDavid du Colombier if (!getfontnum(cp, &cp)) /* max */ 11623e12c5d1SDavid du Colombier return 0; 11633e12c5d1SDavid du Colombier while (WHITESPACE(*cp)) 11643e12c5d1SDavid du Colombier cp++; 11653e12c5d1SDavid du Colombier for (p = cp; *cp && !WHITESPACE(*cp); cp++) 11663e12c5d1SDavid du Colombier ; 11673e12c5d1SDavid du Colombier /* construct a path name, if needed */ 11683e12c5d1SDavid du Colombier n = 0; 11693e12c5d1SDavid du Colombier if (*p != '/' && slash) { 11703e12c5d1SDavid du Colombier n = slash-fname+1; 11713e12c5d1SDavid du Colombier if (n < sizeof(pathname)) 11723e12c5d1SDavid du Colombier memcpy(pathname, fname, n); 11733e12c5d1SDavid du Colombier else n = 0; 11743e12c5d1SDavid du Colombier } 11753e12c5d1SDavid du Colombier if (n+cp-p < sizeof(pathname)) { 11763e12c5d1SDavid du Colombier memcpy(pathname+n, p, cp-p); 11773e12c5d1SDavid du Colombier n += cp-p; 11783e12c5d1SDavid du Colombier pathname[n] = 0; 11799a747e4fSDavid du Colombier if (access(pathname, AEXIST) < 0) 11803e12c5d1SDavid du Colombier return 0; 11813e12c5d1SDavid du Colombier } 11823e12c5d1SDavid du Colombier } 11833e12c5d1SDavid du Colombier if (i) { 11848d37e088SDavid du Colombier print(mime ? "text/plain\n" : "font file\n"); 11853e12c5d1SDavid du Colombier return 1; 11863e12c5d1SDavid du Colombier } 11873e12c5d1SDavid du Colombier return 0; 11883e12c5d1SDavid du Colombier } 11893e12c5d1SDavid du Colombier 11903e12c5d1SDavid du Colombier int 11913e12c5d1SDavid du Colombier getfontnum(uchar *cp, uchar **rp) 11923e12c5d1SDavid du Colombier { 11933e12c5d1SDavid du Colombier while (WHITESPACE(*cp)) /* extract ulong delimited by whitespace */ 11943e12c5d1SDavid du Colombier cp++; 11953e12c5d1SDavid du Colombier if (*cp < '0' || *cp > '9') 11963e12c5d1SDavid du Colombier return 0; 11973e12c5d1SDavid du Colombier strtoul((char *)cp, (char **)rp, 0); 11983e12c5d1SDavid du Colombier if (!WHITESPACE(**rp)) 11993e12c5d1SDavid du Colombier return 0; 12003e12c5d1SDavid du Colombier return 1; 12013e12c5d1SDavid du Colombier } 12027dd7cddfSDavid du Colombier 12037dd7cddfSDavid du Colombier int 1204fb7f0c93SDavid du Colombier isrtf(void) 12057dd7cddfSDavid du Colombier { 1206fb7f0c93SDavid du Colombier if(strstr((char *)buf, "\\rtf1")){ 1207f2e8132aSDavid du Colombier print(mime ? "application/rtf\n" : "rich text format\n"); 1208f2e8132aSDavid du Colombier return 1; 1209f2e8132aSDavid du Colombier } 1210f2e8132aSDavid du Colombier return 0; 1211f2e8132aSDavid du Colombier } 1212f2e8132aSDavid du Colombier 1213f2e8132aSDavid du Colombier int 1214f2e8132aSDavid du Colombier ismsdos(void) 1215f2e8132aSDavid du Colombier { 1216f2e8132aSDavid du Colombier if (buf[0] == 0x4d && buf[1] == 0x5a){ 1217f2e8132aSDavid du Colombier print(mime ? "application/x-msdownload\n" : "MSDOS executable\n"); 12187dd7cddfSDavid du Colombier return 1; 12197dd7cddfSDavid du Colombier } 12207dd7cddfSDavid du Colombier return 0; 12217dd7cddfSDavid du Colombier } 1222b7327ca2SDavid du Colombier 1223b7327ca2SDavid du Colombier int 1224b7327ca2SDavid du Colombier iself(void) 1225b7327ca2SDavid du Colombier { 1226b7327ca2SDavid du Colombier char *cpu[] = { /* NB: incomplete and arbitary list */ 1227b7327ca2SDavid du Colombier [1] "WE32100", 1228b7327ca2SDavid du Colombier [2] "SPARC", 1229b7327ca2SDavid du Colombier [3] "i386", 1230b7327ca2SDavid du Colombier [4] "M68000", 1231b7327ca2SDavid du Colombier [5] "M88000", 1232b7327ca2SDavid du Colombier [6] "i486", 1233b7327ca2SDavid du Colombier [7] "i860", 1234b7327ca2SDavid du Colombier [8] "R3000", 1235b7327ca2SDavid du Colombier [9] "S370", 1236b7327ca2SDavid du Colombier [10] "R4000", 1237b7327ca2SDavid du Colombier [15] "HP-PA", 1238b7327ca2SDavid du Colombier [18] "sparc v8+", 1239b7327ca2SDavid du Colombier [19] "i960", 1240b7327ca2SDavid du Colombier [20] "PPC-32", 1241b7327ca2SDavid du Colombier [21] "PPC-64", 1242b7327ca2SDavid du Colombier [40] "ARM", 1243b7327ca2SDavid du Colombier [41] "Alpha", 1244b7327ca2SDavid du Colombier [43] "sparc v9", 1245b7327ca2SDavid du Colombier [50] "IA-46", 1246f9247424SDavid du Colombier [62] "AMD64", 1247b7327ca2SDavid du Colombier [75] "VAX", 1248b7327ca2SDavid du Colombier }; 1249b7327ca2SDavid du Colombier 1250b7327ca2SDavid du Colombier 1251b7327ca2SDavid du Colombier if (memcmp(buf, "\x7fELF", 4) == 0){ 1252b7327ca2SDavid du Colombier if (!mime){ 1253b7327ca2SDavid du Colombier int n = (buf[19] << 8) | buf[18]; 12548a2c5ad0SDavid du Colombier char *p = "unknown"; 12558a2c5ad0SDavid du Colombier 12568a2c5ad0SDavid du Colombier if (n > 0 && n < nelem(cpu) && cpu[n]) 12578a2c5ad0SDavid du Colombier p = cpu[n]; 12588a2c5ad0SDavid du Colombier else { 12598a2c5ad0SDavid du Colombier /* try the other byte order */ 12608a2c5ad0SDavid du Colombier n = (buf[18] << 8) | buf[19]; 12618a2c5ad0SDavid du Colombier if (n > 0 && n < nelem(cpu) && cpu[n]) 12628a2c5ad0SDavid du Colombier p = cpu[n]; 12638a2c5ad0SDavid du Colombier } 1264b7327ca2SDavid du Colombier print("%s ELF executable\n", p); 1265b7327ca2SDavid du Colombier } 1266b7327ca2SDavid du Colombier else 1267b7327ca2SDavid du Colombier print("application/x-elf-executable"); 1268b7327ca2SDavid du Colombier return 1; 1269b7327ca2SDavid du Colombier } 1270b7327ca2SDavid du Colombier 1271b7327ca2SDavid du Colombier return 0; 1272b7327ca2SDavid du Colombier } 1273