~ubuntu-branches/ubuntu/warty/libapache2-mod-python/warty

« back to all changes in this revision

Viewing changes to src/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Thom May
  • Date: 2004-09-06 20:27:57 UTC
  • Revision ID: james.westby@ubuntu.com-20040906202757-yzpyu1bcabgpjtiu
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2004 Apache Software Foundation 
 
3
 * 
 
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
 
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
 
13
 * implied.  See the License for the specific language governing
 
14
 * permissions and limitations under the License.
 
15
 *
 
16
 * Originally developed by Gregory Trubetskoy.
 
17
 *
 
18
 *
 
19
 * util.c 
 
20
 *
 
21
 * $Id: util.c,v 1.19 2004/02/16 19:47:27 grisha Exp $
 
22
 *
 
23
 * See accompanying documentation and source code comments 
 
24
 * for details.
 
25
 *
 
26
 */
 
27
 
 
28
#include "mod_python.h"
 
29
 
 
30
/**
 
31
 ** tuple_from_array_header
 
32
 **
 
33
 *   Given an array header return a tuple. The array elements
 
34
 *   assumed to be strings.
 
35
 */
 
36
 
 
37
PyObject * tuple_from_array_header(const apr_array_header_t *ah)
 
38
{
 
39
 
 
40
    PyObject *t;
 
41
    int i;
 
42
    char **s;
 
43
 
 
44
    if (ah == NULL)
 
45
    {
 
46
        Py_INCREF(Py_None);
 
47
        return Py_None;
 
48
    }
 
49
    else
 
50
    {
 
51
        t = PyTuple_New(ah->nelts);
 
52
 
 
53
        s = (char **) ah->elts;
 
54
        for (i = 0; i < ah->nelts; i++) {
 
55
            PyTuple_SetItem(t, i, PyString_FromString(s[i]));
 
56
        }
 
57
        return t;
 
58
    }
 
59
}
 
60
 
 
61
/**
 
62
 ** tuple_from_method_list
 
63
 **
 
64
 *   Given an apr_method_list_t return a tuple. 
 
65
 */
 
66
 
 
67
PyObject * tuple_from_method_list(const ap_method_list_t *l)
 
68
{
 
69
 
 
70
    PyObject *t;
 
71
    int i;
 
72
    char **methods;
 
73
 
 
74
    if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
 
75
        Py_INCREF(Py_None);
 
76
        return Py_None;
 
77
    }
 
78
    else {
 
79
        t = PyTuple_New(l->method_list->nelts);
 
80
        
 
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]));
 
84
        }
 
85
        return t;
 
86
    }
 
87
}
 
88
 
 
89
/**
 
90
 ** tuple_from_finfo
 
91
 **
 
92
 *  makes a tuple similar to return of os.stat() from apr_finfo_t
 
93
 *
 
94
 */
 
95
 
 
96
PyObject *tuple_from_finfo(apr_finfo_t *f)
 
