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