]> granicus.if.org Git - apache/commitdiff
Added mod_cgi and mod_netware as built in module in the NetWare build
authorBradley Nicholes <bnicholes@apache.org>
Fri, 31 May 2002 17:16:09 +0000 (17:16 +0000)
committerBradley Nicholes <bnicholes@apache.org>
Fri, 31 May 2002 17:16:09 +0000 (17:16 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95445 13f79535-47bb-0310-9956-ffa450edef68

modules/arch/netware/mod_netware.c [new file with mode: 0644]
os/netware/modules.c

diff --git a/modules/arch/netware/mod_netware.c b/modules/arch/netware/mod_netware.c
new file mode 100644 (file)
index 0000000..cf3aa02
--- /dev/null
@@ -0,0 +1,412 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+
+#include "apr_strings.h"
+#include "apr_portable.h"
+#include "apr_buckets.h"
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "util_script.h"
+#include "mod_core.h"
+#include "apr_optional.h"
+#include "apr_lib.h"
+
+#ifdef NETWARE
+
+
+module AP_MODULE_DECLARE_DATA netware_module;
+
+typedef struct {
+    apr_table_t *file_type_handlers;    /* CGI map from file types to CGI modules */
+    apr_table_t *extra_env_vars;        /* Environment variables to be added to the CGI environment */
+} netware_dir_config;
+
+
+static void *create_netware_dir_config(apr_pool_t *p, char *dir)
+{
+    netware_dir_config *new = (netware_dir_config*) apr_palloc(p, sizeof(netware_dir_config));
+
+    new->file_type_handlers = apr_table_make(p, 10);
+    new->extra_env_vars = apr_table_make(p, 10);
+
+    return new;
+}
+
+static void *merge_netware_dir_configs(apr_pool_t *p, void *basev, void *addv)
+{
+    netware_dir_config *base = (netware_dir_config *) basev;
+    netware_dir_config *add = (netware_dir_config *) addv;
+    netware_dir_config *new = (netware_dir_config *) apr_palloc(p, sizeof(netware_dir_config));
+
+    new->file_type_handlers = apr_table_overlay(p, add->file_type_handlers, base->file_type_handlers);
+    new->extra_env_vars = apr_table_overlay(p, add->extra_env_vars, base->extra_env_vars);
+
+    return new;
+}
+
+static const char *set_extension_map(cmd_parms *cmd, netware_dir_config *m, char *CGIhdlr, char *ext)
+{
+    if (*ext == '.')
+        ++ext;
+    apr_table_set(m->file_type_handlers, ext, CGIhdlr);
+    return NULL;
+}
+
+
+static apr_array_header_t *split_argv(apr_pool_t *p, const char *interp,
+                                      const char *cgiprg, const char *cgiargs)
+{
+    apr_array_header_t *args = apr_array_make(p, 8, sizeof(char*));
+    char *d = apr_palloc(p, strlen(interp)+1);
+    const char *ch = interp; 
+    const char **arg;
+    int prgtaken = 0;
+    int argtaken = 0;
+    int inquo;
+    int sl;
+
+    while (*ch) {
+        /* Skip on through Deep Space */
+        if (isspace(*ch)) {
+            ++ch; continue;
+        }
+        /* One Arg */
+        if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '*')) {
+            const char *cgiarg = cgiargs;
+            argtaken = 1;
+            for (;;) {
+                char *w = ap_getword_nulls(p, &cgiarg, '+');
+                if (!*w) {
+                    break;
+                }
+                ap_unescape_url(w);
+                arg = (const char**)apr_array_push(args);
+                *arg = ap_escape_shell_cmd(p, w);
+            }
+            ch += 2;
+            continue;
+        }
+        if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '1')) {
+            /* Todo: Make short name!!! */
+            prgtaken = 1;
+            arg = (const char**)apr_array_push(args);
+            if (*ch == '%') {
+                char *repl = apr_pstrdup(p, cgiprg);
+                *arg = repl;
+                while ((repl = strchr(repl, '/'))) {
+                    *repl++ = '\\';
+                }
+            }
+            else {
+                *arg = cgiprg;
+            }
+            ch += 2;
+            continue;
+        }
+        if ((*ch == '\"') && ((*(ch + 1) == '$') 
+                              || (*(ch + 1) == '%')) && (*(ch + 2) == '1') 
+            && (*(ch + 3) == '\"')) {
+            prgtaken = 1;
+            arg = (const char**)apr_array_push(args);
+            if (*(ch + 1) == '%') {
+                char *repl = apr_pstrdup(p, cgiprg);
+                *arg = repl;
+                while ((repl = strchr(repl, '/'))) {
+                    *repl++ = '\\';
+                }
+            }
+            else {
+                *arg = cgiprg;
+            }
+            ch += 4;
+            continue;
+        }
+        arg = (const char**)apr_array_push(args);
+        *arg = d;
+        inquo = 0;
+        while (*ch) {
+            if (isspace(*ch) && !inquo) {
+                ++ch; break;
+            }
+            /* Get 'em backslashes */
+            for (sl = 0; *ch == '\\'; ++sl) {
+                *d++ = *ch++;
+            }
+            if (sl & 1) {
+                /* last unmatched '\' + '"' sequence is a '"' */
+                if (*ch == '\"') {
+                    *(d - 1) = *ch++;
+                }
+                continue;
+            }
+            if (*ch == '\"') {
+                /* '""' sequence within quotes is a '"' */
+                if (*++ch == '\"' && inquo) {
+                    *d++ = *ch++; continue;
+                }
+                /* Flip quote state */
+                inquo = !inquo;
+                if (isspace(*ch) && !inquo) {
+                    ++ch; break;
+                }
+                /* All other '"'s are Munched */
+                continue;
+            }
+            /* Anything else is, well, something else */
+            *d++ = *ch++;
+        }
+        /* Term that arg, already pushed on args */
+        *d++ = '\0';
+    }
+
+    if (!prgtaken) {
+        arg = (const char**)apr_array_push(args);
+        *arg = cgiprg;
+    }
+
+    if (!argtaken) {
+        const char *cgiarg = cgiargs;
+        for (;;) {
+            char *w = ap_getword_nulls(p, &cgiarg, '+');
+            if (!*w) {
+                break;
+            }
+            ap_unescape_url(w);
+            arg = (const char**)apr_array_push(args);
+            *arg = ap_escape_shell_cmd(p, w);
+        }
+    }
+
+    arg = (const char**)apr_array_push(args);
+    *arg = NULL;
+
+    return args;
+}
+
+
+static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
+                                         request_rec *r, apr_pool_t *p, 
+                                         int process_cgi, apr_cmdtype_e *type)
+{
+    const char *ext = NULL;
+    const char *interpreter = NULL;
+    netware_dir_config *d;
+    apr_file_t *fh;
+    const char *args = "";
+
+    d = (netware_dir_config *)ap_get_module_config(r->per_dir_config, 
+                                               &netware_module);
+
+    if (process_cgi) {
+        /* Handle the complete file name, we DON'T want to follow suexec, since
+         * an unrooted command is as predictable as shooting craps in Win32.
+         *
+         * Notice that unlike most mime extension parsing, we have to use the
+         * win32 parsing here, therefore the final extension is the only one
+         * we will consider
+         */
+        *cmd = r->filename;
+        if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) {
+            args = r->args;
+        }
+    }
+    ext = strrchr(apr_filename_of_pathname(*cmd), '.');
+    
+    if (*ext == '.')
+        ++ext;
+
+    /* If it is an NLM then just execute it. */
+    if (stricmp(ext, "nlm")) {
+        *cmd = apr_table_get(d->file_type_handlers, ext);
+        if (*cmd == NULL) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "Could not find a command associated with the %s extension", ext);
+            return APR_EBADF;
+        }
+
+    }
+
+    apr_tokenize_to_argv(r->filename, (char***)argv, p);
+    *type = APR_PROGRAM;
+
+//    /* 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 so.
+//     * Let apr_proc_create do all of the .bat/.cmd dirty work.
+//     */
+//    if (ext && (!strcasecmp(ext,".exe") || !strcasecmp(ext,".com")
+//                || !strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) {
+//        interpreter = "";
+//    }
+//    if (!interpreter && ext 
+//          && (d->script_interpreter_source 
+//                     == INTERPRETER_SOURCE_REGISTRY
+//           || d->script_interpreter_source 
+//                     == INTERPRETER_SOURCE_REGISTRY_STRICT)) {
+//         /* Check the registry */
+//        int strict = (d->script_interpreter_source 
+//                      == INTERPRETER_SOURCE_REGISTRY_STRICT);
+//        interpreter = get_interpreter_from_win32_registry(r->pool, ext,
+//                                                          strict);
+//        if (interpreter && *type != APR_SHELLCMD) {
+//            *type = APR_PROGRAM_PATH;
+//        }
+//        else {
+//            ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+//                 strict ? "No ExecCGI verb found for files of type '%s'."
+//                        : "No ExecCGI or Open verb found for files of type '%s'.", 
+//                 ext);
+//        }
+//    }
+//    if (!interpreter) {
+//        apr_status_t rv;
+//        char buffer[1024];
+//        apr_size_t bytes = sizeof(buffer);
+//        int i;
+//
+//        /* Need to peek into the file figure out what it really is... 
+//         * ### aught to go back and build a cache for this one of these days.
+//         */
+//        if (((rv = apr_file_open(&fh, *cmd, APR_READ | APR_BUFFERED,
+//                                 APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) 
+//            || ((rv = apr_file_read(fh, buffer, &bytes)) != APR_SUCCESS)) {
+//            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+//                          "Failed to read cgi file %s for testing", *cmd);
+//            return rv;
+//        }
+//        apr_file_close(fh);
+//
+//        /* Script or executable, that is the question... */
+//        if ((buffer[0] == '#') && (buffer[1] == '!')) {
+//            /* Assuming file is a script since it starts with a shebang */
+//            for (i = 2; i < sizeof(buffer); i++) {
+//                if ((buffer[i] == '\r') || (buffer[i] == '\n')) {
+//                    buffer[i] = '\0';
+//                    break;
+//                }
+//            }
+//            if (i < sizeof(buffer)) {
+//                interpreter = buffer + 2;
+//                while (isspace(*interpreter)) {
+//                    ++interpreter;
+//                }
+//                if (*type != APR_SHELLCMD) {
+//                    *type = APR_PROGRAM_PATH;
+//                }
+//            }
+//        }
+//        else {
+//            /* Not a script, is it an executable? */
+//            IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer;    
+//            if ((bytes >= sizeof(IMAGE_DOS_HEADER))
+//                && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) {
+//                if (hdr->e_lfarlc < 0x40) {
+//                    /* Ought to invoke this 16 bit exe by a stub, (cmd /c?) */
+//                    interpreter = "";
+//                }
+//                else {
+//                    interpreter = "";
+//                }
+//            }
+//        }
+//    }
+//    if (!interpreter) {
+//        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+//                      "%s is not executable; ensure interpreted scripts have "
+//                      "\"#!\" first line", *cmd);
+//        return APR_EBADF;
+//    }
+//
+//    *argv = (const char **)(split_argv(p, interpreter, *cmd,
+//                                       args)->elts);
+//    *cmd = (*argv)[0];
+    return APR_SUCCESS;
+}
+
+APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_cgi_build_command,
+                        (const char **cmd, const char ***argv, 
+                         request_rec *r, apr_pool_t *p, 
+                         int replace_cmd, apr_cmdtype_e *type));
+
+static void register_hooks(apr_pool_t *p)
+{
+    APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
+}
+
+static const command_rec netware_cmds[] = {
+AP_INIT_ITERATE2("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO, 
+              "full path to the CGI NLM module followed by one or more file extensions"),
+{ NULL }
+};
+
+module AP_MODULE_DECLARE_DATA netware_module = {
+   STANDARD20_MODULE_STUFF,
+   create_netware_dir_config,     /* create per-dir config */
+   merge_netware_dir_configs,     /* merge per-dir config */
+   NULL,                        /* server config */
+   NULL,                        /* merge server config */
+   netware_cmds,                  /* command apr_table_t */
+   register_hooks               /* register hooks */
+};
+
+#endif
index d677ed38736f73a362147101d0421ec126b330f0..966f9c731efd7795eccb772ad06e8ca76d8adb7d 100644 (file)
@@ -18,7 +18,7 @@ extern module negotiation_module;
 extern module include_module;
 extern module autoindex_module;
 extern module dir_module;
