You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by bj...@hyperreal.org on 1999/07/19 11:48:29 UTC

cvs commit: apache-1.3/src/main util.c util_script.c

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)
       {