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