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