Annotation of libwww/Library/src/HTRules.c, revision 2.9

2.1       timbl       1: /*     Configuration manager for Hypertext Daemon              HTRules.c
                      2: **     ==========================================
                      3: **
                      4: **
                      5: ** History:
                      6: **      3 Jun 91       Written TBL
                      7: **     10 Aug 91       Authorisation added after Daniel Martin (pass, fail)
                      8: **                     Rule order in file changed
                      9: **                     Comments allowed with # on 1st char of rule line
                     10: **      17 Jun 92       Bug fix: pass and fail failed if didn't contain '*' TBL
2.9     ! secret     11: **       1 Sep 93       Bug fix: no memory check - Nathan Torkington
        !            12: **                      BYTE_ADDRESSING removed - Arthur Secret
        !            13: **                      
2.1       timbl      14: */
                     15: 
                     16: /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
                     17: #include "HTRules.h"
                     18: 
                     19: #include <stdio.h>
                     20: #include "tcp.h"
                     21: #include "HTFile.h"
                     22: 
                     23: #define LINE_LENGTH 256
                     24: 
                     25: 
                     26: typedef struct _rule {
                     27:        struct _rule *  next;
                     28:        HTRuleOp        op;
                     29:        char *          pattern;
                     30:        char *          equiv;
                     31: } rule;
                     32: 
                     33: /*     Module-wide variables
                     34: **     ---------------------
                     35: */
                     36: 
                     37: PRIVATE rule * rules = 0;      /* Pointer to first on list */
                     38: #ifndef PUT_ON_HEAD
                     39: PRIVATE rule * rule_tail = 0;  /* Pointer to last on list */
                     40: #endif
                     41: 
                     42: /*     Add rule to the list                                    HTAddRule()
                     43: **     --------------------
                     44: **
                     45: **  On entry,
                     46: **     pattern         points to 0-terminated string containing a single "*"
                     47: **     equiv           points to the equivalent string with * for the
                     48: **                     place where the text matched by * goes.
                     49: **  On exit,
                     50: **     returns         0 if success, -1 if error.
                     51: */
2.9     ! secret     52: 
2.1       timbl      53: #ifdef __STDC__
                     54: PUBLIC int HTAddRule (HTRuleOp op, const char * pattern, const char * equiv)
                     55: #else
                     56: int HTAddRule(op, pattern, equiv)
                     57:     HTRuleOp   op;
                     58:     char *     pattern;
                     59:     char *     equiv;
                     60: #endif
