|
|
researchv10 Norman
static char sccsid[] = "@(#)file.c 4.1 10/1/80";
/*
* file - determine type of file
*/
#include <pagsiz.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <a.out.h>
int in;
int i = 0;
unsigned char buf[BUFSIZ];
char *troff[] = { /* new troff intermediate lang */
"x","T","res","init","font","202","V0","p1",0};
char *fort[] = {
"function","subroutine","common","dimension","block","integer",
"real","data","double",0};
char *asc[] = {
"chmk","mov","tst","clr","jmp",0};
char *c[] = {
"int","char","float","double","struct",
"extern","static","typedef",0};
char *as[] = {
"globl","byte","align","text","data","comm",0};
int ifile;
main(argc, argv)
char **argv;
{
FILE *fl;
register char *p;
char ap[128];
extern char _sobuf[];
if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
if ((fl = fopen(argv[2], "r")) == NULL) {
printf("Can't open %s\n", argv[2]);
exit(2);
}
while ((p = fgets(ap, 128, fl)) != NULL) {
int l = strlen(p);
if (l>0)
p[l-1] = '\0';
printf("%s: ", p);
type(p);
if (ifile>=0)
close(ifile);
}
exit(1);
}
while(argc > 1) {
printf("%s: ", argv[1]);
type(argv[1]);
fflush(stdout);
argc--;
argv++;
if (ifile >= 0)
close(ifile);
}
}
type(file)
char *file;
{
int j,nl;
char ch;
struct stat mbuf;
ifile = -1;
if(stat(file, &mbuf) < 0) {
if(lstat(file,&mbuf)>=0 && (mbuf.st_mode&S_IFMT)==S_IFLNK)
printf("symbolic link, cannot stat\n");
else
printf("cannot stat\n");
return;
}
switch (mbuf.st_mode & S_IFMT) {
case S_IFCHR:
printf("character");
goto spcl;
case S_IFDIR:
printf("directory\n");
return;
case S_IFBLK:
printf("block");
spcl:
printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev));
return;
}
ifile = open(file, 0);
if(ifile < 0) {
printf("cannot open\n");
return;
}
in = read(ifile, buf, BUFSIZ);
if(in == 0){
printf("empty\n");
return;
}
if(in>=64){
int i, bucket[8];
float cs;
for(i=0; i<8; i++) bucket[i] = 0;
for(i=0; i<64; i++) bucket[(buf[i]>>5)&07] += 1;
cs = 0.;
for(i=0; i<8; i++) cs += (bucket[i]-8)*(bucket[i]-8);
cs /= 8.;
if(cs <= 24.322){
if(buf[0]==037 && buf[1]==0235) {
char * p = file + strlen(file);
if(p[-1]=='Z' && p[-2]=='.') {
printf("compressed\n");
return;
}
}
printf("encrypted\n");
return;
}
}
switch (*(short *) buf)
{
case 070707:
cpio:
printf("cpio archive\n");
goto out;
}
switch(*(int *)buf)
{
case 0413:
printf("demand paged ");
case 0410:
printf("pure ");
goto exec;
case 0411:
printf("jfr 411 executable\n");
return;
case 0406:
printf ("mpx 68000 ");
goto exec;
case 0407:
exec:
printf("executable");
if(((int *)buf)[4] != 0) {
printf(" not stripped");
if(oldo(buf))
printf(" (old format symbol table)");
}
if(*(int *)buf==0413 && ((int *)buf)[1]-((int *)buf)[5]==0x11F)
printf(" infected");
printf("\n");
goto out;
case 0177555:
printf("very old archive\n");
goto out;
case 0177545:
printf("old archive\n");
goto out;
case 0135246: /* andrew/ehg */
printf("view2d input file\n");
goto out;
case 0135256: /* andrew */
printf("apl file\n");
goto out;
case 0164200: /* td */
printf("Lucasfilm picture\n");
goto out;
case 0600560:
printf("mux downloadable file\n");
goto out;
default:
switch (*(short *) buf+1) {
case 0405:
case 0407:
case 0410:
case 0411:
printf ("pdp-11 executable\n");
goto out;
}
}
if (in >= 32 && buf[0] == 0x00 && buf[1] == 0x00) {
if (buf[2] == 0x01 && buf[3] == 0x07) {
printf("68020 plan9 executable\n");
goto out;
}
if (buf[2] == 0x04 && buf[3] == 0x07) {
printf("mips plan9 executable\n");
goto out;
}
}
if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) {
printf("archive random library\n");
goto out;
}
if (strncmp(buf, "!<arch>\n", 8)==0) {
printf("archive\n");
goto out;
}
if (strncmp(buf, "070707", 6) == 0)
{
printf("ascii ");
goto cpio;
}
if(strncmp(buf, "#!/bin/echo ", 12)==0){
printf("cyntax object file\n");
goto out;
}
if(strncmp(buf, "#!", 2)==0) {
if(script(buf,in))
goto out;
}
if(strncmp(buf, "TYPE=", 5)==0){ /* td */
for(i=5;i!=in && buf[i]!='\n';i++);
printf("%.*s picture\n", i, buf);
goto out;
}
if(strncmp(buf, "%!", 2)==0){
printf("postscript\n");
goto out;
}
if (strncmp(buf, "@document(", 10) == 0) {
printf("imagen\n");
goto out;
}
if (strncmp(buf, "\0334\033\037\013", 5) == 0) {
printf("daisy\n");
goto out;
}
if(buf[0] == '\0') {
if(buf[1] == '\0'){
printf("bitmap\n");
goto out;
}
if(strncmp(buf+1,"S data\001", 7)==0){
printf("S data object\n");
goto out;
}
}
if( (((unsigned char)buf[0])==247) && (buf[1]==2) ){
printf("tex dvi\n");
goto out;
}
i = 0;
if(ccom() == 0)goto notc;
while(buf[i] == '#'){
j = i;
while(buf[i++] != '\n'){
if(i - j > 255){
printf("data\n");
goto out;
}
if(i >= in)goto notc;
}
if(ccom() == 0)goto notc;
}
check:
if(lookup(c) == 1){
while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
printf("c program text");
goto outa;
}
nl = 0;
while(buf[i] != '('){
if(buf[i] <= 0)
goto notas;
if(buf[i] == ';'){
i++;
goto check;
}
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
while(buf[i] != ')'){
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
while(buf[i] != '{'){
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
printf("c program text");
goto outa;
notc:
i = 0;
while(buf[i] == 'c' || buf[i] == '#'){
while(buf[i++] != '\n')if(i >= in)goto notfort;
}
if(lookup(fort) == 1){
printf("fortran program text");
goto outa;
}
notfort:
i=0;
if(ascom() == 0)goto notas;
j = i-1;
if(buf[i] == '.'){
i++;
if(lookup(as) == 1){
printf("assembler program text");
goto outa;
}
else if(buf[j] == '\n' && isalpha(buf[j+2])){
printf("roff, nroff, or eqn input text");
goto outa;
}
}
while(lookup(asc) == 0){
if(ascom() == 0)goto notas;
while(buf[i] != '\n' && buf[i++] != ':')
if(i >= in)goto notas;
while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
j = i-1;
if(buf[i] == '.'){
i++;
if(lookup(as) == 1){
printf("assembler program text");
goto outa;
}
else if(buf[j] == '\n' && isalpha(buf[j+2])){
printf("roff, nroff, or eqn input text");
goto outa;
}
}
}
printf("assembler program text");
goto outa;
notas:
for(i=0; i < in; i++)if(buf[i]&0200){
if (buf[0]=='\100' && buf[1]=='\357') {
printf("troff (CAT) output\n");
goto out;
}
if(buf[0] == 037 && buf[1] == 036){
char *p = file;
while(*p++);
if(*(p-2) != 'z' || *(p-3) != '.')
printf("probably ");
printf("packed\n");
goto out;
}
if(buf[0] == 037 && buf[1] == 0235) {
char *p = file;
while(*p++);
if(*(p-2) != 'Z' || *(p-3) != '.')
printf("probably ");
printf("compressed\n");
goto out;
}
printf("data\n");
goto out;
}
if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
printf("shell script text");
else if (troffint(buf, in))
;
else if (english(buf, in))
printf("English text");
else
printf("ascii text");
outa:
while(i < in)
if((buf[i++]&0377) > 127){
printf(" with garbage\n");
goto out;
}
/* if next few lines in then read whole file looking for nulls ...
while((in = read(ifile,buf,BUFSIZ)) > 0)
for(i = 0; i < in; i++)
if((buf[i]&0377) > 127){
printf(" with garbage\n");
goto out;
}
/*.... */
printf("\n");
out:;
}
oldo(cp)
char *cp;
{
struct exec ex;
struct stat stb;
ex = *(struct exec *)cp;
if (fstat(ifile, &stb) < 0)
return(0);
if (N_STROFF(ex)+sizeof(off_t) > stb.st_size)
return (1);
return (0);
}
script(buf,n)
char *buf;
{
int i,j;
int text = 1;
for(j=2; j<n; j++)
if(buf[j]!=' '&&buf[j]!='\t')
break;
for(i=j; i<n; i++)
if(buf[i]==' ' || buf[i]=='\n')
goto found;
return 0;
found:
buf[i] = 0;
for(i=0; i<n; i++)
if(buf[i]>=0177)
text = 0;
printf("%s script%s\n",buf+j, text?" text":"");
return 1;
}
troffint(bp, n)
char *bp;
int n;
{
int k, l;
char s[14];
i = 0;
for (k = 0; k < 8; k++) {
if (buf[i] == 'x' && buf[i+1] == ' ') { /* x [T|init|font|...] */
if (strncmp(&buf[i+2], "T ", 2) == 0) {
l = i;
while (l < n && buf[l++] != '\n');
strncpy(s, &buf[i+4], l - (i+4) - 1);
printf("troff intermediate output text for %s",s);
i = l;
return 1;
}
while (i < n && buf[i++] != '\n')
;
} else if ((buf[i] == 'f' || buf[i] == 's' ||
buf[i] == 'p' || buf[i] == 'V' || buf[i] == 'H')
&& isdigit(buf[i+1])) /* p1 | f2 | s3 | V4... */
while (i < n && buf[i++] != '\n')
;
else
return 0;
}
printf("troff intermediate output text");
return 1;
}
lookup(tab)
char *tab[];
{
char r;
int k,j,l;
while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
for(j=0; tab[j] != 0; j++){
l=0;
for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
if(r == '\0')
if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
|| buf[k] == '{' || buf[k] == '/'){
i=k;
return(1);
}
}
return(0);
}
ccom(){
char cc;
while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
if(buf[i] == '/' && buf[i+1] == '*'){
i += 2;
while(buf[i] != '*' || buf[i+1] != '/'){
if(buf[i] == '\\')i += 2;
else i++;
if(i >= in)return(0);
}
if((i += 2) >= in)return(0);
}
if(buf[i] == '\n')if(ccom() == 0)return(0);
return(1);
}
ascom(){
while(buf[i] == '/'){
i++;
while(buf[i++] != '\n')if(i >= in)return(0);
while(buf[i] == '\n')if(i++ >= in)return(0);
}
return(1);
}
english (bp, n)
char *bp;
{
# define NASC 128
int ct[NASC], j, vow, freq, rare;
int badpun = 0, punct = 0;
if (n<50) return(0); /* no point in statistics on squibs */
for(j=0; j<NASC; j++)
ct[j]=0;
for(j=0; j<n; j++)
{
if (bp[j]<NASC)
ct[bp[j]|040]++;
switch (bp[j])
{
case '.':
case ',':
case ')':
case '%':
case ';':
case ':':
case '?':
punct++;
if ( j < n-1 &&
bp[j+1] != ' ' &&
bp[j+1] != '\n')
badpun++;
}
}
if (badpun*5 > punct)
return(0);
vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
if (2*ct[';'] > ct['e']) return(0);
if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
return (vow*5 >= n-ct[' '] && freq >= 10*rare);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.