|
|
researchv9-SUN3(old)
static char sccsid[] = "@(#)file.c 4.1 10/1/80";
/*
* file - determine type of file
*/
#ifdef vax
#include <pagsiz.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <a.out.h>
int in;
int i = 0;
char buf[BUFSIZ];
char *troff[] = { /* new troff intermediate lang */
"x","T","res","init","font","202","V0","p1",0};
char *fort[] = {
"function","subroutine","common","dimension","block","integer",
"real","data","double",0};
char *asc[] = {
"chmk","mov","tst","clr","jmp",0};
char *c[] = {
"int","char","float","double","struct","extern",0};
char *as[] = {
"globl","byte","align","text","data","comm",0};
int ifile;
main(argc, argv)
char **argv;
{
FILE *fl;
register char *p;
char ap[128];
extern char _sobuf[];
if (argc>1 && argv[1][0]=='-' && argv[1][1]=='f') {
if ((fl = fopen(argv[2], "r")) == NULL) {
printf("Can't open %s\n", argv[2]);
exit(2);
}
while ((p = fgets(ap, 128, fl)) != NULL) {
int l = strlen(p);
if (l>0)
p[l-1] = '\0';
printf("%s: ", p);
type(p);
if (ifile>=0)
close(ifile);
}
exit(1);
}
while(argc > 1) {
printf("%s: ", argv[1]);
type(argv[1]);
fflush(stdout);
argc--;
argv++;
if (ifile >= 0)
close(ifile);
}
}
type(file)
char *file;
{
int j,nl;
char ch;
struct stat mbuf;
ifile = -1;
if(stat(file, &mbuf) < 0) {
printf("cannot stat\n");
return;
}
switch (mbuf.st_mode & S_IFMT) {
case S_IFCHR:
printf("character");
goto spcl;
case S_IFDIR:
printf("directory\n");
return;
case S_IFBLK:
printf("block");
spcl:
printf(" special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev));
return;
}
ifile = open(file, 0);
if(ifile < 0) {
printf("cannot open\n");
return;
}
in = read(ifile, buf, BUFSIZ);
if(in == 0){
printf("empty\n");
return;
}
if(in>=64){
int i, bucket[8];
float cs;
for(i=0; i<8; i++) bucket[i] = 0;
for(i=0; i<64; i++) bucket[(buf[i]>>5)&07] += 1;
cs = 0.;
for(i=0; i<8; i++) cs += (bucket[i]-8)*(bucket[i]-8);
cs /= 8.;
if(cs <= 24.322){
printf("encrypted\n");
return;
}
}
if( (((unsigned char)buf[0])==247) && (buf[1]==2) ){
printf("tex dvi\n");
return;
}
switch (*(short *) buf)
{
case 070707:
cpio:
printf("cpio archive\n");
goto out;
}
switch(*(int *)buf)
{
case 0413:
printf("old sun2 demand paged ");
goto exec;
case 0200413:
printf("mc68010 demand paged ");
goto exec;
case 0400413:
printf("mc68020 demand paged ");
goto exec;
case 0410:
printf("old sun2 pure ");
goto exec;
case 0200410:
printf("mc68010 pure ");
goto exec;
case 0400410:
printf("mc68020 pure ");
goto exec;
case 0411:
printf("jfr 411 executable\n");
return;
case 0406:
printf ("mpx 68000 ");
goto exec;
case 0200407:
printf("mc68010 ");
goto exec;
case 0400407:
printf("mc68020 ");
goto exec;
case 0407:
exec:
printf("executable");
if(((int *)buf)[4] != 0) {
printf(" not stripped");
if(oldo(buf))
printf(" (old format symbol table)");
}
printf("\n");
goto out;
case 0177555:
printf("very old archive\n");
goto out;
case 0177545:
printf("old archive\n");
goto out;
case 0135246: /* andrew/ehg */
printf("view2d input file\n");
goto out;
case 0135256: /* andrew */
printf("apl file\n");
goto out;
case 0164200: /* td */
printf("Lucasfilm picture\n");
goto out;
case 0600560:
printf("mux downloadable file\n");
goto out;
default:
switch (*(short *) buf+1) {
case 0405:
case 0407:
case 0410:
case 0411:
printf ("pdp-11 executable\n");
goto out;
}
}
if(strncmp(buf, "!<arch>\n__.SYMDEF", 17) == 0 ) {
printf("archive random library\n");
goto out;
}
if (strncmp(buf, "!<arch>\n", 8)==0) {
printf("archive\n");
goto out;
}
if (strncmp(buf, "070707", 6) == 0)
{
printf("ascii ");
goto cpio;
}
if(strncmp(buf, "#!/bin/echo ", 12)==0){
printf("cyntax object file\n");
goto out;
}
if(strncmp(buf, "TYPE=", 5)==0){ /* td */
for(i=5;i!=in && buf[i]!='\n';i++);
printf("%.*s picture\n", i, buf);
goto out;
}
i = 0;
if(ccom() == 0)goto notc;
while(buf[i] == '#'){
j = i;
while(buf[i++] != '\n'){
if(i - j > 255){
printf("data\n");
goto out;
}
if(i >= in)goto notc;
}
if(ccom() == 0)goto notc;
}
check:
if(lookup(c) == 1){
while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
printf("c program text");
goto outa;
}
nl = 0;
while(buf[i] != '('){
if(buf[i] <= 0)
goto notas;
if(buf[i] == ';'){
i++;
goto check;
}
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
while(buf[i] != ')'){
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
while(buf[i] != '{'){
if(buf[i++] == '\n')
if(nl++ > 6)goto notc;
if(i >= in)goto notc;
}
printf("c program text");
goto outa;
notc:
i = 0;
while(buf[i] == 'c' || buf[i] == '#'){
while(buf[i++] != '\n')if(i >= in)goto notfort;
}
if(lookup(fort) == 1){
printf("fortran program text");
goto outa;
}
notfort:
i=0;
if(ascom() == 0)goto notas;
j = i-1;
if(buf[i] == '.'){
i++;
if(lookup(as) == 1){
printf("assembler program text");
goto outa;
}
else if(buf[j] == '\n' && isalpha(buf[j+2])){
printf("roff, nroff, or eqn input text");
goto outa;
}
}
while(lookup(asc) == 0){
if(ascom() == 0)goto notas;
while(buf[i] != '\n' && buf[i++] != ':')
if(i >= in)goto notas;
while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
j = i-1;
if(buf[i] == '.'){
i++;
if(lookup(as) == 1){
printf("assembler program text");
goto outa;
}
else if(buf[j] == '\n' && isalpha(buf[j+2])){
printf("roff, nroff, or eqn input text");
goto outa;
}
}
}
printf("assembler program text");
goto outa;
notas:
for(i=0; i < in; i++)if(buf[i]&0200){
if (buf[0]=='\100' && buf[1]=='\357') {
printf("troff (CAT) output\n");
goto out;
}
if(buf[0] == 037 && buf[1] == 036){
char *p = file;
while(*p++);
if(*(p-2) != 'z' || *(p-3) != '.')
printf("probably ");
printf("packed\n");
goto out;
}
printf("data\n");
goto out;
}
if (mbuf.st_mode&((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
printf("commands text");
else if (troffint(buf, in))
printf("troff intermediate output text");
else if (english(buf, in))
printf("English text");
else
printf("ascii text");
outa:
while(i < in)
if((buf[i++]&0377) > 127){
printf(" with garbage\n");
goto out;
}
/* if next few lines in then read whole file looking for nulls ...
while((in = read(ifile,buf,BUFSIZ)) > 0)
for(i = 0; i < in; i++)
if((buf[i]&0377) > 127){
printf(" with garbage\n");
goto out;
}
/*.... */
printf("\n");
out:;
}
oldo(cp)
char *cp;
{
struct exec ex;
struct stat stb;
ex = *(struct exec *)cp;
if (fstat(ifile, &stb) < 0)
return(0);
if (N_STROFF(ex)+sizeof(off_t) > stb.st_size)
return (1);
return (0);
}
troffint(bp, n)
char *bp;
int n;
{
int k;
i = 0;
for (k = 0; k < 8; k++) {
if (buf[i] == 'x' && buf[i+1] == ' ') /* x [T|init|font|...] */
while (i < n && buf[i++] != '\n')
;
else if ((buf[i] == 'f' || buf[i] == 's' ||
buf[i] == 'p' || buf[i] == 'V' || buf[i] == 'H')
&& isdigit(buf[i+1])) /* p1 | f2 | s3 | V4... */
while (i < n && buf[i++] != '\n')
;
else
return 0;
}
return 1;
}
lookup(tab)
char *tab[];
{
char r;
int k,j,l;
while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
for(j=0; tab[j] != 0; j++){
l=0;
for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
if(r == '\0')
if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
|| buf[k] == '{' || buf[k] == '/'){
i=k;
return(1);
}
}
return(0);
}
ccom(){
char cc;
while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
if(buf[i] == '/' && buf[i+1] == '*'){
i += 2;
while(buf[i] != '*' || buf[i+1] != '/'){
if(buf[i] == '\\')i += 2;
else i++;
if(i >= in)return(0);
}
if((i += 2) >= in)return(0);
}
if(buf[i] == '\n')if(ccom() == 0)return(0);
return(1);
}
ascom(){
while(buf[i] == '/'){
i++;
while(buf[i++] != '\n')if(i >= in)return(0);
while(buf[i] == '\n')if(i++ >= in)return(0);
}
return(1);
}
english (bp, n)
char *bp;
{
# define NASC 128
int ct[NASC], j, vow, freq, rare;
int badpun = 0, punct = 0;
if (n<50) return(0); /* no point in statistics on squibs */
for(j=0; j<NASC; j++)
ct[j]=0;
for(j=0; j<n; j++)
{
if (bp[j]<NASC)
ct[bp[j]|040]++;
switch (bp[j])
{
case '.':
case ',':
case ')':
case '%':
case ';':
case ':':
case '?':
punct++;
if ( j < n-1 &&
bp[j+1] != ' ' &&
bp[j+1] != '\n')
badpun++;
}
}
if (badpun*5 > punct)
return(0);
vow = ct['a'] + ct['e'] + ct['i'] + ct['o'] + ct['u'];
freq = ct['e'] + ct['t'] + ct['a'] + ct['i'] + ct['o'] + ct['n'];
rare = ct['v'] + ct['j'] + ct['k'] + ct['q'] + ct['x'] + ct['z'];
if (2*ct[';'] > ct['e']) return(0);
if ( (ct['>']+ct['<']+ct['/'])>ct['e']) return(0); /* shell file test */
return (vow*5 >= n-ct[' '] && freq >= 10*rare);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.