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