home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
MISC
/
file.lzh
/
readmagic.c
< prev
next >
Wrap
Text File
|
1995-04-27
|
7KB
|
293 lines
/************************************************************************
* readmagic.c *
************************************************************************
* code to read in magic files and build a data structure with the info *
************************************************************************
* Original code: Scott McGee 10/2/93 *
***********************************************************************/
#include <file.h>
MagicList *readMagic(filename)
char *filename;
{
MagicList *list;
MagicList *tail;
MagicList *new;
FILE *fp;
char linebuf[MAXLINELEN];
char *buf;
int status = SUCCESS;
/* open the file */
if((fp = fopen(filename, "r")) == (FILE*) NULL){
fprintf(stderr, "Magic file \"%s\" could not be opened! (error # %d)\n", filename, errno);
return(NULL);
}
list = NULL;
/* parse file */
while(status == SUCCESS){
buf = linebuf;
if(fgets(buf, MAXLINELEN-1, fp) == NULL){
/* error */
status = ERROR;
break;
}
/* skip comments */
while(*buf == '#'){
if(fgets(buf, MAXLINELEN-1, fp) == NULL){
/* error */
status = ERROR;
break;
}
}
buf[strlen(buf)-1] = '\0';
new = decodeLine(buf);
if(new != NULL){
if(list == NULL){
list = new;
tail = list;
}else
tail->next = new;
tail = new;
}else{
status = ERROR;
}
}
return(list);
}
MagicList *decodeLine(buf)
char *buf;
{
MagicList *new;
char *tok;
int val;
char oldbuf[MAXLINELEN];
#ifdef DEBUG_READMAGIC
strcpy(oldbuf, buf);
#endif
new = (MagicList *) grab(sizeof(struct MAGICLIST));
/* check for a 'continuaion' line */
if(*buf == '>'){ /* got one! */
buf++;
new->continuation = TRUE;
}else
new->continuation = FALSE;
/* check first token and get offset */
tok = strtok(buf, " \t");
if(tok == NULL){
free(new);
return(NULL);
}
new->offset = strtoul(tok, (char **)NULL, 0);
/* get next token and set type field */
tok = strtok(NULL, " \t");
if(tok == NULL){
free(new);
return(NULL);
}
if(strncmp(tok, "byte", 4) == 0){
new->type = BYTE;
tok = tok + 4;
}else if(strncmp(tok, "short", 5) == 0){
new->type = SHORT;
tok = tok + 5;
}else if(strncmp(tok, "leshort", 7) == 0){
new->type = LESHORT;
tok = tok + 7;
}else if(strncmp(tok, "beshort", 7) == 0){
new->type = BESHORT;
tok = tok + 7;
}else if(strncmp(tok, "long", 4) == 0){
new->type = LONG;
tok = tok + 4;
}else if(strncmp(tok, "lelong", 6) == 0){
new->type = LELONG;
tok = tok + 6;
}else if(strncmp(tok, "belong", 6) == 0){
new->type = BELONG;
tok = tok + 6;
}else if(strncmp(tok, "string", 6) == 0){
new->type = STRING;
tok = tok + 6;
}else{
free(new);
return(NULL);
}
if(*tok == '&'){
new->maskFlag = TRUE;
tok++;
new->mask = strtoul(tok, NULL, 0);
}else
new->maskFlag = FALSE;
/* get value token and check for operators */
if(new->type != STRING){
tok = strtok(NULL, " \t");
if(tok == NULL){
free(new);
return(NULL);
}
switch(*tok){
case '=':
new->op = EQUAL;
tok++;
break;
case '<':
new->op = LESS;
tok++;
break;
case '>':
new->op = GREATER;
tok++;
break;
case '&':
new->op = AND;
tok++;
break;
case '^':
new->op = OR;
tok++;
break;
case 'x':
new->op = ANY;
tok++;
break;
default:
new->op = NONE;
}
/* decode value from token */
new->value = strtoul(tok, NULL, 0);
new->stringValue = NULL;
}else{
tok = strtok(NULL, "\t");
new->stringValue = stringDecode(tok);
}
#ifdef DEBUG_READMAGIC
if(new->type == STRING){
printf("%s\n", oldbuf);
printf("->%s\n", new->stringValue);
}
#endif
/* get message */
tok = tok + strlen(tok) + 1; /* skip previous token */
tok = tok + strspn(tok, " \t"); /* skip white space */
new->message = (char *) grab(sizeof(char) * (strlen(tok) + 1));
strcpy(new->message, tok);
new->next = NULL;
return(new);
}
char *stringDecode(str)
char *str;
{
char buf[MAXLINELEN];
char *new;
char *old;
int i;
new = buf;
old = str;
while(*old != '\0'){
if(*old != '\\'){
*new = *old;
new++;
old++;
}else{
switch(old[1]){
#if defined(__STDC__) || defined(_ANSI_EXT)
case 'a': *new = '\a'; /* bell */
break;
#endif
case 'b': *new = '\b'; /* backspace */
break;
case 'f': *new = '\f'; /* form feed */
break;
case 'n': *new = '\n'; /* newline */
break;
case 'r': *new = '\r'; /* carriage return */
break;
case 't': *new = '\t'; /* tab */
break;
case 'v': *new = '\v'; /* vertical tab */
break;
case '\'': *new = '\''; /* single quote */
break;
case '\"': *new = '\"'; /* double quote */
break;
#if defined(__STDC__) || defined(_ANSI_EXT)
case '?': *new = '\?'; /* question mark */
break;
#endif
case '\\': *new = '\\'; /* backslash */
break;
case 'x': *new = '\0'; /* hex value escape */
for(i=0;i<2;i++){
*new = *new << 4;
*new += old[2] - '0';
old++;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': *new = '\0'; /* assume 3 octal digits */
for(i=0;i<3;i++){
*new = *new << 3;
*new += old[1] - '0';
old++;
}
old--;
break;
default: *new = old[1]; /* just copy the escaped char */
}
old += 2;
new++;
}
}
/* now, null terminate it and malloc up a copy to return */
*new = '\0';
if(strlen(buf) > 0){
new = (char *) grab(sizeof(char) * (strlen(buf) + 1));
strcpy(new, buf);
return(new);
}
return(NULL);
}