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