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