Define 4.1
[unix-history] / usr / src / usr.bin / file / file.c
CommitLineData
def89b26 1static char sccsid[] = "@(#)file.c 4.1 %G%";
fd2fc6c6
BJ
2/*
3 * file - determine type of file
4 */
5
6#include <pagsiz.h>
7#include <sys/types.h>
8#include <stat.h>
9#include <stdio.h>
10#include <ctype.h>
75ea79ff 11#include <a.out.h>
fd2fc6c6
BJ
12int in;
13int i = 0;
14char buf[BUFSIZ];
15char *troff[] = { /* new troff intermediate lang */
16 "x","T","res","init","font","202","V0","p1",0};
17char *fort[] = {
18 "function","subroutine","common","dimension","block","integer",
19 "real","data","double",0};
20char *asc[] = {
21 "chmk","mov","tst","clr","jmp",0};
22char *c[] = {
23 "int","char","float","double","struct","extern",0};
24char *as[] = {
25 "globl","byte","align","text","data","comm",0};
26int ifile;
27
28main(argc, argv)
29char **argv;
30{
31 FILE *fl;
32 register char *p;
33 char ap[128];
34 extern char _sobuf[];
35
36 if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
37 if ((fl = fopen(argv[2], "r")) == NULL) {
38 printf("Can't open %s\n", argv[2]);
39 exit(2);
40 }
41 while ((p = fgets(ap, 128, fl)) != NULL) {
42 int l = strlen(p);
43 if (l>0)
44 p[l-1] = '\0';
45 printf("%s: ", p);
46 type(p);
47 if (ifile>=0)
48 close(ifile);
49 }
50 exit(1);
51 }
52 while(argc > 1) {
53 printf("%s: ", argv[1]);
54 type(argv[1]);
55 fflush(stdout);
56 argc--;
57 argv++;
58 if (ifile >= 0)
59 close(ifile);
60 }
61}
62
63type(file)
64char *file;
65{
66 int j,nl;
67 char ch;
68 struct stat mbuf;
69
70 ifile = -1;
71 if(stat(file, &mbuf) < 0) {
72 printf("cannot stat\n");
73 return;
74 }
75 switch (mbuf.st_mode & S_IFMT) {
76
77 case S_IFCHR:
78 printf("character");
79 goto spcl;
80
81 case S_IFDIR:
82 printf("directory\n");
83 return;
84
85 case S_IFMPC:
86 printf("char multiplexor\n");
87 return;
88
89 case S_IFMPB:
90 printf("block multiplexor\n");
91 return;
92
93 case S_IFBLK:
94 printf("block");
95
96spcl:
97 printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev));
98 return;
99 }
100
101 ifile = open(file, 0);
102 if(ifile < 0) {
103 printf("cannot open\n");
104 return;
105 }
106 in = read(ifile, buf, BUFSIZ);
107 if(in == 0){
108 printf("empty\n");
109 return;
110 }
111 switch(*(int *)buf) {
112
113 case 0413:
114 printf("demand paged ");
115
116 case 0410:
117 printf("pure ");
118 goto exec;
119
120 case 0411:
121 printf("jfr or pdp-11 unix 411 executable\n");
122 return;
123
124 case 0407:
125exec:
126 printf("executable");
127 if(((int *)buf)[4] != 0) {
128 printf(" not stripped");
129 if(oldo(buf))
130 printf(" (old format symbol table)");
131 }
132 printf("\n");
133 goto out;
134
135 case 0177555:
136 printf("very old archive\n");
137 goto out;
138
139 case 0177545:
140 printf("old archive\n");
141 goto out;
c083f459
BJ
142
143 case 070707:
144 printf("cpio data\n");
145 goto out;
fd2fc6c6
BJ
146 }
147
148 if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) {
149 printf("archive random library\n");
150 goto out;
151 }
152 if (strncmp(buf, "!<arch>\n", 8)==0) {
153 printf("archive\n");
154 goto out;
155 }
156 i = 0;
157 if(ccom() == 0)goto notc;
158 while(buf[i] == '#'){
159 j = i;
160 while(buf[i++] != '\n'){
161 if(i - j > 255){
162 printf("data\n");
163 goto out;
164 }
165 if(i >= in)goto notc;
166 }
167 if(ccom() == 0)goto notc;
168 }
169check:
170 if(lookup(c) == 1){
171 while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
172 printf("c program text");
173 goto outa;
174 }
175 nl = 0;
176 while(buf[i] != '('){
177 if(buf[i] <= 0)
178 goto notas;
179 if(buf[i] == ';'){
180 i++;
181 goto check;
182 }
183 if(buf[i++] == '\n')
184 if(nl++ > 6)goto notc;
185 if(i >= in)goto notc;
186 }
187 while(buf[i] != ')'){
188 if(buf[i++] == '\n')
189 if(nl++ > 6)goto notc;
190 if(i >= in)goto notc;
191 }
192 while(buf[i] != '{'){
193 if(buf[i++] == '\n')
194 if(nl++ > 6)goto notc;
195 if(i >= in)goto notc;
196 }
197 printf("c program text");
198 goto outa;
199notc:
200 i = 0;
201 while(buf[i] == 'c' || buf[i] == '#'){
202 while(buf[i++] != '\n')if(i >= in)goto notfort;
203 }
204 if(lookup(fort) == 1){
205 printf("fortran program text");
206 goto outa;
207 }
208notfort:
209 i=0;
210 if(ascom() == 0)goto notas;
211 j = i-1;
212 if(buf[i] == '.'){
213 i++;
214 if(lookup(as) == 1){
215 printf("assembler program text");
216 goto outa;
217 }
218 else if(buf[j] == '\n' && isalpha(buf[j+2])){
219 printf("roff, nroff, or eqn input text");
220 goto outa;
221 }
222 }
223 while(lookup(asc) == 0){
224 if(ascom() == 0)goto notas;
225 while(buf[i] != '\n' && buf[i++] != ':')
226 if(i >= in)goto notas;
227 while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
228 j = i-1;
229 if(buf[i] == '.'){
230 i++;
231 if(lookup(as) == 1){
232 printf("assembler program text");
233 goto outa;
234 }
235 else if(buf[j] == '\n' && isalpha(buf[j+2])){
236 printf("roff, nroff, or eqn input text");
237 goto outa;
238 }
239 }
240 }
241 printf("assembler program text");
242 goto outa;
243notas:
244 for(i=0; i < in; i++)if(buf[i]&0200){
245 if (buf[0]=='\100' && buf[1]=='\357') {
246 printf("troff (CAT) output\n");
247 goto out;
248 }
249 printf("data\n");
250 goto out;
251 }
252 if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
253 printf("commands text");
254 else if (troffint(buf, in))
255 printf("troff intermediate output text");
256 else if (english(buf, in))
257 printf("English text");
258 else
259 printf("ascii text");
260outa:
261 while(i < in)
262 if((buf[i++]&0377) > 127){
263 printf(" with garbage\n");
264 goto out;
265 }
266 /* if next few lines in then read whole file looking for nulls ...
267 while((in = read(ifile,buf,BUFSIZ)) > 0)
268 for(i = 0; i < in; i++)
269 if((buf[i]&0377) > 127){
270 printf(" with garbage\n");
271 goto out;
272 }
273 /*.... */
274 printf("\n");
275out:;
276}
277
278oldo(cp)
279char *cp;
280{
281 struct exec ex;
282 struct stat stb;
283
284 ex = *(struct exec *)cp;
285 if (fstat(ifile, &stb) < 0)
286 return(0);
287 if (N_STROFF(ex)+sizeof(off_t) > stb.st_size)
288 return (1);
289 return (0);
290}
291
292
293
294troffint(bp, n)
295char *bp;
296int n;
297{
298 int k;
299
300 i = 0;
301 for (k = 0; k < 6; k++) {
302 if (lookup(troff) == 0)
303 return(0);
304 if (lookup(troff) == 0)
305 return(0);
306 while (i < n && buf[i] != '\n')
307 i++;
308 if (i++ >= n)
309 return(0);
310 }
311 return(1);
312}
313lookup(tab)
314char *tab[];
315{
316 char r;
317 int k,j,l;
318 while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
319 for(j=0; tab[j] != 0; j++){
320 l=0;
321 for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
322 if(r == '\0')
323 if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
324 || buf[k] == '{' || buf[k] == '/'){
325 i=k;
326 return(1);
327 }
328 }
329 return(0);
330}
331ccom(){
332 char cc;
333 while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
334 if(buf[i] == '/' && buf[i+1] == '*'){
335 i += 2;
336 while(buf[i] != '*' || buf[i+1] != '/'){
337 if(buf[i] == '\\')i += 2;
338 else i++;
339 if(i >= in)return(0);
340 }
341 if((i += 2) >= in)return(0);
342 }
343 if(buf[i] == '\n')if(ccom() == 0)return(0);
344 return(1);
345}
346ascom(){
347 while(buf[i] == '/'){
348 i++;
349 while(buf[i++] != '\n')if(i >= in)return(0);
350 while(buf[i] == '\n')if(i++ >= in)return(0);
351 }
352 return(1);
353}
354
355english (bp, n)
356char *bp;
357{
358# define NASC 128
359 int ct[NASC], j, vow, freq, rare;
360 int badpun = 0, punct = 0;
361 if (n<50) return(0); /* no point in statistics on squibs */
362 for(j=0; j<NASC; j++)
363 ct[j]=0;
364 for(j=0; j<n; j++)
365 {
366 if (bp[j]<NASC)
367 ct[bp[j]|040]++;
368 switch (bp[j])
369 {
370 case '.':
371 case ',':
372 case ')':
373 case '%':
374 case ';':
375 case ':':
376 case '?':
377 punct++;
378 if ( j < n-1 &&
379 bp[j+1] != ' ' &&
380 bp[j+1] != '\n')
381 badpun++;
382 }
383 }
384 if (badpun*5 > punct)
385 return(0);
386 vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
387 freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
388 rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
389 if (2*ct[';'] > ct['e']) return(0);
390 if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
391 return (vow*5 >= n-ct[' '] && freq >= 10*rare);
392}