stoddard 98/08/05 19:03:39
Modified: src/main util_script.c Log: Ref PR2356 - Handle SSI exec tag correctly. In ap_call_exec, handle shellcmd parameter, use COMMAND.COM on Win95 and CMD.EXE on NT. Revision Changes Path 1.125 +96 -80 apache-1.3/src/main/util_script.c Index: util_script.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/util_script.c,v retrieving revision 1.124 retrieving revision 1.125 diff -u -r1.124 -r1.125 --- util_script.c 1998/08/05 23:07:54 1.124 +++ util_script.c 1998/08/06 02:03:38 1.125 @@ -795,86 +795,92 @@ quoted_filename = ap_pstrcat(r->pool, "\"", r->filename, "\"", NULL); - exename = strrchr(r->filename, '/'); - if (!exename) { - exename = strrchr(r->filename, '\\'); - } - if (!exename) { - exename = r->filename; - } - else { - exename++; - } - dot = strrchr(exename, '.'); - if (dot) { - if (!strcasecmp(dot, ".BAT") - || !strcasecmp(dot, ".CMD") - || !strcasecmp(dot, ".EXE") - || !strcasecmp(dot, ".COM")) { - is_exe = 1; - } - } - - if (!is_exe) { - program = fopen(r->filename, "rb"); - if (!program) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "fopen(%s) failed", r->filename); - return (pid); - } - sz = fread(interpreter, 1, sizeof(interpreter) - 1, program); - if (sz < 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "fread of %s failed", r->filename); - fclose(program); - return (pid); - } - interpreter[sz] = 0; - fclose(program); - if (!strncmp(interpreter, "#!", 2)) { - is_script = 1; - for (i = 2; i < sizeof(interpreter); i++) { - if ((interpreter[i] == '\r') - || (interpreter[i] == '\n')) { - break; - } - } - interpreter[i] = 0; - for (i = 2; interpreter[i] == ' '; ++i) - ; - memmove(interpreter+2,interpreter+i,strlen(interpreter+i)+1); - } - else { - /* Check to see if it's a executable */ - IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter; - if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512) { - is_binary = 1; - } - } - } - /* Bail out if we haven't figured out what kind of - * file this is by now.. - */ - if (!is_exe && !is_script && !is_binary) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, - "%s is not executable; ensure interpreted scripts have " - "\"#!\" first line", - r->filename); - return (pid); - } + if (!shellcmd) { + exename = strrchr(r->filename, '/'); + if (!exename) { + exename = strrchr(r->filename, '\\'); + } + if (!exename) { + exename = r->filename; + } + else { + exename++; + } + dot = strrchr(exename, '.'); + if (dot) { + if (!strcasecmp(dot, ".BAT") + || !strcasecmp(dot, ".CMD") + || !strcasecmp(dot, ".EXE") + || !strcasecmp(dot, ".COM")) { + is_exe = 1; + } + } - /* - * Make child process use hPipeOutputWrite as standard out, - * and make sure it does not show on screen. - */ - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - si.wShowWindow = SW_HIDE; - si.hStdInput = pinfo->hPipeInputRead; - si.hStdOutput = pinfo->hPipeOutputWrite; - si.hStdError = pinfo->hPipeErrorWrite; + if (!is_exe) { + program = fopen(r->filename, "rb"); + if (!program) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "fopen(%s) failed", r->filename); + return (pid); + } + sz = fread(interpreter, 1, sizeof(interpreter) - 1, program); + if (sz < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "fread of %s failed", r->filename); + fclose(program); + return (pid); + } + interpreter[sz] = 0; + fclose(program); + if (!strncmp(interpreter, "#!", 2)) { + is_script = 1; + for (i = 2; i < sizeof(interpreter); i++) { + if ((interpreter[i] == '\r') + || (interpreter[i] == '\n')) { + break; + } + } + interpreter[i] = 0; + for (i = 2; interpreter[i] == ' '; ++i) + ; + memmove(interpreter+2,interpreter+i,strlen(interpreter+i)+1); + } + else { + /* Check to see if it's a executable */ + IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter; + if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512) { + is_binary = 1; + } + } + } + /* Bail out if we haven't figured out what kind of + * file this is by now.. + */ + if (!is_exe && !is_script && !is_binary) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, + "%s is not executable; ensure interpreted scripts have " + "\"#!\" first line", + r->filename); + return (pid); + } + } - if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { + if (shellcmd) { + char *shell_cmd = "CMD.EXE /C "; + OSVERSIONINFO osver; + osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + /* + * Use CMD.EXE for NT, COMMAND.COM for WIN95 + */ + if (GetVersionEx(&osver)) { + if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT) { + shell_cmd = "COMMAND.COM /C "; + } + } + pCommand = ap_pstrcat(r->pool, shell_cmd, argv0, NULL); + } + else if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { if (is_exe || is_binary) { /* * When the CGI is a straight binary executable, @@ -953,13 +959,23 @@ quoted_filename, " ", arguments, NULL); } } + + /* + * Make child process use hPipeOutputWrite as standard out, + * and make sure it does not show on screen. + */ + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.hStdInput = pinfo->hPipeInputRead; + si.hStdOutput = pinfo->hPipeOutputWrite; + si.hStdError = pinfo->hPipeErrorWrite; /* * Win32's CreateProcess call requires that the environment * be passed in an environment block, a null terminated block of * null terminated strings. - */ - + */ i = 0; iEnvBlockLen = 1; while (env[i]) {