2.9     ! secret     61: { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
        !            62:     rule *      temp;
        !            63:     char *      pPattern;
        !            64: 
        !            65:     temp = (rule *)malloc(sizeof(*temp));
        !            66:     if (temp==NULL) 
        !            67:        outofmem(__FILE__, "HTAddRule"); 
        !            68:     pPattern = (char *)malloc(strlen(pattern)+1);
        !            69:     if (pPattern==NULL) 
        !            70:        outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      71:     if (equiv) {               /* Two operands */
                     72:        char *  pEquiv = (char *)malloc(strlen(equiv)+1);
2.9     ! secret     73:        if (pEquiv==NULL) 
        !            74:            outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      75:         temp->equiv = pEquiv;
                     76:         strcpy(pEquiv, equiv);
                     77:     } else {
                     78:         temp->equiv = 0;
                     79:     }
                     80:     temp->pattern = pPattern;
                     81:     temp->op = op;
                     82: 
                     83:     strcpy(pPattern, pattern);
                     84:     if (TRACE) printf("Rule: For `%s' op %i `%s'\n", pattern, op, equiv);
                     85: 
                     86: #ifdef PUT_ON_HEAD
                     87:     temp->next = rules;
                     88:     rules = temp;
                     89: #else
                     90:     temp->next = 0;
                     91:     if (rule_tail) rule_tail->next = temp;
                     92:     else rules = temp;
                     93:     rule_tail = temp;
                     94: #endif
                     95: 
                     96:         
                     97:     return 0;
                     98: }
                     99: 
                    100: 
                    101: /*     Clear all rules                                         HTClearRules()
                    102: **     ---------------
                    103: **
                    104: ** On exit,
                    105: **     There are no rules
                    106: **     returns         0 if success, -1 if error.
                    107: **
                    108: ** See also
                    109: **     HTAddRule()
                    110: */
                    111: #ifdef __STDC__
                    112: int HTClearRules(void)
                    113: #else
                    114: int HTClearRules()
                    115: #endif
                    116: {
                    117:     while (rules) {
                    118:        rule * temp = rules;
                    119:        rules = temp->next;
                    120:        free(temp->pattern);
                    121:        free(temp->equiv);
                    122:        free(temp);
                    123:     }
                    124: #ifndef PUT_ON_HEAD
                    125:     rule_tail = 0;
                    126: #endif
                    127: 
                    128:     return 0;
                    129: }
                    130: 
                    131: 
                    132: /*     Translate by rules                                      HTTranslate()
                    133: **     ------------------
                    134: **
                    135: **     The most recently defined rules are applied first.
                    136: **
                    137: ** On entry,
                    138: **     required        points to a string whose equivalent value is neeed
                    139: ** On exit,
                    140: **     returns         the address of the equivalent string allocated from
                    141: **                     the heap which the CALLER MUST FREE. If no translation
                    142: **                     occured, then it is a copy of te original.
                    143: */
                    144: #ifdef __STDC__
                    145: char * HTTranslate(const char * required)
                    146: #else
                    147: char * HTTranslate(required)
                    148:        char * required;
                    149: #endif
                    150: {
                    151:     rule * r;
                    152:     char * current = (char *)malloc(strlen(required)+1);
2.9     ! secret    153:     if (current==NULL) outofmem(__FILE__, "HTTranslate"); /* NT */
2.1       timbl     154:     strcpy(current, required);
                    155:     
                    156:     for(r = rules; r; r = r->next) {
                    157:         char * p = r->pattern;
                    158:        int m;   /* Number of characters matched against wildcard */
                    159:        CONST char * q = current;
                    160:        for(;*p && *q; p++, q++) {   /* Find first mismatch */
                    161:            if (*p!=*q) break;
                    162:        }
                    163: 
                    164:        if (*p == '*') {                /* Match up to wildcard */
                    165:            m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
                    166:            if(m<0) continue;           /* tail is too short to match */
                    167:            if (0!=strcmp(q+m, p+1)) continue;  /* Tail mismatch */
                    168:        } else                          /* Not wildcard */
                    169:            if (*p != *q) continue;     /* plain mismatch: go to next rule */
                    170: 
                    171:        switch (r->op) {                /* Perform operation */
                    172:        case HT_Pass:                           /* Authorised */
                    173:                if (!r->equiv) {
                    174:                    if (TRACE) printf("HTRule: Pass `%s'\n", current);
                    175:                    return current;
                    176:                }
                    177:                /* Fall through ...to map and pass */
                    178:                
                    179:        case HT_Map:
                    180:            if (*p == *q) { /* End of both strings, no wildcard */
                    181:                  if (TRACE) printf(
                    182:                               "For `%s' using `%s'\n", current, r->equiv);  
                    183:                  StrAllocCopy(current, r->equiv); /* use entire translation */
                    184:            } else {
                    185:                  char * ins = strchr(r->equiv, '*');   /* Insertion point */
                    186:                  if (ins) {    /* Consistent rule!!! */
                    187:                        char * temp = (char *)malloc(
                    188:                                strlen(r->equiv)-1 + m + 1);
2.9     ! secret    189:                        if (temp==NULL) 
        !           190:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     191:                        strncpy(temp,   r->equiv, ins-r->equiv);
                    192:                        /* Note: temp may be unterminated now! */
                    193:                        strncpy(temp+(ins-r->equiv), q, m);  /* Matched bit */
                    194:                        strcpy (temp+(ins-r->equiv)+m, ins+1);  /* Last bit */
                    195:                        if (TRACE) printf("For `%s' using `%s'\n",
                    196:                                                current, temp);
                    197:                        free(current);
                    198:                        current = temp;                 /* Use this */
                    199: 
                    200:                    } else {    /* No insertion point */
                    201:                        char * temp = (char *)malloc(strlen(r->equiv)+1);
2.9     ! secret    202:                        if (temp==NULL) 
        !           203:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     204:                        strcpy(temp, r->equiv);
                    205:                        if (TRACE) printf("For `%s' using `%s'\n",
                    206:                                                current, temp);
                    207:                        free(current);
                    208:                        current = temp;                 /* Use this */
                    209:                    } /* If no insertion point exists */
                    210:                }
                    211:                if (r->op == HT_Pass) {
                    212:                    if (TRACE) printf("HTRule: ...and pass `%s'\n", current);
                    213:                    return current;
                    214:                }
                    215:                break;
                    216: 
                    217:            case HT_Invalid:
                    218:            case HT_Fail:                               /* Unauthorised */
                    219:                    if (TRACE) printf("HTRule: *** FAIL `%s'\n", current);
                    220:                    return (char *)0;
                    221:                                    
                    222:                } /* if tail matches ... switch operation */
                    223: 
                    224:     } /* loop over rules */
                    225: 
                    226: 
                    227:     return current;
                    228: }
                    229: 
