diff options
Diffstat (limited to 'WWW/Library/Implementation/HTRules.c')
-rw-r--r-- | WWW/Library/Implementation/HTRules.c | 260 |
1 files changed, 253 insertions, 7 deletions
diff --git a/WWW/Library/Implementation/HTRules.c b/WWW/Library/Implementation/HTRules.c index 97df34e6..6140765e 100644 --- a/WWW/Library/Implementation/HTRules.c +++ b/WWW/Library/Implementation/HTRules.c @@ -15,6 +15,7 @@ ** 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. ** */ @@ -35,10 +36,17 @@ typedef struct _rule { 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 <LYUtils.h> /* for LYFixCursesOn - kw */ +#include <HTAlert.h> + /* Global variables ** ---------------- */ @@ -68,15 +76,17 @@ PRIVATE rule * rule_tail = 0; /* Pointer to last on list */ ** returns 0 if success, -1 if error. */ -PUBLIC int HTAddRule ARGS3( +PUBLIC int HTAddRule ARGS5( HTRuleOp, op, CONST char *, pattern, - CONST char *, equiv) + CONST char *, equiv, + CONST char *, cond_op, + CONST char *, cond) { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */ rule * temp; char * pPattern; - temp = (rule *)malloc(sizeof(*temp)); + temp = (rule *)calloc(1, sizeof(*temp)); if (temp==NULL) outofmem(__FILE__, "HTAddRule"); pPattern = (char *)malloc(strlen(pattern)+1); @@ -91,14 +101,23 @@ PUBLIC int HTAddRule ARGS3( } else { temp->equiv = 0; } + if (cond_op) { + StrAllocCopy(temp->condition_op, cond_op); + StrAllocCopy(temp->condition, cond); + } temp->pattern = pPattern; temp->op = op; strcpy(pPattern, pattern); if (equiv) { - CTRACE(tfp, "Rule: For `%s' op %d `%s'\n", pattern, op, equiv); + CTRACE(tfp, "Rule: For `%s' op %d `%s'", pattern, op, equiv); } else { - CTRACE(tfp, "Rule: For `%s' op %d\n", pattern, op); + CTRACE(tfp, "Rule: For `%s' op %d", pattern, op); + } + if (cond_op) { + CTRACE(tfp, "\t%s %s\n", cond_op, cond ? cond : "<null>"); + } else { + CTRACE(tfp, "\n"); } if (!rules) { @@ -137,6 +156,8 @@ void HTClearRules NOARGS rules = temp->next; FREE(temp->pattern); FREE(temp->equiv); + FREE(temp->condition_op); + FREE(temp->condition); FREE(temp); } #ifndef PUT_ON_HEAD @@ -144,7 +165,32 @@ void HTClearRules NOARGS #endif } - +PRIVATE BOOL rule_cond_ok ARGS1( + 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 = (redirection_attempts > 0); + else if (!strcmp(r->condition, "userspec")) + result = LYUserSpecifiedURL; + else { + CTRACE(tfp, "....... rule ignored, unrecognized `%s %s'!\n", + r->condition_op, r->condition ? r->condition : "<null>"); + return NO; + } + if (!strcmp(r->condition_op, "if")) + return result; + else + return (!result); + +} /* Translate by rules HTTranslate() ** ------------------ ** @@ -169,6 +215,9 @@ char * HTTranslate ARGS1( { rule * r; char *current = NULL; + char *msgtmp = NULL, *pMsg; + int proxy_none_flag = 0; + int permitredir_flag = 0; StrAllocCopy(current, required); HTAA_clearProtections(); /* Reset from previous call -- AL */ @@ -188,6 +237,9 @@ char * HTTranslate ARGS1( } 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 */ #ifdef ACCESS_AUTH @@ -225,14 +277,53 @@ char * HTTranslate ARGS1( break; #endif /* ACCESS_AUTH */ + 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 */ @@ -264,9 +355,49 @@ char * HTTranslate ARGS1( } /* 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 = (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 = (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, + r->equiv ? r->equiv : "<null>"); + } else { + char * temp = NULL; + StrAllocCopy(temp, "Proxied="); + StrAllocCat(temp, r->equiv); + StrAllocCat(temp, current); + CTRACE(tfp, "HTRule: proxy server found: %s\n", + r->equiv ? r->equiv : "<null>"); + FREE(current); + return temp; } break; @@ -280,6 +411,12 @@ char * HTTranslate ARGS1( } /* loop over rules */ + if (proxy_none_flag) { + char * temp = NULL; + StrAllocCopy(temp, "NoProxy="); + StrAllocCat(temp, current); + return temp; + } return current; } @@ -298,6 +435,7 @@ PUBLIC int HTSetConfiguration ARGS1( char * line = NULL; char * pointer = line; char *word1, *word2, *word3; + char *cond_op=NULL, *cond=NULL; float quality, secs, secs_per_byte; int maxbytes; int status; @@ -357,13 +495,121 @@ PUBLIC int HTSetConfiguration ARGS1( 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 { - HTAddRule(op, word2, word3); + 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 */ + char *cp = word3, *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", strlen(cond))) { + cond = "redirected"; /* recognized, canonical case - kw */ + } else if (cond && strlen(cond) >= 8 && + !strncasecomp(cond, "userspecified", strlen(cond))) { + cond = "userspec"; /* also allow abbreviation - kw */ + } + HTAddRule(op, word2, word3, cond_op, cond); } } FREE(line); |