home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / FILE39.ZIP / ascmagic.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  4KB  |  144 lines

  1. /*
  2.  * Ascii magic -- file types that we know based on keywords
  3.  * that can appear anywhere in the file.
  4.  *
  5.  * Copyright (c) Ian F. Darwin, 1987.
  6.  * Written by Ian F. Darwin.
  7.  *
  8.  * This software is not subject to any license of the American Telephone
  9.  * and Telegraph Company or of the Regents of the University of California.
  10.  *
  11.  * Permission is granted to anyone to use this software for any purpose on
  12.  * any computer system, and to alter it and redistribute it freely, subject
  13.  * to the following restrictions:
  14.  *
  15.  * 1. The author is not responsible for the consequences of use of this
  16.  *    software, no matter how awful, even if they arise from flaws in it.
  17.  *
  18.  * 2. The origin of this software must not be misrepresented, either by
  19.  *    explicit claim or by omission.  Since few users ever read sources,
  20.  *    credits must appear in the documentation.
  21.  *
  22.  * 3. Altered versions must be plainly marked as such, and must not be
  23.  *    misrepresented as being the original software.  Since few users
  24.  *    ever read sources, credits must appear in the documentation.
  25.  *
  26.  * 4. This notice may not be removed or altered.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32. #include <stdlib.h>
  33. #ifndef MSC
  34. #include <unistd.h>
  35. #endif
  36. #include "file.h"
  37. #include "names.h"
  38.  
  39. #ifndef    lint
  40. static char *moduleid = 
  41.     "@(#)$Id: ascmagic.c,v 1.14 93/03/24 17:34:34 ian Exp $";
  42. #endif    /* lint */
  43.  
  44.             /* an optimisation over plain strcmp() */
  45. #define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  46.  
  47. int
  48. ascmagic(buf, nbytes)
  49. unsigned char *buf;
  50. int nbytes;    /* size actually read */
  51. {
  52.     int i, isblock, has_escapes = 0;
  53.     unsigned char *s;
  54.     char nbuf[HOWMANY+1];    /* one extra for terminating '\0' */
  55.     char *token;
  56.     register struct names *p;
  57.  
  58.     /* these are easy, do them first */
  59.  
  60.     /*
  61.      * for troff, look for . + letter + letter or .\";
  62.      * this must be done to disambiguate tar archives' ./file
  63.      * and other trash from real troff input.
  64.      */
  65.     if (*buf == '.') {
  66.         unsigned char *tp = buf + 1;
  67.  
  68.         while (isascii(*tp) && isspace(*tp))
  69.             ++tp;    /* skip leading whitespace */
  70.         if ((isascii(*tp) && (isalnum(*tp) || *tp=='\\') &&
  71.             isascii(*(tp+1)) && (isalnum(*(tp+1)) || *tp=='"'))) {
  72.             ckfputs("troff or preprocessor input text", stdout);
  73.             return 1;
  74.         }
  75.     }
  76.     if ((*buf == 'c' || *buf == 'C') && 
  77.         isascii(*(buf + 1)) && isspace(*(buf + 1))) {
  78.         ckfputs("fortran program text", stdout);
  79.         return 1;
  80.     }
  81.  
  82.     /* look for tokens from names.h - this is expensive! */
  83.     /* make a copy of the buffer here because strtok() will destroy it */
  84. #ifdef OS2            /* bugfix, not OS/2 specific */
  85.     s = (unsigned char*) memcpy(nbuf, buf, nbytes);
  86.     has_escapes = (memchr(s, '\033', nbytes) != NULL);
  87. #else
  88.     s = (unsigned char*) memcpy(nbuf, buf, HOWMANY);
  89.     has_escapes = (memchr(s, '\033', HOWMANY) != NULL);
  90. #endif
  91.     while ((token = strtok((char*)s, " \t\n\r\f")) != NULL) {
  92.         s = NULL;    /* make strtok() keep on tokin' */
  93.         for (p = names; p < names + NNAMES; p++) {
  94.             if (STREQ(p->name, token)) {
  95.                 ckfputs(types[p->type], stdout);
  96.                 if (has_escapes)
  97.                     ckfputs(" (with escape sequences)", 
  98.                         stdout);
  99.                 return 1;
  100.             }
  101.         }
  102.     }
  103.  
  104.     switch (is_tar(buf)) {
  105.     case 1:
  106.         ckfputs("tar archive", stdout);
  107.         return 1;
  108.     case 2:
  109.         ckfputs("POSIX tar archive", stdout);
  110.         return 1;
  111.     }
  112.  
  113.     if (i = is_compress(buf, &isblock)) {
  114.         if (zflag) {
  115.             unsigned char *newbuf;
  116.             int newsize;
  117.  
  118.             if (newsize = uncompress(buf, &newbuf, nbytes)) {
  119.                 tryit(newbuf, newsize);
  120.                 free(newbuf);
  121.             }
  122.             printf(" (%scompressed data - %d bits)",
  123.                 isblock ? "block " : "", i);
  124.         }
  125.          else printf("%scompressed data - %d bits",
  126.             isblock ? "block " : "", i);
  127.         return 1;
  128.     }
  129.  
  130.     for (i = 0; i < nbytes; i++) {
  131.         if (!isascii(*(buf+i)))
  132.             return 0;    /* not all ascii */
  133.     }
  134.  
  135.     /* all else fails, but it is ascii... */
  136.     ckfputs("ascii text", stdout);
  137.     if (has_escapes) {
  138.         ckfputs(" (with escape sequences)", stdout);
  139.     }
  140.     return 1;
  141. }
  142.  
  143.  
  144.