97
{
 
98
    PyObject *t;
 
99
 
 
100
    if (f->filetype == APR_NOFILE) {
 
101
        Py_INCREF(Py_None);
 
102
        return Py_None;
 
103
    }
 
104
      
 
105
    t = PyTuple_New(12);
 
106
 
 
107
    if (f->valid & APR_FINFO_PROT) {
 
108
        PyTuple_SET_ITEM(t, 0, PyInt_FromLong(f->protection));
 
109
    } else {
 
110
        Py_INCREF(Py_None);
 
111
        PyTuple_SET_ITEM(t, 0, Py_None);
 
112
    }
 
113
    if (f->valid & APR_FINFO_INODE) {
 
114
        PyTuple_SET_ITEM(t, 1, PyInt_FromLong(f->inode));
 
115
    } else {
 
116
        Py_INCREF(Py_None);
 
117
        PyTuple_SET_ITEM(t, 1, Py_None);
 
118
    }
 
119
    if (f->valid & APR_FINFO_DEV) {
 
120
        PyTuple_SET_ITEM(t, 2, PyInt_FromLong(f->device));
 
121
    } else {
 
122
        Py_INCREF(Py_None);
 
123
        PyTuple_SET_ITEM(t, 2, Py_None);
 
124
    }
 
125
    if (f->valid & APR_FINFO_NLINK) {
 
126
        PyTuple_SET_ITEM(t, 3, PyInt_FromLong(f->nlink));
 
127
    } else {
 
128
        Py_INCREF(Py_None);
 
129
        PyTuple_SET_ITEM(t, 3, Py_None);
 
130
    }
 
131
    if (f->valid & APR_FINFO_USER) {
 
132
        PyTuple_SET_ITEM(t, 4, PyInt_FromLong(f->user));
 
133
    } else {
 
134
        Py_INCREF(Py_None);
 
135
        PyTuple_SET_ITEM(t, 4, Py_None);
 
136
    }
 
137
    if (f->valid & APR_FINFO_GROUP) {
 
138
        PyTuple_SET_ITEM(t, 5, PyInt_FromLong(f->group));
 
139
    } else {
 
140
        Py_INCREF(Py_None);
 
141
        PyTuple_SET_ITEM(t, 5, Py_None);
 
142
    }
 
143
    if (f->valid & APR_FINFO_SIZE) {
 
144
        PyTuple_SET_ITEM(t, 6, PyInt_FromLong(f->size));
 
145
    } else {
 
146
        Py_INCREF(Py_None);
 
147
        PyTuple_SET_ITEM(t, 6, Py_None);
 
148
    }
 
149
    if (f->valid & APR_FINFO_ATIME) {
 
150
        PyTuple_SET_ITEM(t, 7, PyInt_FromLong(f->atime*0.000001));
 
151
    } else {
 
152
        Py_INCREF(Py_None);
 
153
        PyTuple_SET_ITEM(t, 7, Py_None);
 
154
    }
 
155
    if (f->valid & APR_FINFO_MTIME) {
 
156
        PyTuple_SET_ITEM(t, 8, PyInt_FromLong(f->mtime*0.000001));
 
157
    } else {
 
158
        Py_INCREF(Py_None);
 
159
        PyTuple_SET_ITEM(t, 8, Py_None);
 
160
    }
 
161
    if (f->valid & APR_FINFO_CTIME) {
 
162
        PyTuple_SET_ITEM(t, 9, PyInt_FromLong(f->ctime*0.000001));
 
163
    } else {
 
164
        Py_INCREF(Py_None);
 
165
        PyTuple_SET_ITEM(t, 9, Py_None);
 
166
    }
 
167
    if (f->fname) {
 
168
        PyTuple_SET_ITEM(t, 10, PyString_FromString(f->fname));
 
169
    }
 
170
    else {
 
171
        Py_INCREF(Py_None);
 
172
        PyTuple_SET_ITEM(t, 10, Py_None);
 
173
    }
 
174
    if (f->valid & APR_FINFO_NAME) {
 
175
        PyTuple_SET_ITEM(t, 11, PyString_FromString(f->name));
 
176
    } else {
 
177
        Py_INCREF(Py_None);
 
178
        PyTuple_SET_ITEM(t, 11, Py_None);
 
179
    }
 
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... */
 
183
 
 
184
    return t;
 
185
}
 
186
 
 
187
/**
 
188
 ** tuple_from_apr_uri
 
189
 **
 
190
 *  makes a tuple from uri_components
 
191
 *
 
192
 */
 
193
 
 
194
PyObject *tuple_from_apr_uri(apr_uri_t *u)
 
195
{
 
196
    PyObject *t;
 
197
 
 
198
    t = PyTuple_New(9);
 
199
 
 
200
    if (u->scheme) {
 
201
        PyTuple_SET_ITEM(t, 0, PyString_FromString(u->scheme));
 
202
    }
 
203
    else {
 
204
        Py_INCREF(Py_None);
 
205
        PyTuple_SET_ITEM(t, 0, Py_None);
 
206
    }
 
207
    if (u->hostinfo) {
 
208
        PyTuple_SET_ITEM(t, 1, PyString_FromString(u->hostinfo));
 
209
    }
 
210
    else {
 
211
        Py_INCREF(Py_None);
 
212
        PyTuple_SET_ITEM(t, 1, Py_None);
 
213
    }
 
214
    if (u->user) {
 
215
        PyTuple_SET_ITEM(t, 2, PyString_FromString(u->user));
 
216
    }
 
217
    else {
 
218
        Py_INCREF(Py_None);
 
219
        PyTuple_SET_ITEM(t, 2, Py_None);
 
220
    }
 
221
    if (u->password) {
 
222
        PyTuple_SET_ITEM(t, 3, PyString_FromString(u->password));
 
223
    }
 
224
    else {
 
225
        Py_INCREF(Py_None);
 
226
        PyTuple_SET_ITEM(t, 3, Py_None);
 
227
    }
 
228
    if (u->hostname) {
 
229
        PyTuple_SET_ITEM(t, 4, PyString_FromString(u->hostname));
 
230
    }
 
231
    else {
 
232
        Py_INCREF(Py_None);
 
233
        PyTuple_SET_ITEM(t, 4, Py_None);
 
234
    }
 
235
    if (u->port_str) {
 
236
        PyTuple_SET_ITEM(t, 5, PyInt_FromLong(u->port));
 
237
    }
 
238
    else {
 
239
        Py_INCREF(Py_None);
 
240
        PyTuple_SET_ITEM(t, 5, Py_None);
 
241
    }
 
242
    if (u->path) {
 
243
        PyTuple_SET_ITEM(t, 6, PyString_FromString(u->path));
 
244
    }
 
245
    else {
 
246
        Py_INCREF(Py_None);
 
247
        PyTuple_SET_ITEM(t, 6, Py_None);
 
248
    }
 
249
    if (u->query) {
 
250
        PyTuple_SET_ITEM(t, 7, PyString_FromString(u->query));
 
251
    }
 
252
    else {
 
253
        Py_INCREF(Py_None);
 
254
        PyTuple_SET_ITEM(t, 7, Py_None);
 
255
    }
 
256
    if (u->fragment) {
 
257
        PyTuple_SET_ITEM(t, 8, PyString_FromString(u->fragment));
 
258
    }
 
259
    else {
 
260
        Py_INCREF(Py_None);
 
261
        PyTuple_SET_ITEM(t, 8, Py_None);
 
262
    }
 
263
    /* XXX hostent, is_initialized, dns_* */
 
264
 
 
265
    return t;
 
266
}
 
