Annotation of src/usr.bin/file/ascmagic.c, Revision 1.7
1.7 ! deraadt 1: /* $OpenBSD: ascmagic.c,v 1.6 2003/03/11 21:26:26 ian Exp $ */
1.3 millert 2:
1.1 deraadt 3: /*
4: * ASCII magic -- file types that we know based on keywords
5: * that can appear anywhere in the file.
6: *
1.6 ian 7: * Copyright (c) Ian F. Darwin 1986-1995.
8: * Software written by Ian F. Darwin and others;
9: * maintained 1995-present by Christos Zoulas and others.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice immediately at the beginning of the file, without modification,
16: * this list of conditions, and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
25: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
1.1 deraadt 32: */
33:
34: #include <stdio.h>
35: #include <string.h>
36: #include <ctype.h>
37: #include <stdlib.h>
38: #include <unistd.h>
1.4 mickey 39: #include <err.h>
1.1 deraadt 40: #include "file.h"
41: #include "names.h"
42:
43: #ifndef lint
1.7 ! deraadt 44: static char *moduleid = "$OpenBSD: ascmagic.c,v 1.6 2003/03/11 21:26:26 ian Exp $";
1.1 deraadt 45: #endif /* lint */
46:
47: /* an optimisation over plain strcmp() */
48: #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
49:
50: int
51: ascmagic(buf, nbytes)
52: unsigned char *buf;
53: int nbytes; /* size actually read */
54: {
55: int i, has_escapes = 0;
56: unsigned char *s;
57: char nbuf[HOWMANY+1]; /* one extra for terminating '\0' */
58: char *token;
1.5 mpech 59: struct names *p;
1.1 deraadt 60:
61: /*
62: * Do the tar test first, because if the first file in the tar
63: * archive starts with a dot, we can confuse it with an nroff file.
64: */
65: switch (is_tar(buf, nbytes)) {
66: case 1:
67: ckfputs("tar archive", stdout);
68: return 1;
69: case 2:
70: ckfputs("POSIX tar archive", stdout);
71: return 1;
72: }
73:
74: /*
75: * for troff, look for . + letter + letter or .\";
76: * this must be done to disambiguate tar archives' ./file
77: * and other trash from real troff input.
78: */
79: if (*buf == '.') {
80: unsigned char *tp = buf + 1;
81:
82: while (isascii(*tp) && isspace(*tp))
83: ++tp; /* skip leading whitespace */
84: if ((isascii(*tp) && (isalnum(*tp) || *tp=='\\') &&
85: isascii(tp[1]) && (isalnum(tp[1]) || tp[1] == '"'))) {
86: ckfputs("troff or preprocessor input text", stdout);
87: return 1;
88: }
89: }
90: if ((*buf == 'c' || *buf == 'C') &&
91: isascii(buf[1]) && isspace(buf[1])) {
92: ckfputs("fortran program text", stdout);
93: return 1;
94: }
95:
1.3 millert 96:
97: /* Make sure we are dealing with ascii text before looking for tokens */
98: for (i = 0; i < nbytes; i++) {
99: if (!isascii(buf[i]))
100: return 0; /* not all ASCII */
101: }
102:
1.1 deraadt 103: /* look for tokens from names.h - this is expensive! */
104: /* make a copy of the buffer here because strtok() will destroy it */
105: s = (unsigned char*) memcpy(nbuf, buf, nbytes);
106: s[nbytes] = '\0';
107: has_escapes = (memchr(s, '\033', nbytes) != NULL);
108: while ((token = strtok((char *) s, " \t\n\r\f")) != NULL) {
109: s = NULL; /* make strtok() keep on tokin' */
110: for (p = names; p < names + NNAMES; p++) {
111: if (STREQ(p->name, token)) {
112: ckfputs(types[p->type], stdout);
113: if (has_escapes)
114: ckfputs(" (with escape sequences)",
115: stdout);
116: return 1;
117: }
118: }
119: }
120:
121: /* all else fails, but it is ASCII... */
122: ckfputs("ASCII text", stdout);
123: if (has_escapes) {
124: ckfputs(" (with escape sequences)", stdout);
125: }
126: return 1;
127: }
128:
129: