home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
MISC
/
file.lzh
/
file.c
< prev
next >
Wrap
Text File
|
1995-04-27
|
17KB
|
737 lines
/************************************************************************
* file.c *
************************************************************************
* A utility to determine the type of a file. *
************************************************************************
* Original code: Scott McGee 4/1/93 *
***********************************************************************/
/***********************************************************************
revision history:
ed who when what
------------------------------------------------------------------------
sam 12/03/93 major rewrite to allow the use of magic db files
sam 12/20/93 added leshort, beshort, lelong, and belong types
sam 12/23/93 fixed -z option to read magic file
sam 12/24/93 added support for MAGIC_FILE environment variable
sam 12/26/93 added -r option
sam 12/28/93 added tar file identification using istar.c
sam 12/31/93 added OS-9 Module id (hard coded) w/ module name
sam 01/01/94 added -help option
1 sam 01/07/94 added -x option
sam 01/08/94 handle both OS-9 and OS-9000 files under both OS's
2 sam 01/22/94 given to Microware for review
sam 03/22/95 Microware released rights back to me
3 sam 04/04/95 edition number code moved to file.c from help.c
sam 04/04/95 readFile fixed to pass size to istar() and checkMagic()
4 sam 04/27/95 moved OS-9/9K modhead structs to file.h
***********************************************************************/
#define MAIN
#include <file.h>
#undef MAIN
#define edition_number 4
/* set the edition number */
#if defined(_OSK) || defined(_OS9000)
#if !defined(_BSD)
_asm("_sysedit: equ %0", edition_number);
#endif
#endif
char *byteSwap(buf, count)
char *buf;
int count;
{
int i;
char new[32];
count--;
for(i=0;i<=count;i++){
new[i] = buf[count - i];
}
return(new);
}
int strucmp(str1, str2)
char *str1;
char *str2;
{
char *new1;
char *new2;
char *ptr;
int result;
if(str1 == NULL)
return(-1);
if(str2 == NULL)
return(1);
new1 = (char *) grab(strlen(str1)*sizeof(char));
strcpy(new1, str1);
ptr = new1;
while(*ptr != '\0'){
*ptr = tolower(*ptr);
ptr++;
}
new2 = (char *) grab(strlen(str2)*sizeof(char));
strcpy(new2, str2);
ptr = new2;
while(*ptr != '\0'){
*ptr = tolower(*ptr);
ptr++;
}
result = strcmp(new1, new2);
free(new1);
free(new2);
return(result);
}
int struncmp(str1, str2, cnt)
char *str1;
char *str2;
int cnt;
{
char *new1;
char *new2;
char *ptr;
int result;
if(str1 == NULL)
return(-1);
if(str2 == NULL)
return(1);
new1 = (char *) grab(strlen(str1)*sizeof(char));
strcpy(new1, str1);
ptr = new1;
while(*ptr != '\0'){
*ptr = tolower(*ptr);
ptr++;
}
new2 = (char *) grab(strlen(str2)*sizeof(char));
strcpy(new2, str2);
ptr = new2;
while(*ptr != '\0'){
*ptr = tolower(*ptr);
ptr++;
}
result = strncmp(new1, new2, cnt);
free(new1);
free(new2);
return(result);
}
void readFile(filename)
char *filename;
{
struct modhead *mh;
static char buf[BUFSIZ];
static char buf2[BUFSIZ];
char *name;
DIR *dp;
FILE *fp = NULL;
int path;
int offset;
int result;
int size;
int len;
int text;
int cntrl;
int i;
unsigned short test;
fType type = UNKNOWN;
/* check for trailing '/' from ls command */
if(filename[strlen(filename)-1] == '/')
filename[strlen(filename)-1] = '\0';
/* Check to see if it is a directory */
dp = opendir(filename);
if(dp != NULL){
printf("%-16s directory\n", filename);
if(recursive == TRUE)
dirFiles(filename, dp);
closedir(dp);
return;
}
/* Not a directory, read start of file for type checks */
if(exec_relative == TRUE){
fp = fopen(filename, "rx");
if(fp != NULL)
path = fileno(fp);
else
path = -1;
}else
path = open(filename, READ_ONLY);
if(path == -1) {
#if defined(_OSK) || defined(_OS9000)
if((errno == E_BPNAM) || (errno == E_PNNF)){
#else
if(errno == ENOENT){
#endif
printf("%-16s file not found\n", filename);
return;
}else{
printf("%-16s error %d reading file\n", filename, errno);
return;
}
}
result = size = read(path, buf, BUFSIZ);
if(result == 0){
close(path);
type = EMPTY;
goto NAME_CHECKS;
}else if(result < 0){
close(path);
type = NOPERMIT;
goto NAME_CHECKS;
}
/* check for OS-9/OS-9000 (native) Module */
if(*(short *) buf == 0x4afc){
#ifndef _LIL_END
mh = (modhead *) buf;
printf("%-16s OS-9 ", filename);
switch((mh->tylan & 0xff00) >> 8){
#else
mh = (modhead *) buf;
printf("%-16s OS-9000 ", filename);
switch((mh->tylan & 0xff00) >> 8){
#endif
case 1: printf("Program ");
break;
case 2: printf("Subroutine ");
break;
case 4: printf("Data ");
break;
case 11: printf("Trap Library ");
break;
case 12: printf("System ");
break;
case 13: printf("File Manager ");
break;
case 14: printf("Device Driver ");
break;
case 15: printf("Device Descriptor ");
}
printf("Module");
offset = *((int *) (buf+0x000c));
if(offset < size - 32)
printf(" \"%s\"", buf+offset);
else{
if(fp == NULL)
fp = fdopen(path, "r");
result = fseek(fp, offset, SEEK_SET);
if(result == 0){
result = size = read(path, buf2, BUFSIZ);
if(result != 0)
printf(" \"%s\"", buf2);
}
}
offset = *((int *) (buf+0x0004));
if((offset < size) && (*(short *) buf == 0x4afc))
printf(" (...)");
else{
fp = fdopen(path, "r");
result = fseek(fp, offset, SEEK_SET);
if(result == 0){
result = size = read(path, buf2, BUFSIZ);
if((result != 0) && (*(short *) buf2 == 0x4afc))
printf(" (...)");
}
}
printf("\n");
close(path);
return;
}else if(*(unsigned short *) buf == 0xfc4a){
#ifdef _LIL_END
mh = (modhhead *) buf;
printf("%-16s OS-9 ", filename);
switch((mh->tylan & 0xff00) >> 8){
#else
mh = (modhead *) buf;
printf("%-16s OS-9000 ", filename);
switch((mh->tylan & 0xff00) >> 8){
#endif
case 1: printf("Program ");
break;
case 2: printf("Subroutine ");
break;
case 4: printf("Data ");
break;
case 11: printf("Trap Library ");
break;
case 12: printf("System ");
break;
case 13: printf("File Manager ");
break;
case 14: printf("Device Driver ");
break;
case 15: printf("Device Descriptor ");
}
printf("Module");
offset = *((int *) (buf+0x000c));
offset = *((int *)byteSwap((char *) &offset, sizeof(int)));
if(offset < size - 32)
printf(" \"%s\"", buf+offset);
else{
fp = fdopen(path, "r");
result = fseek(fp, offset, SEEK_SET);
if(result == 0){
result = size = read(path, buf2, BUFSIZ);
if(result != 0)
printf(" \"%s\"", buf2);
}
}
offset = *((int *) (buf+0x0004));
offset = *((int *)byteSwap((char *) &offset, sizeof(int)));
if((offset < size) && (*(unsigned short *) buf == 0xfc4a))
printf(" (...)");
else{
fp = fdopen(path, "r");
result = fseek(fp, offset, SEEK_SET);
if(result == 0){
result = size = read(path, buf2, BUFSIZ);
if(result != 0){
test = *(byteSwap(buf2, sizeof(short)));
if(*(unsigned short *) test == 0xfc4a)
printf(" (...)");
}
}
}
printf("\n");
close(path);
return;
}else
close(path);
/* check for tar file */
result = istar(buf, size);
if(result == POSIX_TAR){
printf("%-16s POSIX tar file\n", filename);
return;
}else if(result == OLD_TAR){
printf("%-16s tar file\n", filename);
return;
}
/* check magic file here */
if(checkMagic(filename, buf, size) == TRUE)
return;
/* OK, magic file hasn't identified it, so lets see if it is a BIN
or TEXT and then do name checks */
text = 0;
cntrl = 0;
for(i=0;i<result;i++){
if(buf[i] == '\n')
text++;
else if(buf[i] == '\t')
text++;
else if(iscntrl(buf[i]))
cntrl++;
else
text++;
}
if((cntrl != 0) && ((text / cntrl) < 7))
type = BIN;
else
type = MISC;
NAME_CHECKS:
name = strrchr(filename, '/');
if(name == NULL)
name = filename;
else
name++;
len = strlen(name);
if(len > 2){
if(strcmp(&(name[len-2]), ".c") == 0)
type = C_SOURCE;
else if(strcmp(&(name[len-2]), ".h") == 0)
type = C_HEADER;
else if(strcmp(&(name[len-2]), ".a") == 0)
type = ASM_SOURCE;
}
if(len > 4){
if(strucmp(&name[len-4], ".doc") == 0)
type = TEXT;
else if(strucmp(&name[len-4], ".txt") == 0)
type = TEXT;
else if(strucmp(&name[len-4], ".asc") == 0)
type = TEXT;
else if(strucmp(&name[len-4], ".ume") == 0)
type = UME;
}
if(len > 6){
if(struncmp(name, "readme", 6) == 0)
type = TEXT;
else if(strucmp(&name[len-6], "readme") == 0)
type = TEXT;
}
if(len >= 8){
if(struncmp(name, "makefile", 8) == 0)
type = MAKEFILE;
else if(strucmp(&name[len-8], "makefile") == 0)
type = MAKEFILE;
}
/* OK, we identified it as best we can, print out the results */
switch(type){
case EMPTY:
printf("%-16s an empty (zero length) file\n", filename);
break;
case NOPERMIT:
printf("%-16s permission denied\n", filename);
break;
case MISC:
printf("%-16s unidentified text file\n", filename);
break;
case BIN:
printf("%-16s unidentified binary file\n", filename);
break;
case ASM_SOURCE:
printf("%-16s assembly source file\n", filename);
break;
case MAKEFILE:
printf("%-16s makefile\n", filename);
break;
case TEXT:
printf("%-16s text file\n", filename);
break;
case C_SOURCE:
printf("%-16s C Source file\n", filename);
break;
case C_HEADER:
printf("%-16s C Header file\n", filename);
break;
case UME:
printf("%-16s Ultimuse music file\n", filename);
break;
default:
printf("%-16s unknown file type\n", filename);
}
}
void getFileNames(filename)
char *filename;
{
FILE *fp;
char file[MAXLINELEN];
int result;
if(filename != NULL){
fp = fopen(filename, "r");
if(fp == NULL){
_errmsg(0, "Cannot open file \"%s\" for input\n", filename);
return;
}
}else
fp = stdin;
result = fscanf(fp, " %s", file);
while((result != EOF) && (result != 0)){
readFile(file);
result = fscanf(fp, " %s", file);
}
fclose(fp);
}
int checkMagic(filename, buf, size)
char *filename;
char *buf;
int size;
{
MagicList *magic;
int match = FALSE;
int local_match;
char byte_value;
unsigned short short_value;
long long_value;
magic = magicList;
while(magic != NULL){
while((match == FALSE) && (magic->continuation == TRUE)){
if(magic->next == NULL)
return(match);
magic = magic->next;
}
if(magic->offset >= size){
magic = magic->next;
continue;
}
if((match == TRUE) && (magic->continuation == FALSE))
return(match);
local_match = FALSE;
switch(magic->type){
case BYTE:
byte_value = buf[magic->offset];
if(magic->maskFlag == TRUE)
byte_value = byte_value & (char) magic->mask;
switch(magic->op){
case LESS:
if(byte_value < magic->value) {
local_match = TRUE;
}
break;
case GREATER:
if(byte_value > magic->value) {
local_match = TRUE;
}
break;
case AND:
if((byte_value & (char) magic->value) == (char) magic->value) {
local_match = TRUE;
}
break;
case OR:
if((byte_value & (char) magic->value) != (char) magic->value) {
local_match = TRUE;
}
break;
case ANY:
local_match = TRUE;
break;
default:
if(byte_value == magic->value) {
local_match = TRUE;
}
}
if(local_match == TRUE){
if(magic->continuation != TRUE)
printf("%-16s\t", filename);
printf(magic->message, byte_value);
}
break;
case LESHORT:
short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
#ifndef _LIL_END
short_value = *(unsigned short *)byteSwap((char *)&short_value, sizeof(short));
#endif
if(magic->maskFlag == TRUE)
short_value = short_value & (unsigned short) magic->mask;
goto DOSHORT;
case BESHORT:
short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
#ifdef _LIL_END
short_value = *(unsigned short *)byteSwap((char *)&short_value, sizeof(short));
#endif
if(magic->maskFlag == TRUE)
short_value = short_value & (unsigned short) magic->mask;
goto DOSHORT;
case SHORT:
short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
short_value = *(unsigned short *)swap((char *)&short_value, sizeof(short));
if(magic->maskFlag == TRUE)
short_value = short_value & (unsigned short) magic->mask;
DOSHORT:
switch(magic->op){
case LESS:
if(short_value < magic->value) {
local_match = TRUE;
}
break;
case GREATER:
if(short_value > magic->value) {
local_match = TRUE;
}
break;
case AND:
if((short_value & (char) magic->value) == (char) magic->value) {
local_match = TRUE;
}
break;
case OR:
if((short_value & (char) magic->value) != (char) magic->value) {
local_match = TRUE;
}
break;
case ANY:
local_match = TRUE;
break;
default:
if(short_value == magic->value) {
local_match = TRUE;
}
}
if(local_match == TRUE){
if(magic->continuation != TRUE)
printf("%-16s\t", filename);
printf(magic->message, short_value);
}
break;
case LELONG:
long_value = (unsigned long) *((unsigned long *) &buf[magic->offset]);
#ifndef _LIL_END
long_value = *(unsigned long *)byteSwap((char *)&long_value, sizeof(long));
#endif
if(magic->maskFlag == TRUE)
long_value = long_value & (unsigned long) magic->mask;
goto DOLONG;
case BELONG:
long_value = (unsigned long) *((unsigned long *) &buf[magic->offset]);
#ifdef _LIL_END
long_value = *(unsigned long *)byteSwap((char *)&long_value, sizeof(long));
#endif
if(magic->maskFlag == TRUE)
long_value = long_value & (unsigned long) magic->mask;
goto DOLONG;
case LONG:
long_value = *((long *) &buf[magic->offset]);
long_value = *(unsigned long *)swap((char *)&long_value, sizeof(long));
if(magic->maskFlag == TRUE)
long_value = long_value & magic->mask;
DOLONG:
switch(magic->op){
case LESS:
if(long_value < magic->value) {
local_match = TRUE;
}
break;
case GREATER:
if(long_value > magic->value) {
local_match = TRUE;
}
break;
case AND:
if((long_value & (char) magic->value) == (char) magic->value) {
local_match = TRUE;
}
break;
case OR:
if((long_value & (char) magic->value) != (char) magic->value) {
local_match = TRUE;
}
break;
case ANY:
local_match = TRUE;
break;
default:
if(long_value == magic->value) {
local_match = TRUE;
}
}
if(local_match == TRUE){
if(magic->continuation != TRUE)
printf("%-16s\t", filename);
printf(magic->message, long_value);
}
break;
case STRING:
if(strncmp(&buf[magic->offset], magic->stringValue,
strlen(magic->stringValue)) == 0) {
if(magic->continuation != TRUE)
printf("%-16s\t", filename);
printf(magic->message, magic->stringValue);
local_match = TRUE;
}
break;
default: fprintf(stderr, "Error! Bad magic file type!\n");
return(FALSE);
}
if(local_match == TRUE)
match = TRUE;
if(match == TRUE){
if((magic->next == NULL) || (magic->next->continuation == FALSE))
printf("\n");
else if(local_match == TRUE)
printf(" ");
magic = magic->next;
if((magic != NULL) && (magic->continuation != TRUE))
magic = NULL;
}else{
magic = magic->next;
}
}
return(match);
}
void dirFiles(filename, dp)
char *filename;
DIR *dp;
{
#if (defined(_OSK) || defined(_OS9000))
struct direct *entry;
#else
struct dirent *entry;
#endif
char *path;
while((entry = readdir(dp)) != NULL){
if(entry->d_name[0] != '.'){
path = (char *) grab(sizeof(char) * (strlen(filename) +
strlen(entry->d_name) + 2));
strcpy(path, filename);
strcat(path, "/");
strcat(path, entry->d_name);
readFile(path);
free(path);
}
}
}