~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to sapi/aolserver/aolserver.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   +----------------------------------------------------------------------+
 
3
   | PHP Version 5                                                        |
 
4
   +----------------------------------------------------------------------+
 
5
   | Copyright (c) 1997-2004 The PHP Group                                |
 
6
   +----------------------------------------------------------------------+
 
7
   | This source file is subject to version 3.0 of the PHP license,       |
 
8
   | that is bundled with this package in the file LICENSE, and is        |
 
9
   | available through the world-wide-web at the following url:           |
 
10
   | http://www.php.net/license/3_0.txt.                                  |
 
11
   | If you did not receive a copy of the PHP license and are unable to   |
 
12
   | obtain it through the world-wide-web, please send a note to          |
 
13
   | license@php.net so we can mail you a copy immediately.               |
 
14
   +----------------------------------------------------------------------+
 
15
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
 
16
   +----------------------------------------------------------------------+
 
17
 */
 
18
 
 
19
/*
 
20
 * TODO:
 
21
 * - write documentation
 
22
 * - CGI/1.1 conformance
 
23
 */
 
24
 
 
25
/* $Id: aolserver.c,v 1.77.2.1 2005/07/04 12:47:26 dmitry Exp $ */
 
26
 
 
27
/* conflict between PHP and AOLserver headers */
 
28
#define Debug php_Debug
 
29
#include "php.h"
 
30
#undef Debug
 
31
 
 
32
#ifdef HAVE_AOLSERVER
 
33
 
 
34
#ifndef ZTS
 
35
#error AOLserver module is only useable in thread-safe mode
 
36
#endif
 
37
 
 
38
#include "ext/standard/info.h"
 
39
#define SECTION(name)  PUTS("<h2>" name "</h2>\n")
 
40
 
 
41
#define NS_BUF_SIZE 511
 
42
 
 
43
#include "php_ini.h"
 
44
#include "php_globals.h"
 
45
#include "SAPI.h"
 
46
#include "php_main.h"
 
47
#include "php_variables.h"
 
48
 
 
49
#include "ns.h"
 
50
 
 
51
#include "php_version.h"
 
52
 
 
53
/* This symbol is used by AOLserver to tell the API version we expect */
 
54
 
 
55
int Ns_ModuleVersion = 1;
 
56
 
 
57
#define NSG(v) TSRMG(ns_globals_id, ns_globals_struct *, v)
 
58
 
 
59
/* php_ns_context is per-server (thus only once at all) */
 
60
 
 
61
typedef struct {
 
62
        sapi_module_struct *sapi_module;
 
63
        char *ns_server;
 
64
        char *ns_module;
 
65
} php_ns_context;
 
66
 
 
67
/* ns_globals_struct is per-thread */
 
68
 
 
69
typedef struct {
 
70
        Ns_Conn *conn;
 
71
        size_t data_avail;
 
72
} ns_globals_struct;
 
73
 
 
74
/* TSRM id */
 
75
 
 
76
static int ns_globals_id;
 
77
 
 
78
/* global context */
 
79
 
 
80
static php_ns_context *global_context;
 
81
 
 
82
static void php_ns_config(php_ns_context *ctx, char global);
 
83
 
 
84
/*
 
85
 * php_ns_sapi_ub_write() writes data to the client connection.
 
86
 */
 
87
 
 
88
static int
 
89
php_ns_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
 
90
{
 
91
        int n;
 
92
        uint sent = 0;
 
93
 
 
94
        while (str_length > 0) {
 
95
                n = Ns_ConnWrite(NSG(conn), (void *) str, str_length);
 
96
 
 
97
                if (n == -1)
 
98
                        php_handle_aborted_connection();
 
99
 
 
100
                str += n;
 
101
                sent += n;
 
102
                str_length -= n;
 
103
        }
 
104
        
 
105
        return sent;
 
106
}
 
107
 
 
108
/*
 
109
 * php_ns_sapi_header_handler() sets a HTTP reply header to be 
 
110
 * sent to the client.
 
111
 */
 
112
 
 
113
static int
 
114
php_ns_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
 
