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); }