home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / file.lzh / readmagic.c < prev    next >
Text File  |  1995-04-27  |  7KB  |  293 lines

  1. /************************************************************************
  2.  * readmagic.c                                                          *
  3.  ************************************************************************
  4.  * code to read in magic files and build a data structure with the info *
  5.  ************************************************************************
  6.  * Original code: Scott McGee  10/2/93                                  *
  7.  ***********************************************************************/
  8.  
  9. #include <file.h>
  10.  
  11.  
  12. MagicList *readMagic(filename)
  13.   char *filename;
  14. {
  15.     MagicList *list;
  16.     MagicList *tail;
  17.     MagicList *new;
  18.     FILE      *fp;
  19.     char      linebuf[MAXLINELEN];
  20.     char      *buf;
  21.     int       status = SUCCESS;
  22.  
  23.     /* open the file */
  24.     if((fp = fopen(filename, "r")) == (FILE*) NULL){
  25.         fprintf(stderr, "Magic file \"%s\" could not be opened! (error # %d)\n", filename, errno);
  26.         return(NULL);
  27.     }
  28.  
  29.     list = NULL;
  30.  
  31.     /* parse file */
  32.  
  33.     while(status == SUCCESS){
  34.         buf = linebuf;
  35.         if(fgets(buf, MAXLINELEN-1, fp) == NULL){
  36.             /* error */
  37.             status = ERROR;
  38.             break;
  39.         }
  40.  
  41.         /* skip comments */
  42.         while(*buf == '#'){
  43.             if(fgets(buf, MAXLINELEN-1, fp) == NULL){
  44.                 /* error */
  45.                 status = ERROR;
  46.                 break;
  47.             }
  48.         }
  49.  
  50.         buf[strlen(buf)-1] = '\0';
  51.  
  52.         new = decodeLine(buf);
  53.         if(new != NULL){
  54.             if(list == NULL){
  55.                 list = new;
  56.                    tail = list;
  57.             }else
  58.                 tail->next = new;
  59.             tail = new;
  60.         }else{
  61.             status = ERROR;
  62.         }
  63.     }
  64.  
  65.     return(list);
  66. }
  67.  
  68.  
  69. MagicList *decodeLine(buf)
  70.   char *buf;
  71. {
  72.     MagicList *new;
  73.     char      *tok;
  74.     int       val;
  75.  
  76.     char      oldbuf[MAXLINELEN];
  77.  
  78. #ifdef DEBUG_READMAGIC
  79.     strcpy(oldbuf, buf);
  80. #endif
  81.  
  82.     new = (MagicList *) grab(sizeof(struct MAGICLIST));
  83.  
  84.        /* check for a 'continuaion' line */
  85.     if(*buf == '>'){        /* got one! */
  86.         buf++;
  87.         new->continuation = TRUE;
  88.     }else
  89.         new->continuation = FALSE;
  90.  
  91.     /* check first token and get offset */
  92.     tok = strtok(buf, " \t");
  93.     if(tok == NULL){
  94.         free(new);
  95.         return(NULL);
  96.     }
  97.     new->offset = strtoul(tok, (char **)NULL, 0);
  98.  
  99.     /* get next token and set type field */
  100.     tok = strtok(NULL, " \t");
  101.     if(tok == NULL){
  102.         free(new);
  103.         return(NULL);
  104.     }
  105.     if(strncmp(tok, "byte", 4) == 0){
  106.         new->type = BYTE;
  107.         tok = tok + 4;
  108.     }else if(strncmp(tok, "short", 5) == 0){
  109.            new->type = SHORT;
  110.            tok = tok + 5;
  111.     }else if(strncmp(tok, "leshort", 7) == 0){
  112.            new->type = LESHORT;
  113.            tok = tok + 7;
  114.     }else if(strncmp(tok, "beshort", 7) == 0){
  115.            new->type = BESHORT;
  116.            tok = tok + 7;
  117.     }else if(strncmp(tok, "long", 4) == 0){
  118.            new->type = LONG;
  119.            tok = tok + 4;
  120.     }else if(strncmp(tok, "lelong", 6) == 0){
  121.            new->type = LELONG;
  122.            tok = tok + 6;
  123.     }else if(strncmp(tok, "belong", 6) == 0){
  124.            new->type = BELONG;
  125.            tok = tok + 6;
  126.     }else if(strncmp(tok, "string", 6) == 0){
  127.            new->type = STRING;
  128.            tok = tok + 6;
  129.     }else{
  130.         free(new);
  131.         return(NULL);
  132.     }
  133.     if(*tok == '&'){
  134.         new->maskFlag = TRUE;
  135.         tok++;
  136.         new->mask = strtoul(tok, NULL, 0);
  137.     }else
  138.         new->maskFlag = FALSE;
  139.  
  140.     /* get value token and check for operators */
  141.     if(new->type != STRING){
  142.         tok = strtok(NULL, " \t");
  143.         if(tok == NULL){
  144.             free(new);
  145.             return(NULL);
  146.         }
  147.         switch(*tok){
  148.             case '=':
  149.             new->op = EQUAL;
  150.             tok++;
  151.             break;
  152.             
  153.             case '<':
  154.             new->op = LESS;
  155.             tok++;
  156.             break;
  157.             
  158.             case '>':
  159.             new->op = GREATER;
  160.             tok++;
  161.             break;
  162.             
  163.             case '&':
  164.             new->op = AND;
  165.             tok++;
  166.             break;
  167.             
  168.             case '^':
  169.             new->op = OR;
  170.             tok++;
  171.             break;
  172.             
  173.             case 'x':
  174.             new->op = ANY;
  175.             tok++;
  176.             break;
  177.             
  178.             default:
  179.             new->op = NONE;
  180.         }
  181.  
  182.         /* decode value from token */
  183.         new->value = strtoul(tok, NULL, 0);
  184.         new->stringValue = NULL;
  185.     }else{
  186.         tok = strtok(NULL, "\t");
  187.         new->stringValue = stringDecode(tok);
  188.     }
  189.  
  190. #ifdef DEBUG_READMAGIC
  191.     if(new->type == STRING){
  192.         printf("%s\n", oldbuf);
  193.         printf("->%s\n", new->stringValue);
  194.     }
  195. #endif
  196.  
  197.     /* get message */
  198.     tok = tok + strlen(tok) + 1;         /* skip previous token */
  199.     tok = tok + strspn(tok, " \t");      /* skip white space    */
  200.     new->message = (char *) grab(sizeof(char) * (strlen(tok) + 1));
  201.     strcpy(new->message, tok);
  202.  
  203.     new->next = NULL;
  204.  
  205.     return(new);
  206. }
  207.  
  208.  
  209. char *stringDecode(str)
  210.   char *str;
  211. {
  212.     char buf[MAXLINELEN];
  213.     char *new;
  214.     char *old;
  215.     int  i;
  216.  
  217.     new = buf;
  218.     old = str;
  219.  
  220.     while(*old != '\0'){
  221.         if(*old != '\\'){
  222.             *new = *old;
  223.             new++;
  224.             old++;
  225.         }else{
  226.             switch(old[1]){
  227. #if defined(__STDC__) || defined(_ANSI_EXT)
  228.                 case 'a':  *new = '\a'; /* bell */
  229.                            break;
  230. #endif
  231.                 case 'b':  *new = '\b'; /* backspace */
  232.                            break;
  233.                 case 'f':  *new = '\f'; /* form feed */
  234.                            break;
  235.                 case 'n':  *new = '\n'; /* newline */
  236.                            break;
  237.                 case 'r':  *new = '\r'; /* carriage return */
  238.                            break;
  239.                 case 't':  *new = '\t'; /* tab */
  240.                            break;
  241.                 case 'v':  *new = '\v'; /* vertical tab */
  242.                            break;
  243.                 case '\'': *new = '\''; /* single quote */
  244.                            break;
  245.                 case '\"': *new = '\"'; /* double quote */
  246.                            break;
  247. #if defined(__STDC__) || defined(_ANSI_EXT)
  248.                 case '?':  *new = '\?'; /* question mark */
  249.                            break;
  250. #endif
  251.                 case '\\': *new = '\\'; /* backslash */
  252.                            break;
  253.                 case 'x':  *new = '\0'; /* hex value escape */
  254.                            for(i=0;i<2;i++){
  255.                                *new = *new << 4;
  256.                                *new += old[2] - '0';
  257.                                old++;
  258.                            }
  259.                            break;
  260.  
  261.                 case '0':
  262.                 case '1':
  263.                 case '2':
  264.                 case '3':
  265.                 case '4':
  266.                 case '5':
  267.                 case '6':
  268.                 case '7':  *new = '\0'; /* assume 3 octal digits */
  269.                            for(i=0;i<3;i++){
  270.                                *new = *new << 3;
  271.                                *new += old[1] - '0';
  272.                                old++;
  273.                            }
  274.                            old--;
  275.                            break;
  276.                 default:   *new = old[1];  /* just copy the escaped char */
  277.             }
  278.             old += 2;
  279.             new++;
  280.         }
  281.     }
  282.  
  283.     /* now, null terminate it and malloc up a copy to return */
  284.        *new = '\0';
  285.        if(strlen(buf) > 0){
  286.            new = (char *) grab(sizeof(char) * (strlen(buf) + 1));
  287.            strcpy(new, buf);
  288.            return(new);
  289.        }
  290.     return(NULL);
  291. }
  292.  
  293.