home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 278.lha / File_v1.0 / file.c (.txt) < prev    next >
LaTeX Document  |  1989-08-08  |  9KB  |  254 lines

  1.  * file v1.0 - a Unix-like utility to determine the type of a file
  2.  * Copyright 1989 Edwin Hoogerbeets
  3.  * This code is freely redistributable as long as no charge other than
  4.  * reasonable copying fees is levied for it.
  5.  * Usage: file file [file ...]
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <libraries/dosextens.h>
  9. #include <exec/memory.h>
  10. #define toint(a) (int)((a) - '0')
  11. #define BLOCKSIZE 484L              /* almost size of one disk block */
  12. typedef struct asdf {
  13.   int  length;
  14.   char *name;
  15.   char *pattern;
  16. } pattern;
  17. /* for binary files that start with a magic number */
  18. pattern bmagic[] = {
  19.   4,"Amiga load file",                "\x00\x00\x03\xf3",
  20.   4,"Amiga object file",              "\x00\x00\x03\xe7",
  21.   2,"Amiga run-time library",         "\xec\x62",
  22.   2,"Manx 3.6 run-time library",      "\x61\x6a",
  23.   2,"Manx 3.6 object file",           "\x41\x4a",
  24.   2,"Manx 3.4 object file",           "\x6a\x67",
  25.   27,"TeX device independent output file",
  26.                                       "\xf7\x02\x01\x83\x92\xc0"
  27.                                       "\x1c\x3b\x00\x00\x00\x00"
  28.                                       "\x03\xe8\x1b\x20\x54\x65"
  29.                                       "\x58\x20\x6f\x75\x74\x70"
  30.                                       "\x75\x74\x20",
  31.   2,"Amiga icon .info file",          "\xe3\x10",
  32.   4,"Amiga .info file",               "\xf3\x4c\x00\x12",
  33.   2,"Amiga .font file",               "\x0f\x00",
  34.   2,"SEA ARC compressed archive",     "\x1a\x08",
  35.   NULL, NULL, NULL,
  36. /* for ascii files that start with a magic number */
  37. pattern amagic[] = {
  38.   2, "shell script file",             "#!",
  39.   2, "ARexx script file",             "/*",
  40.   4, "execute script file",           ".key",
  41.   4, "execute script file",           ".bra",
  42.   4, "execute script file",           ".ket",
  43.   NULL, NULL, NULL,
  44. /* patterns to search for in ascii files */
  45. pattern asearch[] = {
  46.   14,"LaTeX source code",            "\\documentstyle",
  47.   6, "TeX source code",              "\n\\",
  48.   4, "C source code",                "int ",
  49.   5, "C source code",                "\n#inc",
  50.   5, "C source code",                "\n#def",
  51.   2, "C source code",                "{\n",
  52.   21,"Modula II source code",        "IMPLEMENTATION MODULE",
  53.   17,"Modula II source code",        "DEFINITION MODULE",
  54.   5, "execute script file",          "\n.key",
  55.   5, "execute script file",          "\n.bra",
  56.   5, "execute script file",          "\n.ket",
  57.   1, "yacc input file",              "\n%TOKEN",
  58.   1, "yacc or lex input file",       "\n%%",
  59.   1, "shell commands",               "\nalias",
  60.   1, "shell commands",               "\nAlias",
  61.   1, "shell commands",               "\nset",
  62.   1, "commands text",                "\nrun",
  63.   1, "commands text",                "\nRun",
  64.   1, "uuencoded file",               "\nbegin ",
  65.   NULL, NULL, NULL,
  66. pattern IFFforms[] = {
  67.   4,"IFF interleave bit map file",        "ILBM",
  68.   4,"IFF Amiga compressed bit map files", "ACBM",
  69.   4,"IFF anim format file",               "ANIM",
  70.   4,"IFF instrument file",                "8SVX",
  71.   4,"IFF simple music file",              "SMUS",
  72.   NULL, NULL, NULL,
  73. pattern compress = {
  74.   2,"block compressed %d bit code data",  "\x1f\x9d",
  75. pattern zoo = {
  76.   4,"Zoo archive",                        "ZOO ",
  77. int type(ty,name)
  78. char *ty,*name;
  79.   printf("%-16s %s\n",name,ty);
  80. int memncmp(a,b,length)
  81. char *a, *b;
  82. int length;
  83.   register int index;
  84.   for ( index = 0; index < length; index++ ) {
  85.     if ( a[index] != b[index] ) {
  86.       return(a[index] > b[index] ? -1 : 1);
  87.     }
  88.   return(0);
  89. char *strrpbrk(str, charset)
  90. register char *str, *charset;
  91.   register char *temp;
  92.   extern char *index();
  93.   temp = str + strlen(str) - 1;
  94.   while ( temp != (str - 1)  && !index(charset, *temp) )
  95.     --temp;
  96.   return( (temp != (str - 1)) ? temp : NULL);
  97. char *basename(buf)
  98. register char *buf;
  99.   register char *foo = strrpbrk(buf,":/");
  100.   return( foo ? (foo + 1) : buf );
  101. usage(name)
  102. char *name;
  103.   printf("usage: %s file [file ...]\n",name);
  104.   exit(-1);
  105. main(argc,argv)
  106. int argc;
  107. char **argv;
  108.   register int index;
  109.   register char *myname;
  110.   /* if there are no arguments, take from the stdin */
  111.   if ( argc <= 1 ) {
  112.     usage(argv[0]);
  113.   myname = basename(argv[0]);
  114.   for ( index = 1 ; index < argc ; index++ ) {
  115.     filetype(myname,argv[index]);
  116. #define FIBSIZE (long) sizeof(struct FileInfoBlock)
  117. extern char *AllocMem();
  118. extern struct FileLock *Lock();
  119. /* find whether file is directory or real file */
  120. filetype(myname,filename)
  121. char *myname, *filename;
  122.   struct FileLock *lock;
  123.   struct FileInfoBlock *fib;
  124.   if ( lock = Lock(filename,ACCESS_READ) ) {
  125.     if ( fib = (struct FileInfoBlock *) AllocMem(FIBSIZE,MEMF_CLEAR) ) {
  126.       Examine(lock,fib);
  127.       dofile(myname,filename,fib);
  128.       UnLock(lock);
  129.       FreeMem(fib,FIBSIZE);
  130.     } else {
  131.       UnLock(lock);
  132.       fprintf(stderr,"%s: not enough memory!\n",myname,filename);
  133.       exit(-1);
  134.     }
  135.   } else {
  136.     fprintf(stderr,"%s: could not access file %s\n",myname,filename);
  137. /* find what type of file filename is */
  138. int dofile(myname,filename,fib)
  139. char *myname, *filename;
  140. struct FileInfoBlock *fib;
  141.   register char *f = &fib->fib_FileName[0];
  142.   if ( fib->fib_DirEntryType > 0 ) {
  143.     type("directory",f);
  144.   } else if ( fib->fib_Size == 0 ) {
  145.     type("empty",f);
  146.   } else {
  147.     char *buf;
  148.     long filehandle;
  149.     if ( !(filehandle = Open(filename,MODE_OLDFILE)) ) {
  150.       fprintf(stderr,"%s: could not open file %s\n",myname,filename);
  151.       return(0);
  152.     }
  153.     if ( !(buf = AllocMem(BLOCKSIZE+1,MEMF_PUBLIC)) ) {
  154.       fprintf(stderr,"%s: not enough memory\n",myname);
  155.       Close(filehandle);
  156.       return(0);
  157.     }
  158.     if ( !Read(filehandle,buf,BLOCKSIZE) ) {
  159.       fprintf(stderr,"%s: read error on file %s\n",myname,f);
  160.       FreeMem(buf,BLOCKSIZE+1);
  161.       Close(filehandle);
  162.       return(0);
  163.     }
  164.     matchtype(myname,buf,f,fib);
  165.     Close(filehandle);
  166.     FreeMem(buf,BLOCKSIZE+1);
  167.   return(0);
  168. int isasciifile(buf,len)
  169. char *buf;
  170. int len;
  171.   register int index, flag = 1;
  172.   for ( index = 0; index < len ; index++ ) {
  173.     if ( !isprint(buf[index]) && !isspace(buf[index]) ) {
  174.       flag = 0;
  175.       break;
  176.     }
  177.   return(flag);
  178. matchtype(myname,buf,file, fib)
  179. char *myname, *buf, *file;
  180. struct FileInfoBlock *fib;
  181.   register int index;
  182.   int len = (fib->fib_Size < BLOCKSIZE) ? fib->fib_Size : BLOCKSIZE;
  183.   if ( isasciifile(buf,len) ) {
  184.     index = 0;
  185.     /* check magic numbers */
  186.     while ( asearch[index].length ) {
  187.       if ( search(asearch[index].pattern,buf,len) ) {
  188.         type(asearch[index].name,file);
  189.         return(0);
  190.       }
  191.       ++index;
  192.     }
  193.     index = 0;
  194.     /* check magic numbers */
  195.     while ( amagic[index].length ) {
  196.       if ( !memncmp(amagic[index].pattern,buf,amagic[index].length) ) {
  197.         type(amagic[index].name,file);
  198.         return(0);
  199.       }
  200.       ++index;
  201.     }
  202.     /* check script bit */
  203.     if ( fib->fib_Protection & (1<<6) ) {
  204.       type("script file",file);
  205.       return(0);
  206.     }
  207.     type("text",file);
  208.   } else {
  209.     index = 0;
  210.     /* check magic numbers */
  211.     while ( bmagic[index].length ) {
  212.       if ( !memncmp(bmagic[index].pattern,buf,bmagic[index].length) ) {
  213.         type(bmagic[index].name,file);
  214.         return(0);
  215.       }
  216.       ++index;
  217.     }
  218.     /* check for IFF forms -- assume FORM is first header block */
  219.     if ( !memncmp("FORM",buf,4) ) {
  220.       char buffer[40];
  221.       index = 0;
  222.       buffer[0] = '\0';
  223.       while ( IFFforms[index].length ) {
  224.         if ( !memncmp(IFFforms[index].pattern,&buf[8],IFFforms[index].length) ) {
  225.           type(IFFforms[index].name,file);
  226.           return(0);
  227.         }
  228.         ++index;
  229.       }
  230.       sprintf(buffer,"IFF form %c%c%c%c",buf[8],buf[9],buf[10],buf[11]);
  231.       type(buffer,file);
  232.       return(0);
  233.     }
  234.     if ( !memncmp(compress.pattern,buf,compress.length) ) {
  235.       char buffer[40];
  236.       sprintf(buffer,compress.name,buf[2]&0x0f);
  237.       type(buffer,file);
  238.       return(0);
  239.     }
  240.     if ( !memncmp(zoo.pattern,buf,zoo.length) ) {
  241.       /* make a string out of ZOO x.xx Archive\0 to print out */
  242.       buf[16] = '\0';
  243.       type(buf,file);
  244.       return(0);
  245.     }
  246.     type("data",file);
  247. int search(pat, text, len)
  248. char *pat, *text;
  249. register int len;
  250.   register int index = 0, patlen = strlen(pat);
  251.   while ( memncmp(pat,&text[index],patlen) && index < len ) {
  252.     index++;
  253.   return(index < len ? 1 : 0);
  254.