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