115
{
 
116
        char *header_name, *header_content;
 
117
        char *p;
 
118
 
 
119
        header_name = sapi_header->header;
 
120
        header_content = p = strchr(header_name, ':');
 
121
 
 
122
        if (p) {
 
123
                *p = '\0';
 
124
                do {
 
125
                        header_content++;
 
126
                } while (*header_content == ' ');
 
127
 
 
128
                if (!strcasecmp(header_name, "Content-type")) {
 
129
                        Ns_ConnSetTypeHeader(NSG(conn), header_content);
 
130
                } else {
 
131
                        Ns_ConnSetHeaders(NSG(conn), header_name, header_content);
 
132
                }
 
133
 
 
134
                *p = ':';
 
135
        }
 
136
 
 
137
        sapi_free_header(sapi_header);
 
138
        
 
139
        return 0;
 
140
}
 
141
 
 
142
/*
 
143
 * php_ns_sapi_send_headers() flushes the headers to the client.
 
144
 * Called before real content is sent by PHP.
 
145
 */
 
146
 
 
147
static int
 
148
php_ns_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
 
149
{
 
150
        if(SG(sapi_headers).send_default_content_type) {
 
151
                Ns_ConnSetRequiredHeaders(NSG(conn), "text/html", 0);
 
152
        }
 
153
        
 
154
        Ns_ConnFlushHeaders(NSG(conn), SG(sapi_headers).http_response_code);
 
155
        
 
156
        return SAPI_HEADER_SENT_SUCCESSFULLY;
 
157
}
 
158
 
 
159
/*
 
160
 * php_ns_sapi_read_post() reads a specified number of bytes from
 
161
 * the client. Used for POST/PUT requests.
 
162
 */
 
163
 
 
164
static int
 
165
php_ns_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
 
166
{
 
167
        uint max_read;
 
168
        uint total_read = 0;
 
169
 
 
170
        max_read = MIN(NSG(data_avail), count_bytes);
 
171
        
 
172
        total_read = Ns_ConnRead(NSG(conn), buf, max_read);
 
173
        
 
174
        if(total_read == NS_ERROR) {
 
175
                total_read = -1;
 
176
        } else {
 
177
                NSG(data_avail) -= total_read;
 
178
        }
 
179
 
 
180
        return total_read;
 
181
}
 
182
 
 
183
/* 
 
184
 * php_ns_sapi_read_cookies() returns the Cookie header from
 
185
 * the HTTP request header
 
186
 */
 
187
        
 
188
static char *php_ns_sapi_read_cookies(TSRMLS_D)
 
189
{
 
190
        int i;
 
191
        char *http_cookie = NULL;
 
192
        
 
193
        i = Ns_SetIFind(NSG(conn->headers), "cookie");
 
194
        if(i != -1) {
 
195
                http_cookie = Ns_SetValue(NSG(conn->headers), i);
 
196
        }
 
197
 
 
198
        return http_cookie;
 
199
}
 
200
 
 
201
static void php_info_aolserver(ZEND_MODULE_INFO_FUNC_ARGS)
 
202
{
 
203
        char buf[512];
 
204
        int uptime = Ns_InfoUptime();
 
205
        int i;
 
206
        
 
207
        php_info_print_table_start();
 
208
        php_info_print_table_row(2, "SAPI module version", "$Id: aolserver.c,v 1.77.2.1 2005/07/04 12:47:26 dmitry Exp $");
 
209
        php_info_print_table_row(2, "Build date", Ns_InfoBuildDate());
 
210
        php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile());
 
211
        php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog());
 
212
        php_info_print_table_row(2, "Installation path", Ns_InfoHomePath());
 
213
        php_info_print_table_row(2, "Hostname of server", Ns_InfoHostname());
 
214
        php_info_print_table_row(2, "Source code label", Ns_InfoLabel());
 
215
        php_info_print_table_row(2, "Server platform", Ns_InfoPlatform());
 
216
        snprintf(buf, 511, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion());
 
217
        php_info_print_table_row(2, "Server version", buf);
 
218
        snprintf(buf, 511, "%d day(s), %02d:%02d:%02d", 
 
219
                        uptime / 86400,
 
220
                        (uptime / 3600) % 24,
 
221
                        (uptime / 60) % 60,
 
222
                        uptime % 60);
 
223
        php_info_print_table_row(2, "Server uptime", buf);
 