267
 
 
268
 
 
269
/**
 
270
 ** python_decref
 
271
 ** 
 
272
 *   This helper function is used with apr_pool_cleanup_register to destroy
 
273
 *   python objects when a certain pool is destroyed.
 
274
 */
 
275
 
 
276
apr_status_t python_decref(void *object)
 
277
{
 
278
    Py_XDECREF((PyObject *) object);
 
279
    return 0;
 
280
}
 
281
 
 
282
/**
 
283
 ** find_module
 
284
 ** 
 
285
 *   Find an Apache module by name, used by get_addhandler_extensions
 
286
 */
 
287
 
 
288
static module *find_module(char *name)
 
289
{
 
290
    int n; 
 
291
    for (n = 0; ap_loaded_modules[n]; ++n) {
 
292
 
 
293
        if (strcmp(name, ap_loaded_modules[n]->name) == 0)
 
294
            return ap_loaded_modules[n];
 
295
 
 
296
    }
 
297
    return NULL;
 
298
}
 
299
 
 
300
/**
 
301
 ** get_addhandler_extensions
 
302
 ** 
 
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.
 
306
 *
 
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.
 
311
 */
 
312
 
 
313
char * get_addhandler_extensions(request_rec *req)
 
314
{
 
315
 
 
316
    /* these typedefs are copied from mod_mime.c */
 
317
 
 
318
    typedef struct {
 
319
        apr_hash_t  *extension_mappings;  
 
320
        apr_array_header_t *remove_mappings; 
 
321
        char *default_language;
 
322
        int multimatch;
 
323
    } mime_dir_config;
 
324
 
 
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... */
 
333
    } extension_info;
 
334
 
 
335
    mime_dir_config *mconf;
 
336
 
 
337
    apr_hash_index_t *hi;
 
338
    void *val;
 
339
    void *key;
 
340
    extension_info *ei;
 
341
    char *result = NULL;
 
342
 
 
343
    module *mod_mime = find_module("mod_mime.c");
 
344
    mconf = (mime_dir_config *) ap_get_module_config(req->per_dir_config, mod_mime);
 
345
 
 
346
    if (mconf->extension_mappings) {
 
347
 
 
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;
 
351
            if (ei->handler) 
 
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);
 
355
        }
 
356
    }
 
357
 
 
358
    return result;
 
359
}
 
360
 
 
361
/**
 
362
 ** find_memberdef
 
363
 ** 
 
364
 *   Find a memberdef in a PyMemberDef array
 
365
 */
 
366
 
 
367
PyMemberDef *find_memberdef(const PyMemberDef *mlist, const char *name)
 
368
{
 
369
    const PyMemberDef *md;
 
370
 
 
371
    for (md = mlist; md->name != NULL; md++)
 
372
        if (strcmp(md->name, name) == 0)
 
373
            return (PyMemberDef *)md;
 
374
 
 
375
    /* this should never happen or the mlist is screwed up */
 
376
    return NULL;
 
377
}
 
378
 
 
379
/**
 
380
 ** cfgtree_walk
 
381
 **
 
382
 *  walks ap_directive_t tree returning a list of
 
383
 *  tuples and lists
 
384
 */
 
385
 
 
386
PyObject *cfgtree_walk(ap_directive_t *dir)
 
387
{
 
388
 
 
389
    PyObject *list = PyList_New(0);
 
390
    if (!list)
 
391
        return PyErr_NoMemory();
 
392
 
 
393
    while (dir) {
 
394
 
 
395
        PyObject *t = Py_BuildValue("(s, s)", dir->directive, dir->args);
 
396
        if (!t)
 
397
            return PyErr_NoMemory();
 
398
 
 
399
        PyList_Append(list, t);
 
400
 
 
401
        if (dir->first_child) {
 
402
 
 
403
            PyObject *child = cfgtree_walk(dir->first_child);
 
404
            if (!child)
 
405
                return PyErr_NoMemory();
 
406
 
 
407
            PyList_Append(list, child);
 
408
 
 
409
        }
 
410
 
 
411
        dir = dir->next;
 
412
    } 
 
413
 
 
414
    return list;
 
415
}