1*6719Smckusick static char sccsid[] = "@(#)file.c 4.4 (Berkeley) 4.4"; 2613Sbill /* 3613Sbill * file - determine type of file 4613Sbill */ 5613Sbill 6613Sbill #include <pagsiz.h> 7613Sbill #include <sys/types.h> 8613Sbill #include <stat.h> 9613Sbill #include <stdio.h> 10613Sbill #include <ctype.h> 11904Sbill #include <a.out.h> 12613Sbill int in; 13613Sbill int i = 0; 14613Sbill char buf[BUFSIZ]; 15613Sbill char *troff[] = { /* new troff intermediate lang */ 16613Sbill "x","T","res","init","font","202","V0","p1",0}; 17613Sbill char *fort[] = { 18613Sbill "function","subroutine","common","dimension","block","integer", 19613Sbill "real","data","double",0}; 20613Sbill char *asc[] = { 21613Sbill "chmk","mov","tst","clr","jmp",0}; 22613Sbill char *c[] = { 23613Sbill "int","char","float","double","struct","extern",0}; 24613Sbill char *as[] = { 25613Sbill "globl","byte","align","text","data","comm",0}; 26613Sbill int ifile; 27613Sbill 28613Sbill main(argc, argv) 29613Sbill char **argv; 30613Sbill { 31613Sbill FILE *fl; 32613Sbill register char *p; 33613Sbill char ap[128]; 34613Sbill extern char _sobuf[]; 35613Sbill 36613Sbill if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') { 37613Sbill if ((fl = fopen(argv[2], "r")) == NULL) { 38613Sbill printf("Can't open %s\n", argv[2]); 39613Sbill exit(2); 40613Sbill } 41613Sbill while ((p = fgets(ap, 128, fl)) != NULL) { 42613Sbill int l = strlen(p); 43613Sbill if (l>0) 44613Sbill p[l-1] = '\0'; 45613Sbill printf("%s: ", p); 46613Sbill type(p); 47613Sbill if (ifile>=0) 48613Sbill close(ifile); 49613Sbill } 50613Sbill exit(1); 51613Sbill } 52613Sbill while(argc > 1) { 53613Sbill printf("%s: ", argv[1]); 54613Sbill type(argv[1]); 55613Sbill fflush(stdout); 56613Sbill argc--; 57613Sbill argv++; 58613Sbill if (ifile >= 0) 59613Sbill close(ifile); 60613Sbill } 61613Sbill } 62613Sbill 63613Sbill type(file) 64613Sbill char *file; 65613Sbill { 66613Sbill int j,nl; 67613Sbill char ch; 68613Sbill struct stat mbuf; 69613Sbill 70613Sbill ifile = -1; 71*6719Smckusick if (lstat(file, &mbuf) < 0) { 72613Sbill printf("cannot stat\n"); 73613Sbill return; 74613Sbill } 75613Sbill switch (mbuf.st_mode & S_IFMT) { 76613Sbill 77613Sbill case S_IFCHR: 78613Sbill printf("character"); 79613Sbill goto spcl; 80613Sbill 81*6719Smckusick case S_IFLNK: 82*6719Smckusick printf("symbolic link\n"); 83*6719Smckusick return; 84*6719Smckusick 85613Sbill case S_IFDIR: 86613Sbill printf("directory\n"); 87613Sbill return; 88613Sbill 89613Sbill case S_IFBLK: 90613Sbill printf("block"); 91613Sbill 92613Sbill spcl: 93613Sbill printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev)); 94613Sbill return; 95613Sbill } 96613Sbill 97613Sbill ifile = open(file, 0); 98613Sbill if(ifile < 0) { 99613Sbill printf("cannot open\n"); 100613Sbill return; 101613Sbill } 102613Sbill in = read(ifile, buf, BUFSIZ); 103613Sbill if(in == 0){ 104613Sbill printf("empty\n"); 105613Sbill return; 106613Sbill } 107613Sbill switch(*(int *)buf) { 108613Sbill 109613Sbill case 0413: 110613Sbill printf("demand paged "); 111613Sbill 112613Sbill case 0410: 113613Sbill printf("pure "); 114613Sbill goto exec; 115613Sbill 116613Sbill case 0411: 117613Sbill printf("jfr or pdp-11 unix 411 executable\n"); 118613Sbill return; 119613Sbill 120613Sbill case 0407: 121613Sbill exec: 122613Sbill printf("executable"); 123613Sbill if(((int *)buf)[4] != 0) { 124613Sbill printf(" not stripped"); 125613Sbill if(oldo(buf)) 126613Sbill printf(" (old format symbol table)"); 127613Sbill } 128613Sbill printf("\n"); 129613Sbill goto out; 130613Sbill 131613Sbill case 0177555: 132613Sbill printf("very old archive\n"); 133613Sbill goto out; 134613Sbill 135613Sbill case 0177545: 136613Sbill printf("old archive\n"); 137613Sbill goto out; 138897Sbill 139897Sbill case 070707: 140897Sbill printf("cpio data\n"); 141897Sbill goto out; 142613Sbill } 143613Sbill 144613Sbill if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) { 145613Sbill printf("archive random library\n"); 146613Sbill goto out; 147613Sbill } 148613Sbill if (strncmp(buf, "!<arch>\n", 8)==0) { 149613Sbill printf("archive\n"); 150613Sbill goto out; 151613Sbill } 1525900Sroot if (mbuf.st_size % 512 == 0) { /* it may be a PRESS file */ 1535900Sroot lseek(ifile, -512L, 2); /* last block */ 1545900Sroot if (read(ifile, buf, BUFSIZ) > 0 1555900Sroot && *(short int *)buf == 12138) { 1565900Sroot printf("PRESS file\n"); 1575900Sroot goto out; 1585900Sroot } 1595900Sroot } 160613Sbill i = 0; 161613Sbill if(ccom() == 0)goto notc; 162613Sbill while(buf[i] == '#'){ 163613Sbill j = i; 164613Sbill while(buf[i++] != '\n'){ 165613Sbill if(i - j > 255){ 166613Sbill printf("data\n"); 167613Sbill goto out; 168613Sbill } 169613Sbill if(i >= in)goto notc; 170613Sbill } 171613Sbill if(ccom() == 0)goto notc; 172613Sbill } 173613Sbill check: 174613Sbill if(lookup(c) == 1){ 175613Sbill while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc; 176613Sbill printf("c program text"); 177613Sbill goto outa; 178613Sbill } 179613Sbill nl = 0; 180613Sbill while(buf[i] != '('){ 181613Sbill if(buf[i] <= 0) 182613Sbill goto notas; 183613Sbill if(buf[i] == ';'){ 184613Sbill i++; 185613Sbill goto check; 186613Sbill } 187613Sbill if(buf[i++] == '\n') 188613Sbill if(nl++ > 6)goto notc; 189613Sbill if(i >= in)goto notc; 190613Sbill } 191613Sbill while(buf[i] != ')'){ 192613Sbill if(buf[i++] == '\n') 193613Sbill if(nl++ > 6)goto notc; 194613Sbill if(i >= in)goto notc; 195613Sbill } 196613Sbill while(buf[i] != '{'){ 197613Sbill if(buf[i++] == '\n') 198613Sbill if(nl++ > 6)goto notc; 199613Sbill if(i >= in)goto notc; 200613Sbill } 201613Sbill printf("c program text"); 202613Sbill goto outa; 203613Sbill notc: 204613Sbill i = 0; 205613Sbill while(buf[i] == 'c' || buf[i] == '#'){ 206613Sbill while(buf[i++] != '\n')if(i >= in)goto notfort; 207613Sbill } 208613Sbill if(lookup(fort) == 1){ 209613Sbill printf("fortran program text"); 210613Sbill goto outa; 211613Sbill } 212613Sbill notfort: 213613Sbill i=0; 214613Sbill if(ascom() == 0)goto notas; 215613Sbill j = i-1; 216613Sbill if(buf[i] == '.'){ 217613Sbill i++; 218613Sbill if(lookup(as) == 1){ 219613Sbill printf("assembler program text"); 220613Sbill goto outa; 221613Sbill } 222613Sbill else if(buf[j] == '\n' && isalpha(buf[j+2])){ 223613Sbill printf("roff, nroff, or eqn input text"); 224613Sbill goto outa; 225613Sbill } 226613Sbill } 227613Sbill while(lookup(asc) == 0){ 228613Sbill if(ascom() == 0)goto notas; 229613Sbill while(buf[i] != '\n' && buf[i++] != ':') 230613Sbill if(i >= in)goto notas; 231613Sbill while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas; 232613Sbill j = i-1; 233613Sbill if(buf[i] == '.'){ 234613Sbill i++; 235613Sbill if(lookup(as) == 1){ 236613Sbill printf("assembler program text"); 237613Sbill goto outa; 238613Sbill } 239613Sbill else if(buf[j] == '\n' && isalpha(buf[j+2])){ 240613Sbill printf("roff, nroff, or eqn input text"); 241613Sbill goto outa; 242613Sbill } 243613Sbill } 244613Sbill } 245613Sbill printf("assembler program text"); 246613Sbill goto outa; 247613Sbill notas: 248613Sbill for(i=0; i < in; i++)if(buf[i]&0200){ 249613Sbill if (buf[0]=='\100' && buf[1]=='\357') { 250613Sbill printf("troff (CAT) output\n"); 251613Sbill goto out; 252613Sbill } 253613Sbill printf("data\n"); 254613Sbill goto out; 255613Sbill } 256613Sbill if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6))) 257613Sbill printf("commands text"); 258613Sbill else if (troffint(buf, in)) 259613Sbill printf("troff intermediate output text"); 260613Sbill else if (english(buf, in)) 261613Sbill printf("English text"); 262613Sbill else 263613Sbill printf("ascii text"); 264613Sbill outa: 265613Sbill while(i < in) 266613Sbill if((buf[i++]&0377) > 127){ 267613Sbill printf(" with garbage\n"); 268613Sbill goto out; 269613Sbill } 270613Sbill /* if next few lines in then read whole file looking for nulls ... 271613Sbill while((in = read(ifile,buf,BUFSIZ)) > 0) 272613Sbill for(i = 0; i < in; i++) 273613Sbill if((buf[i]&0377) > 127){ 274613Sbill printf(" with garbage\n"); 275613Sbill goto out; 276613Sbill } 277613Sbill /*.... */ 278613Sbill printf("\n"); 279613Sbill out:; 280613Sbill } 281613Sbill 282613Sbill oldo(cp) 283613Sbill char *cp; 284613Sbill { 285613Sbill struct exec ex; 286613Sbill struct stat stb; 287613Sbill 288613Sbill ex = *(struct exec *)cp; 289613Sbill if (fstat(ifile, &stb) < 0) 290613Sbill return(0); 291613Sbill if (N_STROFF(ex)+sizeof(off_t) > stb.st_size) 292613Sbill return (1); 293613Sbill return (0); 294613Sbill } 295613Sbill 296613Sbill 297613Sbill 298613Sbill troffint(bp, n) 299613Sbill char *bp; 300613Sbill int n; 301613Sbill { 302613Sbill int k; 303613Sbill 304613Sbill i = 0; 305613Sbill for (k = 0; k < 6; k++) { 306613Sbill if (lookup(troff) == 0) 307613Sbill return(0); 308613Sbill if (lookup(troff) == 0) 309613Sbill return(0); 310613Sbill while (i < n && buf[i] != '\n') 311613Sbill i++; 312613Sbill if (i++ >= n) 313613Sbill return(0); 314613Sbill } 315613Sbill return(1); 316613Sbill } 317613Sbill lookup(tab) 318613Sbill char *tab[]; 319613Sbill { 320613Sbill char r; 321613Sbill int k,j,l; 322613Sbill while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++; 323613Sbill for(j=0; tab[j] != 0; j++){ 324613Sbill l=0; 325613Sbill for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++); 326613Sbill if(r == '\0') 327613Sbill if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t' 328613Sbill || buf[k] == '{' || buf[k] == '/'){ 329613Sbill i=k; 330613Sbill return(1); 331613Sbill } 332613Sbill } 333613Sbill return(0); 334613Sbill } 335613Sbill ccom(){ 336613Sbill char cc; 337613Sbill while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0); 338613Sbill if(buf[i] == '/' && buf[i+1] == '*'){ 339613Sbill i += 2; 340613Sbill while(buf[i] != '*' || buf[i+1] != '/'){ 341613Sbill if(buf[i] == '\\')i += 2; 342613Sbill else i++; 343613Sbill if(i >= in)return(0); 344613Sbill } 345613Sbill if((i += 2) >= in)return(0); 346613Sbill } 347613Sbill if(buf[i] == '\n')if(ccom() == 0)return(0); 348613Sbill return(1); 349613Sbill } 350613Sbill ascom(){ 351613Sbill while(buf[i] == '/'){ 352613Sbill i++; 353613Sbill while(buf[i++] != '\n')if(i >= in)return(0); 354613Sbill while(buf[i] == '\n')if(i++ >= in)return(0); 355613Sbill } 356613Sbill return(1); 357613Sbill } 358613Sbill 359613Sbill english (bp, n) 360613Sbill char *bp; 361613Sbill { 362613Sbill # define NASC 128 363613Sbill int ct[NASC], j, vow, freq, rare; 364613Sbill int badpun = 0, punct = 0; 365613Sbill if (n<50) return(0); /* no point in statistics on squibs */ 366613Sbill for(j=0; j<NASC; j++) 367613Sbill ct[j]=0; 368613Sbill for(j=0; j<n; j++) 369613Sbill { 370613Sbill if (bp[j]<NASC) 371613Sbill ct[bp[j]|040]++; 372613Sbill switch (bp[j]) 373613Sbill { 374613Sbill case '.': 375613Sbill case ',': 376613Sbill case ')': 377613Sbill case '%': 378613Sbill case ';': 379613Sbill case ':': 380613Sbill case '?': 381613Sbill punct++; 382613Sbill if ( j < n-1 && 383613Sbill bp[j+1] != ' ' && 384613Sbill bp[j+1] != '\n') 385613Sbill badpun++; 386613Sbill } 387613Sbill } 388613Sbill if (badpun*5 > punct) 389613Sbill return(0); 390613Sbill vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u']; 391613Sbill freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n']; 392613Sbill rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z']; 393613Sbill if (2*ct[';'] > ct['e']) return(0); 394613Sbill if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */ 395613Sbill return (vow*5 >= n-ct[' '] && freq >= 10*rare); 396613Sbill } 397