224
        php_info_print_table_end();
 
225
 
 
226
        SECTION("HTTP Headers Information");
 
227
        php_info_print_table_start();
 
228
        php_info_print_table_colspan_header(2, "HTTP Request Headers");
 
229
        php_info_print_table_row(2, "HTTP Request", NSG(conn)->request->line);
 
230
        for (i = 0; i < Ns_SetSize(NSG(conn)->headers); i++) {
 
231
                php_info_print_table_row(2, Ns_SetKey(NSG(conn)->headers, i), Ns_SetValue(NSG(conn)->headers, i));
 
232
        }
 
233
 
 
234
        php_info_print_table_colspan_header(2, "HTTP Response Headers");
 
235
        for (i = 0; i < Ns_SetSize(NSG(conn)->outputheaders); i++) {
 
236
                php_info_print_table_row(2, Ns_SetKey(NSG(conn)->outputheaders, i), Ns_SetValue(NSG(conn)->outputheaders, i));
 
237
        }
 
238
        php_info_print_table_end();
 
239
}
 
240
 
 
241
PHP_FUNCTION(getallheaders);
 
242
 
 
243
static function_entry aolserver_functions[] = {
 
244
        PHP_FE(getallheaders, NULL)
 
245
        {NULL, NULL, NULL}
 
246
};
 
247
 
 
248
static zend_module_entry php_aolserver_module = {
 
249
        STANDARD_MODULE_HEADER,
 
250
        "AOLserver",
 
251
        aolserver_functions,
 
252
        NULL,
 
253
        NULL,
 
254
        NULL,
 
255
        NULL,
 
256
        php_info_aolserver,
 
257
        NULL,
 
258
        STANDARD_MODULE_PROPERTIES
 
259
};
 
260
 
 
261
PHP_FUNCTION(getallheaders)
 
262
{
 
263
        int i;
 
264
 
 
265
        array_init(return_value);
 
266
        
 
267
        for (i = 0; i < Ns_SetSize(NSG(conn->headers)); i++) {
 
268
                char *key = Ns_SetKey(NSG(conn->headers), i);
 
269
                char *value = Ns_SetValue(NSG(conn->headers), i);
 
270
                
 
271
                add_assoc_string(return_value, key, value, 1);
 
272
        }
 
273
}
 
274
 
 
275
static int
 
276
php_ns_startup(sapi_module_struct *sapi_module)
 
277
{
 
278
        if (php_module_startup(sapi_module, &php_aolserver_module, 1) == FAILURE) {
 
279
                return FAILURE;
 
280
        } else {
 
281
                return SUCCESS;
 
282
        }
 
283
}
 
284
 
 
285
 
 
286
/*
 
287
 * php_ns_sapi_register_variables() populates the php script environment
 
288
 * with a number of variables. HTTP_* variables are created for
 
289
 * the HTTP header data, so that a script can access these.
 
290
 */
 
291
 
 
292
#define ADD_STRINGX(name, buf)                                                                          \
 
293
        php_register_variable(name, buf, track_vars_array TSRMLS_CC)
 
294
 
 
295
#define ADD_STRING(name)                                                                                \
 
296
        ADD_STRINGX(name, buf)
 
297
 
 
298
static void
 
299
php_ns_sapi_register_variables(zval *track_vars_array TSRMLS_DC)
 
