bjh         99/07/19 02:48:28

  Modified:    src/include httpd.h
               src/main util.c util_script.c
  Log:
  OS/2: Fix spawning of CGI scripts to use appropriate type of command line
  escapes for OS/2's cmd.exe.
  
  Revision  Changes    Path
  1.285     +1 -0      apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.284
  retrieving revision 1.285
  diff -u -r1.284 -r1.285
  --- httpd.h   1999/06/30 08:12:48     1.284
  +++ httpd.h   1999/07/19 09:48:24     1.285
  @@ -992,6 +992,7 @@
   API_EXPORT(char *) ap_uuencode(pool *p, char *string); 
   #ifdef OS2
   void os2pathname(char *path);
  +char *ap_double_quotes(pool *p, char *str);
   #endif
   
   API_EXPORT(int)    ap_regexec(const regex_t *preg, const char *string,
  
  
  
  1.166     +26 -0     apache-1.3/src/main/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/util.c,v
  retrieving revision 1.165
  retrieving revision 1.166
  diff -u -r1.165 -r1.166
  --- util.c    1999/06/17 22:58:16     1.165
  +++ util.c    1999/07/19 09:48:26     1.166
  @@ -2140,6 +2140,32 @@
   
       strcpy(path, newpath);
   };
  +
  +/* quotes in the string are doubled up.
  + * Used to escape quotes in args passed to OS/2's cmd.exe
  + */
  +char *ap_double_quotes(pool *p, char *str)
  +{
  +    int num_quotes = 0;
  +    int len = 0;
  +    char *quote_doubled_str, *dest;
  +    
  +    while (str[len]) {
  +        num_quotes += str[len++] == '\"';
  +    }
  +    
  +    quote_doubled_str = ap_palloc(p, len + num_quotes + 1);
  +    dest = quote_doubled_str;
  +    
  +    while (*str) {
  +        if (*str == '\"')
  +            *(dest++) = '\"';
  +        *(dest++) = *(str++);
  +    }
  +    
  +    *dest = 0;
  +    return quote_doubled_str;
  +}
   #endif
   
   
  
  
  
  1.143     +112 -35   apache-1.3/src/main/util_script.c
  
  Index: util_script.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/util_script.c,v
  retrieving revision 1.142
  retrieving revision 1.143
  diff -u -r1.142 -r1.143
  --- util_script.c     1999/06/28 22:38:26     1.142
  +++ util_script.c     1999/07/19 09:48:27     1.143
  @@ -67,6 +67,11 @@
   #include "util_script.h"
   #include "util_date.h"               /* For parseHTTPdate() */
   
  +#ifdef OS2
  +#define INCL_DOS
  +#include <os2.h>
  +#endif
  +
   /*
    * Various utility functions which are common to a whole lot of
    * script-type extensions mechanisms, and might as well be gathered
  @@ -750,54 +755,126 @@
   #ifdef OS2
       {
        /* Additions by Alec Kloss, to allow exec'ing of scripts under OS/2 */
  -     int is_script;
  +     int is_script = 0;
        char interpreter[2048]; /* hope it's enough for the interpreter path */
  +     char error_object[260];
        FILE *program;
  -
  +        char *cmdline = r->filename, *cmdline_pos;
  +        int cmdlen;
  +     char *args = "", *args_end;
  +     ULONG rc;
  +        RESULTCODES rescodes;
  +        int env_len, e;
  +        char *env_block, *env_block_pos;
  +
  +     if (r->args && r->args[0] && !strchr(r->args, '='))
  +         args = r->args;
  +         
        program = fopen(r->filename, "rt");
  +     
        if (!program) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "fopen(%s) failed",
                         r->filename);
            return (pid);
        }
  +     
        fgets(interpreter, sizeof(interpreter), program);
        fclose(program);
  +     
        if (!strncmp(interpreter, "#!", 2)) {
            is_script = 1;
  -         interpreter[strlen(interpreter) - 1] = '\0';
  -     }
  -     else {
  -         is_script = 0;
  -     }
  -
  -     if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) {
  -         /* More additions by Alec Kloss for OS/2 */
  -         if (is_script) {
  -             /* here's the stuff to run the interpreter */
  -             pid = spawnle(P_NOWAIT, interpreter + 2, interpreter + 2, 
r->filename, NULL, env);
  -         }
  -         else if (strstr(strupr(r->filename), ".CMD") > 0) {
  -             /* Special case to allow use of REXX commands as scripts. */
  -             os2pathname(r->filename);
  -             pid = spawnle(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/C", 
r->filename, NULL, env);
  -         }
  -         else {
  -             pid = spawnle(P_NOWAIT, r->filename, argv0, NULL, env);
  -         }
  -     }
  -     else {
  -         if (strstr(strupr(r->filename), ".CMD") > 0) {
  -             /* Special case to allow use of REXX commands as scripts. */
  -             os2pathname(r->filename);
  -             pid = spawnve(P_NOWAIT, SHELL_PATH, create_argv_cmd(r->pool, 
argv0, r->args,
  -                                               r->filename), env);
  -         }
  -         else {
  -             pid = spawnve(P_NOWAIT, r->filename,
  -                   create_argv(r->pool, NULL, NULL, NULL, argv0, r->args), 
env);
  -         }
  +            interpreter[strlen(interpreter) - 1] = '\0';
  +            if (interpreter[2] != '/' && interpreter[2] != '\\' && 
interpreter[3] != ':') {
  +                char buffer[300];
  +                if (DosSearchPath(SEARCH_ENVIRONMENT, "PATH", interpreter+2, 
buffer, sizeof(buffer)) == 0) {
  +                    strcpy(interpreter+2, buffer);
  +                } else {
  +                    strcat(interpreter, ".exe");
  +                    if (DosSearchPath(SEARCH_ENVIRONMENT, "PATH", 
interpreter+2, buffer, sizeof(buffer)) == 0) {
  +                        strcpy(interpreter+2, buffer);
  +                    }
  +                }
  +            }
  +     }
  +
  +        if (is_script) {
  +            cmdline = ap_pstrcat(r->pool, interpreter+2, " ", r->filename, 
NULL);
  +        }
  +        else if (strstr(strupr(r->filename), ".CMD") > 0) {
  +            /* Special case to allow use of REXX commands as scripts. */
  +            os2pathname(r->filename);
  +            cmdline = ap_pstrcat(r->pool, SHELL_PATH, " /C ", r->filename, 
NULL);
  +        }
  +        else {
  +            cmdline = r->filename;
  +     }
  +     
  +        args = ap_pstrdup(r->pool, args);
  +        ap_unescape_url(args);
  +        args = ap_double_quotes(r->pool, args);
  +        args_end = args + strlen(args);
  +
  +        if (args_end - args > 4000) { /* cmd.exe won't handle lines longer 
than 4k */
  +            args_end = args + 4000;
  +            *args_end = 0;
  +        }
  +
  +        /* +4 = 1 space between progname and args, 2 for double null at end, 
2 for possible quote on first arg */
  +        cmdlen = strlen(cmdline) + strlen(args) + 4; 
  +        cmdline_pos = cmdline;
  +
  +        while (*cmdline_pos) {
  +            cmdlen += 2 * (*cmdline_pos == '+');  /* Allow space for each 
arg to be quoted */
  +            cmdline_pos++;
  +        }
  +
  +        cmdline = ap_pstrndup(r->pool, cmdline, cmdlen);
  +        cmdline_pos = cmdline + strlen(cmdline);
  +
  +     while (args < args_end) {
  +            char *arg;
  +         
  +            arg = ap_getword_nc(r->pool, &args, '+');
  +
  +            if (strpbrk(arg, "&|<> "))
  +                arg = ap_pstrcat(r->pool, "\"", arg, "\"", NULL);
  +
  +            *(cmdline_pos++) = ' ';
  +            strcpy(cmdline_pos, arg);
  +            cmdline_pos += strlen(cmdline_pos);
  +        }
  +
  +        *(++cmdline_pos) = 0; /* Add required second terminator */
  +     args = strchr(cmdline, ' ');
  +     
  +     if (args) {
  +         *args = 0;
  +         args++;
  +     }
  +
  +        /* Create environment block from list of envariables */
  +        for (env_len=1, e=0; env[e]; e++)
  +            env_len += strlen(env[e]) + 1;
  +
  +        env_block = ap_palloc(r->pool, env_len);
  +        env_block_pos = env_block;
  +
  +        for (e=0; env[e]; e++) {
  +            strcpy(env_block_pos, env[e]);
  +            env_block_pos += strlen(env_block_pos) + 1;
  +        }
  +
  +        *env_block_pos = 0; /* environment block is terminated by a double 
null */
  +
  +     rc = DosExecPgm(error_object, sizeof(error_object), EXEC_ASYNC, 
cmdline, env_block, &rescodes, cmdline);
  +     
  +     if (rc) {
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "DosExecPgm(%s %s) 
failed, %s - %s",
  +                          cmdline, args ? args : "", 
ap_os_error_message(rc), error_object );
  +         return -1;
        }
  -     return (pid);
  +     
  +     return rescodes.codeTerminate;
       }
   #elif defined(WIN32)
       {
  
  
  

Reply via email to