int isrfc822(void);
int ismbox(void);
int islimbo(void);
+int istga(void);
int ismp3(void);
+int ismp4(void);
int ismung(void);
int isp9bit(void);
int isp9font(void);
int istar(void);
int isface(void);
int isexec(void);
-int p9bitnum(uchar*);
+int isudiff(void);
+int p9bitnum(char*, int*);
int p9subfont(uchar*);
void print_utf(void);
void type(char*, int);
iff, /* interchange file format (strings) */
longoff, /* recognizable by 4 bytes at some offset */
isoffstr, /* recognizable by string at some offset */
+ isudiff, /* unified diff output */
isrfc822, /* email file */
ismbox, /* mail box */
istar, /* recognizable by tar checksum */
- ishtml, /* html keywords */
iscint, /* compiler/assembler intermediate */
+ ishtml, /* html keywords */
islimbo, /* limbo source */
isc, /* c & alef compiler key words */
isas, /* assembler key words */
ismsdos, /* msdos exe (virus file attachement) */
isicocur, /* windows icon or cursor file */
isface, /* ascii face file */
+ istga,
ismp3,
+ ismp4,
/* last resorts */
ismung, /* entropy compressed/encrypted */
int mime;
-char OCTET[] = "application/octet-stream\n";
-char PLAIN[] = "text/plain\n";
+char OCTET[] = "application/octet-stream";
+char PLAIN[] = "text/plain";
void
main(int argc, char *argv[])
}
fname = file;
if ((fd = open(file, OREAD)) < 0) {
- print("cannot open: %r\n");
+ fprint(2, "cannot open: %r\n");
return;
}
filetype(fd);
close(fd);
}
-/*
- * Unicode 4.0 4-byte runes.
- */
-typedef int Rune1;
-
-enum {
- UTFmax1 = 4,
-};
-
-int
-fullrune1(char *p, int n)
-{
- int c;
-
- if(n >= 1) {
- c = *(uchar*)p;
- if(c < 0x80)
- return 1;
- if(n >= 2 && c < 0xE0)
- return 1;
- if(n >= 3 && c < 0xF0)
- return 1;
- if(n >= 4)
- return 1;
- }
- return 0;
-}
-
-int
-chartorune1(Rune1 *rune, char *str)
+void
+utfconv(void)
{
- int c, c1, c2, c3, n;
Rune r;
+ uchar *rb;
+ char *p, *e;
+ int i;
- c = *(uchar*)str;
- if(c < 0xF0){
- r = 0;
- n = chartorune(&r, str);
- *rune = r;
- return n;
- }
- c &= ~0xF0;
- c1 = *(uchar*)(str+1) & ~0x80;
- c2 = *(uchar*)(str+2) & ~0x80;
- c3 = *(uchar*)(str+3) & ~0x80;
- n = (c<<18) | (c1<<12) | (c2<<6) | c3;
- if(n < 0x10000 || n > 0x10FFFF){
- *rune = Runeerror;
- return 1;
+ if(nbuf < 4)
+ return;
+
+ if(memcmp(buf, "\x00\x00\xFE\xFF", 4) == 0){
+ if(!mime)
+ print("utf-32be ");
+ return;
+ } else
+ if(memcmp(buf, "\xFE\xFF\x00\x00", 4) == 0){
+ if(!mime)
+ print("utf-32le ");
+ return;
+ } else
+ if(memcmp(buf, "\xEF\xBB\xBF", 3) == 0){
+ memmove(buf, buf+3, nbuf-3);
+ nbuf -= 3;
+ return;
+ } else
+ if(memcmp(buf, "\xFE\xFF", 2) == 0){
+ if(!mime)
+ print("utf-16be ");
+
+ nbuf -= 2;
+ rb = malloc(nbuf+1);
+ memmove(rb, buf+2, nbuf);
+ p = (char*)buf;
+ e = p+sizeof(buf)-UTFmax-1;
+ for(i=0; i<nbuf && p < e; i+=2){
+ r = rb[i+1] | rb[i]<<8;
+ p += runetochar(p, &r);
+ }
+ *p = 0;
+ free(rb);
+ nbuf = p - (char*)buf;
+ } else
+ if(memcmp(buf, "\xFF\xFE", 2) == 0){
+ if(!mime)
+ print("utf-16le ");
+
+ nbuf -= 2;
+ rb = malloc(nbuf+1);
+ memmove(rb, buf+2, nbuf);
+ p = (char*)buf;
+ e = p+sizeof(buf)-UTFmax-1;
+ for(i=0; i<nbuf && p < e; i+=2){
+ r = rb[i] | rb[i+1]<<8;
+ p += runetochar(p, &r);
+ }
+ *p = 0;
+ free(rb);
+ nbuf = p - (char*)buf;
}
- *rune = n;
- return 4;
}
void
filetype(int fd)
{
- Rune1 r;
+ Rune r;
int i, f, n;
char *p, *eob;
free(mbuf);
mbuf = dirfstat(fd);
if(mbuf == nil){
- print("cannot stat: %r\n");
+ fprint(2, "cannot stat: %r\n");
return;
}
if(mbuf->mode & DMDIR) {
- print(mime ? OCTET : "directory\n");
+ print("%s\n", mime ? OCTET : "directory");
return;
}
if(mbuf->type != 'M' && mbuf->type != '|') {
- print(mime ? OCTET : "special file #%C/%s\n",
- mbuf->type, mbuf->name);
+ if(mime)
+ print("%s\n", OCTET);
+ else
+ print("special file #%C/%s\n", mbuf->type, mbuf->name);
return;
}
/* may be reading a pipe on standard input */
nbuf = readn(fd, buf, sizeof(buf)-1);
if(nbuf < 0) {
- print("cannot read: %r\n");
+ fprint(2, "cannot read: %r\n");
return;
}
if(nbuf == 0) {
- print(mime ? PLAIN : "empty file\n");
+ print("%s\n", mime ? PLAIN : "empty file");
return;
}
buf[nbuf] = 0;
+ utfconv();
+
/*
* build histogram table
*/
language[i].count = 0;
eob = (char *)buf+nbuf;
for(n = 0, p = (char *)buf; p < eob; n++) {
- if (!fullrune1(p, eob-p) && eob-p < UTFmax1)
+ if (!fullrune(p, eob-p) && eob-p < UTFmax)
break;
- p += chartorune1(&r, p);
+ p += chartorune(&r, p);
if (r == 0)
f = Cnull;
else if (r <= 0x7f) {
if (nbuf < 100 && !mime)
print(mime ? PLAIN : "short ");
if (guess == Fascii)
- print(mime ? PLAIN : "Ascii\n");
+ print("%s\n", mime ? PLAIN : "Ascii");
else if (guess == Feascii)
- print(mime ? PLAIN : "extended ascii\n");
+ print("%s\n", mime ? PLAIN : "extended ascii");
else if (guess == Flatin)
- print(mime ? PLAIN : "latin ascii\n");
+ print("%s\n", mime ? PLAIN : "latin ascii");
else if (guess == Futf && utf_count() < 4)
print_utf();
- else print(mime ? OCTET : "binary\n");
+ else print("%s\n", mime ? OCTET : "binary");
}
void
int i, printed, j;
if(mime){
- print(PLAIN);
+ print("%s\n", PLAIN);
return;
}
if (chkascii()) {
* when read from a file.
*/
Filemagic long0tab[] = {
- 0xF16DF16D, 0xFFFFFFFF, "pac1 audio file\n", OCTET,
+ 0xF16DF16D, 0xFFFFFFFF, "pac1 audio file", OCTET,
/* "pac1" */
- 0x31636170, 0xFFFFFFFF, "pac3 audio file\n", OCTET,
+ 0x31636170, 0xFFFFFFFF, "pac3 audio file", OCTET,
/* "pXc2 */
- 0x32630070, 0xFFFF00FF, "pac4 audio file\n", OCTET,
- 0xBA010000, 0xFFFFFFFF, "mpeg system stream\n", OCTET,
- 0x43614c66, 0xFFFFFFFF, "FLAC audio file\n", "audio/flac",
- 0x30800CC0, 0xFFFFFFFF, "inferno .dis executable\n", OCTET,
- 0x04034B50, 0xFFFFFFFF, "zip archive\n", "application/zip",
- 070707, 0xFFFF, "cpio archive\n", "application/x-cpio",
- 0x2F7, 0xFFFF, "tex dvi\n", "application/dvi",
- 0xfaff, 0xfeff, "mp3 audio\n", "audio/mpeg",
- 0xfeff0000, 0xffffffff, "utf-32be\n", "text/plain charset=utf-32be",
- 0xfffe, 0xffffffff, "utf-32le\n", "text/plain charset=utf-32le",
- 0xfeff, 0xffff, "utf-16be\n", "text/plain charset=utf-16be",
- 0xfffe, 0xffff, "utf-16le\n", "text/plain charset=utf-16le",
+ 0x32630070, 0xFFFF00FF, "pac4 audio file", OCTET,
+ 0xBA010000, 0xFFFFFFFF, "mpeg system stream", OCTET,
+ 0x43614c66, 0xFFFFFFFF, "FLAC audio file", "audio/flac",
+ 0x30800CC0, 0xFFFFFFFF, "inferno .dis executable", OCTET,
+ 0x04034B50, 0xFFFFFFFF, "zip archive", "application/zip",
+ 070707, 0xFFFF, "cpio archive", "application/x-cpio",
+ 0x2F7, 0xFFFF, "tex dvi", "application/dvi",
+ 0xfaff, 0xfeff, "mp3 audio", "audio/mpeg",
+ 0xf0ff, 0xf6ff, "aac audio", "audio/mpeg",
/* 0xfeedface: this could alternately be a Next Plan 9 boot image */
- 0xcefaedfe, 0xFFFFFFFF, "32-bit power Mach-O executable\n", OCTET,
+ 0xcefaedfe, 0xFFFFFFFF, "32-bit power Mach-O executable", OCTET,
/* 0xfeedfacf */
- 0xcffaedfe, 0xFFFFFFFF, "64-bit power Mach-O executable\n", OCTET,
+ 0xcffaedfe, 0xFFFFFFFF, "64-bit power Mach-O executable", OCTET,
/* 0xcefaedfe */
- 0xfeedface, 0xFFFFFFFF, "386 Mach-O executable\n", OCTET,
+ 0xfeedface, 0xFFFFFFFF, "386 Mach-O executable", OCTET,
/* 0xcffaedfe */
- 0xfeedfacf, 0xFFFFFFFF, "amd64 Mach-O executable\n", OCTET,
+ 0xfeedfacf, 0xFFFFFFFF, "amd64 Mach-O executable", OCTET,
/* 0xcafebabe */
- 0xbebafeca, 0xFFFFFFFF, "Mach-O universal executable\n", OCTET,
+ 0xbebafeca, 0xFFFFFFFF, "Mach-O universal executable", OCTET,
/*
* venti & fossil magic numbers are stored big-endian on disk,
* thus the numbers appear reversed in this table.
*/
- 0xad4e5cd1, 0xFFFFFFFF, "venti arena\n", OCTET,
- 0x2bb19a52, 0xFFFFFFFF, "paq archive\n", OCTET,
+ 0xad4e5cd1, 0xFFFFFFFF, "venti arena", OCTET,
+ 0x2bb19a52, 0xFFFFFFFF, "paq archive", OCTET,
+ 0x1a53454e, 0xFFFFFFFF, "NES ROM", OCTET,
+ /* tcpdump pcap file */
+ 0xa1b2c3d4, 0xFFFFFFFF, "pcap file", "application/vnd.tcpdump.pcap",
+ 0xd4c3b2a1, 0xFFFFFFFF, "pcap file", "application/vnd.tcpdump.pcap",
+ 0xa1b23c4d, 0xFFFFFFFF, "pcap file", "application/vnd.tcpdump.pcap",
+ 0x4d3cb2a1, 0xFFFFFFFF, "pcap file", "application/vnd.tcpdump.pcap",
};
int
for(i=0; i<ntab; i++)
if((x&tab[i].mask) == tab[i].x){
- print(mime ? tab[i].mime : tab[i].desc);
+ print("%s\n", mime ? tab[i].mime : tab[i].desc);
return 1;
}
return 0;
* venti & fossil magic numbers are stored big-endian on disk,
* thus the numbers appear reversed in this table.
*/
- 256*1024, 0xe7a5e4a9, 0xFFFFFFFF, "venti arenas partition\n", OCTET,
- 256*1024, 0xc75e5cd1, 0xFFFFFFFF, "venti index section\n", OCTET,
- 128*1024, 0x89ae7637, 0xFFFFFFFF, "fossil write buffer\n", OCTET,
- 4, 0x31647542, 0xFFFFFFFF, "OS X finder properties\n", OCTET,
+ 256*1024, 0xe7a5e4a9, 0xFFFFFFFF, "venti arenas partition", OCTET,
+ 256*1024, 0xc75e5cd1, 0xFFFFFFFF, "venti index section", OCTET,
+ 128*1024, 0x89ae7637, 0xFFFFFFFF, "fossil write buffer", OCTET,
+ 4, 0x31647542, 0xFFFFFFFF, "OS X finder properties", OCTET,
+ 0x100, 0x41474553, 0xFFFFFFFF, "SEGA ROM", OCTET,
+ 0x1fc, 0xAA550000, 0xFFFF0000, "bootable disk image", OCTET,
};
int
continue;
x = LENDIAN(buf);
if((x&tp->mask) == tp->x){
- print(mime? tp->mime: tp->desc);
+ print("%s\n", mime ? tp->mime : tp->desc);
return 1;
}
}
seek(fd, 0, 0); /* reposition to start of file */
if(crackhdr(fd, &f)) {
- print(mime ? OCTET : "%s\n", f.name);
+ print("%s\n", mime ? OCTET : f.name);
return 1;
}
return 0;
"\x1f\x9d", "compressed", 2, "application/x-compress",
"\x1f\x8b", "gzip compressed", 2, "application/x-gzip",
"BZh", "bzip2 compressed", 3, "application/x-bzip2",
- "!<arch>\n__.SYMDEF", "archive random library", 16, "application/octet-stream",
- "!<arch>\n", "archive", 8, "application/octet-stream",
- "070707", "cpio archive - ascii header", 6, "application/octet-stream",
- "#!/bin/rc", "rc executable file", 9, "text/plain",
- "#!/bin/sh", "sh executable file", 9, "text/plain",
+ "!<arch>\n__.SYMDEF", "archive random library", 16, OCTET,
+ "!<arch>\n", "archive", 8, OCTET,
+ "070707", "cpio archive - ascii header", 6, OCTET,
+ "#!/bin/rc", "rc executable file", 9, PLAIN,
+ "#!/bin/sh", "sh executable file", 9, PLAIN,
"%!", "postscript", 2, "application/postscript",
"\004%!", "postscript", 3, "application/postscript",
"x T post", "troff output for post", 8, "application/troff",
"BM", "bmp", 2, "image/bmp",
"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", "microsoft office document", 8, "application/doc",
"<MakerFile ", "FrameMaker file", 11, "application/framemaker",
- "\033E\033", "HP PCL printer data", 3, OCTET,
- "\033&", "HP PCL printer data", 2, OCTET,
- "\033%-12345X", "HPJCL file", 9, "application/hpjcl",
+ "\033E\033", "HP PCL printer data", 3, OCTET,
+ "\033&", "HP PCL printer data", 2, OCTET,
+ "\033%-12345X", "HPJCL file", 9, "application/hpjcl",
"\033Lua", "Lua bytecode", 4, OCTET,
"ID3", "mp3 audio with id3", 3, "audio/mpeg",
"OggS", "ogg audio", 4, "audio/ogg",
".snd", "sun audio", 4, "audio/basic",
"\211PNG", "PNG image", 4, "image/png",
- "P3\n", "ppm", 3, "image/ppm",
- "P6\n", "ppm", 3, "image/ppm",
+ "P1\n", "ppm", 3, "image/ppm",
+ "P2\n", "ppm", 3, "image/ppm",
+ "P3\n", "ppm", 3, "image/ppm",
+ "P4\n", "ppm", 3, "image/ppm",
+ "P5\n", "ppm", 3, "image/ppm",
+ "P6\n", "ppm", 3, "image/ppm",
"/* XPM */\n", "xbm", 10, "image/xbm",
".HTML ", "troff -ms input", 6, "text/troff",
".LP", "troff -ms input", 3, "text/troff",
".if", "troff input", 3, "text/troff",
".nr", "troff input", 3, "text/troff",
".tr", "troff input", 3, "text/troff",
- "vac:", "venti score", 4, "text/plain",
+ "vac:", "venti score", 4, PLAIN,
"-----BEGIN CERTIFICATE-----\n",
- "pem certificate", -1, "text/plain",
+ "pem certificate", -1, PLAIN,
"-----BEGIN TRUSTED CERTIFICATE-----\n",
- "pem trusted certificate", -1, "text/plain",
+ "pem trusted certificate", -1, PLAIN,
"-----BEGIN X509 CERTIFICATE-----\n",
- "pem x.509 certificate", -1, "text/plain",
- "subject=/C=", "pem certificate with header", -1, "text/plain",
+ "pem x.509 certificate", -1, PLAIN,
+ "subject=/C=", "pem certificate with header", -1, PLAIN,
"process snapshot ", "process snapshot", -1, "application/snapfs",
"d8:announce", "torrent file", 11, "application/x-bittorrent",
"[playlist]", "playlist", 10, "application/x-scpls",
"#EXTM3U", "playlist", 7, "audio/x-mpegurl",
"BEGIN:VCARD\r\n", "vCard", 13, "text/directory;profile=vcard",
"BEGIN:VCARD\n", "vCard", 12, "text/directory;profile=vcard",
+ "AT&T", "DjVu document", 4, "image/vnd.djvu",
+ "Extended module: ", "XM audio", 17, "audio/xm",
+ "MThd", "midi audio", 4, "audio/midi",
+ "MUS\x1a", "mus audio", 4, "audio/mus",
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xaa\x99\x55\x66", "Xilinx bitstream (not byteswappped)", 52, OCTET,
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xbb\x00\x00\x00\x44\x00\x22\x11\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\x66\x55\x99\xaa", "Xilinx bitstream (byteswappped)", 52, OCTET,
0,0,0,0
};
if(l == -1)
l = strlen(p->key);
if(nbuf >= l && memcmp(buf, p->key, l) == 0) {
- if(mime)
- print("%s\n", p->mime);
- else
- print("%s\n", p->filetype);
+ print("%s\n", mime ? p->mime : p->filetype);
return 1;
}
}
if(buf[i] == '\n')
break;
if(mime)
- print(OCTET);
+ print("%s\n", OCTET);
else
print("%.*s picture\n", utfnlen((char*)buf+5, i-5), (char*)buf+5);
return 1;
struct FILE_STRING;
} offstrs[] = {
32*1024, "\001CD001\001", "ISO9660 CD image", 7, "application/x-iso9660-image",
+ 32*4, "DICM", "DICOM medical imaging data", 4, "application/dicom",
0, 0, 0, 0, 0
};
if (readn(fd, buf, n) != n)
continue;
if(memcmp(buf, p->key, n) == 0) {
- if(mime)
- print("%s\n", p->mime);
- else
- print("%s\n", p->filetype);
+ print("%s\n", mime ? p->mime : p->filetype);
return 1;
}
}
else if (strncmp((char*)buf+8, "AVI ", 4) == 0)
print("%s\n", mime? "video/avi": "avi video");
else
- print("%s\n", mime? "application/octet-stream":
- "riff file");
+ print("%s\n", mime? OCTET : "riff file");
return 1;
}
return 0;
0,
};
+int
+isudiff(void)
+{
+ char *p;
+
+ p = (char*)buf;
+ if((p = strstr(p, "diff")) != nil)
+ if((p = strchr(p, '\n')) != nil)
+ if(strncmp(++p, "--- ", 4) == 0)
+ if((p = strchr(p, '\n')) != nil)
+ if(strncmp(++p, "+++ ", 4) == 0)
+ if((p = strchr(p, '\n')) != nil)
+ if(strncmp(++p, "@@ ", 3) == 0){
+ print("%s\n", mime ? "text/plain" : "unified diff output");
+ return 1;
+ }
+ return 0;
+}
+
int
ishtml(void)
{
p += n;
if(p < buf+nbuf && strchr("\t\r\n />", *p)){
if(++count > 2) {
- print(mime ? "text/html\n" : "HTML file\n");
+ print("%s\n", mime ? "text/html" : "HTML file");
return 1;
}
}
p = q+1;
}
if(count >= 3){
- print(mime ? "message/rfc822\n" : "email file\n");
+ print("%s\n", mime ? "message/rfc822" : "email file");
return 1;
}
return 0;
return 0;
*q = 0;
if(strncmp(p, "From ", 5) == 0 && strstr(p, " remote from ") == nil){
- print(mime ? "text/plain\n" : "mail box\n");
+ print("%s\n", mime ? PLAIN : "mail box");
return 1;
}
*q = '\n';
if(type < 0)
return 0;
if(mime)
- print(OCTET);
+ print("%s\n", OCTET);
else
print("%s intermediate\n", name);
return 1;
yes:
if(mime){
- print(PLAIN);
+ print("%s\n", PLAIN);
return 1;
}
if(wfreq[Alword] > 0)
int
islimbo(void)
{
-
/*
* includes
*/
if(wfreq[Lword] < 4)
return 0;
- print(mime ? PLAIN : "limbo program\n");
+ print("%s\n", mime ? PLAIN : "limbo program");
return 1;
}
int
isas(void)
{
-
/*
* includes
*/
if(wfreq[Aword] < 2)
return 0;
- print(mime ? PLAIN : "as program\n");
+ print("%s\n", mime ? PLAIN : "as program");
+ return 1;
+}
+
+int
+istga(void)
+{
+ uchar *p;
+
+ p = buf;
+ if(nbuf < 18)
+ return 0;
+ if((p[12] | p[13]<<8) == 0) /* width */
+ return 0;
+ if((p[14] | p[15]<<8) == 0) /* height */
+ return 0;
+ if(p[16] != 8 && p[16] != 15 && p[16] != 16 && p[16] != 24 && p[16] != 32) /* bpp */
+ return 0;
+ if(((p[2]|(1<<3)) & (~3)) != (1<<3)) /* rle flag */
+ return 0;
+ if(p[1] == 0){ /* non color-mapped */
+ if((p[2]&3) != 2 && (p[2]&3) != 3)
+ return 0;
+ if((p[5] | p[6]<<8) != 0) /* palette length */
+ return 0;
+ } else
+ if(p[1] == 1){ /* color-mapped */
+ if((p[2]&3) != 1 || p[7] == 0)
+ return 0;
+ if((p[5] | p[6]<<8) == 0) /* palette length */
+ return 0;
+ } else
+ return 0;
+ print("%s\n", mime ? "image/tga" : "targa image");
return 1;
}
e = p + nbuf-1;
while((p < e) && (p = memchr(p, 0xFF, e - p))){
if((p[1] & 0xFE) == 0xFA){
- print(mime ? "audio/mpeg\n" : "mp3 audio\n");
+ print("%s\n", mime ? "audio/mpeg" : "mp3 audio");
return 1;
}
p++;
return 0;
}
+int
+ismp4(void)
+{
+ if(nbuf <= 12)
+ return 0;
+ if(memcmp(&buf[4], "ftyp", 4) != 0)
+ return 0;
+ if(memcmp(&buf[8], "isom", 4) == 0){
+ print("%s\n", mime ? "video/mp4" : "mp4 video");
+ return 1;
+ }
+ if(memcmp(&buf[8], "M4A ", 4) == 0){
+ print("%s\n", mime ? "audio/m4a" : "m4a audio");
+ return 1;
+ }
+ return 0;
+}
+
/*
* low entropy means encrypted
*/
cs /= 8.;
if(cs <= 24.322) {
if(buf[0]==0x1f && buf[1]==0x9d)
- print(mime ? "application/x-compress" : "compressed\n");
+ print("%s\n", mime ? "application/x-compress" : "compressed");
else
if(buf[0]==0x1f && buf[1]==0x8b)
- print(mime ? "application/x-gzip" : "gzip compressed\n");
+ print("%s\n", mime ? "application/x-gzip" : "gzip compressed");
else
if(buf[0]=='B' && buf[1]=='Z' && buf[2]=='h')
- print(mime ? "application/x-bzip2" : "bzip2 compressed\n");
+ print("%s\n", mime ? "application/x-bzip2" : "bzip2 compressed");
else
if(buf[0]==0x78 && buf[1]==0x9c)
- print(mime ? "application/x-deflate" : "zlib compressed\n");
+ print("%s\n", mime ? "application/x-deflate" : "zlib compressed");
else
- print(mime ? OCTET : "encrypted\n");
+ print("%s\n", mime ? OCTET : "encrypted");
return 1;
}
return 0;
rare += cfreq[tolower(*p)];
}
if(vow*5 >= nbuf-cfreq[' '] && comm >= 10*rare) {
- print(mime ? PLAIN : "English text\n");
+ print("%s\n", mime ? PLAIN : "English text");
return 1;
}
return 0;
*/
#define P9BITLEN 12
int
-p9bitnum(uchar *bp)
+p9bitnum(char *s, int *v)
{
- int n, c, len;
+ char *es;
- len = P9BITLEN;
- while(*bp == ' ') {
- bp++;
- len--;
- if(len <= 0)
- return -1;
- }
- n = 0;
- while(len > 1) {
- c = *bp++;
- if(!isdigit(c))
- return -1;
- n = n*10 + c-'0';
- len--;
- }
- if(*bp != ' ')
+ if(s[P9BITLEN-1] != ' ')
+ return -1;
+ s[P9BITLEN-1] = '\0';
+ *v = strtol(s, &es, 10);
+ s[P9BITLEN-1] = ' ';
+ if(es != &s[P9BITLEN-1])
return -1;
- return n;
+ return 0;
}
int
if(s == es)
return -1;
if('0'<=*s && *s<='9')
- return 1<<strtol(s, 0, 0);
+ return 1<<strtol(s, nil, 0);
*newp = 1;
d = 0;
while(s<es && *s!=' '){
- s++; /* skip letter */
- d += strtoul(s, &s, 10);
+ if(strchr("rgbkamx", *s) == nil)
+ return -1;
+ s++;
+ if('0'<=*s && *s<='9')
+ d += strtoul(s, &s, 10);
+ else
+ return -1;
}
if(d % 8 == 0 || 8 % d == 0)
isp9bit(void)
{
int dep, lox, loy, hix, hiy, px, new, cmpr;
- ulong t;
long len;
char *newlabel;
uchar *cp;
cp = buf;
cmpr = 0;
- newlabel = "old ";
-
if(memcmp(cp, "compressed\n", 11) == 0) {
cmpr = 1;
cp = buf + 11;
}
- dep = depthof((char*)cp + 0*P9BITLEN, &new);
- if(new)
- newlabel = "";
- lox = p9bitnum(cp + 1*P9BITLEN);
- loy = p9bitnum(cp + 2*P9BITLEN);
- hix = p9bitnum(cp + 3*P9BITLEN);
- hiy = p9bitnum(cp + 4*P9BITLEN);
- if(dep < 0 || lox < 0 || loy < 0 || hix < 0 || hiy < 0)
+ if((dep = depthof((char*)cp + 0*P9BITLEN, &new)) < 0)
+ return 0;
+ newlabel = new ? "" : "old ";
+ if(p9bitnum((char*)cp + 1*P9BITLEN, &lox) < 0)
+ return 0;
+ if(p9bitnum((char*)cp + 2*P9BITLEN, &loy) < 0)
+ return 0;
+ if(p9bitnum((char*)cp + 3*P9BITLEN, &hix) < 0)
+ return 0;
+ if(p9bitnum((char*)cp + 4*P9BITLEN, &hiy) < 0)
+ return 0;
+
+ hix -= lox;
+ hiy -= loy;
+ if(hix <= 0 || hiy <= 0)
return 0;
if(dep < 8){
px = 8/dep; /* pixels per byte */
/* set l to number of bytes of data per scan line */
- if(lox >= 0)
- len = (hix+px-1)/px - lox/px;
- else{ /* make positive before divide */
- t = (-lox)+px-1;
- t = (t/px)*px;
- len = (t+hix+px-1)/px;
- }
+ len = (hix+px-1)/px;
}else
- len = (hix-lox)*dep/8;
- len *= hiy - loy; /* col length */
+ len = hix*dep/8;
+ len *= hiy; /* col length */
len += 5 * P9BITLEN; /* size of initial ascii */
/*
* for subfont, the subfont header should follow immediately.
*/
if (cmpr) {
- print(mime ? "image/p9bit\n" : "Compressed %splan 9 image or subfont, depth %d\n",
- newlabel, dep);
+ print(mime ? "image/p9bit\n" : "Compressed %splan 9 image or subfont, depth %d, size %dx%d\n",
+ newlabel, dep, hix, hiy);
return 1;
}
/*
*/
if (len != 0 && (mbuf->length == 0 || mbuf->length == len ||
mbuf->length > len && mbuf->length < len+P9BITLEN)) {
- print(mime ? "image/p9bit\n" : "%splan 9 image, depth %d\n", newlabel, dep);
+ print(mime ? "image/p9bit\n" : "%splan 9 image, depth %d, size %dx%d\n",
+ newlabel, dep, hix, hiy);
return 1;
}
if (p9subfont(buf+len)) {
- print(mime ? "image/p9bit\n" : "%ssubfont file, depth %d\n", newlabel, dep);
+ print(mime ? "image/p9bit\n" : "%ssubfont file, depth %d, size %dx%d\n",
+ newlabel, dep, hix, hiy);
return 1;
}
return 0;
if (p+3*P9BITLEN > buf+sizeof(buf))
return 1;
- n = p9bitnum(p + 0*P9BITLEN); /* char count */
- if (n < 0)
+ if (p9bitnum((char*)p + 0*P9BITLEN, &n) < 0) /* char count */
return 0;
- h = p9bitnum(p + 1*P9BITLEN); /* height */
- if (h < 0)
+ if (p9bitnum((char*)p + 1*P9BITLEN, &h) < 0) /* height */
return 0;
- a = p9bitnum(p + 2*P9BITLEN); /* ascent */
- if (a < 0)
+ if (p9bitnum((char*)p + 2*P9BITLEN, &a) < 0) /* ascent */
return 0;
- return 1;
+ if(n > 0 && h > 0 && a >= 0)
+ return 1;
+ return 0;
}
#define WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
}
}
if (i) {
- print(mime ? "text/plain\n" : "font file\n");
+ print("%s\n", mime ? PLAIN : "font file");
return 1;
}
return 0;
print("%s ELF %s\n", p, t);
}
else
- print("application/x-elf-executable");
+ print("application/x-elf-executable\n");
return 1;
}
print("face image depth %d\n", ldepth);
return 1;
}
-