300
{
 
301
        int i;
 
302
        char buf[NS_BUF_SIZE + 1];
 
303
        char *tmp;
 
304
 
 
305
        for(i = 0; i < Ns_SetSize(NSG(conn->headers)); i++) {
 
306
                char *key = Ns_SetKey(NSG(conn->headers), i);
 
307
                char *value = Ns_SetValue(NSG(conn->headers), i);
 
308
                char *p;
 
309
                char c;
 
310
 
 
311
                snprintf(buf, NS_BUF_SIZE, "HTTP_%s", key);
 
312
                
 
313
                for(p = buf + 5; (c = *p); p++) {
 
314
                        c = toupper(c);
 
315
                        if(c < 'A' || c > 'Z') {
 
316
                                c = '_';
 
317
                        }
 
318
                        *p = c;
 
319
                }
 
320
 
 
321
                ADD_STRINGX(buf, value);
 
322
        }
 
323
        
 
324
        snprintf(buf, NS_BUF_SIZE, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion());
 
325
        ADD_STRING("SERVER_SOFTWARE");
 
326
        snprintf(buf, NS_BUF_SIZE, "HTTP/%1.1f", NSG(conn)->request->version);
 
327
        ADD_STRING("SERVER_PROTOCOL");
 
328
 
 
329
        ADD_STRINGX("REQUEST_METHOD", NSG(conn)->request->method);
 
330
 
 
331
        if(NSG(conn)->request->query)
 
332
                ADD_STRINGX("QUERY_STRING", NSG(conn)->request->query);
 
333
        
 
334
        ADD_STRINGX("SERVER_BUILDDATE", Ns_InfoBuildDate());
 
335
 
 
336
        ADD_STRINGX("REMOTE_ADDR", Ns_ConnPeer(NSG(conn)));
 
337
 
 
338
        snprintf(buf, NS_BUF_SIZE, "%d", Ns_ConnPeerPort(NSG(conn)));
 
339
        ADD_STRING("REMOTE_PORT");
 
340
 
 
341
        snprintf(buf, NS_BUF_SIZE, "%d", Ns_ConnPort(NSG(conn)));
 
342
        ADD_STRING("SERVER_PORT");
 
343
 
 
344
        tmp = Ns_ConnHost(NSG(conn));
 
345
        if (tmp)
 
346
                ADD_STRINGX("SERVER_NAME", tmp);
 
347
 
 
348
        ADD_STRINGX("PATH_TRANSLATED", SG(request_info).path_translated);
 
349
        ADD_STRINGX("REQUEST_URI", SG(request_info).request_uri);
 
350
        ADD_STRINGX("PHP_SELF", SG(request_info).request_uri);
 
351
 
 
352
        ADD_STRINGX("GATEWAY_INTERFACE", "CGI/1.1");
 
353
 
 
354
        snprintf(buf, NS_BUF_SIZE, "%d", Ns_InfoBootTime());
 
355
        ADD_STRING("SERVER_BOOTTIME");
 
356
}
 
357
 
 
358
 
 
359
 
 
360
/* this structure is static (as in "it does not change") */
 
361
 
 
362
static sapi_module_struct aolserver_sapi_module = {
 
363
        "aolserver",
 
364
        "AOLserver",
 
365
 
 
366
        php_ns_startup,                                                 /* startup */
 
367
        php_module_shutdown_wrapper,                    /* shutdown */
 
368
 
 
369
        NULL,                                                                   /* activate */
 
370
        NULL,                                                                   /* deactivate */
 
371
 
 
372
        php_ns_sapi_ub_write,                                   /* unbuffered write */
 
373
        NULL,                                                                   /* flush */
 
374
        NULL,                                                                   /* get uid */
 
375
        NULL,                                                                   /* getenv */
 
376
 
 
377
        php_error,                                                              /* error handler */
 
378
 
 
379
        php_ns_sapi_header_handler,                             /* header handler */
 
380
        php_ns_sapi_send_headers,                               /* send headers handler */
 
381
        NULL,                                                                   /* send header handler */
 
382
 
 
383
        php_ns_sapi_read_post,                                  /* read POST data */
 
384
        php_ns_sapi_read_cookies,                               /* read Cookies */
 
385
 
 
386
        php_ns_sapi_register_variables,
 
387
        NULL,                                                                   /* Log message */
 
388
 
 
389
        STANDARD_SAPI_MODULE_PROPERTIES
 
390
};
 
391
 
 
392
/*
 
393
 * php_ns_module_main() is called by the per-request handler and
 
394
 * "executes" the script
 
395
 */
 
396
 
 
397
static int
 
398
php_ns_module_main(TSRMLS_D)
 
399
{
 
400
        zend_file_handle file_handle;
 
401
 
 
402
        file_handle.type = ZEND_HANDLE_FILENAME;
 
403
        file_handle.filename = SG(request_info).path_translated;
 
404
        file_handle.free_filename = 0;
 
405
        file_handle.opened_path = NULL;
 
406
        
 
407
        php_ns_config(global_context, 0);
 
408
        if (php_request_startup(TSRMLS_C) == FAILURE) {
 
409
                return NS_ERROR;
 
410
        }
 
411
        
 
412
        php_execute_script(&file_handle TSRMLS_CC);
 
413
        php_request_shutdown(NULL);
 
414
 
 
415
        return NS_OK;
 
416
}
 
