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

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
2.12      luotonen   13: **     11 Sep 93  MD   Changed %i into %d in debug printf. 
2.10      duns       14: **                     VMS does not recognize %i.
                     15: **                     Bug Fix: in case of PASS, only one parameter to printf.
2.12      luotonen   16: **     19 Sep 93  AL   Added Access Authorization stuff.
                     17: **      1 Nov 93  AL   Added htbin.
2.15      luotonen   18: **     30 Nov 93  AL   Added HTTranslateReq().
2.11      luotonen   19: **
2.1       timbl      20: */
                     21: 
                     22: /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
                     23: #include "HTRules.h"
                     24: 
                     25: #include <stdio.h>
                     26: #include "tcp.h"
                     27: #include "HTFile.h"
2.17    ! luotonen   28: #include "HTParse.h"   /* HTParse() */
2.1       timbl      29: 
                     30: #define LINE_LENGTH 256
                     31: 
                     32: 
                     33: typedef struct _rule {
                     34:        struct _rule *  next;
                     35:        HTRuleOp        op;
                     36:        char *          pattern;
                     37:        char *          equiv;
                     38: } rule;
                     39: 
2.17    ! luotonen   40: /*     Global variables
2.12      luotonen   41: **     ----------------
                     42: */
2.17    ! luotonen   43: PUBLIC char * HTBinDir = NULL;         /* Physical /htbin directory    */
        !            44:                                         /* path (this is obsolite, and */
        !            45:                                         /* only used if HTSearchScript */
        !            46:                                         /* is given as non-absolute -- */
        !            47:                                         /* and this is only for rule   */
        !            48:                                         /* file backward-compatibility.        */
        !            49: PUBLIC char * HTSearchScript = NULL;   /* Search script name.          */
        !            50: PUBLIC char * HTPutScript = NULL;      /* Script to handle PUT         */
        !            51: PUBLIC char * HTPostScript = NULL;     /* Script to handle POST        */
2.12      luotonen   52: 
2.13      luotonen   53: 
2.1       timbl      54: /*     Module-wide variables
                     55: **     ---------------------
                     56: */
                     57: 
                     58: PRIVATE rule * rules = 0;      /* Pointer to first on list */
                     59: #ifndef PUT_ON_HEAD
                     60: PRIVATE rule * rule_tail = 0;  /* Pointer to last on list */
                     61: #endif
                     62: 
2.11      luotonen   63: 
2.1       timbl      64: /*     Add rule to the list                                    HTAddRule()
                     65: **     --------------------
                     66: **
                     67: **  On entry,
                     68: **     pattern         points to 0-terminated string containing a single "*"
                     69: **     equiv           points to the equivalent string with * for the
                     70: **                     place where the text matched by * goes.
                     71: **  On exit,
                     72: **     returns         0 if success, -1 if error.
                     73: */
2.9       secret     74: 
2.15      luotonen   75: PUBLIC int HTAddRule ARGS3(HTRuleOp,           op,
                     76:                           CONST char *,        pattern,
                     77:                           CONST char *,        equiv)
2.9       secret     78: { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
                     79:     rule *      temp;
                     80:     char *      pPattern;
                     81: 
                     82:     temp = (rule *)malloc(sizeof(*temp));
                     83:     if (temp==NULL) 
                     84:        outofmem(__FILE__, "HTAddRule"); 
                     85:     pPattern = (char *)malloc(strlen(pattern)+1);
                     86:     if (pPattern==NULL) 
                     87:        outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      88:     if (equiv) {               /* Two operands */
                     89:        char *  pEquiv = (char *)malloc(strlen(equiv)+1);
2.9       secret     90:        if (pEquiv==NULL) 
                     91:            outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      92:         temp->equiv = pEquiv;
                     93:         strcpy(pEquiv, equiv);
                     94:     } else {
                     95:         temp->equiv = 0;
                     96:     }
                     97:     temp->pattern = pPattern;
                     98:     temp->op = op;
                     99: 
                    100:     strcpy(pPattern, pattern);
2.10      duns      101:     if (TRACE) {
                    102:        if (equiv)
2.17    ! luotonen  103:           fprintf(stderr, "Rule: For `%s' op %d `%s'\n", pattern, op, equiv);
2.10      duns      104:        else
2.17    ! luotonen  105:           fprintf(stderr, "Rule: For `%s' op %d\n", pattern, op);
2.10      duns      106:     }
2.1       timbl     107: 
                    108: #ifdef PUT_ON_HEAD
                    109:     temp->next = rules;
                    110:     rules = temp;
                    111: #else
                    112:     temp->next = 0;
                    113:     if (rule_tail) rule_tail->next = temp;
                    114:     else rules = temp;
                    115:     rule_tail = temp;
                    116: #endif
                    117: 
                    118:         
                    119:     return 0;
                    120: }
                    121: 
                    122: 
                    123: /*     Clear all rules                                         HTClearRules()
                    124: **     ---------------
                    125: **
                    126: ** On exit,
                    127: **     There are no rules
                    128: **     returns         0 if success, -1 if error.
                    129: **
                    130: ** See also
                    131: **     HTAddRule()
                    132: */
