home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / msdos / lynx / source / www / library / implemen / htrules.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-25  |  11.3 KB  |  429 lines

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