# 2.11BSD#431 - /usr/src/usr.bin/file.c

##### Functions

    ascom             X
    ccom              X
    english           X
    lookup            X
    main              X
    shell             X
    shellscript       X
    troffint          X
    type              X

##### Variables

    as                X
    asc               X
    buf               X
    c                 X
    csh               X
    fort              X
    i                 X
    ifile             X
    in                X
    sh                X
    troff             X

##### Macros

    NASC              X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static  char sccsid[] = "@(#)file.c	4.12.3 (2.11BSD) 1997/7/29";
       3: #endif
       4: /*
       5:  * file - determine type of file
       6:  */
       7:
       8: #include <sys/param.h>
       9: #include <sys/stat.h>
      10: #include <stdio.h>
      11: #include <ctype.h>
      12: #include <a.out.h>
      13: #include <errno.h>
      14: #include <string.h>
      15:
      16: int in;
      17: int i  = 0;
      18: char buf[BUFSIZ];
      19: char *troff[] = {   /* new troff intermediate lang */
      20:     "x","T","res","init","font","202","V0","p1",0};
      21: char *fort[] = {
      22:     "function","subroutine","common","dimension","block","integer",
      23:     "real","data","double",0};
      24: char *asc[] = {
      25:     "sys","mov","tst","clr","jmp",0};
      26: char *c[] = {
      27:     "int","char","float","double","struct","extern",0};
      28: char *as[] = {
      29:     "globl","byte","align","text","data","comm",0};
      30: char *sh[] = {
      31:     "fi", "elif", "esac", "done", "export",
      32:     "readonly", "trap", "PATH", "HOME", 0 };
      33: char *csh[] = {
      34:     "alias", "breaksw", "endsw", "foreach", "limit",  "onintr",
      35:     "repeat", "setenv", "source", "path", "home", 0 };
      36: int ifile;
      37:
      38: main(argc, argv)
      39: char **argv;
      40: {
      41:     register FILE *fl;
      42:     register char *p;
      43:     char ap[MAXPATHLEN + 1];
      44:
      45:     if (argc < 2) {
      46:         fprintf(stderr, "usage: %s file ...\n", argv[0]);
      47:         exit(3);
      48:     }
      49:
      50:     if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
      51:         if ((fl = fopen(argv[2], "r")) == NULL) {
      52:             perror(argv[2]);
      53:             exit(2);
      54:         }
      55:         while ((p = fgets(ap, sizeof ap, fl)) != NULL) {
      56:             int l = strlen(p);
      57:             if (l>0)
      58:                 p[l-1] = '\0';
      59:             printf("%s:	", p);
      60:             type(p);
      61:             if (ifile>=0)
      62:                 close(ifile);
      63:         }
      64:         exit(1);
      65:     }
      66:     while(argc > 1) {
      67:         printf("%s:	", argv[1]);
      68:         type(argv[1]);
      69:         fflush(stdout);
      70:         argc--;
      71:         argv++;
      72:         if (ifile >= 0)
      73:             close(ifile);
      74:     }
      75:     exit(0);
      76: }
      77:
      78: type(file)
      79: char *file;
      80: {
      81:     register int j;
      82:     int nl;
      83:     char ch;
      84:     struct stat mbuf;
      85:     char slink[MAXPATHLEN + 1];
      86:
      87:     ifile = -1;
      88:     if (lstat(file, &mbuf) < 0) {
      89:         printf("%s\n", strerror(errno));
      90:         return;
      91:     }
      92:     switch (mbuf.st_mode & S_IFMT) {
      93:
      94:     case S_IFLNK:
      95:         printf("symbolic link");
      96:         j = readlink(file, slink, sizeof slink - 1);
      97:         if (j >= 0) {
      98:             slink[j] = '\0';
      99:             printf(" to %s", slink);
     100:         }
     101:         printf("\n");
     102:         return;
     103:
     104:     case S_IFDIR:
     105:         if (mbuf.st_mode & S_ISVTX)
     106:             printf("append-only ");
     107:         printf("directory\n");
     108:         return;
     109:
     110:     case S_IFCHR:
     111:     case S_IFBLK:
     112:         printf("%s special (%d/%d)\n",
     113:             (mbuf.st_mode&S_IFMT) == S_IFCHR ? "character" : "block",
     114:              major(mbuf.st_rdev), minor(mbuf.st_rdev));
     115:         return;
     116:
     117:     case S_IFSOCK:
     118:         printf("socket\n");
     119:         return;
     120:     }
     121:
     122:     ifile = open(file, 0);
     123:     if(ifile < 0) {
     124:         printf("%s\n", strerror(errno));
     125:         return;
     126:     }
     127:     in = read(ifile, buf, BUFSIZ);
     128:     if(in == 0){
     129:         printf("empty\n");
     130:         return;
     131:     }
     132:     switch(*(int *)buf) {
     133:
     134:     case 0413:
     135:         printf("demand paged ");
     136:
     137:     case 0410:
     138:         printf("pure ");
     139:         goto exec;
     140:
     141:     case 0411:
     142:         printf("separate ");
     143:         goto exec;
     144:
     145:     case A_MAGIC4:
     146:         printf("replacement text ");
     147:         goto exec;
     148:
     149:     case A_MAGIC5:
     150:         printf("overlaid pure ");
     151:         goto exec;
     152:
     153:     case A_MAGIC6:
     154:         printf("overlaid separate ");
     155:         goto exec;
     156:
     157:     case 0407:
     158: exec:
     159:         if (mbuf.st_mode & S_ISUID)
     160:             printf("set-uid ");
     161:         if (mbuf.st_mode & S_ISGID)
     162:             printf("set-gid ");
     163:         if (mbuf.st_mode & S_ISVTX)
     164:             printf("sticky ");
     165:         printf("executable");
     166:         if(((int *)buf)[4] != 0)
     167:             printf(" not stripped");
     168:         if (((int *)buf)[1] == 0 && ((int *)buf)[2] != 0 &&
     169:             ((int *)buf)[3] == 0)
     170:             printf(" (likely vax)");
     171:         printf("\n");
     172:         return;
     173:
     174:     case 0177555:
     175:         printf("very old archive\n");
     176:         return;
     177:
     178:     case 0177545:
     179:         printf("old archive\n");
     180:         return;
     181:
     182:     case 070707:
     183:         printf("cpio data\n");
     184:         return;
     185:     }
     186:
     187:     if (buf[0] == '#' && buf[1] == '!' && shellscript(buf+2, &mbuf))
     188:         return;
     189:     if (buf[0] == '\037' && buf[1] == '\235') {
     190:         if (buf[2]&0x80)
     191:             printf("block ");
     192:         printf("compressed %d bit code data\n", buf[2]&0x1f);
     193:         return;
     194:     }
     195:     if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) {
     196:         printf("archive random library\n");
     197:         return;
     198:     }
     199:     if (strncmp(buf, "!<arch>\n", 8)==0) {
     200:         printf("archive\n");
     201:         return;
     202:     }
     203:     if (mbuf.st_size % 512 == 0) {  /* it may be a PRESS file */
     204:         lseek(ifile, -512L, 2); /* last block */
     205:         if (read(ifile, buf, BUFSIZ) > 0 && *(short *)buf == 12138) {
     206:             printf("PRESS file\n");
     207:             return;
     208:         }
     209:     }
     210:     i = 0;
     211:     if(ccom() == 0)goto notc;
     212:     while(buf[i] == '#'){
     213:         j = i;
     214:         while(buf[i++] != '\n'){
     215:             if(i - j > 255){
     216:                 printf("data\n");
     217:                 return;
     218:             }
     219:             if(i >= in)goto notc;
     220:         }
     221:         if(ccom() == 0)goto notc;
     222:     }
     223: check:
     224:     if(lookup(c) == 1){
     225:         while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
     226:         printf("c program text");
     227:         goto outa;
     228:     }
     229:     nl = 0;
     230:     while(buf[i] != '('){
     231:         if(buf[i] <= 0)
     232:             goto notas;
     233:         if(buf[i] == ';'){
     234:             i++;
     235:             goto check;
     236:         }
     237:         if(buf[i++] == '\n')
     238:             if(nl++ > 6)goto notc;
     239:         if(i >= in)goto notc;
     240:     }
     241:     while(buf[i] != ')'){
     242:         if(buf[i++] == '\n')
     243:             if(nl++ > 6)goto notc;
     244:         if(i >= in)goto notc;
     245:     }
     246:     while(buf[i] != '{'){
     247:         if(buf[i++] == '\n')
     248:             if(nl++ > 6)goto notc;
     249:         if(i >= in)goto notc;
     250:     }
     251:     printf("c program text");
     252:     goto outa;
     253: notc:
     254:     i = 0;
     255:     while(buf[i] == 'c' || buf[i] == '#'){
     256:         while(buf[i++] != '\n')if(i >= in)goto notfort;
     257:     }
     258:     if(lookup(fort) == 1){
     259:         printf("fortran program text");
     260:         goto outa;
     261:     }
     262: notfort:
     263:     i=0;
     264:     if(ascom() == 0)goto notas;
     265:     j = i-1;
     266:     if(buf[i] == '.'){
     267:         i++;
     268:         if(lookup(as) == 1){
     269:             printf("assembler program text");
     270:             goto outa;
     271:         }
     272:         else if(buf[j] == '\n' && isalpha(buf[j+2])){
     273:             printf("roff, nroff, or eqn input text");
     274:             goto outa;
     275:         }
     276:     }
     277:     while(lookup(asc) == 0){
     278:         if(ascom() == 0)goto notas;
     279:         while(buf[i] != '\n' && buf[i++] != ':')
     280:             if(i >= in)goto notas;
     281:         while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
     282:         j = i-1;
     283:         if(buf[i] == '.'){
     284:             i++;
     285:             if(lookup(as) == 1){
     286:                 printf("assembler program text");
     287:                 goto outa;
     288:             }
     289:             else if(buf[j] == '\n' && isalpha(buf[j+2])){
     290:                 printf("roff, nroff, or eqn input text");
     291:                 goto outa;
     292:             }
     293:         }
     294:     }
     295:     printf("assembler program text");
     296:     goto outa;
     297: notas:
     298:     for(i=0; i < in; i++)if(buf[i]&0200){
     299:         if (buf[0]=='\100' && buf[1]=='\357')
     300:             printf("troff (CAT) output\n");
     301:         else
     302:             printf("data\n");
     303:         return;
     304:     }
     305:     if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6))) {
     306:         if (mbuf.st_mode & S_ISUID)
     307:             printf("set-uid ");
     308:         if (mbuf.st_mode & S_ISGID)
     309:             printf("set-gid ");
     310:         if (mbuf.st_mode & S_ISVTX)
     311:             printf("sticky ");
     312:         if (shell(buf, in, sh))
     313:             printf("shell script");
     314:         else if (shell(buf, in, csh))
     315:             printf("c-shell script");
     316:         else
     317:             printf("commands text");
     318:     } else if (troffint(buf, in))
     319:         printf("troff intermediate output text");
     320:     else if (shell(buf, in, sh))
     321:         printf("shell commands");
     322:     else if (shell(buf, in, csh))
     323:         printf("c-shell commands");
     324:     else if (english(buf, in))
     325:         printf("English text");
     326:     else
     327:         printf("ascii text");
     328: outa:
     329:     while(i < in)
     330:         if((buf[i++]&0377) > 127){
     331:             printf(" with garbage\n");
     332:             return;
     333:         }
     334:     /* if next few lines in then read whole file looking for nulls ...
     335: 		while((in = read(ifile,buf,BUFSIZ)) > 0)
     336: 			for(i = 0; i < in; i++)
     337: 				if((buf[i]&0377) > 127){
     338: 					printf(" with garbage\n");
     339: 					return;
     340: 				}
     341: 		/*.... */
     342:     printf("\n");
     343: }
     344:
     345: troffint(bp, n)
     346: char *bp;
     347: int n;
     348: {
     349:     int k;
     350:
     351:     i = 0;
     352:     for (k = 0; k < 6; k++) {
     353:         if (lookup(troff) == 0)
     354:             return(0);
     355:         if (lookup(troff) == 0)
     356:             return(0);
     357:         while (i < n && buf[i] != '\n')
     358:             i++;
     359:         if (i++ >= n)
     360:             return(0);
     361:     }
     362:     return(1);
     363: }
     364: lookup(tab)
     365: char *tab[];
     366: {
     367:     char r;
     368:     int k,j,l;
     369:     while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
     370:     for(j=0; tab[j] != 0; j++){
     371:         l=0;
     372:         for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
     373:         if(r == '\0')
     374:             if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
     375:                 || buf[k] == '{' || buf[k] == '/'){
     376:                 i=k;
     377:                 return(1);
     378:             }
     379:     }
     380:     return(0);
     381: }
     382: ccom(){
     383:     char cc;
     384:     while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
     385:     if(buf[i] == '/' && buf[i+1] == '*'){
     386:         i += 2;
     387:         while(buf[i] != '*' || buf[i+1] != '/'){
     388:             if(buf[i] == '\\')i += 2;
     389:             else i++;
     390:             if(i >= in)return(0);
     391:         }
     392:         if((i += 2) >= in)return(0);
     393:     }
     394:     if(buf[i] == '\n')if(ccom() == 0)return(0);
     395:     return(1);
     396: }
     397: ascom(){
     398:     while(buf[i] == '/'){
     399:         i++;
     400:         while(buf[i++] != '\n')if(i >= in)return(0);
     401:         while(buf[i] == '\n')if(i++ >= in)return(0);
     402:     }
     403:     return(1);
     404: }
     405:
     406: english (bp, n)
     407: char *bp;
     408: {
     409: # define NASC 128
     410:     int ct[NASC], j, vow, freq, rare;
     411:     int badpun = 0, punct = 0;
     412:     if (n<50) return(0); /* no point in statistics on squibs */
     413:     for(j=0; j<NASC; j++)
     414:         ct[j]=0;
     415:     for(j=0; j<n; j++)
     416:     {
     417:         if (bp[j]<NASC)
     418:             ct[bp[j]|040]++;
     419:         switch (bp[j])
     420:         {
     421:         case '.':
     422:         case ',':
     423:         case ')':
     424:         case '%':
     425:         case ';':
     426:         case ':':
     427:         case '?':
     428:             punct++;
     429:             if ( j < n-1 &&
     430:                 bp[j+1] != ' ' &&
     431:                 bp[j+1] != '\n')
     432:                 badpun++;
     433:         }
     434:     }
     435:     if (badpun*5 > punct)
     436:         return(0);
     437:     vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
     438:     freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
     439:     rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
     440:     if (2*ct[';'] > ct['e']) return(0);
     441:     if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
     442:     return (vow*5 >= n-ct[' '] && freq >= 10*rare);
     443: }
     444:
     445: shellscript(buf, sb)
     446:     char buf[];
     447:     struct stat *sb;
     448: {
     449:     register char *tp;
     450:     char *cp, *xp, *index();
     451:
     452:     cp = index(buf, '\n');
     453:     if (cp == 0 || cp - buf > in)
     454:         return (0);
     455:     for (tp = buf; tp != cp && isspace(*tp); tp++)
     456:         if (!isascii(*tp))
     457:             return (0);
     458:     for (xp = tp; tp != cp && !isspace(*tp); tp++)
     459:         if (!isascii(*tp))
     460:             return (0);
     461:     if (tp == xp)
     462:         return (0);
     463:     if (sb->st_mode & S_ISUID)
     464:         printf("set-uid ");
     465:     if (sb->st_mode & S_ISGID)
     466:         printf("set-gid ");
     467:     if (strncmp(xp, "/bin/sh", tp-xp) == 0)
     468:         xp = "shell";
     469:     else if (strncmp(xp, "/bin/csh", tp-xp) == 0)
     470:         xp = "c-shell";
     471:     else
     472:         *tp = '\0';
     473:     printf("executable %s script\n", xp);
     474:     return (1);
     475: }
     476:
     477: shell(bp, n, tab)
     478:     char *bp;
     479:     int n;
     480:     char *tab[];
     481: {
     482:
     483:     i = 0;
     484:     do {
     485:         if (buf[i] == '#' || buf[i] == ':')
     486:             while (i < n && buf[i] != '\n')
     487:                 i++;
     488:         if (++i >= n)
     489:             break;
     490:         if (lookup(tab) == 1)
     491:             return (1);
     492:     } while (i < n);
     493:     return (0);
     494: }

