1: /* 2: * determine type of file 3: */ 4: 5: #include <sys/param.h> 6: #include <sys/stat.h> 7: #include <stdio.h> 8: #include <ctype.h> 9: int in; 10: int i = 0; 11: char buf[512]; 12: char *fort[] = { 13: "function","subroutine","common","dimension","block","integer", 14: "real","data","double",0}; 15: char *asc[] = { 16: "sys","mov","tst","clr","jmp",0}; 17: char *c[] = { 18: "int","char","float","double","struct","extern",0}; 19: char *as[] = { 20: "globl","byte","even","text","data","bss","comm",0}; 21: int ifile; 22: 23: main(argc, argv) 24: char **argv; 25: { 26: FILE *fl; 27: register char *p; 28: char ap[128]; 29: 30: if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') { 31: if ((fl = fopen(argv[2], "r")) == NULL) { 32: printf("Can't open %s\n", argv[2]); 33: exit(2); 34: } 35: while ((p = fgets(ap, 128, fl)) != NULL) { 36: int l = strlen(p); 37: if (l>0) 38: p[l-1] = '\0'; 39: printf("%s: ", p); 40: type(p); 41: if (ifile>=0) 42: close(ifile); 43: } 44: exit(1); 45: } 46: while(argc > 1) { 47: printf("%s: ", argv[1]); 48: type(argv[1]); 49: argc--; 50: argv++; 51: if (ifile >= 0) 52: close(ifile); 53: } 54: } 55: 56: type(file) 57: char *file; 58: { 59: int j,nl; 60: char ch; 61: struct stat mbuf; 62: 63: ifile = -1; 64: if(stat(file, &mbuf) < 0) { 65: printf("cannot stat\n"); 66: return; 67: } 68: switch (mbuf.st_mode & S_IFMT) { 69: 70: case S_IFCHR: 71: printf("character"); 72: goto spcl; 73: 74: case S_IFDIR: 75: printf("directory\n"); 76: return; 77: 78: case S_IFBLK: 79: printf("block"); 80: 81: spcl: 82: printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev)); 83: return; 84: } 85: 86: ifile = open(file, 0); 87: if(ifile < 0) { 88: printf("cannot open\n"); 89: return; 90: } 91: in = read(ifile, buf, 512); 92: if(in == 0){ 93: printf("empty\n"); 94: return; 95: } 96: switch(*(int *)buf) { 97: 98: case 0410: 99: printf("pure "); 100: goto exec; 101: 102: case 0411: 103: printf("separate "); 104: 105: case 0407: 106: exec: 107: printf("executable"); 108: if(((int *)buf)[4] != 0) 109: printf(" not stripped"); 110: printf("\n"); 111: goto out; 112: 113: case 0177555: 114: printf("old archive\n"); 115: goto out; 116: 117: case 0177545: 118: printf("archive\n"); 119: goto out; 120: } 121: 122: i = 0; 123: if(ccom() == 0)goto notc; 124: while(buf[i] == '#'){ 125: j = i; 126: while(buf[i++] != '\n'){ 127: if(i - j > 255){ 128: printf("data\n"); 129: goto out; 130: } 131: if(i >= in)goto notc; 132: } 133: if(ccom() == 0)goto notc; 134: } 135: check: 136: if(lookup(c) == 1){ 137: while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc; 138: printf("c program text"); 139: goto outa; 140: } 141: nl = 0; 142: while(buf[i] != '('){ 143: if(buf[i] <= 0) 144: goto notas; 145: if(buf[i] == ';'){ 146: i++; 147: goto check; 148: } 149: if(buf[i++] == '\n') 150: if(nl++ > 6)goto notc; 151: if(i >= in)goto notc; 152: } 153: while(buf[i] != ')'){ 154: if(buf[i++] == '\n') 155: if(nl++ > 6)goto notc; 156: if(i >= in)goto notc; 157: } 158: while(buf[i] != '{'){ 159: if(buf[i++] == '\n') 160: if(nl++ > 6)goto notc; 161: if(i >= in)goto notc; 162: } 163: printf("c program text"); 164: goto outa; 165: notc: 166: i = 0; 167: while(buf[i] == 'c' || buf[i] == '#'){ 168: while(buf[i++] != '\n')if(i >= in)goto notfort; 169: } 170: if(lookup(fort) == 1){ 171: printf("fortran program text"); 172: goto outa; 173: } 174: notfort: 175: i=0; 176: if(ascom() == 0)goto notas; 177: j = i-1; 178: if(buf[i] == '.'){ 179: i++; 180: if(lookup(as) == 1){ 181: printf("assembler program text"); 182: goto outa; 183: } 184: else if(buf[j] == '\n' && isalpha(buf[j+2])){ 185: printf("roff, nroff, or eqn input text"); 186: goto outa; 187: } 188: } 189: while(lookup(asc) == 0){ 190: if(ascom() == 0)goto notas; 191: while(buf[i] != '\n' && buf[i++] != ':') 192: if(i >= in)goto notas; 193: while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas; 194: j = i-1; 195: if(buf[i] == '.'){ 196: i++; 197: if(lookup(as) == 1){ 198: printf("assembler program text"); 199: goto outa; 200: } 201: else if(buf[j] == '\n' && isalpha(buf[j+2])){ 202: printf("roff, nroff, or eqn input text"); 203: goto outa; 204: } 205: } 206: } 207: printf("assembler program text"); 208: goto outa; 209: notas: 210: for(i=0; i < in; i++)if(buf[i]&0200){ 211: if (buf[0]=='\100' && buf[1]=='\357') { 212: printf("troff output\n"); 213: goto out; 214: } 215: printf("data\n"); 216: goto out; 217: } 218: if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6))) 219: printf("commands text"); 220: else 221: if (english(buf, in)) 222: printf("English text"); 223: else 224: printf("ascii text"); 225: outa: 226: while(i < in) 227: if((buf[i++]&0377) > 127){ 228: printf(" with garbage\n"); 229: goto out; 230: } 231: /* if next few lines in then read whole file looking for nulls ... 232: while((in = read(ifile,buf,512)) > 0) 233: for(i = 0; i < in; i++) 234: if((buf[i]&0377) > 127){ 235: printf(" with garbage\n"); 236: goto out; 237: } 238: /*.... */ 239: printf("\n"); 240: out:; 241: } 242: lookup(tab) 243: char *tab[]; 244: { 245: char r; 246: int k,j,l; 247: while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++; 248: for(j=0; tab[j] != 0; j++){ 249: l=0; 250: for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++); 251: if(r == '\0') 252: if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t' 253: || buf[k] == '{' || buf[k] == '/'){ 254: i=k; 255: return(1); 256: } 257: } 258: return(0); 259: } 260: ccom(){ 261: char cc; 262: while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0); 263: if(buf[i] == '/' && buf[i+1] == '*'){ 264: i += 2; 265: while(buf[i] != '*' || buf[i+1] != '/'){ 266: if(buf[i] == '\\')i += 2; 267: else i++; 268: if(i >= in)return(0); 269: } 270: if((i += 2) >= in)return(0); 271: } 272: if(buf[i] == '\n')if(ccom() == 0)return(0); 273: return(1); 274: } 275: ascom(){ 276: while(buf[i] == '/'){ 277: i++; 278: while(buf[i++] != '\n')if(i >= in)return(0); 279: while(buf[i] == '\n')if(i++ >= in)return(0); 280: } 281: return(1); 282: } 283: 284: english (bp, n) 285: char *bp; 286: { 287: # define NASC 128 288: int ct[NASC], j, vow, freq, rare; 289: int badpun = 0, punct = 0; 290: if (n<50) return(0); /* no point in statistics on squibs */ 291: for(j=0; j<NASC; j++) 292: ct[j]=0; 293: for(j=0; j<n; j++) 294: { 295: if (bp[j]<NASC) 296: ct[bp[j]|040]++; 297: switch (bp[j]) 298: { 299: case '.': 300: case ',': 301: case ')': 302: case '%': 303: case ';': 304: case ':': 305: case '?': 306: punct++; 307: if ( j < n-1 && 308: bp[j+1] != ' ' && 309: bp[j+1] != '\n') 310: badpun++; 311: } 312: } 313: if (badpun*5 > punct) 314: return(0); 315: vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u']; 316: freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n']; 317: rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z']; 318: if (2*ct[';'] > ct['e']) return(0); 319: if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */ 320: return (vow*5 >= n-ct[' '] && freq >= 10*rare); 321: }