417
 
 
418
/*
 
419
 * php_ns_request_ctor() initializes the per-request data structure
 
420
 * and fills it with data provided by the web server
 
421
 */
 
422
 
 
423
static void 
 
424
php_ns_request_ctor(TSRMLS_D)
 
425
{
 
426
        char *server;
 
427
        Ns_DString ds;
 
428
        char *root;
 
429
        int index;
 
430
        char *tmp;
 
431
        
 
432
        server = Ns_ConnServer(NSG(conn));
 
433
        
 
434
#define safe_strdup(x) ((x)?strdup((x)):NULL)
 
435
        SG(request_info).query_string = safe_strdup(NSG(conn->request->query));
 
436
 
 
437
        Ns_DStringInit(&ds);
 
438
        Ns_UrlToFile(&ds, server, NSG(conn->request->url));
 
439
        
 
440
        /* path_translated is the absolute path to the file */
 
441
        SG(request_info).path_translated = safe_strdup(Ns_DStringValue(&ds));
 
442
        Ns_DStringFree(&ds);
 
443
        root = Ns_PageRoot(server);
 
444
        SG(request_info).request_uri = strdup(SG(request_info).path_translated + strlen(root));
 
445
        SG(request_info).request_method = NSG(conn)->request->method;
 
446
        SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
 
447
        index = Ns_SetIFind(NSG(conn)->headers, "content-type");
 
448
        SG(request_info).content_type = index == -1 ? NULL : 
 
449
                Ns_SetValue(NSG(conn)->headers, index);
 
450
        SG(sapi_headers).http_response_code = 200;
 
451
 
 
452
        tmp = Ns_ConnAuthUser(NSG(conn));
 
453
        if (tmp)
 
454
                tmp = estrdup(tmp);
 
455
        SG(request_info).auth_user = tmp;
 
456
 
 
457
        tmp = Ns_ConnAuthPasswd(NSG(conn));
 
458
        if (tmp)
 
459
                tmp = estrdup(tmp);
 
460
        SG(request_info).auth_password = tmp;
 
461
 
 
462
        NSG(data_avail) = SG(request_info).content_length;
 
463
}
 
464
 
 
465
/*
 
466
 * php_ns_request_dtor() destroys all data associated with
 
467
 * the per-request structure 
 
468
 */
 
469
 
 
470
static void
 
471
php_ns_request_dtor(TSRMLS_D)
 
472
{
 
473
        free(SG(request_info).path_translated);
 
474
        if (SG(request_info).query_string)
 
475
                free(SG(request_info).query_string);
 
476
        free(SG(request_info).request_uri);
 
477
}
 
478
 
 
479
/*
 
480
 * The php_ns_request_handler() is called per request and handles
 
481
 * everything for one request.
 
482
 */
 
483
 
 
484
static int
 
485
php_ns_request_handler(void *context, Ns_Conn *conn)
 
486
{
 
487
        int status = NS_OK;
 
488
        TSRMLS_FETCH();
 
489
        
 
490
        NSG(conn) = conn;
 
491
        
 
492
        SG(server_context) = global_context;
 
493
 
 
494
        php_ns_request_ctor(TSRMLS_C);
 
495
        
 
496
        status = php_ns_module_main(TSRMLS_C);
 
497
        
 
498
        php_ns_request_dtor(TSRMLS_C);
 
499
 
 
500
        return status;
 
501
}
 
502
 
 
503
/*
 
504
 * php_ns_config() fetches the configuration data.
 
505
 *
 
506
 * It understands the "map" and "php_value" command.
 
507
 */
 
508
 
 
509
static void 
 
510
php_ns_config(php_ns_context *ctx, char global)
 
