1 static char sccsid[] = "@(#)file.c 4.1 10/01/80"; 2 /* 3 * file - determine type of file 4 */ 5 6 #include <pagsiz.h> 7 #include <sys/types.h> 8 #include <stat.h> 9 #include <stdio.h> 10 #include <ctype.h> 11 #include <a.out.h> 12 int in; 13 int i = 0; 14 char buf[BUFSIZ]; 15 char *troff[] = { /* new troff intermediate lang */ 16 "x","T","res","init","font","202","V0","p1",0}; 17 char *fort[] = { 18 "function","subroutine","common","dimension","block","integer", 19 "real","data","double",0}; 20 char *asc[] = { 21 "chmk","mov","tst","clr","jmp",0}; 22 char *c[] = { 23 "int","char","float","double","struct","extern",0}; 24 char *as[] = { 25 "globl","byte","align","text","data","comm",0}; 26 int ifile; 27 28 main(argc, argv) 29 char **argv; 30 { 31 FILE *fl; 32 register char *p; 33 char ap[128]; 34 extern char _sobuf[]; 35 36 if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') { 37 if ((fl = fopen(argv[2], "r")) == NULL) { 38 printf("Can't open %s\n", argv[2]); 39 exit(2); 40 } 41 while ((p = fgets(ap, 128, fl)) != NULL) { 42 int l = strlen(p); 43 if (l>0) 44 p[l-1] = '\0'; 45 printf("%s: ", p); 46 type(p); 47 if (ifile>=0) 48 close(ifile); 49 } 50 exit(1); 51 } 52 while(argc > 1) { 53 printf("%s: ", argv[1]); 54 type(argv[1]); 55 fflush(stdout); 56 argc--; 57 argv++; 58 if (ifile >= 0) 59 close(ifile); 60 } 61 } 62 63 type(file) 64 char *file; 65 { 66 int j,nl; 67 char ch; 68 struct stat mbuf; 69 70 ifile = -1; 71 if(stat(file, &mbuf) < 0) { 72 printf("cannot stat\n"); 73 return; 74 } 75 switch (mbuf.st_mode & S_IFMT) { 76 77 case S_IFCHR: 78 printf("character"); 79 goto spcl; 80 81 case S_IFDIR: 82 printf("directory\n"); 83 return; 84 85 case S_IFMPC: 86 printf("char multiplexor\n"); 87 return; 88 89 case S_IFMPB: 90 printf("block multiplexor\n"); 91 return; 92 93 case S_IFBLK: 94 printf("block"); 95 96 spcl: 97 printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev)); 98 return; 99 } 100 101 ifile = open(file, 0); 102 if(ifile < 0) { 103 printf("cannot open\n"); 104 return; 105 } 106 in = read(ifile, buf, BUFSIZ); 107 if(in == 0){ 108 printf("empty\n"); 109 return; 110 } 111 switch(*(int *)buf) { 112 113 case 0413: 114 printf("demand paged "); 115 116 case 0410: 117 printf("pure "); 118 goto exec; 119 120 case 0411: 121 printf("jfr or pdp-11 unix 411 executable\n"); 122 return; 123 124 case 0407: 125 exec: 126 printf("executable"); 127 if(((int *)buf)[4] != 0) { 128 printf(" not stripped"); 129 if(oldo(buf)) 130 printf(" (old format symbol table)"); 131 } 132 printf("\n"); 133 goto out; 134 135 case 0177555: 136 printf("very old archive\n"); 137 goto out; 138 139 case 0177545: 140 printf("old archive\n"); 141 goto out; 142 143 case 070707: 144 printf("cpio data\n"); 145 goto out; 146 } 147 148 if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) { 149 printf("archive random library\n"); 150 goto out; 151 } 152 if (strncmp(buf, "!<arch>\n", 8)==0) { 153 printf("archive\n"); 154 goto out; 155 } 156 i = 0; 157 if(ccom() == 0)goto notc; 158 while(buf[i] == '#'){ 159 j = i; 160 while(buf[i++] != '\n'){ 161 if(i - j > 255){ 162 printf("data\n"); 163 goto out; 164 } 165 if(i >= in)goto notc; 166 } 167 if(ccom() == 0)goto notc; 168 } 169 check: 170 if(lookup(c) == 1){ 171 while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc; 172 printf("c program text"); 173 goto outa; 174 } 175 nl = 0; 176 while(buf[i] != '('){ 177 if(buf[i] <= 0) 178 goto notas; 179 if(buf[i] == ';'){ 180 i++; 181 goto check; 182 } 183 if(buf[i++] == '\n') 184 if(nl++ > 6)goto notc; 185 if(i >= in)goto notc; 186 } 187 while(buf[i] != ')'){ 188 if(buf[i++] == '\n') 189 if(nl++ > 6)goto notc; 190 if(i >= in)goto notc; 191 } 192 while(buf[i] != '{'){ 193 if(buf[i++] == '\n') 194 if(nl++ > 6)goto notc; 195 if(i >= in)goto notc; 196 } 197 printf("c program text"); 198 goto outa; 199 notc: 200 i = 0; 201 while(buf[i] == 'c' || buf[i] == '#'){ 202 while(buf[i++] != '\n')if(i >= in)goto notfort; 203 } 204 if(lookup(fort) == 1){ 205 printf("fortran program text"); 206 goto outa; 207 } 208 notfort: 209 i=0; 210 if(ascom() == 0)goto notas; 211 j = i-1; 212 if(buf[i] == '.'){ 213 i++; 214 if(lookup(as) == 1){ 215 printf("assembler program text"); 216 goto outa; 217 } 218 else if(buf[j] == '\n' && isalpha(buf[j+2])){ 219 printf("roff, nroff, or eqn input text"); 220 goto outa; 221 } 222 } 223 while(lookup(asc) == 0){ 224 if(ascom() == 0)goto notas; 225 while(buf[i] != '\n' && buf[i++] != ':') 226 if(i >= in)goto notas; 227 while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas; 228 j = i-1; 229 if(buf[i] == '.'){ 230 i++; 231 if(lookup(as) == 1){ 232 printf("assembler program text"); 233 goto outa; 234 } 235 else if(buf[j] == '\n' && isalpha(buf[j+2])){ 236 printf("roff, nroff, or eqn input text"); 237 goto outa; 238 } 239 } 240 } 241 printf("assembler program text"); 242 goto outa; 243 notas: 244 for(i=0; i < in; i++)if(buf[i]&0200){ 245 if (buf[0]=='\100' && buf[1]=='\357') { 246 printf("troff (CAT) output\n"); 247 goto out; 248 } 249 printf("data\n"); 250 goto out; 251 } 252 if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6))) 253 printf("commands text"); 254 else if (troffint(buf, in)) 255 printf("troff intermediate output text"); 256 else if (english(buf, in)) 257 printf("English text"); 258 else 259 printf("ascii text"); 260 outa: 261 while(i < in) 262 if((buf[i++]&0377) > 127){ 263 printf(" with garbage\n"); 264 goto out; 265 } 266 /* if next few lines in then read whole file looking for nulls ... 267 while((in = read(ifile,buf,BUFSIZ)) > 0) 268 for(i = 0; i < in; i++) 269 if((buf[i]&0377) > 127){ 270 printf(" with garbage\n"); 271 goto out; 272 } 273 /*.... */ 274 printf("\n"); 275 out:; 276 } 277 278 oldo(cp) 279 char *cp; 280 { 281 struct exec ex; 282 struct stat stb; 283 284 ex = *(struct exec *)cp; 285 if (fstat(ifile, &stb) < 0) 286 return(0); 287 if (N_STROFF(ex)+sizeof(off_t) > stb.st_size) 288 return (1); 289 return (0); 290 } 291 292 293 294 troffint(bp, n) 295 char *bp; 296 int n; 297 { 298 int k; 299 300 i = 0; 301 for (k = 0; k < 6; k++) { 302 if (lookup(troff) == 0) 303 return(0); 304 if (lookup(troff) == 0) 305 return(0); 306 while (i < n && buf[i] != '\n') 307 i++; 308 if (i++ >= n) 309 return(0); 310 } 311 return(1); 312 } 313 lookup(tab) 314 char *tab[]; 315 { 316 char r; 317 int k,j,l; 318 while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++; 319 for(j=0; tab[j] != 0; j++){ 320 l=0; 321 for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++); 322 if(r == '\0') 323 if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t' 324 || buf[k] == '{' || buf[k] == '/'){ 325 i=k; 326 return(1); 327 } 328 } 329 return(0); 330 } 331 ccom(){ 332 char cc; 333 while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0); 334 if(buf[i] == '/' && buf[i+1] == '*'){ 335 i += 2; 336 while(buf[i] != '*' || buf[i+1] != '/'){ 337 if(buf[i] == '\\')i += 2; 338 else i++; 339 if(i >= in)return(0); 340 } 341 if((i += 2) >= in)return(0); 342 } 343 if(buf[i] == '\n')if(ccom() == 0)return(0); 344 return(1); 345 } 346 ascom(){ 347 while(buf[i] == '/'){ 348 i++; 349 while(buf[i++] != '\n')if(i >= in)return(0); 350 while(buf[i] == '\n')if(i++ >= in)return(0); 351 } 352 return(1); 353 } 354 355 english (bp, n) 356 char *bp; 357 { 358 # define NASC 128 359 int ct[NASC], j, vow, freq, rare; 360 int badpun = 0, punct = 0; 361 if (n<50) return(0); /* no point in statistics on squibs */ 362 for(j=0; j<NASC; j++) 363 ct[j]=0; 364 for(j=0; j<n; j++) 365 { 366 if (bp[j]<NASC) 367 ct[bp[j]|040]++; 368 switch (bp[j]) 369 { 370 case '.': 371 case ',': 372 case ')': 373 case '%': 374 case ';': 375 case ':': 376 case '?': 377 punct++; 378 if ( j < n-1 && 379 bp[j+1] != ' ' && 380 bp[j+1] != '\n') 381 badpun++; 382 } 383 } 384 if (badpun*5 > punct) 385 return(0); 386 vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u']; 387 freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n']; 388 rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z']; 389 if (2*ct[';'] > ct['e']) return(0); 390 if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */ 391 return (vow*5 >= n-ct[' '] && freq >= 10*rare); 392 } 393