upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / modules / arch / netware / mod_netware.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr_strings.h"
18 #include "apr_portable.h"
19 #include "apr_buckets.h"
20 #include "ap_config.h"
21 #include "httpd.h"
22 #include "http_config.h"
23 #include "http_core.h"
24 #include "http_protocol.h"
25 #include "http_request.h"
26 #include "http_log.h"
27 #include "util_script.h"
28 #include "mod_core.h"
29 #include "apr_optional.h"
30 #include "apr_lib.h"
31 #include "mod_cgi.h"
32
33 #ifdef NETWARE
34
35
36 module AP_MODULE_DECLARE_DATA netware_module;
37
38 typedef struct {
39     apr_table_t *file_type_handlers;    /* CGI map from file types to CGI modules */
40     apr_table_t *file_handler_mode;     /* CGI module mode (spawn in same address space or not) */
41     apr_table_t *extra_env_vars;        /* Environment variables to be added to the CGI environment */
42 } netware_dir_config;
43
44
45 static void *create_netware_dir_config(apr_pool_t *p, char *dir)
46 {
47     netware_dir_config *new = (netware_dir_config*) apr_palloc(p, sizeof(netware_dir_config));
48
49     new->file_type_handlers = apr_table_make(p, 10);
50     new->file_handler_mode = apr_table_make(p, 10);
51     new->extra_env_vars = apr_table_make(p, 10);
52
53     apr_table_set(new->file_type_handlers, "NLM", "OS");
54
55     return new;
56 }
57
58 static void *merge_netware_dir_configs(apr_pool_t *p, void *basev, void *addv)
59 {
60     netware_dir_config *base = (netware_dir_config *) basev;
61     netware_dir_config *add = (netware_dir_config *) addv;
62     netware_dir_config *new = (netware_dir_config *) apr_palloc(p, sizeof(netware_dir_config));
63
64     new->file_type_handlers = apr_table_overlay(p, add->file_type_handlers, base->file_type_handlers);
65     new->file_handler_mode = apr_table_overlay(p, add->file_handler_mode, base->file_handler_mode);
66     new->extra_env_vars = apr_table_overlay(p, add->extra_env_vars, base->extra_env_vars);
67
68     return new;
69 }
70
71 static const char *set_extension_map(cmd_parms *cmd, netware_dir_config *m,
72                                      char *CGIhdlr, char *ext, char *detach)
73 {
74     int i, len;
75
76     if (*ext == '.')
77         ++ext;
78   
79     if (CGIhdlr != NULL) {
80         len = strlen(CGIhdlr);    
81         for (i=0; i<len; i++) {
82             if (CGIhdlr[i] == '\\') {
83                 CGIhdlr[i] = '/';
84             }
85         }
86     }
87
88     apr_table_set(m->file_type_handlers, ext, CGIhdlr);
89     if (detach) {
90         apr_table_set(m->file_handler_mode, ext, "y");
91     }
92
93     return NULL;
94 }
95
96 static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
97                                          request_rec *r, apr_pool_t *p, 
98                                          cgi_exec_info_t *e_info)
99 {
100     char *ext = NULL;
101     char *cmd_only, *ptr;
102     const char *new_cmd;
103     netware_dir_config *d;
104     apr_file_t *fh;
105     const char *args = "";
106
107     d = (netware_dir_config *)ap_get_module_config(r->per_dir_config, 
108                                                &netware_module);
109
110     if (e_info->process_cgi) {
111         /* Handle the complete file name, we DON'T want to follow suexec, since
112          * an unrooted command is as predictable as shooting craps in Win32.
113          *
114          * Notice that unlike most mime extension parsing, we have to use the
115          * win32 parsing here, therefore the final extension is the only one
116          * we will consider
117          */
118         *cmd = r->filename;
119         if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) {
120             args = r->args;
121         }
122     }
123
124     cmd_only = apr_pstrdup(p, *cmd);
125     e_info->cmd_type = APR_PROGRAM;
126
127     /* truncate any arguments from the cmd */
128     for (ptr = cmd_only; *ptr && (*ptr != ' '); ptr++);
129     *ptr = '\0';
130
131     /* Figure out what the extension is so that we can matche it. */
132     ext = strrchr(apr_filepath_name_get(cmd_only), '.');
133
134     /* If there isn't an extension then give it an empty string */
135     if (!ext) {
136         ext = "";
137     }
138     
139     /* eliminate the '.' if there is one */
140     if (*ext == '.')
141         ++ext;
142
143     /* check if we have a registered command for the extension*/
144     new_cmd = apr_table_get(d->file_type_handlers, ext);
145     e_info->detached = AP_PROC_DETACHED;
146     if (new_cmd == NULL) {
147         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
148                   "Could not find a command associated with the %s extension", ext);
149         return APR_EBADF;
150     }
151     if (stricmp(new_cmd, "OS")) {
152         /* If we have a registered command then add the file that was passed in as a
153           parameter to the registered command. */
154         *cmd = apr_pstrcat (p, new_cmd, " ", cmd_only, NULL);
155
156         /* Run in its own address space if specified */
157         if(apr_table_get(d->file_handler_mode, ext))
158             e_info->detached |= AP_PROC_NEWADDRSPACE;
159     }
160
161     /* Tokenize the full command string into its arguments */
162     apr_tokenize_to_argv(*cmd, (char***)argv, p);
163
164     /* The first argument should be the executible */
165     *cmd = ap_server_root_relative(p, *argv[0]);
166
167     return APR_SUCCESS;
168 }
169
170 static void register_hooks(apr_pool_t *p)
171 {
172     APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
173 }
174
175 static const command_rec netware_cmds[] = {
176 AP_INIT_TAKE23("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO, 
177               "Full path to the CGI NLM module followed by a file extension. If the "
178               "first parameter is set to \"OS\" then the following file extension is "
179               "treated as NLM. The optional parameter \"detach\" can be specified if "
180               "the NLM should be launched in its own address space."),
181 { NULL }
182 };
183
184 module AP_MODULE_DECLARE_DATA netware_module = {
185    STANDARD20_MODULE_STUFF,
186    create_netware_dir_config,     /* create per-dir config */
187    merge_netware_dir_configs,     /* merge per-dir config */
188    NULL,                        /* server config */
189    NULL,                        /* merge server config */
190    netware_cmds,                  /* command apr_table_t */
191    register_hooks               /* register hooks */
192 };
193
194 #endif