You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Jay Soffian <ja...@cimedia.com> on 1998/02/14 03:20:45 UTC

mod_include/1803: patches to mod_include to allow for file tests

>Number:         1803
>Category:       mod_include
>Synopsis:       patches to mod_include to allow for file tests
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          change-request
>Submitter-Id:   apache
>Arrival-Date:   Fri Feb 13 18:30:00 PST 1998
>Last-Modified:
>Originator:     jay@cimedia.com
>Organization:
apache
>Release:        1.3b3
>Environment:
Linux redshift.cimedia.com 2.0.32 #19 Fri Jan 9 21:46:10 EST 1998 i686 unknown
>Description:
Here are some patches agains mod_include to allow for the following
file test operators:
-d, -e, -f, -r, -w, -x, -s
>How-To-Repeat:
Apply this patch:

*** mod_include.c.orig  Fri Feb 13 19:25:26 1998
--- mod_include.c       Fri Feb 13 20:57:20 1998
***************
*** 1072,1081 ****
      token_string,
      token_and, token_or, token_not, token_eq, token_ne,
      token_rbrace, token_lbrace, token_group,
!     token_ge, token_le, token_gt, token_lt
  };
  struct token {
      enum token_type type;
      char value[MAX_STRING_LEN];
  };
  
--- 1072,1090 ----
      token_string,
      token_and, token_or, token_not, token_eq, token_ne,
      token_rbrace, token_lbrace, token_group,
!     token_ge, token_le, token_gt, token_lt,
!     token_ftest
  };
+ 
+ enum token_subtype {
+     ftest_d, ftest_e, ftest_f, 
+     ftest_r, ftest_w, ftest_x,
+     ftest_s
+ };
+ 
  struct token {
      enum token_type type;
+     enum token_subtype subtype;
      char value[MAX_STRING_LEN];
  };
  
***************
*** 1149,1154 ****
--- 1158,1194 ----
              token->type = token_lt;
              return (string);
          }
+     case '-':
+         switch (*string) {
+         case 'd': /* file exists and is directory */
+             token->subtype = ftest_d;
+             token->type = token_ftest;
+             return (string +1);
+         case 'e': /* file exists */
+             token->subtype = ftest_e;
+             token->type = token_ftest;
+             return (string +1);
+         case 'f': /* file exists and is regular file */
+             token->subtype = ftest_f;
+             token->type = token_ftest;
+             return (string +1);
+         case 'r': /* file exists and is readable */
+             token->subtype = ftest_r;
+             token->type = token_ftest;
+             return (string +1);
+         case 'w': /* file exists and is writeable */
+             token->subtype = ftest_w;
+             token->type = token_ftest;
+             return (string +1);
+         case 'x': /* file exists and is executable */
+             token->subtype = ftest_x;
+             token->type = token_ftest;
+             return (string +1);
+         case 's': /* file exists and has size greater than zero */
+             token->subtype = ftest_s;
+             token->type = token_ftest;
+             return (string +1);
+         }
      default:
          token->type = token_string;
          break;
***************
*** 1241,1247 ****
      char buffer[MAX_STRING_LEN];
      pool *expr_pool;
      int retval = 0;
! 
      if ((parse = expr) == (char *) NULL) {
          return (0);
      }
--- 1281,1287 ----
      char buffer[MAX_STRING_LEN];
      pool *expr_pool;
      int retval = 0;
!     struct stat stat_buf1, stat_buf2;
      if ((parse = expr) == (char *) NULL) {
          return (0);
      }
***************
*** 1292,1297 ****
--- 1332,1338 ----
              case token_and:
              case token_or:
              case token_lbrace:
+           case token_ftest:
              case token_not:
              case token_ge:
              case token_gt:
***************
*** 1327,1332 ****
--- 1368,1374 ----
                  case token_string:
                  case token_group:
                  case token_not:
+               case token_ftest:
                  case token_eq:
                  case token_ne:
                  case token_and:
