Research V7 development
[unix-history] / usr / src / cmd / file.c
CommitLineData
80a00278
KT
1/*
2 * determine type of file
3 */
4
5#include <sys/param.h>
6#include <sys/stat.h>
7#include <stdio.h>
8#include <ctype.h>
9int in;
10int i = 0;
11char buf[512];
12char *fort[] = {
13 "function","subroutine","common","dimension","block","integer",
14 "real","data","double",0};
15char *asc[] = {
16 "sys","mov","tst","clr","jmp",0};
17char *c[] = {
18 "int","char","float","double","struct","extern",0};
19char *as[] = {
20 "globl","byte","even","text","data","bss","comm",0};
21int ifile;
22
23main(argc, argv)
24char **argv;
25{
26 FILE *fl;
27 register char *p;
28 char ap[128];
29
30 if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
31 if ((fl = fopen(argv[2], "r")) == NULL) {
32 printf("Can't open %s\n", argv[2]);
33 exit(2);
34 }
35 while ((p = fgets(ap, 128, fl)) != NULL) {
36 int l = strlen(p);
37 if (l>0)
38 p[l-1] = '\0';
39 printf("%s: ", p);
40 type(p);
41 if (ifile>=0)
42 close(ifile);
43 }
44 exit(1);
45 }
46 while(argc > 1) {
47 printf("%s: ", argv[1]);
48 type(argv[1]);
49 argc--;
50 argv++;
51 if (ifile >= 0)
52 close(ifile);
53 }
54}
55
56type(file)
57char *file;
58{
59 int j,nl;
60 char ch;
61 struct stat mbuf;
62
63 ifile = -1;
64 if(stat(file, &mbuf) < 0) {
65 printf("cannot stat\n");
66 return;
67 }
68 switch (mbuf.st_mode & S_IFMT) {
69
70 case S_IFCHR:
71 printf("character");
72 goto spcl;
73
74 case S_IFDIR:
75 printf("directory\n");
76 return;
77
78 case S_IFBLK:
79 printf("block");
80
81spcl:
82 printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev));
83 return;
84 }
85
86 ifile = open(file, 0);
87 if(ifile < 0) {
88 printf("cannot open\n");
89 return;
90 }
91 in = read(ifile, buf, 512);
92 if(in == 0){
93 printf("empty\n");
94 return;
95 }
96 switch(*(int *)buf) {
97
98 case 0410:
99 printf("pure ");
100 goto exec;
101
102 case 0411:
103 printf("separate ");
104
105 case 0407:
106exec:
107 printf("executable");
108 if(((int *)buf)[4] != 0)
109 printf(" not stripped");
110 printf("\n");
111 goto out;
112
113 case 0177555:
114 printf("old archive\n");
115 goto out;
116
117 case 0177545:
118 printf("archive\n");
119 goto out;
120 }
121
122 i = 0;
123 if(ccom() == 0)goto notc;
124 while(buf[i] == '#'){
125 j = i;
126 while(buf[i++] != '\n'){
127 if(i - j > 255){
128 printf("data\n");
129 goto out;
130 }
131 if(i >= in)goto notc;
132 }
133 if(ccom() == 0)goto notc;
134 }
135check:
136 if(lookup(c) == 1){
137 while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
138 printf("c program text");
139 goto outa;
140 }
141 nl = 0;
142 while(buf[i] != '('){
143 if(buf[i] <= 0)
144 goto notas;
145 if(buf[i] == ';'){
146 i++;
147 goto check;
148 }
149 if(buf[i++] == '\n')
150 if(nl++ > 6)goto notc;
151 if(i >= in)goto notc;
152 }
153 while(buf[i] != ')'){
154 if(buf[i++] == '\n')
155 if(nl++ > 6)goto notc;
156 if(i >= in)goto notc;
157 }
158 while(buf[i] != '{'){
159 if(buf[i++] == '\n')
160 if(nl++ > 6)goto notc;
161 if(i >= in)goto notc;
162 }
163 printf("c program text");
164 goto outa;
165notc:
166 i = 0;
167 while(buf[i] == 'c' || buf[i] == '#'){
168 while(buf[i++] != '\n')if(i >= in)goto notfort;
169 }
170 if(lookup(fort) == 1){
171 printf("fortran program text");
172 goto outa;
173 }
174notfort:
175 i=0;
176 if(ascom() == 0)goto notas;
177 j = i-1;
178 if(buf[i] == '.'){
179 i++;
180 if(lookup(as) == 1){
181 printf("assembler program text");
182 goto outa;
183 }
184 else if(buf[j] == '\n' && isalpha(buf[j+2])){
185 printf("roff, nroff, or eqn input text");
186 goto outa;
187 }
188 }
189 while(lookup(asc) == 0){
190 if(ascom() == 0)goto notas;
191 while(buf[i] != '\n' && buf[i++] != ':')
192 if(i >= in)goto notas;
193 while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
194 j = i-1;
195 if(buf[i] == '.'){
196 i++;
197 if(lookup(as) == 1){
198 printf("assembler program text");
199 goto outa;
200 }
201 else if(buf[j] == '\n' && isalpha(buf[j+2])){
202 printf("roff, nroff, or eqn input text");
203 goto outa;
204 }
205 }
206 }
207 printf("assembler program text");
208 goto outa;
209notas:
210 for(i=0; i < in; i++)if(buf[i]&0200){
211 if (buf[0]=='\100' && buf[1]=='\357') {
212 printf("troff output\n");
213 goto out;
214 }
215 printf("data\n");
216 goto out;
217 }
218 if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
219 printf("commands text");
220 else
221 if (english(buf, in))
222 printf("English text");
223 else
224 printf("ascii text");
225outa:
226 while(i < in)
227 if((buf[i++]&0377) > 127){
228 printf(" with garbage\n");
229 goto out;
230 }
231 /* if next few lines in then read whole file looking for nulls ...
232 while((in = read(ifile,buf,512)) > 0)
233 for(i = 0; i < in; i++)
234 if((buf[i]&0377) > 127){
235 printf(" with garbage\n");
236 goto out;
237 }
238 /*.... */
239 printf("\n");
240out:;
241}
242lookup(tab)
243char *tab[];
244{
245 char r;
246 int k,j,l;
247 while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
248 for(j=0; tab[j] != 0; j++){
249 l=0;
250 for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
251 if(r == '\0')
252 if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
253 || buf[k] == '{' || buf[k] == '/'){
254 i=k;
255 return(1);
256 }
257 }
258 return(0);
259}
260ccom(){
261 char cc;
262 while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
263 if(buf[i] == '/' && buf[i+1] == '*'){
264 i += 2;
265 while(buf[i] != '*' || buf[i+1] != '/'){
266 if(buf[i] == '\\')i += 2;
267 else i++;
268 if(i >= in)return(0);
269 }
270 if((i += 2) >= in)return(0);
271 }
272 if(buf[i] == '\n')if(ccom() == 0)return(0);
273 return(1);
274}
275ascom(){
276 while(buf[i] == '/'){
277 i++;
278 while(buf[i++] != '\n')if(i >= in)return(0);
279 while(buf[i] == '\n')if(i++ >= in)return(0);
280 }
281 return(1);
282}
283
284english (bp, n)
285char *bp;
286{
287# define NASC 128
288 int ct[NASC], j, vow, freq, rare;
289 int badpun = 0, punct = 0;
290 if (n<50) return(0); /* no point in statistics on squibs */
291 for(j=0; j<NASC; j++)
292 ct[j]=0;
293 for(j=0; j<n; j++)
294 {
295 if (bp[j]<NASC)
296 ct[bp[j]|040]++;
297 switch (bp[j])
298 {
299 case '.':
300 case ',':
301 case ')':
302 case '%':
303 case ';':
304 case ':':
305 case '?':
306 punct++;
307 if ( j < n-1 &&
308 bp[j+1] != ' ' &&
309 bp[j+1] != '\n')
310 badpun++;
311 }
312 }
313 if (badpun*5 > punct)
314 return(0);
315 vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
316 freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
317 rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
318 if (2*ct[';'] > ct['e']) return(0);
319 if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
320 return (vow*5 >= n-ct[' '] && freq >= 10*rare);
321}