2.15      luotonen  133: PUBLIC int HTClearRules NOARGS
2.1       timbl     134: {
                    135:     while (rules) {
                    136:        rule * temp = rules;
                    137:        rules = temp->next;
                    138:        free(temp->pattern);
                    139:        free(temp->equiv);
                    140:        free(temp);
                    141:     }
                    142: #ifndef PUT_ON_HEAD
                    143:     rule_tail = 0;
                    144: #endif
                    145: 
                    146:     return 0;
                    147: }
                    148: 
                    149: 
                    150: /*     Translate by rules                                      HTTranslate()
                    151: **     ------------------
                    152: **
2.15      luotonen  153: ** ATTENTION:
                    154: **     THIS FUNCTION HAS BEEN OBSOLITED BY HTTranslateReq()
                    155: **     ON SERVER SIDE -- ON BROWSER SIDE THIS IS STILL USED!
                    156: **     Don't add new server features to this, this already has
                    157: **     more than it can handle cleanly.
                    158: **
                    159: **     The most recently defined rules are applied last.
2.1       timbl     160: **
                    161: ** On entry,
                    162: **     required        points to a string whose equivalent value is neeed
                    163: ** On exit,
                    164: **     returns         the address of the equivalent string allocated from
                    165: **                     the heap which the CALLER MUST FREE. If no translation
                    166: **                     occured, then it is a copy of te original.
2.11      luotonen  167: ** NEW FEATURES:
                    168: **                     When a "protect" or "defprot" rule is mathed,
                    169: **                     a call to HTAA_setCurrentProtection() or
                    170: **                     HTAA_setDefaultProtection() is made to notify
                    171: **                     the Access Authorization module that the file is
                    172: **                     protected, and so it knows how to handle it.
                    173: **                                                             -- AL
2.1       timbl     174: */
2.15      luotonen  175: PUBLIC char * HTTranslate ARGS1(CONST char *, required)
2.1       timbl     176: {
                    177:     rule * r;
2.11      luotonen  178:     char *current = NULL;
                    179:     StrAllocCopy(current, required);
                    180: 
2.15      luotonen  181: #ifdef OLD_CODE
2.11      luotonen  182:     HTAA_clearProtections();   /* Reset from previous call -- AL */
2.15      luotonen  183: #endif
2.11      luotonen  184: 
2.1       timbl     185:     for(r = rules; r; r = r->next) {
                    186:         char * p = r->pattern;
2.11      luotonen  187:        int m=0;   /* Number of characters matched against wildcard */
2.1       timbl     188:        CONST char * q = current;
                    189:        for(;*p && *q; p++, q++) {   /* Find first mismatch */
                    190:            if (*p!=*q) break;
                    191:        }
                    192: 
                    193:        if (*p == '*') {                /* Match up to wildcard */
                    194:            m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
                    195:            if(m<0) continue;           /* tail is too short to match */
                    196:            if (0!=strcmp(q+m, p+1)) continue;  /* Tail mismatch */
                    197:        } else                          /* Not wildcard */
                    198:            if (*p != *q) continue;     /* plain mismatch: go to next rule */
                    199: 
                    200:        switch (r->op) {                /* Perform operation */
2.11      luotonen  201: 
                    202: #ifdef ACCESS_AUTH
                    203:        case HT_DefProt:
                    204:        case HT_Protect:
                    205:            {
                    206:                char *local_copy = NULL;
                    207:                char *p;
                    208:                char *eff_ids = NULL;
                    209:                char *prot_file = NULL;
                    210: 
                    211:                if (TRACE) fprintf(stderr,
                    212:                                   "HTRule: `%s' matched %s %s: `%s'\n",
                    213:                                   current,
                    214:                                   (r->op==HT_Protect ? "Protect" : "DefProt"),
                    215:                                   "rule, setup",
                    216:                                   (r->equiv ? r->equiv :
                    217:                                    (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
                    218: 
                    219:                if (r->equiv) {
                    220:                    StrAllocCopy(local_copy, r->equiv);
                    221:                    p = local_copy;
                    222:                    prot_file = HTNextField(&p);
                    223:                    eff_ids = HTNextField(&p);
                    224:                }
                    225: 
2.15      luotonen  226: #ifdef THESE_NO_LONGER_WORK
2.11      luotonen  227:                if (r->op == HT_Protect)
                    228:                    HTAA_setCurrentProtection(current, prot_file, eff_ids);
                    229:                else
                    230:                    HTAA_setDefaultProtection(current, prot_file, eff_ids);
2.15      luotonen  231: #endif
2.11      luotonen  232:                FREE(local_copy);
                    233: 
                    234:                /* continue translating rules */
                    235:            }
                    236:            break;
                    237: #endif ACCESS_AUTH
                    238: 
2.1       timbl     239:        case HT_Pass:                           /* Authorised */
                    240:                if (!r->equiv) {
2.17    ! luotonen  241:                    CTRACE(stderr, "HTRule: Pass `%s'\n", current);
2.1       timbl     242:                    return current;
                    243:                }
2.11      luotonen  244:                /* Else fall through ...to map and pass */
2.1       timbl     245:                
                    246:        case HT_Map:
                    247:            if (*p == *q) { /* End of both strings, no wildcard */
2.17    ! luotonen  248:                CTRACE(stderr, "For `%s' using `%s'\n", current, r->equiv);  
        !           249:                StrAllocCopy(current, r->equiv); /* use entire translation */
2.1       timbl     250:            } else {
                    251:                  char * ins = strchr(r->equiv, '*');   /* Insertion point */
                    252:                  if (ins) {    /* Consistent rule!!! */
                    253:                        char * temp = (char *)malloc(
                    254:                                strlen(r->equiv)-1 + m + 1);
2.9       secret    255:                        if (temp==NULL) 
                    256:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     257:                        strncpy(temp,   r->equiv, ins-r->equiv);
                    258:                        /* Note: temp may be unterminated now! */
                    259:                        strncpy(temp+(ins-r->equiv), q, m);  /* Matched bit */
                    260:                        strcpy (temp+(ins-r->equiv)+m, ins+1);  /* Last bit */
2.17    ! luotonen  261:                        CTRACE(stderr, "For `%s' using `%s'\n",
2.1       timbl     262:                                                current, temp);
                    263:                        free(current);
                    264:                        current = temp;                 /* Use this */
                    265: 
                    266:                    } else {    /* No insertion point */
                    267:                        char * temp = (char *)malloc(strlen(r->equiv)+1);
2.9       secret    268:                        if (temp==NULL) 
                    269:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     270:                        strcpy(temp, r->equiv);
2.17    ! luotonen  271:                        CTRACE(stderr, "For `%s' using `%s'\n", current, temp);
2.1       timbl     272:                        free(current);
                    273:                        current = temp;                 /* Use this */
                    274:                    } /* If no insertion point exists */
                    275:                }
                    276:                if (r->op == HT_Pass) {
2.17    ! luotonen  277:                    CTRACE(stderr, "HTRule: ...and pass `%s'\n", current);
2.1       timbl     278:                    return current;
                    279:                }
                    280:                break;
                    281: 
2.15      luotonen  282:        case HT_Exec:
2.11      luotonen  283:        case HT_Invalid:
                    284:        case HT_Fail:                           /* Unauthorised */
2.15      luotonen  285:        default:
2.17    ! luotonen  286:            CTRACE(stderr,"HTRule: *** FAIL `%s'\n", current);
        !           287:            return (char *)0;
2.1       timbl     288:                                    
2.11      luotonen  289:        } /* if tail matches ... switch operation */
2.1       timbl     290: 
                    291:     } /* loop over rules */
                    292: 
                    293: 
                    294:     return current;
                    295: }
                    296: 
2.15      luotonen  297: 
                    298: 
2.17    ! luotonen  299: /*     Translate by rules                              HTTranslateReq()
2.15      luotonen  300: **     ------------------
                    301: **
                    302: ** On entry,
                    303: **     req             request structure.
                    304: **     req->simplified simplified pathname (no ..'s etc in it),
                    305: **                     which will be translated.
                    306: **                     If this starts with /htbin/ it is taken
                    307: **                     to be a script call request.
                    308: **
                    309: ** On exit,
                    310: **     returns         YES on success, NO on failure (Forbidden).
                    311: **     req->translated contains the translated filename;
                    312: **                     NULL if a script call.
                    313: **     req->script     contains the executable script name;
                    314: **                     NULL if not a script call.
                    315: */
                    316: PUBLIC BOOL HTTranslateReq ARGS1(HTRequest *, req)
                    317: {
                    318:     rule * r;
                    319:     char *current = NULL;
                    320: 
                    321:     if (!req  ||  !req->simplified)
                    322:        return NO;
                    323: 
2.16      timbl     324:     StrAllocCopy(current, req->simplified);
2.15      luotonen  325: 
                    326:     for(r = rules; r; r = r->next) {
                    327:         char * p = r->pattern;
                    328:        int m=0;   /* Number of characters matched against wildcard */
                    329:        CONST char * q = current;
                    330:        for(;*p && *q; p++, q++) {   /* Find first mismatch */
                    331:            if (*p!=*q) break;
                    332:        }
                    333: 
                    334:        if (*p == '*') {                /* Match up to wildcard */
                    335:            m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
                    336:            if(m<0) continue;           /* tail is too short to match */
                    337:            if (0!=strcmp(q+m, p+1)) continue;  /* Tail mismatch */
                    338:        } else                          /* Not wildcard */
                    339:            if (*p != *q) continue;     /* plain mismatch: go to next rule */
                    340: 
                    341:        switch (r->op) {                /* Perform operation */
                    342: 
                    343: #ifdef ACCESS_AUTH
                    344:        case HT_DefProt:
                    345:        case HT_Protect:
                    346:            {
                    347:                char *local_copy = NULL;
                    348:                char *p;
                    349:                char *eff_ids = NULL;
                    350:                char *prot_file = NULL;
                    351: 
                    352:                if (TRACE) fprintf(stderr,
                    353:                                   "HTRule: `%s' matched %s %s: `%s'\n",
                    354:                                   current,
                    355:                                   (r->op==HT_Protect ? "Protect" : "DefProt"),
                    356:                                   "rule, setup",
                    357:                                   (r->equiv ? r->equiv :
                    358:                                    (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
                    359: 
                    360:                if (r->equiv) {
                    361:                    StrAllocCopy(local_copy, r->equiv);
                    362:                    p = local_copy;
                    363:                    prot_file = HTNextField(&p);
                    364:                    eff_ids = HTNextField(&p);
                    365:                }
                    366: 
                    367:                if (r->op == HT_Protect)
                    368:                    HTAA_setCurrentProtection(req, prot_file, eff_ids);
                    369:                else
                    370:                    HTAA_setDefaultProtection(req, prot_file, eff_ids);
                    371: 
                    372:                FREE(local_copy);
                    373: 
                    374:                /* continue translating rules */
                    375:            }
                    376:            break;
                    377: #endif ACCESS_AUTH
                    378: 
                    379:        case HT_Exec:
                    380:            if (!r->equiv) {
                    381:                if (TRACE) fprintf(stderr,
                    382:                                   "HTRule: Exec `%s', no extra pathinfo\n",
                    383:                                   current);
                    384:                req->script = current;
                    385:                req->script_pathinfo = NULL;
                    386:                return YES;
                    387:            }
                    388:            else if (*p == *q || !strchr(r->equiv, '*')) { /* No wildcards */
                    389:                if (TRACE) fprintf(stderr,
                    390:                                   "HTRule: Exec `%s', no extra pathinfo\n",
                    391:                                   r->equiv);
                    392:                StrAllocCopy(req->script, r->equiv);
                    393:                req->script_pathinfo = NULL;
                    394:                return YES;
                    395:            }
                    396:            else {
                    397:                char *ins = strchr(r->equiv, '*');
                    398:                char *pathinfo;
                    399:                if (!(req->script = (char*)malloc(strlen(r->equiv) + m)))
                    400:                    outofmem(__FILE__, "HTTranslate");
                    401:                strncpy(req->script, r->equiv, ins-r->equiv);
                    402:                strncpy(req->script+(ins-r->equiv), q, m);
                    403:                strcpy(req->script+(ins-r->equiv)+m, ins+1);
                    404:                for (pathinfo = req->script+(ins-r->equiv)+1;
                    405:                     *pathinfo && *pathinfo != '/';
                    406:                     pathinfo++)
                    407:                    ;
2.17    ! luotonen  408:                FREE(req->script_pathinfo);
        !           409:                FREE(req->script_pathtrans);
2.15      luotonen  410:                if (*pathinfo) {
2.17    ! luotonen  411:                    char *tmp;
2.15      luotonen  412:                    StrAllocCopy(req->script_pathinfo, pathinfo);
                    413:                    *pathinfo = 0;
2.17    ! luotonen  414:                    tmp = HTTranslate(req->script_pathinfo);
        !           415:                    if (tmp) {
        !           416:                        req->script_pathtrans =
        !           417:                            HTParse(tmp, "", PARSE_PATH | PARSE_PUNCTUATION);
        !           418:                        free(tmp);
        !           419:                    }
2.15      luotonen  420:                }
                    421:                return YES;
                    422:            }
                    423:            break;
                    424:                             
                    425:        case HT_Pass:                           /* Authorised */
                    426:                if (!r->equiv) {
                    427:                    if (TRACE) fprintf(stderr, "HTRule: Pass `%s'\n", current);
                    428:                    req->translated = current;
                    429:                    return YES;
                    430:                }
                    431:                /* Else fall through ...to map and pass */
                    432:                
                    433:        case HT_Map:
                    434:            if (*p == *q) { /* End of both strings, no wildcard */
2.17    ! luotonen  435:                CTRACE(stderr,"For `%s' using `%s'\n", current, r->equiv);  
        !           436:                StrAllocCopy(current, r->equiv); /* use entire translation */
2.15      luotonen  437:            } else {
                    438:                  char * ins = strchr(r->equiv, '*');   /* Insertion point */
                    439:                  if (ins) {    /* Consistent rule!!! */
                    440:                        char * temp = (char *)malloc(
                    441:                                strlen(r->equiv)-1 + m + 1);
                    442:                        if (temp==NULL) 
                    443:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
                    444:                        strncpy(temp,   r->equiv, ins-r->equiv);
                    445:                        /* Note: temp may be unterminated now! */
                    446:                        strncpy(temp+(ins-r->equiv), q, m);  /* Matched bit */
                    447:                        strcpy (temp+(ins-r->equiv)+m, ins+1);  /* Last bit */
2.17    ! luotonen  448:                        CTRACE(stderr,"For `%s' using `%s'\n", current, temp);
2.15      luotonen  449:                        free(current);
                    450:                        current = temp;                 /* Use this */
                    451: 
                    452:                    } else {    /* No insertion point */
                    453:                        char * temp = (char *)malloc(strlen(r->equiv)+1);
                    454:                        if (temp==NULL) 
                    455:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
                    456:                        strcpy(temp, r->equiv);
2.17    ! luotonen  457:                        CTRACE(stderr, "For `%s' using `%s'\n", current, temp);
2.15      luotonen  458:                        free(current);
                    459:                        current = temp;                 /* Use this */
                    460:                    } /* If no insertion point exists */
                    461:                }
                    462:                if (r->op == HT_Pass) {
                    463:                    if (TRACE) fprintf(stderr, "HTRule: Pass `%s'\n", current);
                    464:                    req->translated = current;
                    465:                    return YES;
                    466:                }
                    467:                break;
                    468: 
                    469:        case HT_Invalid:
                    470:        case HT_Fail:                           /* Unauthorised */
2.17    ! luotonen  471:            CTRACE(stderr, "HTRule: *** FAIL `%s'\n", current);
        !           472:            return NO;
        !           473:            break;
2.15      luotonen  474:        } /* if tail matches ... switch operation */
                    475: 
                    476:     } /* loop over rules */
                    477: 
                    478:     /* Actually here failing might be more appropriate?? */
                    479:     req->translated = current;
                    480:     return YES;
                    481: }
                    482: 
                    483: 
                    484: 
2.7       timbl     485: /*     Load one line of configuration
                    486: **     ------------------------------
                    487: **
                    488: **     Call this, for example, to load a X resource with config info.
                    489: **
                    490: ** returns     0 OK, < 0 syntax error.
                    491: */
2.15      luotonen  492: PUBLIC int HTSetConfiguration ARGS1(CONST char *, config)
2.7       timbl     493: {
                    494:     HTRuleOp op;
                    495:     char * line = NULL;
                    496:     char * pointer = line;
                    497:     char *word1, *word2, *word3;
                    498:     float quality, secs, secs_per_byte;
                    499:     int status;
                    500:     
                    501:     StrAllocCopy(line, config);
                    502:     {
                    503:        char * p = strchr(line, '#');   /* Chop off comments */
                    504:        if (p) *p = 0;
                    505:     }
                    506:     pointer = line;
                    507:     word1 = HTNextField(&pointer);
                    508:     if (!word1) {
                    509:        free(line);
                    510:        return 0;
                    511:     } ;        /* Comment only or blank */
2.11      luotonen  512: 
2.7       timbl     513:     word2 = HTNextField(&pointer);
2.11      luotonen  514: 
                    515:     if (0==strcasecomp(word1, "defprot") ||
                    516:        0==strcasecomp(word1, "protect"))
                    517:        word3 = pointer;  /* The rest of the line to be parsed by AA module */
                    518:     else
                    519:        word3 = HTNextField(&pointer);  /* Just the next word */
                    520: 
2.7       timbl     521:     if (!word2) {
                    522:        fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
                    523:        free(line);
                    524:        return -2;      /*syntax error */
                    525:     }
                    526: 
2.17    ! luotonen  527:     if (0==strcasecomp(word1, "suffix") ||
        !           528:        0==strcasecomp(word1, "addtype")) {
2.8       timbl     529:         char * encoding = HTNextField(&pointer);
                    530:        if (pointer) status = sscanf(pointer, "%f", &quality);
                    531:        else status = 0;
2.17    ! luotonen  532:        HTAddType(word2,        word3,
2.8       timbl     533:                                encoding ? encoding : "binary",
                    534:                                status >= 1? quality : 1.0);
2.7       timbl     535: 
2.17    ! luotonen  536:     } else if (0==strcasecomp(word1, "addencoding") ||
        !           537:               0==strcasecomp(word1, "encoding")) {
        !           538:        if (pointer)
        !           539:            status = sscanf(pointer, "%f", &quality);
        !           540:        else status = 0;
        !           541:        HTAddEncoding(word2, word3,
        !           542:                      status >= 1 ? quality : 1.0);
        !           543: 
        !           544:     } else if (0==strcasecomp(word1, "addlanguage") ||
        !           545:               0==strcasecomp(word1, "language")) {
        !           546:        if (pointer)
        !           547:            status = sscanf(pointer, "%f", &quality);
        !           548:        else status = 0;
        !           549:        HTAddLanguage(word2, word3,
        !           550:                      status >= 1 ? quality : 1.0);
        !           551: 
2.7       timbl     552:     } else if (0==strcasecomp(word1, "presentation")) {
2.8       timbl     553:         if (pointer) status = sscanf(pointer, "%f%f%f",
                    554:                            &quality, &secs, &secs_per_byte);
                    555:         else status = 0;
2.14      timbl     556:        if (!HTConversions) HTConversions = HTList_new();
                    557:        HTSetPresentation(HTConversions, word2, word3,
2.7       timbl     558:                    status >= 1? quality                : 1.0,
2.11      luotonen  559:                    status >= 2 ? secs                  : 0.0,
2.7       timbl     560:                    status >= 3 ? secs_per_byte         : 0.0 );
2.12      luotonen  561: 
2.17    ! luotonen  562:     } else if (0==strncasecomp(word1, "putscript", 9) ||
        !           563:               0==strncasecomp(word1, "put-script", 10)) {
        !           564:        StrAllocCopy(HTPutScript, word2);
        !           565: 
        !           566:     } else if (0==strncasecomp(word1, "postscript", 10) ||
        !           567:               0==strncasecomp(word1, "post-script", 11)) {
        !           568:        StrAllocCopy(HTPostScript, word2);
        !           569: 
2.13      luotonen  570:     } else if (0==strncasecomp(word1, "htbin", 5) ||
                    571:               0==strncasecomp(word1, "bindir", 6)) {
2.15      luotonen  572:        char *bindir = (char*)malloc(strlen(word2) + 3);
                    573:        if (!bindir) outofmem(__FILE__, "HTSetConfiguration");
                    574:        strcpy(bindir, word2);
                    575:        strcat(bindir, "/*");
                    576:        HTAddRule(HT_Exec, "/htbin/*", bindir);
                    577: 
                    578:        /*
                    579:        ** Physical /htbin location -- this is almost obsolite
                    580:        ** (only search may need it).
                    581:        */
                    582:        StrAllocCopy(HTBinDir, word2);
2.13      luotonen  583: 
                    584:     } else if (0==strncasecomp(word1, "search", 6)) {
2.15      luotonen  585:        if (strchr(word2, '/'))
                    586:            StrAllocCopy(HTSearchScript, word2); /* Full search script path */
                    587:        else if (HTBinDir) {
                    588:            if (!(HTSearchScript =
                    589:                  (char*)malloc(strlen(HTBinDir) + strlen(word2) + 2)))
                    590:                outofmem(__FILE__, "HTSetConfiguration");
                    591:            strcpy(HTSearchScript, HTBinDir);
                    592:            strcat(HTSearchScript, "/");
                    593:            strcat(HTSearchScript, word2);
                    594:        }
                    595:        else if (TRACE) fprintf(stderr,
                    596:                "HTRule: Search rule without HTBin rule before ignored\n");
                    597:        if (TRACE) {
                    598:            if (HTSearchScript)
                    599:                fprintf(stderr, "HTRule: Search script set to `%s'\n",
                    600:                        HTSearchScript);
                    601:            else fprintf(stderr, "HTRule: Search script not set\n");
                    602:        }
2.12      luotonen  603: 
2.7       timbl     604:     } else {
                    605:        op =    0==strcasecomp(word1, "map")  ? HT_Map
                    606:            :   0==strcasecomp(word1, "pass") ? HT_Pass
                    607:            :   0==strcasecomp(word1, "fail") ? HT_Fail
2.17    ! luotonen  608:            :   0==strcasecomp(word1, "exec") ? HT_Exec
2.11      luotonen  609:            :   0==strcasecomp(word1, "defprot") ? HT_DefProt
                    610:            :   0==strcasecomp(word1, "protect") ? HT_Protect
2.7       timbl     611:            :                                           HT_Invalid;
                    612:        if (op==HT_Invalid) {
2.17    ! luotonen  613:            CTRACE(stderr, "HTRule: Bad rule `%s'\n", config);
2.7       timbl     614:        } else {  
                    615:            HTAddRule(op, word2, word3);
                    616:        } 
                    617:     }
                    618:     free(line);
                    619:     return 0;
                    620: }
                    621: 
2.1       timbl     622: 
2.11      luotonen  623: /*     Load the rules from a file                              HTLoadRules()
2.1       timbl     624: **     --------------------------
                    625: **
                    626: ** On entry,
                    627: **     Rules can be in any state
                    628: ** On exit,
                    629: **     Any existing rules will have been kept.
2.7       timbl     630: **     Any new rules will have been loaded.
                    631: **     Returns         0 if no error, 0 if error!
2.1       timbl     632: **
                    633: ** Bugs:
                    634: **     The strings may not contain spaces.
                    635: */
                    636: 
                    637: int HTLoadRules ARGS1(CONST char *, filename)
                    638: {
                    639:     FILE * fp = fopen(filename, "r");
                    640:     char line[LINE_LENGTH+1];
                    641:     
                    642:     if (!fp) {
2.17    ! luotonen  643:         CTRACE(stderr, "HTRules: Can't open rules file %s\n", filename);
2.1       timbl     644:        return -1; /* File open error */
                    645:     }
                    646:     for(;;) {
                    647:        if (!fgets(line, LINE_LENGTH+1, fp)) break;     /* EOF or error */
2.7       timbl     648:        (void) HTSetConfiguration(line);
2.1       timbl     649:     }
                    650:     fclose(fp);
2.7       timbl     651:     return 0;          /* No error or syntax errors ignored */
2.1       timbl     652: }
2.11      luotonen  653: 
                    654: 

Webmaster