Moved ttyfree() to ifdef broken. See my reply on the sio change.
[unix-history] / usr.bin / file / ascmagic.c
CommitLineData
15637ed4
RG
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>
286a6f32 30#include <string.h>
15637ed4 31#include <ctype.h>
286a6f32
C
32#include <stdlib.h>
33#include <unistd.h>
15637ed4
RG
34#include "file.h"
35#include "names.h"
36
37#ifndef lint
38static char *moduleid =
286a6f32 39 "@(#)ascmagic.c,v 1.2 1993/06/10 00:38:04 jtc Exp";
15637ed4
RG
40#endif /* lint */
41
15637ed4
RG
42 /* an optimisation over plain strcmp() */
43#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
44
286a6f32
C
45int
46ascmagic(buf, nbytes)
47unsigned char *buf;
48int nbytes; /* size actually read */
15637ed4 49{
286a6f32
C
50 int i, isblock, has_escapes = 0;
51 unsigned char *s;
52 char nbuf[HOWMANY+1]; /* one extra for terminating '\0' */
53 char *token;
15637ed4 54 register struct names *p;
15637ed4
RG
55
56 /* these are easy, do them first */
57
58 /*
286a6f32 59 * for troff, look for . + letter + letter or .\";
15637ed4
RG
60 * this must be done to disambiguate tar archives' ./file
61 * and other trash from real troff input.
62 */
286a6f32
C
63 if (*buf == '.') {
64 unsigned char *tp = buf + 1;
65
66 while (isascii(*tp) && isspace(*tp))
67 ++tp; /* skip leading whitespace */
68 if ((isascii(*tp) && (isalnum(*tp) || *tp=='\\') &&
69 isascii(*(tp+1)) && (isalnum(*(tp+1)) || *tp=='"'))) {
70 ckfputs("troff or preprocessor input text", stdout);
71 return 1;
72 }
15637ed4
RG
73 }
74 if ((*buf == 'c' || *buf == 'C') &&
75 isascii(*(buf + 1)) && isspace(*(buf + 1))) {
76 ckfputs("fortran program text", stdout);
77 return 1;
78 }
79
80 /* look for tokens from names.h - this is expensive! */
286a6f32
C
81 /* make a copy of the buffer here because strtok() will destroy it */
82 s = (unsigned char*) memcpy(nbuf, buf, HOWMANY);
83 has_escapes = (memchr(s, '\033', HOWMANY) != NULL);
84 while ((token = strtok((char*)s, " \t\n\r\f")) != NULL) {
15637ed4
RG
85 s = NULL; /* make strtok() keep on tokin' */
86 for (p = names; p < names + NNAMES; p++) {
87 if (STREQ(p->name, token)) {
88 ckfputs(types[p->type], stdout);
286a6f32
C
89 if (has_escapes)
90 ckfputs(" (with escape sequences)",
91 stdout);
15637ed4
RG
92 return 1;
93 }
94 }
95 }
96
97 switch (is_tar(buf)) {
98 case 1:
99 ckfputs("tar archive", stdout);
100 return 1;
101 case 2:
102 ckfputs("POSIX tar archive", stdout);
103 return 1;
104 }
105
286a6f32
C
106 if (i = is_compress(buf, &isblock)) {
107 if (zflag) {
108 unsigned char *newbuf;
109 int newsize;
110
111 if (newsize = uncompress(buf, &newbuf, nbytes)) {
112 tryit(newbuf, newsize);
113 free(newbuf);
114 }
115 printf(" (%scompressed data - %d bits)",
116 isblock ? "block " : "", i);
117 }
118 else printf("%scompressed data - %d bits",
119 isblock ? "block " : "", i);
120 return 1;
121 }
122
15637ed4
RG
123 for (i = 0; i < nbytes; i++) {
124 if (!isascii(*(buf+i)))
125 return 0; /* not all ascii */
15637ed4
RG
126 }
127
128 /* all else fails, but it is ascii... */
286a6f32
C
129 ckfputs("ascii text", stdout);
130 if (has_escapes) {
131 ckfputs(" (with escape sequences)", stdout);
132 }
15637ed4
RG
133 return 1;
134}
135
136