2
* Copyright 2004 Apache Software Foundation
4
* Licensed under the Apache License, Version 2.0 (the "License"); you
5
* may not use this file except in compliance with the License. You
6
* may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
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
13
* implied. See the License for the specific language governing
14
* permissions and limitations under the License.
16
* Originally developed by Gregory Trubetskoy.
21
* $Id: util.c,v 1.19 2004/02/16 19:47:27 grisha Exp $
23
* See accompanying documentation and source code comments
28
#include "mod_python.h"
31
** tuple_from_array_header
33
* Given an array header return a tuple. The array elements
34
* assumed to be strings.
37
PyObject * tuple_from_array_header(const apr_array_header_t *ah)
51
t = PyTuple_New(ah->nelts);
53
s = (char **) ah->elts;
54
for (i = 0; i < ah->nelts; i++) {
55
PyTuple_SetItem(t, i, PyString_FromString(s[i]));
62
** tuple_from_method_list
64
* Given an apr_method_list_t return a tuple.
67
PyObject * tuple_from_method_list(const ap_method_list_t *l)
74
if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
79
t = PyTuple_New(l->method_list->nelts);
81
methods = (char **)l->method_list->elts;
82
for (i = 0; i < l->method_list->nelts; ++i) {
83
PyTuple_SetItem(t, i, PyString_FromString(methods[i]));
92
* makes a tuple similar to return of os.stat() from apr_finfo_t
96
PyObject *tuple_from_finfo(apr_finfo_t *f)
100
if (f->filetype == APR_NOFILE) {
107
if (f->valid & APR_FINFO_PROT) {
108
PyTuple_SET_ITEM(t, 0, PyInt_FromLong(f->protection));
111
PyTuple_SET_ITEM(t, 0, Py_None);
113
if (f->valid & APR_FINFO_INODE) {
114
PyTuple_SET_ITEM(t, 1, PyInt_FromLong(f->inode));
117
PyTuple_SET_ITEM(t, 1, Py_None);
119
if (f->valid & APR_FINFO_DEV) {
120
PyTuple_SET_ITEM(t, 2, PyInt_FromLong(f->device));
123
PyTuple_SET_ITEM(t, 2, Py_None);
125
if (f->valid & APR_FINFO_NLINK) {
126
PyTuple_SET_ITEM(t, 3, PyInt_FromLong(f->nlink));
129
PyTuple_SET_ITEM(t, 3, Py_None);
131
if (f->valid & APR_FINFO_USER) {
132
PyTuple_SET_ITEM(t, 4, PyInt_FromLong(f->user));
135
PyTuple_SET_ITEM(t, 4, Py_None);
137
if (f->valid & APR_FINFO_GROUP) {
138
PyTuple_SET_ITEM(t, 5, PyInt_FromLong(f->group));
141
PyTuple_SET_ITEM(t, 5, Py_None);
143
if (f->valid & APR_FINFO_SIZE) {
144
PyTuple_SET_ITEM(t, 6, PyInt_FromLong(f->size));
147
PyTuple_SET_ITEM(t, 6, Py_None);
149
if (f->valid & APR_FINFO_ATIME) {
150
PyTuple_SET_ITEM(t, 7, PyInt_FromLong(f->atime*0.000001));
153
PyTuple_SET_ITEM(t, 7, Py_None);
155
if (f->valid & APR_FINFO_MTIME) {
156
PyTuple_SET_ITEM(t, 8, PyInt_FromLong(f->mtime*0.000001));
159
PyTuple_SET_ITEM(t, 8, Py_None);
161
if (f->valid & APR_FINFO_CTIME) {
162
PyTuple_SET_ITEM(t, 9, PyInt_FromLong(f->ctime*0.000001));
165
PyTuple_SET_ITEM(t, 9, Py_None);
168
PyTuple_SET_ITEM(t, 10, PyString_FromString(f->fname));
172
PyTuple_SET_ITEM(t, 10, Py_None);
174
if (f->valid & APR_FINFO_NAME) {
175
PyTuple_SET_ITEM(t, 11, PyString_FromString(f->name));
178
PyTuple_SET_ITEM(t, 11, Py_None);
180
/* it'd be nice to also return the file dscriptor,
181
f->filehand->filedes, but it's platform dependent,
182
so may be later... */
188
** tuple_from_apr_uri
190
* makes a tuple from uri_components
194
PyObject *tuple_from_apr_uri(apr_uri_t *u)
201
PyTuple_SET_ITEM(t, 0, PyString_FromString(u->scheme));
205
PyTuple_SET_ITEM(t, 0, Py_None);
208
PyTuple_SET_ITEM(t, 1, PyString_FromString(u->hostinfo));
212
PyTuple_SET_ITEM(t, 1, Py_None);
215
PyTuple_SET_ITEM(t, 2, PyString_FromString(u->user));
219
PyTuple_SET_ITEM(t, 2, Py_None);
222
PyTuple_SET_ITEM(t, 3, PyString_FromString(u->password));
226
PyTuple_SET_ITEM(t, 3, Py_None);
229
PyTuple_SET_ITEM(t, 4, PyString_FromString(u->hostname));
233
PyTuple_SET_ITEM(t, 4, Py_None);
236
PyTuple_SET_ITEM(t, 5, PyInt_FromLong(u->port));
240
PyTuple_SET_ITEM(t, 5, Py_None);
243
PyTuple_SET_ITEM(t, 6, PyString_FromString(u->path));
247
PyTuple_SET_ITEM(t, 6, Py_None);
250
PyTuple_SET_ITEM(t, 7, PyString_FromString(u->query));
254
PyTuple_SET_ITEM(t, 7, Py_None);
257
PyTuple_SET_ITEM(t, 8, PyString_FromString(u->fragment));
261
PyTuple_SET_ITEM(t, 8, Py_None);
263
/* XXX hostent, is_initialized, dns_* */
272
* This helper function is used with apr_pool_cleanup_register to destroy
273
* python objects when a certain pool is destroyed.
276
apr_status_t python_decref(void *object)
278
Py_XDECREF((PyObject *) object);
285
* Find an Apache module by name, used by get_addhandler_extensions
288
static module *find_module(char *name)
291
for (n = 0; ap_loaded_modules[n]; ++n) {
293
if (strcmp(name, ap_loaded_modules[n]->name) == 0)
294
return ap_loaded_modules[n];
301
** get_addhandler_extensions
303
* Get extensions specified for AddHandler, if any. To do this we
304
* retrieve mod_mime's config. This is used by the publisher to strip
305
* file extentions from modules in the most meaningful way.
307
* XXX This function is a hack and will stop working if mod_mime people
308
* decide to change their code. A better way to implement this would
309
* be via the config tree, but it doesn't seem to be quite there just
310
* yet, because it doesn't have .htaccess directives.
313
char * get_addhandler_extensions(request_rec *req)
316
/* these typedefs are copied from mod_mime.c */
319
apr_hash_t *extension_mappings;
320
apr_array_header_t *remove_mappings;
321
char *default_language;
325
typedef struct extension_info {
326
char *forced_type; /* Additional AddTyped stuff */
327
char *encoding_type; /* Added with AddEncoding... */
328
char *language_type; /* Added with AddLanguage... */
329
char *handler; /* Added with AddHandler... */
330
char *charset_type; /* Added with AddCharset... */
331
char *input_filters; /* Added with AddInputFilter... */
332
char *output_filters; /* Added with AddOutputFilter... */
335
mime_dir_config *mconf;
337
apr_hash_index_t *hi;
343
module *mod_mime = find_module("mod_mime.c");
344
mconf = (mime_dir_config *) ap_get_module_config(req->per_dir_config, mod_mime);
346
if (mconf->extension_mappings) {
348
for (hi = apr_hash_first(req->pool, mconf->extension_mappings); hi; hi = apr_hash_next(hi)) {
349
apr_hash_this(hi, (const void **)&key, NULL, &val);
350
ei = (extension_info *)val;
352
if (strcmp("mod_python", ei->handler) == 0 ||
353
strcmp("python-program", ei->handler) == 0)
354
result = apr_pstrcat(req->pool, (char *)key, " ", result, NULL);
364
* Find a memberdef in a PyMemberDef array
367
PyMemberDef *find_memberdef(const PyMemberDef *mlist, const char *name)
369
const PyMemberDef *md;
371
for (md = mlist; md->name != NULL; md++)
372
if (strcmp(md->name, name) == 0)
373
return (PyMemberDef *)md;
375
/* this should never happen or the mlist is screwed up */
382
* walks ap_directive_t tree returning a list of
386
PyObject *cfgtree_walk(ap_directive_t *dir)
389
PyObject *list = PyList_New(0);
391
return PyErr_NoMemory();
395
PyObject *t = Py_BuildValue("(s, s)", dir->directive, dir->args);
397
return PyErr_NoMemory();
399
PyList_Append(list, t);
401
if (dir->first_child) {
403
PyObject *child = cfgtree_walk(dir->first_child);
405
return PyErr_NoMemory();
407
PyList_Append(list, child);