diff options
Diffstat (limited to 'WWW/Library/Implementation/HTRules.c')
-rw-r--r-- | WWW/Library/Implementation/HTRules.c | 705 |
1 files changed, 0 insertions, 705 deletions
diff --git a/WWW/Library/Implementation/HTRules.c b/WWW/Library/Implementation/HTRules.c deleted file mode 100644 index 35b36719..00000000 --- a/WWW/Library/Implementation/HTRules.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * $LynxId: HTRules.c,v 1.42 2010/06/17 21:33:35 tom Exp $ - * - * Configuration manager for Hypertext Daemon HTRules.c - * ========================================== - * - * - * History: - * 3 Jun 91 Written TBL - * 10 Aug 91 Authorisation added after Daniel Martin (pass, fail) - * Rule order in file changed - * Comments allowed with # on 1st char of rule line - * 17 Jun 92 Bug fix: pass and fail failed if didn't contain '*' TBL - * 1 Sep 93 Bug fix: no memory check - Nathan Torkington - * BYTE_ADDRESSING removed - Arthur Secret - * 11 Sep 93 MD Changed %i into %d in debug printf. - * VMS does not recognize %i. - * Bug Fix: in case of PASS, only one parameter to printf. - * 19 Sep 93 AL Added Access Authorization stuff. - * 1 Nov 93 AL Added htbin. - * 25 May 99 KW Added redirect for lynx. - * - */ - -#include <HTUtils.h> - -/* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */ -#include <HTRules.h> - -#include <HTFile.h> -#include <LYLeaks.h> -#include <HTAAProt.h> - -#define LINE_LENGTH 256 - -typedef struct _rule { - struct _rule *next; - HTRuleOp op; - char *pattern; - char *equiv; - char *condition_op; /* as strings - may be inefficient, */ - char *condition; /* but this is not for a server - kw */ -} rule; - -#ifndef NO_RULES - -#include <HTTP.h> /* for redirecting_url, indirectly HTPermitRedir - kw */ -#include <LYGlobalDefs.h> /* for LYUserSpecifiedURL - kw */ -#include <LYStrings.h> /* for LYscanFloat */ -#include <LYUtils.h> /* for LYFixCursesOn - kw */ -#include <HTAlert.h> - -/* Global variables - * ---------------- - */ -char *HTBinDir = NULL; /* Physical /htbin directory path. */ - - /* In future this should not be global. */ -char *HTSearchScript = NULL; /* Search script name. */ - -/* Module-wide variables - * --------------------- - */ - -static rule *rules = 0; /* Pointer to first on list */ - -#ifndef PUT_ON_HEAD -static rule *rule_tail = 0; /* Pointer to last on list */ -#endif - -/* Add rule to the list HTAddRule() - * -------------------- - * - * On entry, - * pattern points to 0-terminated string containing a single "*" - * equiv points to the equivalent string with * for the - * place where the text matched by * goes. - * On exit, - * returns 0 if success, -1 if error. - */ - -int HTAddRule(HTRuleOp op, const char *pattern, - const char *equiv, - const char *cond_op, - const char *cond) -{ /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */ - rule *temp; - char *pPattern = NULL; - - temp = typecalloc(rule); - if (temp == NULL) - outofmem(__FILE__, "HTAddRule"); - - assert(temp != NULL); - - if (equiv) { /* Two operands */ - char *pEquiv = NULL; - - StrAllocCopy(pEquiv, equiv); - temp->equiv = pEquiv; - } else { - temp->equiv = 0; - } - if (cond_op) { - StrAllocCopy(temp->condition_op, cond_op); - StrAllocCopy(temp->condition, cond); - } - StrAllocCopy(pPattern, pattern); - temp->pattern = pPattern; - temp->op = op; - - if (equiv) { - CTRACE((tfp, "Rule: For `%s' op %d `%s'", pattern, (int) op, equiv)); - } else { - CTRACE((tfp, "Rule: For `%s' op %d", pattern, (int) op)); - } - if (cond_op) { - CTRACE((tfp, "\t%s %s\n", cond_op, NONNULL(cond))); - } else { - CTRACE((tfp, "\n")); - } - - if (!rules) { -#ifdef LY_FIND_LEAKS - atexit(HTClearRules); -#endif - } -#ifdef PUT_ON_HEAD - temp->next = rules; - rules = temp; -#else - temp->next = 0; - if (rule_tail) - rule_tail->next = temp; - else - rules = temp; - rule_tail = temp; -#endif - - return 0; -} - -/* Clear all rules HTClearRules() - * --------------- - * - * On exit, - * There are no rules - * - * See also - * HTAddRule() - */ -void HTClearRules(void) -{ - while (rules) { - rule *temp = rules; - - rules = temp->next; - FREE(temp->pattern); - FREE(temp->equiv); - FREE(temp->condition_op); - FREE(temp->condition); - FREE(temp); - } -#ifndef PUT_ON_HEAD - rule_tail = 0; -#endif -} - -static BOOL rule_cond_ok(rule * r) -{ - BOOL result; - - if (!r->condition_op) - return YES; - if (strcmp(r->condition_op, "if") && strcmp(r->condition_op, "unless")) { - CTRACE((tfp, "....... rule ignored, unrecognized `%s'!\n", - r->condition_op)); - return NO; - } - if (!strcmp(r->condition, "redirected")) - result = (BOOL) (redirection_attempts > 0); - else if (!strcmp(r->condition, "userspec")) - result = LYUserSpecifiedURL; - else { - CTRACE((tfp, "....... rule ignored, unrecognized `%s %s'!\n", - r->condition_op, NONNULL(r->condition))); - return NO; - } - if (!strcmp(r->condition_op, "if")) - return result; - else - return (BOOL) (!result); - -} - -/* Translate by rules HTTranslate() - * ------------------ - * - * The most recently defined rules are applied first. - * - * On entry, - * required points to a string whose equivalent value is needed - * On exit, - * returns the address of the equivalent string allocated from - * the heap which the CALLER MUST FREE. If no translation - * occurred, then it is a copy of the original. - * NEW FEATURES: - * When a "protect" or "defprot" rule is matched, - * a call to HTAA_setCurrentProtection() or - * HTAA_setDefaultProtection() is made to notify - * the Access Authorization module that the file is - * protected, and so it knows how to handle it. - * -- AL - */ -char *HTTranslate(const char *required) -{ - rule *r; - char *current = NULL; - char *msgtmp = NULL; - const char *pMsg; - int proxy_none_flag = 0; - int permitredir_flag = 0; - - StrAllocCopy(current, required); - - HTAA_clearProtections(); /* Reset from previous call -- AL */ - - for (r = rules; r; r = r->next) { - char *p = r->pattern; - int m = 0; /* Number of characters matched against wildcard */ - const char *q = current; - - for (; *p && *q; p++, q++) { /* Find first mismatch */ - if (*p != *q) - break; - } - - if (*p == '*') { /* Match up to wildcard */ - m = (int) strlen(q) - (int) strlen(p + 1); /* Amount to match to wildcard */ - if (m < 0) - continue; /* tail is too short to match */ - if (0 != strcmp(q + m, p + 1)) - continue; /* Tail mismatch */ - } else - /* Not wildcard */ if (*p != *q) - continue; /* plain mismatch: go to next rule */ - - if (!rule_cond_ok(r)) /* check condition, next rule if false - kw */ - continue; - - switch (r->op) { /* Perform operation */ - - case HT_DefProt: - case HT_Protect: -#ifdef ACCESS_AUTH - { - char *local_copy = NULL; - char *p2; - char *eff_ids = NULL; - char *prot_file = NULL; - - CTRACE((tfp, "HTRule: `%s' matched %s %s: `%s'\n", - current, - (r->op == HT_Protect ? "Protect" : "DefProt"), - "rule, setup", - (r->equiv ? r->equiv : - (r->op == HT_Protect ? "DEFAULT" : "NULL!!")))); - - if (r->equiv) { - StrAllocCopy(local_copy, r->equiv); - p2 = local_copy; - prot_file = HTNextField(&p2); - eff_ids = HTNextField(&p2); - } - - if (r->op == HT_Protect) - HTAA_setCurrentProtection(current, prot_file, eff_ids); - else - HTAA_setDefaultProtection(current, prot_file, eff_ids); - - FREE(local_copy); - - /* continue translating rules */ - } -#endif /* ACCESS_AUTH */ - break; - - case HT_UserMsg: /* Produce message immediately */ - LYFixCursesOn("show rule message:"); - HTUserMsg2((r->equiv ? r->equiv : "Rule: %s"), current); - break; - case HT_InfoMsg: /* Produce messages immediately */ - case HT_Progress: - case HT_Alert: - LYFixCursesOn("show rule message:"); /* and fall through */ - case HT_AlwaysAlert: - pMsg = r->equiv ? r->equiv : - (r->op == HT_AlwaysAlert) ? "%s" : "Rule: %s"; - if (strchr(pMsg, '%')) { - HTSprintf0(&msgtmp, pMsg, current); - pMsg = msgtmp; - } - switch (r->op) { /* Actually produce message */ - case HT_InfoMsg: - HTInfoMsg(pMsg); - break; - case HT_Progress: - HTProgress(pMsg); - break; - case HT_Alert: - HTAlert(pMsg); - break; - case HT_AlwaysAlert: - HTAlwaysAlert("Rule alert:", pMsg); - break; - default: - break; - } - FREE(msgtmp); - break; - - case HT_PermitRedir: /* Set special flag */ - permitredir_flag = 1; - CTRACE((tfp, "HTRule: Mark for redirection permitted\n")); - break; - - case HT_Pass: /* Authorised */ - if (!r->equiv) { - if (proxy_none_flag) { - char *temp = NULL; - - StrAllocCopy(temp, "NoProxy="); - StrAllocCat(temp, current); - FREE(current); - current = temp; - } - CTRACE((tfp, "HTRule: Pass `%s'\n", current)); - return current; - } - /* Else fall through ...to map and pass */ - - case HT_Map: - case HT_Redirect: - case HT_RedirectPerm: - if (*p == *q) { /* End of both strings, no wildcard */ - CTRACE((tfp, "For `%s' using `%s'\n", current, r->equiv)); - StrAllocCopy(current, r->equiv); /* use entire translation */ - } else { - char *ins = strchr(r->equiv, '*'); /* Insertion point */ - - if (ins) { /* Consistent rule!!! */ - char *temp = NULL; - - HTSprintf0(&temp, "%.*s%.*s%s", - (int) (ins - r->equiv), - r->equiv, - m, - q, - ins + 1); - CTRACE((tfp, "For `%s' using `%s'\n", - current, temp)); - FREE(current); - current = temp; /* Use this */ - - } else { /* No insertion point */ - char *temp = NULL; - - StrAllocCopy(temp, r->equiv); - CTRACE((tfp, "For `%s' using `%s'\n", - current, temp)); - FREE(current); - current = temp; /* Use this */ - } /* If no insertion point exists */ - } - if (r->op == HT_Pass) { - if (proxy_none_flag) { - char *temp = NULL; - - StrAllocCopy(temp, "NoProxy="); - StrAllocCat(temp, current); - FREE(current); - current = temp; - } - CTRACE((tfp, "HTRule: ...and pass `%s'\n", - current)); - return current; - } else if (r->op == HT_Redirect) { - CTRACE((tfp, "HTRule: ...and redirect to `%s'\n", - current)); - redirecting_url = current; - HTPermitRedir = (BOOL) (permitredir_flag == 1); - return (char *) 0; - } else if (r->op == HT_RedirectPerm) { - CTRACE((tfp, "HTRule: ...and redirect like 301 to `%s'\n", - current)); - redirecting_url = current; - permanent_redirection = TRUE; - HTPermitRedir = (BOOL) (permitredir_flag == 1); - return (char *) 0; - } - break; - - case HT_UseProxy: - if (r->equiv && 0 == strcasecomp(r->equiv, "none")) { - CTRACE((tfp, "For `%s' will not use proxy\n", current)); - proxy_none_flag = 1; - } else if (proxy_none_flag) { - CTRACE((tfp, "For `%s' proxy server ignored: %s\n", - current, - NONNULL(r->equiv))); - } else { - char *temp = NULL; - - StrAllocCopy(temp, "Proxied="); - StrAllocCat(temp, r->equiv); - StrAllocCat(temp, current); - CTRACE((tfp, "HTRule: proxy server found: %s\n", - NONNULL(r->equiv))); - FREE(current); - return temp; - } - break; - - case HT_Invalid: - case HT_Fail: /* Unauthorised */ - CTRACE((tfp, "HTRule: *** FAIL `%s'\n", current)); - FREE(current); - return (char *) 0; - } /* if tail matches ... switch operation */ - - } /* loop over rules */ - - if (proxy_none_flag) { - char *temp = NULL; - - StrAllocCopy(temp, "NoProxy="); - StrAllocCat(temp, current); - FREE(current); - return temp; - } - - return current; -} - -/* Load one line of configuration - * ------------------------------ - * - * Call this, for example, to load a X resource with config info. - * - * returns 0 OK, < 0 syntax error. - */ -int HTSetConfiguration(char *config) -{ - HTRuleOp op; - char *line = NULL; - char *pointer = line; - char *word1; - const char *word2; - const char *word3; - const char *cond_op = NULL; - const char *cond = NULL; - float quality, secs, secs_per_byte; - long maxbytes; - int status; - - StrAllocCopy(line, config); - { - char *p = line; - - /* Chop off comments */ - while ((p = strchr(p, '#'))) { - if (p == line || isspace(UCH(*(p - 1)))) { - *p = 0; - break; - } else { - p++; - } - } - } - pointer = line; - word1 = HTNextField(&pointer); - if (!word1) { - FREE(line); - return 0; - }; /* Comment only or blank */ - - word2 = HTNextField(&pointer); - - if (0 == strcasecomp(word1, "defprot") || - 0 == strcasecomp(word1, "protect")) - word3 = pointer; /* The rest of the line to be parsed by AA module */ - else - word3 = HTNextField(&pointer); /* Just the next word */ - - if (!word2) { - fprintf(stderr, "HTRule: %s %s\n", RULE_NEEDS_DATA, line); - FREE(line); - return -2; /*syntax error */ - } - - if (0 == strcasecomp(word1, "suffix")) { - char *encoding = HTNextField(&pointer); - - status = 0; - if (pointer) - status = LYscanFloat(pointer, &quality); - - HTSetSuffix(word2, word3, - encoding ? encoding : "binary", - status >= 1 ? quality : (float) 1.0); - - } else if (0 == strcasecomp(word1, "presentation")) { - status = 0; - if (pointer) { - const char *temp = pointer; - - if (LYscanFloat2(&temp, &quality)) { - status = 1; - if (LYscanFloat2(&temp, &secs)) { - status = 2; - if (LYscanFloat2(&temp, &secs_per_byte)) { - status = 3; - if (sscanf(temp, "%ld", &maxbytes)) { - status = 4; - } - } - } - } - } - - HTSetPresentation(word2, word3, NULL, - status >= 1 ? quality : 1.0, - status >= 2 ? secs : 0.0, - status >= 3 ? secs_per_byte : 0.0, - status >= 4 ? maxbytes : 0, - mediaCFG); - - } else if (0 == strncasecomp(word1, "htbin", 5) || - 0 == strncasecomp(word1, "bindir", 6)) { - StrAllocCopy(HTBinDir, word2); /* Physical /htbin location */ - - } else if (0 == strncasecomp(word1, "search", 6)) { - StrAllocCopy(HTSearchScript, word2); /* Search script name */ - - } else { - op = 0 == strcasecomp(word1, "map") ? HT_Map - : 0 == strcasecomp(word1, "pass") ? HT_Pass - : 0 == strcasecomp(word1, "fail") ? HT_Fail - : 0 == strcasecomp(word1, "redirect") ? HT_Redirect - : 0 == strncasecomp(word1, "redirectperm", 12) ? HT_RedirectPerm - : 0 == strcasecomp(word1, "redirecttemp") ? HT_Redirect - : 0 == strcasecomp(word1, "permitredirection") ? HT_PermitRedir - : 0 == strcasecomp(word1, "useproxy") ? HT_UseProxy - : 0 == strcasecomp(word1, "alert") ? HT_Alert - : 0 == strcasecomp(word1, "alwaysalert") ? HT_AlwaysAlert - : 0 == strcasecomp(word1, "progress") ? HT_Progress - : 0 == strcasecomp(word1, "usermsg") ? HT_UserMsg - : 0 == strcasecomp(word1, "infomsg") ? HT_InfoMsg - : 0 == strcasecomp(word1, "defprot") ? HT_DefProt - : 0 == strcasecomp(word1, "protect") ? HT_Protect - : HT_Invalid; - if (op == HT_Invalid) { - fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config); - } else { - switch (op) { - case HT_Fail: /* never a or other 2nd parameter */ - case HT_PermitRedir: - cond_op = word3; - if (cond_op && *cond_op) { - word3 = NULL; - cond = HTNextField(&pointer); - } - break; - - case HT_Pass: /* possibly a URL2 */ - if (word3 && (!strcasecomp(word3, "if") || - !strcasecomp(word3, "unless"))) { - cond_op = word3; - word3 = NULL; - cond = HTNextField(&pointer); - break; - } - /* else fall through */ - case HT_Map: /* always a URL2 (or other 2nd parameter) */ - case HT_Redirect: - case HT_RedirectPerm: - case HT_UseProxy: - cond_op = HTNextField(&pointer); - /* check for extra status word in "Redirect" */ - if (op == HT_Redirect && 0 == strcasecomp(word1, "redirect") && - cond_op && - strcasecomp(cond_op, "if") && - strcasecomp(cond_op, "unless")) { - if (0 == strcmp(word2, "301") || - 0 == strcasecomp(word2, "permanent")) { - op = HT_RedirectPerm; - } else if (!(0 == strcmp(word2, "302") || - 0 == strcmp(word2, "303") || - 0 == strcasecomp(word2, "temp") || - 0 == strcasecomp(word2, "seeother"))) { - CTRACE((tfp, "Rule: Ignoring `%s' in Redirect\n", word2)); - } - word2 = word3; - word3 = cond_op; /* cond_op isn't condition op after all */ - cond_op = HTNextField(&pointer); - } - if (cond_op && *cond_op) - cond = HTNextField(&pointer); - break; - - case HT_Progress: - case HT_InfoMsg: - case HT_UserMsg: - case HT_Alert: - case HT_AlwaysAlert: - cond_op = HTNextField(&pointer); - if (cond_op && *cond_op) - cond = HTNextField(&pointer); - if (word3) { /* Fix string with too may %s - kw */ - const char *cp = word3; - char *cp1, *cp2; - - while ((cp1 = strchr(cp, '%'))) { - if (cp1[1] == '\0') { - *cp1 = '\0'; - break; - } else if (cp1[1] == '%') { - cp = cp1 + 2; - continue; - } else - while ((cp2 = strchr(cp1 + 2, '%'))) { - if (cp2[1] == '\0') { - *cp2 = '\0'; - break; - } else if (cp2[1] == '%') { - cp1 = cp2; - } else { - *cp2 = '?'; /* replace bad % */ - cp1 = cp2; - } - } - break; - } - } - break; - - default: - break; - } - if (cond_op && cond && *cond && !strcasecomp(cond_op, "unless")) { - cond_op = "unless"; - } else if (cond_op && cond && *cond && - !strcasecomp(cond_op, "if")) { - cond_op = "if"; - } else if (cond_op || cond) { - fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config); - FREE(line); /* syntax error, condition is a mess - kw */ - return -2; /* NB unrecognized cond passes here - kw */ - } - if (cond && !strncasecomp(cond, "redirected", (int) strlen(cond))) { - cond = "redirected"; /* recognized, canonical case - kw */ - } else if (cond && strlen(cond) >= 8 && - !strncasecomp(cond, "userspecified", (int) strlen(cond))) { - cond = "userspec"; /* also allow abbreviation - kw */ - } - HTAddRule(op, word2, word3, cond_op, cond); - } - } - FREE(line); - return 0; -} - -/* Load the rules from a file HTLoadRules() - * -------------------------- - * - * On entry, - * Rules can be in any state - * On exit, - * Any existing rules will have been kept. - * Any new rules will have been loaded. - * Returns 0 if no error, 0 if error! - * - * Bugs: - * The strings may not contain spaces. - */ - -int HTLoadRules(const char *filename) -{ - FILE *fp = fopen(filename, TXT_R); - char line[LINE_LENGTH + 1]; - - if (!fp) { - CTRACE((tfp, "HTRules: Can't open rules file %s\n", filename)); - return -1; /* File open error */ - } - for (;;) { - if (!fgets(line, LINE_LENGTH + 1, fp)) - break; /* EOF or error */ - (void) HTSetConfiguration(line); - } - fclose(fp); - return 0; /* No error or syntax errors ignored */ -} - -#endif /* NO_RULES */ |