httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@locus.apache.org
Subject cvs commit: apache-1.3/src/main util_script.c http_core.c
Date Thu, 16 Nov 2000 22:28:40 GMT
wrowe       00/11/16 14:28:40

  Modified:    src/main util_script.c http_core.c
  Log:
    This change of the Win32-only code path of http_core and util_script
    now passes the %1 and %* arguments from the script interpreter (usually
    the registry shell\open\command entry) all the way back to the child
    processing code, so we make an intellegent decision about converting
    all cgi script paths to a short path, unless the script interpreter
    has a quoted "%1" argument.  The quoted "%1" argument assures us that
    this script safely handles long paths, including spaces and other odd
    characters within the filename.  [The %* indicates the position for
    additional arguments, which are otherwise appended to the command.]
    We make a bold assumption that cmd.exe likes long paths, while its
    older cousin command.com may not.
  
    This patch also adds environment variable expansion within the script
    interpreter processing for the registry, as %windir%/somecommand.exe
    is a somewhat common in the shell\open\command entries.
  
    This patch finally changes the .bat/.cmd processing to retrieve the
    registry shell\open\command values for those file types if the
    ScriptInterpreterSource Registry directive is in use.
  
  Revision  Changes    Path
  1.156     +95 -26    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.155
  retrieving revision 1.156
  diff -u -r1.155 -r1.156
  --- util_script.c	2000/11/15 01:50:45	1.155
  +++ util_script.c	2000/11/16 22:28:39	1.156
  @@ -956,11 +956,11 @@
       {
           /* Adapted from Alec Kloss' work for OS/2 */
           char *interpreter = NULL;
  +        char *invokename = NULL;
           char *arguments = NULL;
           char *ext = NULL;
  -        char *exename = NULL;
           char *s = NULL;
  -        char *quoted_filename;
  +        char *t = NULL;
           char *pCommand;
           char *pEnvBlock, *pNext;
   
  @@ -989,6 +989,35 @@
                   return (pid);
               }
   
  +            if (interpreter && *interpreter 
  +                    && (s = strstr(interpreter, "\"%1\""))) {
  +                s[1] = '\0';
  +                s += 3;
  +                invokename = ap_pstrdup(r->pool, r->filename);
  +            }
  +            else
  +            {
  +                char shortname[MAX_PATH];
  +                DWORD rv = GetShortPathName(r->filename, shortname, MAX_PATH);
  +                if (!rv || rv >= MAX_PATH) {
  +                    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
  +                                  "%s is not executable; cannot translate "
  +                                  "to a short path name.", r->filename);
  +                    return (pid);
  +                }
  +                invokename = ap_pstrdup(r->pool, shortname);
  +
  +                if (interpreter && *interpreter
  +                        && (s = strstr(interpreter, "%1"))) {
  +                    s[0] = '\0';
  +                    s += 2;
  +                }
  +            }
  +            for (t = invokename; *t; ++t) {
  +                if (*t == '/')
  +                    *t = '\\';
  +            }
  +
               /*
                * Look at the arguments...
                */
  @@ -1032,35 +1061,75 @@
               }
   
               /*
  -             * We have the interpreter (if there is one) and we have 
  -             * the arguments (if there are any).
  -             * Build the command string to pass to CreateProcess. 
  +             * The remaining code merges the interpreter, the backslashed
  +             * and potentially shortened invoke name, the various
  +             * interpreter segments and the arguments.
  +             *
  +             * Note that interpreter started out with %1 %* arguments,
  +             * so the *t character skips the %* arguments list, and the
  +             * *s already skipped the %1 argument (quoted or not.)
                */
  -            quoted_filename = ap_pstrcat(r->pool, "\"", r->filename, "\"", NULL);
  -            for (i = 0; quoted_filename[i]; ++i) {
  -                if (quoted_filename[i] == '/')
  -                    quoted_filename[i] = '\\';
  -            }
   
  -            if (interpreter && *interpreter) {
  -                pCommand = ap_pstrcat(r->pool, interpreter, " ", 
  -                                      quoted_filename, " ", arguments, NULL);
  +            if (s && (t = strstr(s, "%*"))) {
  +                /* interpreter formatted: prog [opts] %1 [opts] %* [opts] 
  +                 */
  +                t[0] = '\0';
  +                t += 2;
  +                pCommand = ap_pstrcat(r->pool, interpreter, invokename,
  +                                               s, arguments, t, NULL);
  +            }
  +            else if (s) {
  +                /* interpreter formatted: prog [opts] %1 [opts] 
  +                 */
  +                pCommand = ap_pstrcat(r->pool, interpreter, invokename,
  +                                               s, " ", arguments, NULL);
               }
  +            else if (interpreter) {
  +                /* interpreter formatted: prog [opts]
  +                 */
  +                pCommand = ap_pstrcat(r->pool, interpreter, " ", invokename,
  +                                               " ", arguments, NULL);
  +            }
               else {
  -                pCommand = ap_pstrcat(r->pool, quoted_filename, " ", arguments, NULL);
  +                /* no interpreter required
  +                 */
  +                pCommand = ap_pstrcat(r->pool, invokename, 
  +                                               " ", arguments, NULL);
               }
   
  -        } else {
  -            char *shellcmd = getenv("COMSPEC");
  -            if (!shellcmd)
  -                shellcmd = SHELL_PATH;
  -            
  -            quoted_filename = ap_pstrcat(r->pool, "\"", argv0, "\"", NULL);
  -            for (i = 0; quoted_filename[i]; ++i)
  -                if (quoted_filename[i] == '/')
  -                    quoted_filename[i] = '\\';
  -
  -            pCommand = ap_pstrcat(r->pool, shellcmd, " /C ", argv0, NULL);
  +        }
  +        else /* shellcmd */
  +        {
  +            char *p, *comspec = getenv("COMSPEC");
  +            if (!comspec)
  +                comspec = SHELL_PATH;
  +            p = strchr(comspec, '\0');
  +            if ((p - comspec >= 11) && !strcasecmp(p - 11, "command.com")) 
  +            {
  +                /* Command.com doesn't like long paths
  +                 */
  +                char shortname[MAX_PATH];
  +                DWORD rv = GetShortPathName(r->filename, shortname, MAX_PATH);
  +                if (!rv || rv >= MAX_PATH) {
  +                    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
  +                                  "%s is not executable; cannot translate "
  +                                  "to a short path name.", r->filename);
  +                    return (pid);
  +                }
  +                pCommand = ap_pstrcat(r->pool, "\"", comspec, "\" /C ", 
  +                                      shortname, NULL);
  +            }
  +            else
  +            {
  +                /* Assume any other shell likes long paths
  +                 */
  +                pCommand = ap_pstrcat(r->pool, "\"", comspec, "\" /C \"", 
  +                                      r->filename, "\"", NULL);
  +                for (p = pCommand; *p; ++p) {
  +                    if (*p == '/')
  +                        *p = '\\';
  +                }
  +            }
           }
   
           /*
  @@ -1068,7 +1137,7 @@
            * and make sure it does not show on screen.
            */
           si.cb = sizeof(si);
  -        si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  +        si.dwFlags     = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
           si.wShowWindow = SW_HIDE;
           si.hStdInput   = pinfo->hPipeInputRead;
           si.hStdOutput  = pinfo->hPipeOutputWrite;
  
  
  
  1.292     +41 -13    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.291
  retrieving revision 1.292
  diff -u -r1.291 -r1.292
  --- http_core.c	2000/11/15 01:44:13	1.291
  +++ http_core.c	2000/11/16 22:28:39	1.292
  @@ -844,25 +844,36 @@
           return NULL;
   
       /*
  +     * The command entry may contain embedded %envvar% entries,
  +     * e.g. %winsysdir%\somecommand.exe %1
  +     *
  +     * Resolve them here
  +     */
  +    size = ExpandEnvironmentStrings(buffer, NULL, 0);
  +    if (size) {
  +        s = ap_palloc(p, size);
  +        if (ExpandEnvironmentStrings(buffer, s, size))
  +            buffer = s;
  +    }
  +
  +    /*
        * The canonical way shell command entries are entered in the Win32 
        * registry is as follows:
  -     *   shell [options] "%1"
  +     *   shell [options] "%1" [options] [%*]
        * where
        *   shell - full path name to interpreter or shell to run.
        *           E.g., c:\usr\local\ntreskit\perl\bin\perl.exe
        *   options - optional switches
  -     *              E.g., \C
  +     *              E.g., /C or -w
        *   "%1" - Place holder for file to run the shell against. 
  -     *          Typically quoted.
  +     *          Quoted for if long path names are accepted.
  +     *          Not quoted if only short paths are acceptd
  +     *
  +     *   %* - additional arguments
        *
  -     * If we find a %1 or a quoted %1, lop it off. 
  +     * Effective in v. 1.3.15, the responsibility is the consumer's
  +     * to make these substitutions.
        */
  -    if (buffer && *buffer) {
  -        if ((s = strstr(buffer, "\"%1")))
  -            *s = '\0';
  -        else if ((s = strstr(buffer, "%1"))) 
  -            *s = '\0';
  -    }
   
       return buffer;
   }
  @@ -896,11 +907,28 @@
       }
       ext = strrchr(exename, '.');
   
  -    if (ext && (!strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) {
  -        char *shellcmd = getenv("COMSPEC");
  +    if (ext && (!strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd")) &&
  +        d->script_interpreter_source != INTERPRETER_SOURCE_REGISTRY) 
  +    {
  +        /* The registry does these for us unless INTERPRETER_SOURCE_REGISTRY
  +         * was not enabled.
  +         */
  +        char *p, *shellcmd = getenv("COMSPEC");
           if (!shellcmd)
               shellcmd = SHELL_PATH;
  -        *interpreter = ap_pstrcat(r->pool, "\"", shellcmd, "\" /C", NULL);
  +        p = strchr(shellcmd, '\0');
  +        if ((p - shellcmd >= 11) && !strcasecmp(p - 11, "command.com")) 
  +        {
  +            /* Command.com doesn't like long paths, doesn't do .cmd
  +             */
  +            if (!strcasecmp(ext,".cmd"))
  +                return eFileTypeUNKNOWN;
  +            *interpreter = ap_pstrcat(r->pool, "\"", shellcmd, "\" /C %1", NULL);
  +        }
  +        else
  +            /* Assume any other likes long paths, and knows .cmd
  +             */
  +            *interpreter = ap_pstrcat(r->pool, "\"", shellcmd, "\" /C \"%1\"", NULL);
           return eFileTypeSCRIPT;
       }
   
  
  
  

Mime
View raw message