bjh         99/11/01 03:45:30

  Modified:    src/modules/standard mod_include.c
  Log:
  First hack at getting mod_include to work. Everything seems to work ok but
  error handling probably needs some work.
  
  Revision  Changes    Path
  1.7       +121 -111  apache-2.0/src/modules/standard/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_include.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- mod_include.c     1999/10/22 16:01:26     1.6
  +++ mod_include.c     1999/11/01 11:45:29     1.7
  @@ -199,20 +199,19 @@
    */
   #define GET_CHAR(f,c,ret,r) \
    { \
  -   int i = getc(f); \
  -   if (i == EOF) { /* either EOF or error -- needs error handling if latter 
*/ \
  -       if (ferror(f)) { \
  +   ap_status_t status = ap_getc(&c, f); \
  +   if (status != APR_SUCCESS) { /* either EOF or error -- needs error 
handling if latter */ \
  +       if (status != APR_EOF) { \
              fprintf(stderr, "encountered error in GET_CHAR macro, " \
                      "mod_include.\n"); \
          } \
          FLUSH_BUF(r); \
  -       ap_pfclose(r->pool, f); \
  +       ap_close(f); \
          return ret; \
      } \
  -   c = (char)i; \
    }
   
  -static int find_string(FILE *in, const char *str, request_rec *r, int 
printing)
  +static int find_string(ap_file_t *in, const char *str, request_rec *r, int 
printing)
   {
       int x, l = strlen(str), p;
       char outbuf[OUTBUFSIZE];
  @@ -245,16 +244,15 @@
   #undef GET_CHAR
   #define GET_CHAR(f,c,r,p) \
    { \
  -   int i = getc(f); \
  -   if (i == EOF) { /* either EOF or error -- needs error handling if latter 
*/ \
  -       if (ferror(f)) { \
  +   ap_status_t status = ap_getc(&c, f); \
  +   if (status != APR_SUCCESS) { /* either EOF or error -- needs error 
handling if latter */ \
  +       if (status != APR_EOF) { \
              fprintf(stderr, "encountered error in GET_CHAR macro, " \
                      "mod_include.\n"); \
          } \
  -       ap_pfclose(p, f); \
  +       ap_close(f); \
          return r; \
      } \
  -   c = (char)i; \
    }
   
   /*
  @@ -357,7 +355,7 @@
    * the tag value is html decoded if dodecode is non-zero
    */
   
  -static char *get_tag(ap_context_t *p, FILE *in, char *tag, int tagbuf_len, 
int dodecode)
  +static char *get_tag(ap_context_t *p, ap_file_t *in, char *tag, int 
tagbuf_len, int dodecode)
   {
       char *t = tag, *tag_val, c, term;
   
  @@ -403,7 +401,7 @@
           GET_CHAR(in, c, NULL, p);       /* space before = */
       }
       if (c != '=') {
  -        ungetc(c, in);
  +        ap_ungetc(c, in);
           return NULL;
       }
   
  @@ -443,7 +441,7 @@
       return ap_pstrdup(p, tag_val);
   }
   
  -static int get_directive(FILE *in, char *dest, size_t len, ap_context_t *p)
  +static int get_directive(ap_file_t *in, char *dest, size_t len, ap_context_t 
*p)
   {
       char *d = dest;
       char c;
  @@ -650,7 +648,7 @@
       return 1;
   }
   
  -static int handle_include(FILE *in, request_rec *r, const char *error, int 
noexec)
  +static int handle_include(ap_file_t *in, request_rec *r, const char *error, 
int noexec)
   {
       char tag[MAX_STRING_LEN];
       char parsed_string[MAX_STRING_LEN];
  @@ -771,26 +769,61 @@
       char *s;
   } include_cmd_arg;
   
  -static int include_cmd_child(void *arg, child_info *pinfo)
  +
  +
  +static ap_status_t build_argv_list(char ***argv, request_rec *r, 
ap_context_t *p)
   {
  -    request_rec *r = ((include_cmd_arg *) arg)->r;
  -    char *s = ((include_cmd_arg *) arg)->s;
  +    int numwords, x, idx;
  +    char *w;
  +    const char *args = r->args;
  +
  +    if (!args || !args[0] || strchr(args, '=')) {
  +       *argv = NULL;
  +    }
  +    else {
  +        /* count the number of keywords */
  +        for (x = 0, numwords = 1; args[x]; x++) {
  +            if (args[x] == '+') {
  +                ++numwords;
  +            }
  +        }
  +        if (numwords > APACHE_ARG_MAX) {
  +            numwords = APACHE_ARG_MAX;       /* Truncate args to prevent 
overrun */
  +        }
  +        *argv = (char **) ap_palloc(p, (numwords + 1) * sizeof(char *));
  +
  +        for (x = 1, idx = 0; x <= numwords; x++) {
  +            w = ap_getword_nulls(p, &args, '+');
  +            ap_unescape_url(w);
  +            (*argv)[idx++] = ap_escape_shell_cmd(p, w);
  +        }
  +        (*argv)[idx] = NULL;
  +    }
  +
  +    return APR_SUCCESS;
  +}
  +
  +
  +
  +static int include_cmd(char *s, request_rec *r)
  +{
  +    include_cmd_arg arg;
  +    BUFF *script_in;
  +    ap_procattr_t *procattr;
  +    ap_proc_t *procnew;
  +    ap_status_t rc;
       ap_table_t *env = r->subprocess_env;
  -    int child_pid = 0;
  -#ifdef DEBUG_INCLUDE_CMD
  -#ifdef OS2
  -    /* under OS/2 /dev/tty is referenced as con */
  -    FILE *dbg = fopen("con", "w");
  -#else
  -    FILE *dbg = fopen("/dev/tty", "w");
  -#endif
  -#endif
  -#ifndef WIN32
  -    char err_string[MAX_STRING_LEN];
  -#endif
  +    char **argv;
  +    ap_os_proc_t pid;
  +    ap_file_t *file;
  +    ap_iol *iol;
   
  -#ifdef DEBUG_INCLUDE_CMD
  -    fprintf(dbg, "Attempting to include command '%s'\n", s);
  +    arg.r = r;
  +    arg.s = s;
  +#ifdef TPF
  +    arg.t.filename = r->filename;
  +    arg.t.subprocess_env = r->subprocess_env;
  +    arg.t.prog_type = FORK_FILE;
   #endif
   
       if (r->path_info && r->path_info[0] != '\0') {
  @@ -815,65 +848,49 @@
                     ap_escape_shell_cmd(r->pool, arg_copy));
       }
   
  -    ap_error_log2stderr(r->server);
  -
  -#ifdef DEBUG_INCLUDE_CMD
  -    fprintf(dbg, "Attempting to exec '%s'\n", s);
  -#endif
  -#ifdef TPF
  -    return (0);
  -#else
  -    ap_cleanup_for_exec();
  -    /* set shellcmd flag to pass arg to SHELL_PATH */
  -    child_pid = ap_call_exec(r, pinfo, s, ap_create_environment(r->pool, 
env),
  -                          1);
  -#if defined(WIN32) || defined(OS2)
  -    return (child_pid);
  -#else
  -    /* Oh, drat.  We're still here.  The log file descriptors are closed,
  -     * so we have to whimper a complaint onto stderr...
  -     */
  -
  -#ifdef DEBUG_INCLUDE_CMD
  -    fprintf(dbg, "Exec failed\n");
  -#endif
  -    ap_snprintf(err_string, sizeof(err_string),
  -                "exec of %s failed, reason: %s (errno = %d)\n",
  -                SHELL_PATH, strerror(errno), errno);
  -    write(STDERR_FILENO, err_string, strlen(err_string));
  -    exit(0);
  -    /* NOT REACHED */
  -    return (child_pid);
  -#endif /* WIN32 */
  -#endif /* TPF */
  -}
  -
  -static int include_cmd(char *s, request_rec *r)
  -{
  -    include_cmd_arg arg;
  -    BUFF *script_in;
  -
  -    arg.r = r;
  -    arg.s = s;
  -#ifdef TPF
  -    arg.t.filename = r->filename;
  -    arg.t.subprocess_env = r->subprocess_env;
  -    arg.t.prog_type = FORK_FILE;
  -#endif
  +    if ((ap_createprocattr_init(&procattr, r->pool) != APR_SUCCESS) ||
  +        (ap_setprocattr_io(procattr, 0, 1, 0) != APR_SUCCESS) ||
  +        (ap_setprocattr_dir(procattr, ap_make_dirstr_parent(r->pool, 
r->filename)) != APR_SUCCESS) ||
  +        (ap_setprocattr_cmdtype(procattr, APR_PROGRAM) != APR_SUCCESS)) {
  +        /* Something bad happened, tell the world. */
  +     ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
  +                   "couldn't create child process: %s", r->filename);
  +        rc = !APR_SUCCESS;
  +    }
  +    else {
  +        build_argv_list(&argv, r, r->pool);
  +        rc = ap_create_process(&procnew, r->filename, argv, 
ap_create_environment(r->pool, env), procattr, r->pool);
   
  -    if (!ap_bspawn_child(r->pool, include_cmd_child, &arg,
  -                      kill_after_timeout, NULL, &script_in, NULL)) {
  -        ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
  -                  "couldn't spawn include command");
  -        return -1;
  +        if (rc != APR_SUCCESS) {
  +            /* Bad things happened. Everyone should have cleaned up. */
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
  +                        "couldn't create child process: %d: %s", rc, 
r->filename);
  +        }
  +        else {
  +#ifndef WIN32
  +            /* pjr - this is a cheap hack for now to get the basics working 
in
  +             *       stages. ap_note_subprocess and free_proc need to be 
redone
  +             *       to make use of ap_proc_t instead of pid.
  +             */
  +            ap_get_os_proc(&pid, procnew);
  +            ap_note_subprocess(r->pool, pid, kill_after_timeout);
  +#endif
  +            /* Fill in BUFF structure for parents pipe to child's stdout */
  +            ap_get_childout(&file, procnew);
  +            iol = ap_create_file_iol(file);
  +            if (!iol)
  +                return APR_EBADF;
  +            script_in = ap_bcreate(r->pool, B_RD);
  +            ap_bpush_iol(script_in, iol);
  +            ap_send_fb(script_in, r);
  +            ap_bclose(script_in);
  +        }
       }
   
  -    ap_send_fb(script_in, r);
  -    ap_bclose(script_in);
       return 0;
   }
   
  -static int handle_exec(FILE *in, request_rec *r, const char *error)
  +static int handle_exec(ap_file_t *in, request_rec *r, const char *error)
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
  @@ -918,7 +935,7 @@
   
   }
   
  -static int handle_echo(FILE *in, request_rec *r, const char *error)
  +static int handle_echo(ap_file_t *in, request_rec *r, const char *error)
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
  @@ -950,7 +967,7 @@
   }
   
   #ifdef USE_PERL_SSI
  -static int handle_perl(FILE *in, request_rec *r, const char *error)
  +static int handle_perl(ap_file_t *in, request_rec *r, const char *error)
   {
       char tag[MAX_STRING_LEN];
       char parsed_string[MAX_STRING_LEN];
  @@ -989,7 +1006,7 @@
   /* error and tf must point to a string with room for at 
    * least MAX_STRING_LEN characters 
    */
  -static int handle_config(FILE *in, request_rec *r, char *error, char *tf,
  +static int handle_config(ap_file_t *in, request_rec *r, char *error, char 
*tf,
                            int *sizefmt)
   {
       char tag[MAX_STRING_LEN];
  @@ -1106,7 +1123,7 @@
   }
   
   
  -static int handle_fsize(FILE *in, request_rec *r, const char *error, int 
sizefmt)
  +static int handle_fsize(ap_file_t *in, request_rec *r, const char *error, 
int sizefmt)
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
  @@ -1146,7 +1163,7 @@
       }
   }
   
  -static int handle_flastmod(FILE *in, request_rec *r, const char *error, 
const char *tf)
  +static int handle_flastmod(ap_file_t *in, request_rec *r, const char *error, 
const char *tf)
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
  @@ -1918,7 +1935,7 @@
       return (retval);
   }
   
  -static int handle_if(FILE *in, request_rec *r, const char *error,
  +static int handle_if(ap_file_t *in, request_rec *r, const char *error,
                        int *conditional_status, int *printing)
   {
       char tag[MAX_STRING_LEN];
  @@ -1961,7 +1978,7 @@
       }
   }
   
  -static int handle_elif(FILE *in, request_rec *r, const char *error,
  +static int handle_elif(ap_file_t *in, request_rec *r, const char *error,
                          int *conditional_status, int *printing)
   {
       char tag[MAX_STRING_LEN];
  @@ -2012,7 +2029,7 @@
       }
   }
   
  -static int handle_else(FILE *in, request_rec *r, const char *error,
  +static int handle_else(ap_file_t *in, request_rec *r, const char *error,
                          int *conditional_status, int *printing)
   {
       char tag[MAX_STRING_LEN];
  @@ -2040,7 +2057,7 @@
       }
   }
   
  -static int handle_endif(FILE *in, request_rec *r, const char *error,
  +static int handle_endif(ap_file_t *in, request_rec *r, const char *error,
                           int *conditional_status, int *printing)
   {
       char tag[MAX_STRING_LEN];
  @@ -2066,7 +2083,7 @@
       }
   }
   
  -static int handle_set(FILE *in, request_rec *r, const char *error)
  +static int handle_set(ap_file_t *in, request_rec *r, const char *error)
   {
       char tag[MAX_STRING_LEN];
       char parsed_string[MAX_STRING_LEN];
  @@ -2104,12 +2121,12 @@
       }
   }
   
  -static int handle_printenv(FILE *in, request_rec *r, const char *error)
  +static int handle_printenv(ap_file_t *in, request_rec *r, const char *error)
   {
       char tag[MAX_STRING_LEN];
       char *tag_val;
       ap_array_header_t *arr = ap_table_elts(r->subprocess_env);
  -    table_entry *elts = (table_entry *) arr->elts;
  +    ap_table_entry_t *elts = (ap_table_entry_t *)arr->elts;
       int i;
   
       if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
  @@ -2136,7 +2153,7 @@
   
   /* This is a stub which parses a file descriptor. */
   
  -static void send_parsed_content(FILE *f, request_rec *r)
  +static void send_parsed_content(ap_file_t *f, request_rec *r)
   {
       char directive[MAX_STRING_LEN], error[MAX_STRING_LEN];
       char timefmt[MAX_STRING_LEN];
  @@ -2320,7 +2337,7 @@
   
   static int send_parsed_file(request_rec *r)
   {
  -    FILE *f;
  +    ap_file_t *f;
       enum xbithack *state =
       (enum xbithack *) ap_get_module_config(r->per_dir_config, 
&includes_module);
       int errstatus;
  @@ -2341,9 +2358,11 @@
                        : r->filename));
           return HTTP_NOT_FOUND;
       }
  +
  +    errstatus = ap_open(&f, r->filename, APR_READ, 0, r->pool);
   
  -    if (!(f = ap_pfopen(r->pool, r->filename, "r"))) {
  -        ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
  +    if (errstatus != APR_SUCCESS) {
  +        ap_log_rerror(APLOG_MARK, APLOG_ERR, errstatus, r,
                       "file permissions deny server access: %s", r->filename);
           return HTTP_FORBIDDEN;
       }
  @@ -2364,7 +2383,7 @@
       ap_send_http_header(r);
   
       if (r->header_only) {
  -        ap_pfclose(r->pool, f);
  +        ap_close(f);
           return OK;
       }
   
  @@ -2455,20 +2474,11 @@
   module MODULE_VAR_EXPORT includes_module =
   {
       STANDARD20_MODULE_STUFF,
  -    NULL,                       /* pre_config */
  -    NULL,                       /* post_config */
  -    NULL,                       /* open_logs */
  -    NULL,                       /* child initializer */
       create_includes_dir_config, /* dir config creater */
       NULL,                       /* dir merger --- default is to override */
       NULL,                       /* server config */
       NULL,                       /* merge server config */
       includes_cmds,              /* command ap_table_t */
       includes_handlers,          /* handlers */
  -    NULL,                       /* check auth */
  -    NULL,                       /* check access */
  -    NULL,                       /* type_checker */
  -    NULL,                       /* fixups */
  -    NULL,                       /* logger */
       NULL                     /* register hooks */
   };
  
  
  

Reply via email to