-//extern module cgi_module;
+extern module cgi_module;
 extern module userdir_module;
 extern module alias_module;
 extern module env_module;
@@ -28,6 +28,7 @@ extern module imap_module;
 extern module actions_module;
 extern module setenvif_module;
 extern module nwssl_module;
+extern module netware_module;
 
 module *ap_prelinked_modules[] = {
   &core_module,
@@ -41,7 +42,7 @@ module *ap_prelinked_modules[] = {
   &include_module,
   &autoindex_module,
   &dir_module,
-//  &cgi_module,
+  &cgi_module,
   &userdir_module,
   &alias_module,
   &env_module,
@@ -51,6 +52,7 @@ module *ap_prelinked_modules[] = {
   &actions_module,
   &setenvif_module,
   &nwssl_module,
+  &netware_module,
   NULL
 };
 
@@ -66,7 +68,7 @@ module *ap_preloaded_modules[] = {
   &include_module,
   &autoindex_module,
   &dir_module,
-//  &cgi_module,
+  &cgi_module,
   &userdir_module,
   &alias_module,
   &env_module,
@@ -76,5 +78,6 @@ module *ap_preloaded_modules[] = {
   &actions_module,
   &setenvif_module,
   &nwssl_module,
+  &netware_module,
   NULL
 };