home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  5.9 KB  |  322 lines

  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. }
  322.