511
{
 
512
        int i;
 
513
        char *path;
 
514
        Ns_Set *set;
 
515
 
 
516
        path = Ns_ConfigGetPath(ctx->ns_server, ctx->ns_module, NULL);
 
517
        set = Ns_ConfigGetSection(path);
 
518
 
 
519
        for (i = 0; set && i < Ns_SetSize(set); i++) {
 
520
                char *key = Ns_SetKey(set, i);
 
521
                char *value = Ns_SetValue(set, i);
 
522
 
 
523
                if (global && !strcasecmp(key, "map")) {
 
524
                        Ns_Log(Notice, "Registering PHP for \"%s\"", value);
 
525
                        Ns_RegisterRequest(ctx->ns_server, "GET", value, php_ns_request_handler, NULL, ctx, 0);
 
526
                        Ns_RegisterRequest(ctx->ns_server, "POST", value, php_ns_request_handler, NULL, ctx, 0);
 
527
                        Ns_RegisterRequest(ctx->ns_server, "HEAD", value, php_ns_request_handler, NULL, ctx, 0);
 
528
 
 
529
        /* 
 
530
         * Deactivated for now. The ini system will cause random crashes when 
 
531
         * accessed from here (since there are no locks to protect the global 
 
532
         * known_directives) 
 
533
         */
 
534
 
 
535
                } else if (!global && !strcasecmp(key, "php_value")) {
 
536
                        Ns_Log(Notice, "php_value has been deactivated temporarily. Please use a php.ini file to pass directives to PHP. Thanks.");
 
537
#if 0
 
538
                        char *val;
 
539
 
 
540
                        val = strchr(value, ' ');
 
541
                        if (val) {
 
542
                                char *new_key;
 
543
                                
 
544
                                new_key = estrndup(value, val - value);
 
545
                                
 
546
                                do { 
 
547
                                        val++; 
 
548
                                } while(*val == ' ');
 
549
 
 
550
                                Ns_Log(Debug, "PHP configuration option '%s=%s'", new_key, val);
 
551
                                zend_alter_ini_entry(new_key, strlen(new_key) + 1, val, 
 
552
                                                strlen(val) + 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
 
553
                                
 
554
                                efree(new_key);
 
555
                        }
 
556
#endif
 
557
                }
 
558
                
 
559
        }
 
560
}
 
561
        
 
562
/*
 
563
 * php_ns_server_shutdown() performs the last steps before the
 
564
 * server exits. Shutdowns basic services and frees memory
 
565
 */
 
566
 
 
567
static void
 
568
php_ns_server_shutdown(void *context)
 
569
{
 
570
        php_ns_context *ctx = (php_ns_context *) context;
 
571
        
 
572
        ctx->sapi_module->shutdown(ctx->sapi_module);
 
573
        sapi_shutdown();
 
574
        tsrm_shutdown();
 
575
 
 
576
        free(ctx->ns_module);
 
577
        free(ctx->ns_server);
 
578
        free(ctx);
 
579
}
 
580
 
 
581
/*
 
582
 * Ns_ModuleInit() is called by AOLserver once at startup
 
583
 *
 
584
 * This functions allocates basic structures and initializes
 
585
 * basic services.
 
586
 */
 
587
 
 
588
int Ns_ModuleInit(char *server, char *module)
 
589
{
 
590
        php_ns_context *ctx;
 
591
        
 
592
        tsrm_startup(1, 1, 0, NULL);
 
593
        sapi_startup(&aolserver_sapi_module);
 
594
        sapi_module.startup(&aolserver_sapi_module);
 
595
        
 
596
        /* TSRM is used to allocate a per-thread structure */
 
597
        ts_allocate_id(&ns_globals_id, sizeof(ns_globals_struct), NULL, NULL);
 
598
        
 
599
        /* the context contains data valid for all threads */
 
600
        ctx = malloc(sizeof *ctx);
 
601
        ctx->sapi_module = &aolserver_sapi_module;
 
602
        ctx->ns_server = strdup(server);
 
603
        ctx->ns_module = strdup(module);
 
604
        
 
605
        /* read the configuration */
 
606
        php_ns_config(ctx, 1);
 
607
 
 
608
        global_context = ctx;
 
609
 
 
610
        /* register shutdown handler */
 
611
        Ns_RegisterServerShutdown(server, php_ns_server_shutdown, ctx);
 
612
 
 
613
        return NS_OK;
 
614
}
 
615
 
 
616
#endif