filetype.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,067 行 · 第 1/2 页
C
1,067 行
#ifndef lintstatic char *sccsid = "@(#)filetype.c 4.3 (ULTRIX) 1/22/91";#endif lint/************************************************************************ * * * Copyright (c) 1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * 001 Richard Hart, Oct. 21, 1987 * * Copied from 4.3 BSD code: * * file.c 4.12 (Berkeley) 11/17/85 * * 002 Richard Hart, Oct. 21, 1987 * * Added named pipes for Sys V support, and other things in the * * current Ultrix file.c * * 003 Richard Hart, Oct. 22, 1987 * * Added use of /etc/magic, like Sys V filecommand * * 004 Richard Hart, Nov. 5, 1987 * * Now uses sys/exec.h for support of a.out magic numbers * * 005 Ricky Palmer, Aug. 5, 1988 * * Ifdef'ed for vax/mips. * * 006 Jon Reeves, Nov 12, 1988 * * Fixed ifdefs to allow mode code to work. * * 007 Tim Burke, June 12, 1989 * * Added check for the tape density of DEV_38000BPI which is used * * on the TA90 tape drive. Print out "loader" if the tape has a * * media loader. * * 008 Tim Burke, Sep 13, 1989 * * Added the following TA90 densities: DEV_38000_CP, DEV_76000BPI * * and DEV_76000_CP. * * 009 Bill Dallas, Jul 05,1990 * * Added the following QIC densities DEV_8000_BPI, DEV_10000_BPI * * and DEV_16000_BPI. * * 010 Robin Miller, January 8, 1991 * * Added additional tape density checks for DEV_54000_BPI (TZK08) * * and DEV_61000_BPI (TLZ04). Also fixed compiler warning error * * by adding '(struct matcher *) 0' on return from fre_match(). * * * ************************************************************************//* * filetype - determine type of file */#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/devio.h>#include <stdio.h>#include <ctype.h>#ifdef vax#include <a.out.h>#endif vax#include "filetype.h"/*** Types*/#define BYTE 0#define SHORT 2#define LONG 4#define STR 8/*** Opcodes*/#define EQ 0#define GT 1#define LT 2#define STRC 3 /* string compare */#define ANY 4#define SUB 64 /* or'ed in *//*** Misc*/#define NENT 200#define BSZ 128#define FBSZ 512#define reg register/*** Structure of magic file entry*/struct entry { char e_level; /* 0 or 1 */ long e_off; /* in bytes */ long e_retcode; /* major and minor type info to return */ char e_type; char e_opcode; union { long num; char *str; } e_value; char *e_str;};typedef struct entry Entry;Entry *mtab;extern char *mfile;extern char *sys_errlist[];struct devget devget;int errno;int sys_nerr;int in;int i = 0;char buf[BUFSIZ];char *execmodes();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 *cstart[] = { "#include", "#ifndef", "static", "stdio.h", 0};char *c[] = { "int","char","float","double","struct","extern","include",0};char *as[] = { "globl","byte","align","text","data","comm",0};char *sh[] = { "fi", "elif", "esac", "done", "export", "readonly", "trap", "PATH", "HOME", 0 };char *csh[] = { "alias", "breaksw", "endsw", "foreach", "limit", "onintr", "repeat", "setenv", "source", "path", "home", 0 };int ifile = -1;int maxexecfn = 2;#define MASH(x, y) (((x)<<16) + (y))longfiletype(file, pflg)char *file;int pflg;{ int j,nl; char ch; int minornum, majornum; long retnum; struct stat mbuf; char slink[MAXPATHLEN + 1]; struct devget *pdevget = &devget; if (ifile >= 0) close(ifile); /* close any file that was opened on a previous call */ ifile = -1; if (lstat(file, &mbuf) < 0) { if (pflg) printf("%s\n", (unsigned)errno < sys_nerr? sys_errlist[errno]: "Cannot stat"); return(MASH(UNKNOWN, UNKNOWN)); } switch (mbuf.st_mode & S_IFMT) { case S_IFLNK: if (pflg) printf("symbolic link"); j = readlink(file, slink, sizeof slink - 1); if (j >= 0) { slink[j] = '\0'; if (pflg) printf(" to %s", slink); } if (pflg) printf("\n"); return(MASH(SLINK, UNKNOWN)); case S_IFDIR: minornum = STANDARD; if (mbuf.st_mode & S_ISVTX) if (pflg) printf("append-only "); minornum = APPENDONLY; if (pflg) printf("directory\n"); return(MASH(DIRECTORY, minornum)); case S_IFPORT: if (pflg) printf("port (named pipe\n"); return(MASH(NAMEDPIPE, UNKNOWN)); case S_IFSOCK: if (pflg) printf("socket\n"); return(MASH(SOCKET, UNKNOWN)); case S_IFBLK: if (pflg) printf("block special (%d/%d)\n", major(mbuf.st_rdev), minor(mbuf.st_rdev)); return(MASH(SPECIAL, BLOCK)); case S_IFCHR: if (!pflg) return(MASH(SPECIAL, CHARACTER)); printf("character special (%d/%d)", major(mbuf.st_rdev), minor(mbuf.st_rdev)); ifile = open(file, (O_RDONLY|O_NDELAY)); if(ifile < 0) ifile = open(file, (O_WRONLY|O_NDELAY)); if(ifile < 0) { printf("\n"); return; } if(ioctl(ifile,DEVIOCGET,(char *) pdevget) < 0) { printf("\n"); } else { if((strcmp(DEV_UNKNOWN,pdevget->interface) == 0) || (pdevget->ctlr_num == -1)) { printf(" "); } else { printf(" %s #%d ", pdevget->interface, pdevget->ctlr_num); } if(!(strcmp(DEV_UNKNOWN,pdevget->device) == 0)) { printf("%s ", pdevget->device); } switch(pdevget->category) { case DEV_TAPE: printf("tape "); break; case DEV_DISK: printf("disk "); break; case DEV_TERMINAL: printf("terminal "); break; case DEV_PRINTER: printf("printer "); break; case DEV_SPECIAL: printf("special_device "); break; default: printf("unknown "); break; } if(!(pdevget->slave_num == -1)) { printf("#%d ", pdevget->slave_num); } if(pdevget->soft_count || pdevget->hard_count) { printf("errors = %d/%d ", pdevget->soft_count, pdevget->hard_count); } if(pdevget->stat & DEV_OFFLINE) { printf("offline "); } else if(pdevget->stat & DEV_WRTLCK) { printf("write-locked "); } if((pdevget->category == DEV_TAPE) && !(pdevget->stat & DEV_OFFLINE)) { if(pdevget->category_stat & DEV_LOADER) { printf("loader "); } if(pdevget->category_stat & DEV_800BPI) { printf("800_bpi\n"); } else if(pdevget->category_stat & DEV_1600BPI) { printf("1600_bpi\n"); } else if(pdevget->category_stat & DEV_6250BPI) { printf("6250_bpi\n"); } else if(pdevget->category_stat & DEV_6666BPI) { printf("6666_bpi\n"); } else if(pdevget->category_stat & DEV_8000_BPI) { printf("8000_bpi\n"); } else if(pdevget->category_stat & DEV_10000_BPI) { printf("10000_bpi\n"); } else if(pdevget->category_stat & DEV_10240BPI) { printf("10240_bpi\n"); } else if(pdevget->category_stat & DEV_16000_BPI) { printf("16000_bpi\n"); } else if(pdevget->category_stat & DEV_38000BPI) { printf("38000_bpi\n"); } else if(pdevget->category_stat & DEV_38000_CP) { printf("38000_bpi compacted\n"); } else if(pdevget->category_stat & DEV_76000BPI) { printf("76000_bpi\n"); } else if(pdevget->category_stat & DEV_76000_CP) { printf("76000_bpi compacted\n"); } else if(pdevget->category_stat & DEV_54000_BPI) { printf("54000_bpi\n"); } else if(pdevget->category_stat & DEV_61000_BPI) { printf("61000_bpi\n"); } else { /* * Density unknown. */ printf("unspecified density\n"); } } else if(pdevget->category == DEV_TERMINAL) { if(pdevget->category_stat & DEV_MODEM) { printf("modem_control "); if(pdevget->category_stat & DEV_MODEM_ON) { printf("on\n"); } else { printf("off\n"); } } else { printf("\n"); } } else { printf("\n"); } } return; } ifile = open(file, 0); if(ifile < 0) { if (pflg) printf("%s\n", (unsigned)errno < sys_nerr? sys_errlist[errno]: "Cannot read"); return(MASH(UNKNOWN, UNKNOWN)); } in = read(ifile, buf, BUFSIZ); if(in == 0){ if (pflg) printf("empty\n"); return(MASH(EMPTY, UNKNOWN)); } if (retnum = ckmtab(&mbuf, pflg)) return(retnum); if (buf[0] == '\037' && buf[1] == '\235') { if (buf[2]&0x80 && pflg) printf("block "); if (pflg) printf("compressed %d bit code data\n", buf[2]&0x1f); return(MASH(COMPRESSED, UNKNOWN)); } if (mbuf.st_size % 512 == 0) { /* it may be a PRESS file */ lseek(ifile, -512L, 2); /* last block */ if (read(ifile, buf, BUFSIZ) > 0 && *(short *)buf == 12138) { if (pflg) printf("PRESS file\n"); return(MASH(PRESS, UNKNOWN)); } } for(i=0; i < in; i++) if(buf[i]&0200){ if (pflg) printf("data\n"); return(MASH(DATA, UNKNOWN)); }; /* check for various types of ascii text files now using keyword lists */ if (cprog() == 1) { if (pflg) printf("c program text"); retnum = CPROG; /* checkgarbage(); */ goto outa; } else if (fortprog() == 1) { if (pflg) printf("fortran program text"); retnum = FORTPROG; goto outa; }notfort: i=0; if(ascom() == 0)goto notas; j = i-1; if(buf[i] == '.'){ i++; if(lookup(as) == 1){ if (pflg) printf("assembler program text"); retnum = ASSEMBLER; goto outa; } else if(buf[j] == '\n' && isalpha(buf[j+2])){ if (pflg) printf("roff, nroff, or eqn input text"); retnum = NROFF; 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){ if (pflg) printf("assembler program text"); retnum = ASSEMBLER; goto outa; } else if(buf[j] == '\n' && isalpha(buf[j+2])){ if (pflg) printf("roff, nroff, or eqn input text"); retnum = NROFF; goto outa; } } } if (pflg) printf("assembler program text"); retnum = ASSEMBLER; goto outa;notas: if (troffint(buf, in)) { if (pflg) printf("troff intermediate output text"); retnum = TROFFINT; } else if (shell(buf, in, sh)) { if (pflg) printf("%sshell commands", execmodes(&mbuf, buf)); retnum = SHELL; } else if (shell(buf, in, csh)) { if (pflg) printf("%sc-shell commands", execmodes(&mbuf, buf)); retnum = CSHELL; } else if (english(buf, in)) { if (pflg) printf("English text"); retnum = ENGLISH; } else { if (pflg) printf("ASCII text"); retnum = UNKNOWN; }outa: while(i < in) if((buf[i++]&0377) > 127){ if (pflg) printf(" with garbage\n"); return(MASH(ASCIIwGARBAGE, retnum)); } /* 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){ if (pflg) printf(" with garbage\n"); return(MASH(ASCIIwGARBAGE, retnum)); } /*.... */ if (pflg) printf("\n"); return(MASH(ASCII, retnum));}mkmtab(cflg)reg int cflg;{ reg Entry *ep; reg FILE *fp; reg int lcnt = 0; auto char buf[BSZ]; auto Entry *mend; auto majnum, minnum; char *strchr(); ep = (Entry *) calloc(sizeof(Entry), NENT); if(ep == NULL) { fprintf(stderr, "file: no memory for magic table.\n"); exit(2); } mtab = ep; mend = &mtab[NENT]; fp = fopen(mfile, "r"); if(fp == NULL) { fprintf(stderr, "file: cannot open magic file <%s>.\n", mfile); exit(2); } while(fgets(buf, BSZ, fp) != NULL) { reg char *p = buf; reg char *p2, *p3; reg char opc; int count; if(*p == '\n' || *p == '#') continue; lcnt++; /* LEVEL */ if(*p == '>') { ep->e_level = 1; p++; } /* OFFSET */ p2 = strchr(p, '\t'); if(p2 == NULL) { if(cflg) fprintf(stderr, "file: magic format error, no tab after %son line %d\n", p, lcnt); continue; } *p2++ = NULL; ep->e_off = atolo(p); while(*p2 == '\t') p2++; /* TYPE */ p = p2; p2 = strchr(p, '\t'); if(p2 == NULL) { if(cflg) fprintf(stderr, "file: magic format error, no tab after %son line %d\n", p, lcnt); continue; } *p2++ = NULL; if(*p == 's') { if(*(p+1) == 'h') ep->e_type = SHORT; else ep->e_type = STR; } else if (*p == 'l') ep->e_type = LONG; while(*p2 == '\t') *p2++; /* OP-VALUE */ p = p2; p2 = strchr(p, '\t'); if(p2 == NULL) { if(cflg) fprintf(stderr, "file: magic format error, no tab after %son line %d\n", p, lcnt); continue; } *p2++ = NULL; if(ep->e_type != STR) { opc = *p++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?