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

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

Webmaster