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