#### Defined functions

ascom defined in line 397; used 2 times

- in line 264, 278

ccom defined in line 382; used 3 times

- in line 211, 221, 394

english defined in line 406; used 1 times

- in line 324

lookup defined in line 364; used 8 times

- in line 224, 258, 268, 277, 285, 353-355(2), 490

main defined in line 38; never used
shell defined in line 477; used 4 times

- in line 312-314(2), 320-322(2)

shellscript defined in line 445; used 1 times

- in line 187

troffint defined in line 345; used 1 times

- in line 318

type defined in line 78; used 2 times

- in line 60, 68

#### Defined variables

as defined in line 28; used 2 times

- in line 268, 285

asc defined in line 24; used 1 times

- in line 277

buf defined in line 18; used 80 times

- in line 127-132(2), 166-169(4), 187-199(9), 205(2), 212-214(2), 225-247(9), 255-256(3), 266, 272(2), 279-283(6), 289(2), 298-299(3), 312-324(6), 330, 357, 369-375(9), 384-388(6), 394-401(4), 445-446(2), 452-455(3), 485-486(3)

c defined in line 26; used 1 times

- in line 224

csh defined in line 33; used 2 times

- in line 314, 322

fort defined in line 21; used 1 times

- in line 258

i defined in line 17; used 83 times

- in line 210-219(6), 225-256(19), 263-267(4), 279-284(10), 298(4), 329-330(2), 351, 357-359(4), 369-376(6), 384-401(19), 483-492(8)

ifile defined in line 36; used 10 times

- in line 61-62(2), 72-73(2), 87, 122-127(3), 204-205(2)

in defined in line 16; used 24 times

- in line 127-128(2), 219, 225, 239-249(3), 256, 280-281(2), 298, 312-329(7), 384, 390-392(2), 400-401(2), 453

sccsid defined in line 2; never used
sh defined in line 30; used 2 times

- in line 312, 320

troff defined in line 19; used 2 times

- in line 353-355(2)

#### Defined macros

NASC defined in line 409; used 3 times

- in line 410-417(3)

Last modified: 1997-07-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1645 |