You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by st...@hyperreal.org on 1999/06/29 00:38:27 UTC
cvs commit: apache-1.3/src/main http_core.c util_script.c
stoddard 99/06/28 15:38:27
Modified: src/include http_core.h
src/main http_core.c util_script.c
Log:
Win32: Fix 16-bit CGI support
PR: 2494
Revision Changes Path
1.59 +3 -2 apache-1.3/src/include/http_core.h
Index: http_core.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/http_core.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- http_core.h 1999/06/22 00:51:28 1.58
+++ http_core.h 1999/06/28 22:38:25 1.59
@@ -156,10 +156,11 @@
/*
* CGI Script stuff for Win32...
*/
-typedef enum { FileTypeUNKNOWN, FileTypeBIN, FileTypeEXE, FileTypeSCRIPT } file_type_e;
+typedef enum { eFileTypeUNKNOWN, eFileTypeBIN, eFileTypeEXE16, eFileTypeEXE32,
+ eFileTypeSCRIPT } file_type_e;
typedef enum { INTERPRETER_SOURCE_UNSET, INTERPRETER_SOURCE_REGISTRY,
INTERPRETER_SOURCE_SHEBANG } interpreter_source_e;
-API_EXPORT(file_type_e) ap_get_win32_interpreter(const request_rec *, char*, char **);
+API_EXPORT(file_type_e) ap_get_win32_interpreter(const request_rec *, char **);
#endif
#ifdef CORE_PRIVATE
1.268 +45 -23 apache-1.3/src/main/http_core.c
Index: http_core.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.267
retrieving revision 1.268
diff -u -r1.267 -r1.268
--- http_core.c 1999/06/24 16:38:45 1.267
+++ http_core.c 1999/06/28 22:38:25 1.268
@@ -848,7 +848,6 @@
}
API_EXPORT (file_type_e) ap_get_win32_interpreter(const request_rec *r,
- char* ext,
char** interpreter )
{
HANDLE hFile;
@@ -856,50 +855,68 @@
BOOLEAN bResult;
char buffer[1024];
core_dir_config *d;
- file_type_e fileType = FileTypeUNKNOWN;
int i;
+ file_type_e fileType = eFileTypeUNKNOWN;
+ char *ext = NULL;
+ char *exename = NULL;
d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
&core_module);
- if (d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY) {
- /*
- * Check the registry
- */
+ /* Find the file extension */
+ exename = strrchr(r->filename, '/');
+ if (!exename) {
+ exename = strrchr(r->filename, '\\');
+ }
+ if (!exename) {
+ exename = r->filename;
+ }
+ else {
+ exename++;
+ }
+ ext = strrchr(exename, '.');
+
+ if (ext && (!strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) {
+ return eFileTypeEXE32;
+ }
+
+ /* If the file has an extension and it is not .com and not .exe and
+ * we've been instructed to search the registry, then do it!
+ */
+ if (ext && strcasecmp(ext,".exe") && strcasecmp(ext,".com") &&
+ d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY) {
+ /* Check the registry */
*interpreter = get_interpreter_from_win32_registry(r->pool, ext);
if (*interpreter)
- return FileTypeSCRIPT;
+ return eFileTypeSCRIPT;
else {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r->server,
"ScriptInterpreterSource config directive set to \"registry\".\n\t"
"Registry was searched but interpreter not found. Trying the shebang line.");
}
- }
+ }
- /*
- * Look for a #! line in the script
- */
+ /* Need to peek into the file figure out what it really is... */
hFile = CreateFile(r->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
if (hFile == INVALID_HANDLE_VALUE) {
- return FileTypeUNKNOWN;
+ return eFileTypeUNKNOWN;
}
-
bResult = ReadFile(hFile, (void*) &buffer, sizeof(buffer) - 1,
&nBytesRead, NULL);
if (!bResult || (nBytesRead == 0)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"ReadFile(%s) failed", r->filename);
CloseHandle(hFile);
- return (FileTypeUNKNOWN);
+ return eFileTypeUNKNOWN;
}
CloseHandle(hFile);
-
buffer[nBytesRead] = '\0';
-
+
+ /* Script or executable, that is the question... */
if ((buffer[0] == '#') && (buffer[1] == '!')) {
- fileType = FileTypeSCRIPT;
+ /* Assuming file is a script since it starts with a shebang */
+ fileType = eFileTypeSCRIPT;
for (i = 2; i < sizeof(buffer); i++) {
if ((buffer[i] == '\r')
|| (buffer[i] == '\n')) {
@@ -907,16 +924,21 @@
}
}
buffer[i] = '\0';
- for (i = 2; buffer[i] == ' '; ++i)
+ for (i = 2; buffer[i] == ' ' ; ++i)
;
*interpreter = ap_pstrdup(r->pool, buffer + i );
}
else {
- /* Check to see if it's a executable */
- IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer;
- if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512) {
- fileType = FileTypeEXE;
+ /* Not a script, is it an executable? */
+ IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer;
+ if ((nBytesRead >= sizeof(IMAGE_DOS_HEADER)) && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) {
+ if (hdr->e_lfarlc < 0x40)
+ fileType = eFileTypeEXE16;
+ else
+ fileType = eFileTypeEXE32;
}
+ else
+ fileType = eFileTypeUNKNOWN;
}
return fileType;
1.142 +20 -33 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.141
retrieving revision 1.142
diff -u -r1.141 -r1.142
--- util_script.c 1999/06/22 00:51:31 1.141
+++ util_script.c 1999/06/28 22:38:26 1.142
@@ -825,34 +825,10 @@
pid = -1;
if (!shellcmd) {
- /* Find the file name */
- exename = strrchr(r->filename, '/');
- if (!exename) {
- exename = strrchr(r->filename, '\\');
- }
- if (!exename) {
- exename = r->filename;
- }
- else {
- exename++;
- }
- ext = strrchr(exename, '.');
- if ((ext) && (!strcasecmp(ext,".bat") ||
- !strcasecmp(ext,".cmd"))) {
- fileType = FileTypeEXE;
- }
- else if ((ext) && (!strcasecmp(ext,".exe") ||
- !strcasecmp(ext,".com"))) {
- /* 16 bit or 32 bit? */
- fileType = FileTypeEXE;
- }
- else {
- /* Maybe a script or maybe a binary.. */
- fileType = ap_get_win32_interpreter(r, ext, &interpreter);
- }
+ fileType = ap_get_win32_interpreter(r, &interpreter);
- if (fileType == FileTypeUNKNOWN) {
+ if (fileType == eFileTypeUNKNOWN) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
"%s is not executable; ensure interpreted scripts have "
"\"#!\" first line",
@@ -969,13 +945,24 @@
if (CreateProcess(NULL, pCommand, NULL, NULL, TRUE, 0, pEnvBlock,
ap_make_dirstr_parent(r->pool, r->filename),
&si, &pi)) {
- pid = pi.dwProcessId;
- /*
- * We must close the handles to the new process and its main thread
- * to prevent handle and memory leaks.
- */
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ if (fileType == eFileTypeEXE16) {
+ /* Hack to get 16-bit CGI's working. It works for all the
+ * standard modules shipped with Apache. pi.dwProcessId is 0
+ * for 16-bit CGIs and all the Unix specific code that calls
+ * ap_call_exec interprets this as a failure case. And we can't
+ * use -1 either because it is mapped to 0 by the caller.
+ */
+ pid = -2;
+ }
+ else {
+ pid = pi.dwProcessId;
+ /*
+ * We must close the handles to the new process and its main thread
+ * to prevent handle and memory leaks.
+ */
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
}
return (pid);
}