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

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

Webmaster