***************
*** 1374,1379 ****
--- 1416,1468 ----
              while (current != (struct parse_node *) NULL) {
                  switch (current->token.type) {
                  case token_not:
+               case token_ftest:
+                 case token_eq:
+                 case token_ne:
+                 case token_and:
+                 case token_or:
+                 case token_lbrace:
+                 case token_ge:
+                 case token_gt:
+                 case token_le:
+                 case token_lt:
+                     break;
+                 default:
+                     aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+                                 "Invalid expression \"%s\" in file %s",
+                                 expr, r->filename);
+                     rputs(error, r);
+                     goto RETURN;
+                 }
+                 break;
+             }
+             if (current == (struct parse_node *) NULL) {
+                 new->left = root;
+                 new->left->parent = new;
+                 new->parent = (struct parse_node *) NULL;
+                 root = new;
+             }
+             else {
+                 new->left = current->right;
+                 current->right = new;
+                 new->parent = current;
+             }
+             current = new;
+             break;
+ 
+         case token_ftest:
+ #ifdef DEBUG_INCLUDE
+             rputs("     Token: ftest\n", r);
+ #endif
+             if (current == (struct parse_node *) NULL) {
+                 root = current = new;
+                 break;
+             }
+             /* Percolate upwards */
+             while (current != (struct parse_node *) NULL) {
+                 switch (current->token.type) {
+                 case token_not:
+                 case token_ftest:
                  case token_eq:
                  case token_ne:
                  case token_and:
***************
*** 1435,1440 ****
--- 1524,1530 ----
                  case token_or:
                      break;
                  case token_not:
+                 case token_ftest:
                  case token_eq:
                  case token_ne:
                  case token_ge:
***************
*** 1496,1501 ****
--- 1586,1592 ----
              while (current != (struct parse_node *) NULL) {
                  switch (current->token.type) {
                  case token_not:
+               case token_ftest:
                  case token_eq:
                  case token_ne:
                  case token_and:
***************
*** 1732,1737 ****
--- 1823,1885 ----
              current = current->parent;
              break;
  
+         case token_ftest:
+ #ifdef DEBUG_INCLUDE
+             rputs("     Evaluate ftest\n", r);
+ #endif
+             if ((current->right == (struct parse_node *) NULL) ||
+                 (current->right->token.type != token_string)) {
+                 aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+                             "Invalid expression \"%s\" in file %s",
+                             expr, r->filename);
+                 rputs(error, r);
+                 goto RETURN;
+             }
+             parse_string(r, current->right->token.value,
+                          buffer, MAX_STRING_LEN, 0);
+             strncpy(current->right->token.value, buffer, MAX_STRING_LEN - 1);
+ #ifdef DEBUG_INCLUDE
+             rvputs(r, "     ftest (", current->right->token.value, ")\n", NULL);
+ #endif
+ 
+           if (!stat(current->right->token.value, &stat_buf1)) {
+             switch (current->token.subtype) {
+             case ftest_e:
+                 current->value = 1;
+                 break;
+             case ftest_d:
+                 current->value = S_ISDIR(stat_buf1.st_mode);
+                 break;
+             case ftest_f:
+                 current->value = S_ISREG(stat_buf1.st_mode);
+                 break;
+             case ftest_r:
+                 current->value = (access(current->right->token.value,R_OK)==0)?1:0;
+                 break;
+             case ftest_w:
+                 current->value = (access(current->right->token.value,W_OK)==0)?1:0;
+                 break;
+             case ftest_x:
+                 current->value = (access(current->right->token.value,X_OK)==0)?1:0;
+                 break;
+             case ftest_s:
+                 current->value = (stat_buf1.st_size>1)?1:0;
+                   break;
+               default:
+                   current->value = 0;     /* Don't return -1 if unknown token */
+             }
+             } else {
+                   current->value = 0;
+             }
+           
+ #ifdef DEBUG_INCLUDE
+             rvputs(r, "     Returning ", current->value ? "1" : "0",
+                    "\n", NULL);
+ #endif
+             current->done = 1;
+             current = current->parent;
+             break;
+ 
          case token_not:
              if (current->right != (struct parse_node *) NULL) {
                  if (!current->right->done) {
***************
*** 1750,1755 ****
--- 1898,1904 ----
              current->done = 1;
              current = current->parent;
              break;
+ 
  
          case token_group:
              if (current->right != (struct parse_node *) NULL) {

[END OF PATCH]
>Fix:
Include the patch in the regular distribution so I don't have to
apache every new version of apache. :)

Note: I haven't a clue if the patches will compile properly under NT
or OS/2. I don't have those platforms available for testing.

Thanks.
%0
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <ap...@Apache.Org> in the Cc line ]
[and leave the subject line UNCHANGED.  This is not done]
[automatically because of the potential for mail loops. ]