2.7       timbl     230: /*     Load one line of configuration
                    231: **     ------------------------------
                    232: **
                    233: **     Call this, for example, to load a X resource with config info.
                    234: **
                    235: ** returns     0 OK, < 0 syntax error.
                    236: */
                    237: PUBLIC int  HTSetConfiguration ARGS1(CONST char *, config)
                    238: {
                    239:     HTRuleOp op;
                    240:     char * line = NULL;
                    241:     char * pointer = line;
                    242:     char *word1, *word2, *word3;
                    243:     float quality, secs, secs_per_byte;
                    244:     int status;
                    245:     
                    246:     StrAllocCopy(line, config);
                    247:     {
                    248:        char * p = strchr(line, '#');   /* Chop off comments */
                    249:        if (p) *p = 0;
                    250:     }
                    251:     pointer = line;
                    252:     word1 = HTNextField(&pointer);
                    253:     if (!word1) {
                    254:        free(line);
                    255:        return 0;
                    256:     } ;        /* Comment only or blank */
                    257:     
                    258:     word2 = HTNextField(&pointer);
                    259:     word3 = HTNextField(&pointer);
                    260:     if (!word2) {
                    261:        fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
                    262:        free(line);
                    263:        return -2;      /*syntax error */
                    264:     }
                    265: 
                    266:     if (0==strcasecomp(word1, "suffix")) {
2.8       timbl     267:         char * encoding = HTNextField(&pointer);
                    268:        if (pointer) status = sscanf(pointer, "%f", &quality);
                    269:        else status = 0;
                    270:        HTSetSuffix(word2,      word3,
                    271:                                encoding ? encoding : "binary",
                    272:                                status >= 1? quality : 1.0);
2.7       timbl     273: 
                    274:     } else if (0==strcasecomp(word1, "presentation")) {
2.8       timbl     275:         if (pointer) status = sscanf(pointer, "%f%f%f",
                    276:                            &quality, &secs, &secs_per_byte);
                    277:         else status = 0;
2.7       timbl     278:        HTSetPresentation(word2, word3,
                    279:                    status >= 1? quality                : 1.0,
                    280:                    status >= 2 ? secs          : 0.0,
                    281:                    status >= 3 ? secs_per_byte         : 0.0 );
2.1       timbl     282: 
2.7       timbl     283:     } else {
                    284:        op =    0==strcasecomp(word1, "map")  ? HT_Map
                    285:            :   0==strcasecomp(word1, "pass") ? HT_Pass
                    286:            :   0==strcasecomp(word1, "fail") ? HT_Fail
                    287:            :                                           HT_Invalid;
                    288:        if (op==HT_Invalid) {
                    289:            fprintf(stderr, "HTRule: Bad rule `%s'\n", config);
                    290:        } else {  
                    291:            HTAddRule(op, word2, word3);
                    292:        } 
                    293:     }
                    294:     free(line);
                    295:     return 0;
                    296: }
                    297: 
2.1       timbl     298: 
                    299: /*     Load the rules from a file                              HtLoadRules()
                    300: **     --------------------------
                    301: **
                    302: ** On entry,
                    303: **     Rules can be in any state
                    304: ** On exit,
                    305: **     Any existing rules will have been kept.
2.7       timbl     306: **     Any new rules will have been loaded.
                    307: **     Returns         0 if no error, 0 if error!
2.1       timbl     308: **
                    309: ** Bugs:
                    310: **     The strings may not contain spaces.
                    311: */
                    312: 
                    313: int HTLoadRules ARGS1(CONST char *, filename)
                    314: {
                    315:     FILE * fp = fopen(filename, "r");
                    316:     char line[LINE_LENGTH+1];
                    317:     
                    318:     if (!fp) {
                    319:         if (TRACE) printf("HTRules: Can't open rules file %s\n", filename);
                    320:        return -1; /* File open error */
                    321:     }
                    322:     for(;;) {
                    323:        if (!fgets(line, LINE_LENGTH+1, fp)) break;     /* EOF or error */
2.7       timbl     324:        (void) HTSetConfiguration(line);
2.1       timbl     325:     }
                    326:     fclose(fp);
2.7       timbl     327:     return 0;          /* No error or syntax errors ignored */
2.1       timbl     328: }

Webmaster