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

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

Webmaster