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