Annotation of libwww/Library/src/HTRules.c, revision 2.18
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.12 luotonen 13: ** 11 Sep 93 MD Changed %i into %d in debug printf.
2.10 duns 14: ** VMS does not recognize %i.
15: ** Bug Fix: in case of PASS, only one parameter to printf.
2.12 luotonen 16: ** 19 Sep 93 AL Added Access Authorization stuff.
17: ** 1 Nov 93 AL Added htbin.
2.15 luotonen 18: ** 30 Nov 93 AL Added HTTranslateReq().
2.11 luotonen 19: **
2.1 timbl 20: */
21:
22: /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
23: #include "HTRules.h"
24:
25: #include <stdio.h>
26: #include "tcp.h"
27: #include "HTFile.h"
2.17 luotonen 28: #include "HTParse.h" /* HTParse() */
2.18 ! luotonen 29: #include "HTAAUtil.h"
! 30:
! 31: #ifndef VMS
! 32: #include <pwd.h> /* Unix password file routine: getpwnam() */
! 33: #endif /* not VMS */
! 34:
2.1 timbl 35:
36: #define LINE_LENGTH 256
37:
38:
39: typedef struct _rule {
40: struct _rule * next;
41: HTRuleOp op;
42: char * pattern;
43: char * equiv;
44: } rule;
45:
2.17 luotonen 46: /* Global variables
2.12 luotonen 47: ** ----------------
48: */
2.17 luotonen 49: PUBLIC char * HTBinDir = NULL; /* Physical /htbin directory */
50: /* path (this is obsolite, and */
51: /* only used if HTSearchScript */
52: /* is given as non-absolute -- */
53: /* and this is only for rule */
54: /* file backward-compatibility. */
55: PUBLIC char * HTSearchScript = NULL; /* Search script name. */
56: PUBLIC char * HTPutScript = NULL; /* Script to handle PUT */
57: PUBLIC char * HTPostScript = NULL; /* Script to handle POST */
2.18 ! luotonen 58: PRIVATE char * HTUserDir = NULL; /* User supported directory name*/
! 59:
2.12 luotonen 60:
2.13 luotonen 61:
2.1 timbl 62: /* Module-wide variables
63: ** ---------------------
64: */
65:
66: PRIVATE rule * rules = 0; /* Pointer to first on list */
67: #ifndef PUT_ON_HEAD
68: PRIVATE rule * rule_tail = 0; /* Pointer to last on list */
69: #endif
70:
2.11 luotonen 71:
2.1 timbl 72: /* Add rule to the list HTAddRule()
73: ** --------------------
74: **
75: ** On entry,
76: ** pattern points to 0-terminated string containing a single "*"
77: ** equiv points to the equivalent string with * for the
78: ** place where the text matched by * goes.
79: ** On exit,
80: ** returns 0 if success, -1 if error.
81: */
2.9 secret 82:
2.15 luotonen 83: PUBLIC int HTAddRule ARGS3(HTRuleOp, op,
84: CONST char *, pattern,
85: CONST char *, equiv)
2.9 secret 86: { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
87: rule * temp;
88: char * pPattern;
89:
90: temp = (rule *)malloc(sizeof(*temp));
91: if (temp==NULL)
92: outofmem(__FILE__, "HTAddRule");
93: pPattern = (char *)malloc(strlen(pattern)+1);
94: if (pPattern==NULL)
95: outofmem(__FILE__, "HTAddRule");
2.1 timbl 96: if (equiv) { /* Two operands */
97: char * pEquiv = (char *)malloc(strlen(equiv)+1);
2.9 secret 98: if (pEquiv==NULL)
99: outofmem(__FILE__, "HTAddRule");
2.1 timbl 100: temp->equiv = pEquiv;
101: strcpy(pEquiv, equiv);
102: } else {
103: temp->equiv = 0;
104: }
105: temp->pattern = pPattern;
106: temp->op = op;
107:
108: strcpy(pPattern, pattern);
2.10 duns 109: if (TRACE) {
110: if (equiv)
2.17 luotonen 111: fprintf(stderr, "Rule: For `%s' op %d `%s'\n", pattern, op, equiv);
2.10 duns 112: else
2.17 luotonen 113: fprintf(stderr, "Rule: For `%s' op %d\n", pattern, op);
2.10 duns 114: }
2.1 timbl 115:
116: #ifdef PUT_ON_HEAD
117: temp->next = rules;
118: rules = temp;
119: #else
120: temp->next = 0;
121: if (rule_tail) rule_tail->next = temp;
122: else rules = temp;
123: rule_tail = temp;
124: #endif
125:
126:
127: return 0;
128: }
129:
130:
131: /* Clear all rules HTClearRules()
132: ** ---------------
133: **
134: ** On exit,
135: ** There are no rules
136: ** returns 0 if success, -1 if error.
137: **
138: ** See also
139: ** HTAddRule()
140: */
2.15 luotonen 141: PUBLIC int HTClearRules NOARGS
2.1 timbl 142: {
143: while (rules) {
144: rule * temp = rules;
145: rules = temp->next;
146: free(temp->pattern);
147: free(temp->equiv);
148: free(temp);
149: }
150: #ifndef PUT_ON_HEAD
151: rule_tail = 0;
152: #endif
153:
154: return 0;
155: }
156:
157:
2.18 ! luotonen 158: PRIVATE char * wrap ARGS1(char *, s)
! 159: {
! 160: if (s && *s=='/') {
! 161: char * n = (char*)malloc(strlen(s) + 6);
! 162: if (!n) outofmem(__FILE__, "HTRules:wrap");
! 163: sprintf(n, "file:%s", s);
! 164: free(s);
! 165: return n;
! 166: }
! 167: return s;
! 168: }
! 169:
! 170:
! 171: PRIVATE char * unwrap ARGS1(char *, s)
! 172: {
! 173: if (s && !strncmp(s, "file:", 5)) {
! 174: char * t;
! 175: char * n = NULL;
! 176:
! 177: if (!strncmp(s, "file://", 7))
! 178: t = strchr(s+7, '/');
! 179: else t = s+5;
! 180:
! 181: if (!t) {
! 182: free(s);
! 183: return NULL;
! 184: }
! 185: StrAllocCopy(n, t);
! 186: free(s);
! 187: return n;
! 188: }
! 189: return s;
! 190: }
! 191:
! 192:
! 193:
2.1 timbl 194: /* Translate by rules HTTranslate()
195: ** ------------------
196: **
2.15 luotonen 197: ** ATTENTION:
198: ** THIS FUNCTION HAS BEEN OBSOLITED BY HTTranslateReq()
199: ** ON SERVER SIDE -- ON BROWSER SIDE THIS IS STILL USED!
200: ** Don't add new server features to this, this already has
201: ** more than it can handle cleanly.
202: **
203: ** The most recently defined rules are applied last.
2.1 timbl 204: **
205: ** On entry,
206: ** required points to a string whose equivalent value is neeed
207: ** On exit,
208: ** returns the address of the equivalent string allocated from
209: ** the heap which the CALLER MUST FREE. If no translation
210: ** occured, then it is a copy of te original.
2.11 luotonen 211: ** NEW FEATURES:
212: ** When a "protect" or "defprot" rule is mathed,
213: ** a call to HTAA_setCurrentProtection() or
214: ** HTAA_setDefaultProtection() is made to notify
215: ** the Access Authorization module that the file is
216: ** protected, and so it knows how to handle it.
217: ** -- AL
2.1 timbl 218: */
2.15 luotonen 219: PUBLIC char * HTTranslate ARGS1(CONST char *, required)
2.1 timbl 220: {
221: rule * r;
2.11 luotonen 222: char *current = NULL;
223: StrAllocCopy(current, required);
224:
2.15 luotonen 225: #ifdef OLD_CODE
2.11 luotonen 226: HTAA_clearProtections(); /* Reset from previous call -- AL */
2.15 luotonen 227: #endif
2.11 luotonen 228:
2.1 timbl 229: for(r = rules; r; r = r->next) {
230: char * p = r->pattern;
2.11 luotonen 231: int m=0; /* Number of characters matched against wildcard */
2.1 timbl 232: CONST char * q = current;
233: for(;*p && *q; p++, q++) { /* Find first mismatch */
234: if (*p!=*q) break;
235: }
236:
237: if (*p == '*') { /* Match up to wildcard */
238: m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
239: if(m<0) continue; /* tail is too short to match */
240: if (0!=strcmp(q+m, p+1)) continue; /* Tail mismatch */
241: } else /* Not wildcard */
242: if (*p != *q) continue; /* plain mismatch: go to next rule */
243:
244: switch (r->op) { /* Perform operation */
2.11 luotonen 245:
246: #ifdef ACCESS_AUTH
247: case HT_DefProt:
248: case HT_Protect:
249: {
250: char *local_copy = NULL;
251: char *p;
252: char *eff_ids = NULL;
253: char *prot_file = NULL;
254:
255: if (TRACE) fprintf(stderr,
256: "HTRule: `%s' matched %s %s: `%s'\n",
257: current,
258: (r->op==HT_Protect ? "Protect" : "DefProt"),
259: "rule, setup",
260: (r->equiv ? r->equiv :
261: (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
262:
263: if (r->equiv) {
264: StrAllocCopy(local_copy, r->equiv);
265: p = local_copy;
266: prot_file = HTNextField(&p);
267: eff_ids = HTNextField(&p);
268: }
269:
2.15 luotonen 270: #ifdef THESE_NO_LONGER_WORK
2.11 luotonen 271: if (r->op == HT_Protect)
272: HTAA_setCurrentProtection(current, prot_file, eff_ids);
273: else
274: HTAA_setDefaultProtection(current, prot_file, eff_ids);
2.15 luotonen 275: #endif
2.11 luotonen 276: FREE(local_copy);
277:
278: /* continue translating rules */
279: }
280: break;
281: #endif ACCESS_AUTH
282:
2.1 timbl 283: case HT_Pass: /* Authorised */
284: if (!r->equiv) {
2.17 luotonen 285: CTRACE(stderr, "HTRule: Pass `%s'\n", current);
2.18 ! luotonen 286: return wrap(current);
2.1 timbl 287: }
2.11 luotonen 288: /* Else fall through ...to map and pass */
2.1 timbl 289:
290: case HT_Map:
291: if (*p == *q) { /* End of both strings, no wildcard */
2.17 luotonen 292: CTRACE(stderr, "For `%s' using `%s'\n", current, r->equiv);
293: StrAllocCopy(current, r->equiv); /* use entire translation */
2.1 timbl 294: } else {
295: char * ins = strchr(r->equiv, '*'); /* Insertion point */
296: if (ins) { /* Consistent rule!!! */
297: char * temp = (char *)malloc(
298: strlen(r->equiv)-1 + m + 1);
2.9 secret 299: if (temp==NULL)
300: outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1 timbl 301: strncpy(temp, r->equiv, ins-r->equiv);
302: /* Note: temp may be unterminated now! */
303: strncpy(temp+(ins-r->equiv), q, m); /* Matched bit */
304: strcpy (temp+(ins-r->equiv)+m, ins+1); /* Last bit */
2.17 luotonen 305: CTRACE(stderr, "For `%s' using `%s'\n",
2.1 timbl 306: current, temp);
307: free(current);
308: current = temp; /* Use this */
309:
310: } else { /* No insertion point */
311: char * temp = (char *)malloc(strlen(r->equiv)+1);
2.9 secret 312: if (temp==NULL)
313: outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1 timbl 314: strcpy(temp, r->equiv);
2.17 luotonen 315: CTRACE(stderr, "For `%s' using `%s'\n", current, temp);
2.1 timbl 316: free(current);
317: current = temp; /* Use this */
318: } /* If no insertion point exists */
319: }
320: if (r->op == HT_Pass) {
2.17 luotonen 321: CTRACE(stderr, "HTRule: ...and pass `%s'\n", current);
2.18 ! luotonen 322: return wrap(current);
2.1 timbl 323: }
324: break;
325:
2.15 luotonen 326: case HT_Exec:
2.11 luotonen 327: case HT_Invalid:
328: case HT_Fail: /* Unauthorised */
2.15 luotonen 329: default:
2.17 luotonen 330: CTRACE(stderr,"HTRule: *** FAIL `%s'\n", current);
331: return (char *)0;
2.1 timbl 332:
2.11 luotonen 333: } /* if tail matches ... switch operation */
2.1 timbl 334:
335: } /* loop over rules */
336:
337:
2.18 ! luotonen 338: return wrap(current);
2.1 timbl 339: }
340:
2.15 luotonen 341:
342:
2.17 luotonen 343: /* Translate by rules HTTranslateReq()
2.15 luotonen 344: ** ------------------
345: **
346: ** On entry,
347: ** req request structure.
2.18 ! luotonen 348: ** req->arg_path simplified pathname (no ..'s etc in it),
2.15 luotonen 349: ** which will be translated.
350: ** If this starts with /htbin/ it is taken
351: ** to be a script call request.
352: **
353: ** On exit,
354: ** returns YES on success, NO on failure (Forbidden).
355: ** req->translated contains the translated filename;
356: ** NULL if a script call.
357: ** req->script contains the executable script name;
358: ** NULL if not a script call.
359: */
360: PUBLIC BOOL HTTranslateReq ARGS1(HTRequest *, req)
361: {
362: rule * r;
363: char *current = NULL;
364:
2.18 ! luotonen 365: if (!req || !req->arg_path)
2.15 luotonen 366: return NO;
367:
2.18 ! luotonen 368: StrAllocCopy(current, req->arg_path);
! 369:
! 370: if (HTUserDir && current[0] == '/' && current[1] == '~') { /* User dir */
! 371: char * username = current+2;
! 372: char * end = strchr(username, '/');
! 373:
! 374: if (end) *end++ = 0;
! 375:
! 376: if (*username) {
! 377: struct passwd * pw = getpwnam(username);
! 378:
! 379: if (pw && pw->pw_dir) {
! 380: int homelen = strlen(pw->pw_dir);
! 381: char * d = (char*)malloc(homelen +
! 382: strlen(HTUserDir) +
! 383: (end ? strlen(end) : 0) + 3);
! 384: strcpy(d, pw->pw_dir);
! 385: if (pw->pw_dir[homelen-1] != '/' && HTUserDir[0] != '/')
! 386: strcat(d, "/");
! 387: strcat(d, HTUserDir);
! 388: if (end) {
! 389: if (HTUserDir[strlen(HTUserDir)-1] != '/')
! 390: strcat(d, "/");
! 391: strcat(d, end);
! 392: }
! 393: CTRACE(stderr, "\"%s\" --user--> \"%s\"\n", current, d);
! 394: free(current);
! 395: current = d;
! 396: }
! 397: else CTRACE(stderr, "HTRule: User dir for '%s' not found\n",
! 398: current);
! 399: }
! 400: else CTRACE(stderr, "HTRule: Invalid user dir request '%s'\n",
! 401: current);
! 402: }
2.15 luotonen 403:
404: for(r = rules; r; r = r->next) {
405: char * p = r->pattern;
406: int m=0; /* Number of characters matched against wildcard */
407: CONST char * q = current;
408: for(;*p && *q; p++, q++) { /* Find first mismatch */
409: if (*p!=*q) break;
410: }
411:
412: if (*p == '*') { /* Match up to wildcard */
413: m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
414: if(m<0) continue; /* tail is too short to match */
415: if (0!=strcmp(q+m, p+1)) continue; /* Tail mismatch */
416: } else /* Not wildcard */
417: if (*p != *q) continue; /* plain mismatch: go to next rule */
418:
419: switch (r->op) { /* Perform operation */
420:
421: #ifdef ACCESS_AUTH
422: case HT_DefProt:
423: case HT_Protect:
424: {
425: char *local_copy = NULL;
426: char *p;
427: char *eff_ids = NULL;
428: char *prot_file = NULL;
429:
430: if (TRACE) fprintf(stderr,
431: "HTRule: `%s' matched %s %s: `%s'\n",
432: current,
433: (r->op==HT_Protect ? "Protect" : "DefProt"),
434: "rule, setup",
435: (r->equiv ? r->equiv :
436: (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
437:
438: if (r->equiv) {
439: StrAllocCopy(local_copy, r->equiv);
440: p = local_copy;
441: prot_file = HTNextField(&p);
442: eff_ids = HTNextField(&p);
443: }
444:
445: if (r->op == HT_Protect)
446: HTAA_setCurrentProtection(req, prot_file, eff_ids);
447: else
448: HTAA_setDefaultProtection(req, prot_file, eff_ids);
449:
450: FREE(local_copy);
451:
452: /* continue translating rules */
453: }
454: break;
455: #endif ACCESS_AUTH
456:
457: case HT_Exec:
458: if (!r->equiv) {
459: if (TRACE) fprintf(stderr,
460: "HTRule: Exec `%s', no extra pathinfo\n",
461: current);
462: req->script = current;
463: req->script_pathinfo = NULL;
2.18 ! luotonen 464: req->script_pathtrans = NULL;
2.15 luotonen 465: return YES;
466: }
467: else if (*p == *q || !strchr(r->equiv, '*')) { /* No wildcards */
468: if (TRACE) fprintf(stderr,
469: "HTRule: Exec `%s', no extra pathinfo\n",
470: r->equiv);
471: StrAllocCopy(req->script, r->equiv);
472: req->script_pathinfo = NULL;
2.18 ! luotonen 473: req->script_pathtrans = NULL;
2.15 luotonen 474: return YES;
475: }
476: else {
477: char *ins = strchr(r->equiv, '*');
478: char *pathinfo;
2.18 ! luotonen 479:
! 480: req->script = (char*)malloc(strlen(r->equiv) + m);
! 481: if (!req->script) outofmem(__FILE__, "HTTranslateReq");
! 482:
2.15 luotonen 483: strncpy(req->script, r->equiv, ins-r->equiv);
484: strncpy(req->script+(ins-r->equiv), q, m);
485: strcpy(req->script+(ins-r->equiv)+m, ins+1);
486: for (pathinfo = req->script+(ins-r->equiv)+1;
487: *pathinfo && *pathinfo != '/';
488: pathinfo++)
489: ;
2.17 luotonen 490: FREE(req->script_pathinfo);
491: FREE(req->script_pathtrans);
2.15 luotonen 492: if (*pathinfo) {
493: StrAllocCopy(req->script_pathinfo, pathinfo);
494: *pathinfo = 0;
2.18 ! luotonen 495: req->script_pathtrans =
! 496: unwrap(HTTranslate(req->script_pathinfo));
2.15 luotonen 497: }
498: return YES;
499: }
500: break;
2.18 ! luotonen 501:
! 502: case HT_Redirect:
! 503: if (!r->equiv) {
! 504: CTRACE(stderr,
! 505: "HTRule: ERROR: No destination for redirect %s\n",
! 506: r->pattern);
! 507: req->reason = HTAA_INVALID_REDIRECT;
! 508: return NO;
! 509: }
! 510: else req->reason = HTAA_OK_REDIRECT;
! 511: /* And fall through to HT_Map... */
! 512:
2.15 luotonen 513: case HT_Pass: /* Authorised */
514: if (!r->equiv) {
515: if (TRACE) fprintf(stderr, "HTRule: Pass `%s'\n", current);
2.18 ! luotonen 516: req->translated = unwrap(current);
2.15 luotonen 517: return YES;
518: }
519: /* Else fall through ...to map and pass */
520:
521: case HT_Map:
522: if (*p == *q) { /* End of both strings, no wildcard */
2.17 luotonen 523: CTRACE(stderr,"For `%s' using `%s'\n", current, r->equiv);
524: StrAllocCopy(current, r->equiv); /* use entire translation */
2.15 luotonen 525: } else {
2.18 ! luotonen 526: char * ins = strchr(r->equiv, '*'); /* Insertion point */
! 527: if (ins) { /* Consistent rule!!! */
! 528: char * temp=(char*)malloc(strlen(r->equiv)-1 + m + 1);
! 529: if (!temp) outofmem(__FILE__, "HTTranslateReq");
! 530:
! 531: strncpy(temp, r->equiv, ins-r->equiv);
! 532: /* Note: temp may be unterminated now! */
! 533: strncpy(temp+(ins-r->equiv), q, m); /* Matched bit */
! 534: strcpy (temp+(ins-r->equiv)+m, ins+1); /* Last bit */
! 535: CTRACE(stderr,"\"%s\" --map*-> \"%s\"\n",current,temp);
! 536: free(current);
! 537: current = temp; /* Use this */
! 538:
! 539: } else { /* No insertion point */
! 540: char * temp = (char *)malloc(strlen(r->equiv)+1);
! 541: if (temp==NULL)
! 542: outofmem(__FILE__, "HTTranslateReq"); /* NT & AS */
! 543: strcpy(temp, r->equiv);
! 544: CTRACE(stderr,"\"%s\" --map--> \"%s\"\n",current,temp);
! 545: free(current);
! 546: current = temp; /* Use this */
! 547: } /* If no insertion point exists */
! 548: }
! 549: if (r->op == HT_Pass) {
! 550: CTRACE(stderr, "HTRule: Pass `%s'\n", current);
! 551: req->translated = unwrap(current);
! 552: return YES;
! 553: }
! 554: else if (r->op == HT_Redirect) {
! 555: CTRACE(stderr, "HTRule: Redirected to `%s'\n", current);
! 556: req->location = current;
! 557: return YES;
! 558: }
! 559: break;
2.15 luotonen 560:
561: case HT_Invalid:
562: case HT_Fail: /* Unauthorised */
2.17 luotonen 563: CTRACE(stderr, "HTRule: *** FAIL `%s'\n", current);
564: return NO;
565: break;
2.15 luotonen 566: } /* if tail matches ... switch operation */
567:
568: } /* loop over rules */
569:
570: /* Actually here failing might be more appropriate?? */
2.18 ! luotonen 571: req->translated = unwrap(current);
2.15 luotonen 572: return YES;
573: }
574:
575:
576:
2.7 timbl 577: /* Load one line of configuration
578: ** ------------------------------
579: **
580: ** Call this, for example, to load a X resource with config info.
581: **
582: ** returns 0 OK, < 0 syntax error.
583: */
2.15 luotonen 584: PUBLIC int HTSetConfiguration ARGS1(CONST char *, config)
2.7 timbl 585: {
586: HTRuleOp op;
587: char * line = NULL;
588: char * pointer = line;
589: char *word1, *word2, *word3;
590: float quality, secs, secs_per_byte;
591: int status;
592:
593: StrAllocCopy(line, config);
594: {
595: char * p = strchr(line, '#'); /* Chop off comments */
596: if (p) *p = 0;
597: }
598: pointer = line;
599: word1 = HTNextField(&pointer);
600: if (!word1) {
601: free(line);
602: return 0;
603: } ; /* Comment only or blank */
2.11 luotonen 604:
2.7 timbl 605: word2 = HTNextField(&pointer);
2.11 luotonen 606:
607: if (0==strcasecomp(word1, "defprot") ||
608: 0==strcasecomp(word1, "protect"))
609: word3 = pointer; /* The rest of the line to be parsed by AA module */
610: else
611: word3 = HTNextField(&pointer); /* Just the next word */
612:
2.7 timbl 613: if (!word2) {
614: fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
615: free(line);
616: return -2; /*syntax error */
617: }
618:
2.17 luotonen 619: if (0==strcasecomp(word1, "suffix") ||
620: 0==strcasecomp(word1, "addtype")) {
2.8 timbl 621: char * encoding = HTNextField(&pointer);
622: if (pointer) status = sscanf(pointer, "%f", &quality);
623: else status = 0;
2.17 luotonen 624: HTAddType(word2, word3,
2.8 timbl 625: encoding ? encoding : "binary",
626: status >= 1? quality : 1.0);
2.7 timbl 627:
2.17 luotonen 628: } else if (0==strcasecomp(word1, "addencoding") ||
629: 0==strcasecomp(word1, "encoding")) {
630: if (pointer)
631: status = sscanf(pointer, "%f", &quality);
632: else status = 0;
633: HTAddEncoding(word2, word3,
634: status >= 1 ? quality : 1.0);
635:
636: } else if (0==strcasecomp(word1, "addlanguage") ||
637: 0==strcasecomp(word1, "language")) {
638: if (pointer)
639: status = sscanf(pointer, "%f", &quality);
640: else status = 0;
641: HTAddLanguage(word2, word3,
642: status >= 1 ? quality : 1.0);
643:
2.7 timbl 644: } else if (0==strcasecomp(word1, "presentation")) {
2.8 timbl 645: if (pointer) status = sscanf(pointer, "%f%f%f",
646: &quality, &secs, &secs_per_byte);
647: else status = 0;
2.14 timbl 648: if (!HTConversions) HTConversions = HTList_new();
649: HTSetPresentation(HTConversions, word2, word3,
2.7 timbl 650: status >= 1? quality : 1.0,
2.11 luotonen 651: status >= 2 ? secs : 0.0,
2.7 timbl 652: status >= 3 ? secs_per_byte : 0.0 );
2.12 luotonen 653:
2.17 luotonen 654: } else if (0==strncasecomp(word1, "putscript", 9) ||
655: 0==strncasecomp(word1, "put-script", 10)) {
656: StrAllocCopy(HTPutScript, word2);
657:
658: } else if (0==strncasecomp(word1, "postscript", 10) ||
659: 0==strncasecomp(word1, "post-script", 11)) {
660: StrAllocCopy(HTPostScript, word2);
661:
2.18 ! luotonen 662: } else if (0==strncasecomp(word1, "userdir", 7)) {
! 663: CTRACE(stderr,
! 664: "User supported directories are '%s' under each user's home\n",
! 665: word2);
! 666: StrAllocCopy(HTUserDir, word2);
! 667:
2.13 luotonen 668: } else if (0==strncasecomp(word1, "htbin", 5) ||
669: 0==strncasecomp(word1, "bindir", 6)) {
2.15 luotonen 670: char *bindir = (char*)malloc(strlen(word2) + 3);
671: if (!bindir) outofmem(__FILE__, "HTSetConfiguration");
672: strcpy(bindir, word2);
673: strcat(bindir, "/*");
674: HTAddRule(HT_Exec, "/htbin/*", bindir);
675:
676: /*
677: ** Physical /htbin location -- this is almost obsolite
678: ** (only search may need it).
679: */
680: StrAllocCopy(HTBinDir, word2);
2.13 luotonen 681:
682: } else if (0==strncasecomp(word1, "search", 6)) {
2.15 luotonen 683: if (strchr(word2, '/'))
684: StrAllocCopy(HTSearchScript, word2); /* Full search script path */
685: else if (HTBinDir) {
686: if (!(HTSearchScript =
687: (char*)malloc(strlen(HTBinDir) + strlen(word2) + 2)))
688: outofmem(__FILE__, "HTSetConfiguration");
689: strcpy(HTSearchScript, HTBinDir);
690: strcat(HTSearchScript, "/");
691: strcat(HTSearchScript, word2);
692: }
693: else if (TRACE) fprintf(stderr,
694: "HTRule: Search rule without HTBin rule before ignored\n");
695: if (TRACE) {
696: if (HTSearchScript)
697: fprintf(stderr, "HTRule: Search script set to `%s'\n",
698: HTSearchScript);
699: else fprintf(stderr, "HTRule: Search script not set\n");
700: }
2.12 luotonen 701:
2.7 timbl 702: } else {
703: op = 0==strcasecomp(word1, "map") ? HT_Map
704: : 0==strcasecomp(word1, "pass") ? HT_Pass
705: : 0==strcasecomp(word1, "fail") ? HT_Fail
2.17 luotonen 706: : 0==strcasecomp(word1, "exec") ? HT_Exec
2.18 ! luotonen 707: : 0==strcasecomp(word1, "redirect")? HT_Redirect
2.11 luotonen 708: : 0==strcasecomp(word1, "defprot") ? HT_DefProt
709: : 0==strcasecomp(word1, "protect") ? HT_Protect
2.7 timbl 710: : HT_Invalid;
711: if (op==HT_Invalid) {
2.17 luotonen 712: CTRACE(stderr, "HTRule: Bad rule `%s'\n", config);
2.7 timbl 713: } else {
714: HTAddRule(op, word2, word3);
715: }
716: }
717: free(line);
718: return 0;
719: }
720:
2.1 timbl 721:
2.11 luotonen 722: /* Load the rules from a file HTLoadRules()
2.1 timbl 723: ** --------------------------
724: **
725: ** On entry,
726: ** Rules can be in any state
727: ** On exit,
728: ** Any existing rules will have been kept.
2.7 timbl 729: ** Any new rules will have been loaded.
730: ** Returns 0 if no error, 0 if error!
2.1 timbl 731: **
732: ** Bugs:
733: ** The strings may not contain spaces.
734: */
735:
736: int HTLoadRules ARGS1(CONST char *, filename)
737: {
738: FILE * fp = fopen(filename, "r");
739: char line[LINE_LENGTH+1];
740:
741: if (!fp) {
2.17 luotonen 742: CTRACE(stderr, "HTRules: Can't open rules file %s\n", filename);
2.1 timbl 743: return -1; /* File open error */
744: }
745: for(;;) {
746: if (!fgets(line, LINE_LENGTH+1, fp)) break; /* EOF or error */
2.7 timbl 747: (void) HTSetConfiguration(line);
2.1 timbl 748: }
749: fclose(fp);
2.7 timbl 750: return 0; /* No error or syntax errors ignored */
2.1 timbl 751: }
2.11 luotonen 752:
753:
Webmaster