summaryrefslogtreecommitdiffstats
path: root/modules/arch/netware/mod_netware.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/arch/netware/mod_netware.c')
-rw-r--r--modules/arch/netware/mod_netware.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/modules/arch/netware/mod_netware.c b/modules/arch/netware/mod_netware.c
new file mode 100644
index 0000000..f873827
--- /dev/null
+++ b/modules/arch/netware/mod_netware.c
@@ -0,0 +1,206 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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"
+#include "mod_cgi.h"
+#include "mpm_common.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 *file_handler_mode; /* CGI module mode (spawn in same address space or not) */
+ 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->file_handler_mode = apr_table_make(p, 10);
+ new->extra_env_vars = apr_table_make(p, 10);
+
+ apr_table_setn(new->file_type_handlers, "NLM", "OS");
+
+ 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->file_handler_mode = apr_table_overlay(p, add->file_handler_mode, base->file_handler_mode);
+ 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, char *detach)
+{
+ int i, len;
+
+ if (*ext == '.')
+ ++ext;
+
+ if (CGIhdlr != NULL) {
+ len = strlen(CGIhdlr);
+ for (i=0; i<len; i++) {
+ if (CGIhdlr[i] == '\\') {
+ CGIhdlr[i] = '/';
+ }
+ }
+ }
+
+ apr_table_set(m->file_type_handlers, ext, CGIhdlr);
+ if (detach) {
+ apr_table_set(m->file_handler_mode, ext, "y");
+ }
+
+ return NULL;
+}
+
+static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
+ request_rec *r, apr_pool_t *p,
+ cgi_exec_info_t *e_info)
+{
+ char *ext = NULL;
+ char *cmd_only, *ptr;
+ const char *new_cmd;
+ netware_dir_config *d;
+ const char *args = "";
+
+ d = (netware_dir_config *)ap_get_module_config(r->per_dir_config,
+ &netware_module);
+
+ if (e_info->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;
+ }
+ }
+
+ cmd_only = apr_pstrdup(p, *cmd);
+ e_info->cmd_type = APR_PROGRAM;
+
+ /* truncate any arguments from the cmd */
+ for (ptr = cmd_only; *ptr && (*ptr != ' '); ptr++);
+ *ptr = '\0';
+
+ /* Figure out what the extension is so that we can match it. */
+ ext = strrchr(apr_filepath_name_get(cmd_only), '.');
+
+ /* If there isn't an extension then give it an empty string */
+ if (!ext) {
+ ext = "";
+ }
+
+ /* eliminate the '.' if there is one */
+ if (*ext == '.') {
+ ++ext;
+ }
+
+ /* check if we have a registered command for the extension*/
+ new_cmd = apr_table_get(d->file_type_handlers, ext);
+ e_info->detached = 1;
+ if (new_cmd == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02135)
+ "Could not find a command associated with the %s extension", ext);
+ return APR_EBADF;
+ }
+ if (stricmp(new_cmd, "OS")) {
+ /* If we have a registered command then add the file that was passed in as a
+ parameter to the registered command. */
+ *cmd = apr_pstrcat (p, new_cmd, " ", cmd_only, NULL);
+
+ /* Run in its own address space if specified */
+ if (apr_table_get(d->file_handler_mode, ext)) {
+ e_info->addrspace = 1;
+ }
+ }
+
+ /* Tokenize the full command string into its arguments */
+ apr_tokenize_to_argv(*cmd, (char***)argv, p);
+
+ /* The first argument should be the executible */
+ *cmd = ap_server_root_relative(p, *argv[0]);
+
+ return APR_SUCCESS;
+}
+
+static int
+netware_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ ap_sys_privileges_handlers(1);
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
+ ap_hook_pre_config(netware_pre_config,
+ NULL, NULL, APR_HOOK_FIRST);
+}
+
+static const command_rec netware_cmds[] = {
+AP_INIT_TAKE23("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO,
+ "Full path to the CGI NLM module followed by a file extension. If the "
+ "first parameter is set to \"OS\" then the following file extension is "
+ "treated as NLM. The optional parameter \"detach\" can be specified if "
+ "the NLM should be launched in its own address space."),
+{ NULL }
+};
+
+AP_DECLARE_MODULE(netware) = {
+ 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