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

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

Webmaster