Annotation of parser3/src/targets/apache13/mod_parser3.c, revision 1.13

1.2       paf         1: /** @file
                      2: Parser: apache 1.3 module, part, compiled by Apache.
                      3: 
1.13    ! moko        4:        Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.2       paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      6: */
                      7: 
1.6       paf         8: #ifdef WIN32
                      9: #include <winsock2.h>
                     10: #endif
1.2       paf        11: 
                     12: #include "httpd.h"
                     13: #include "http_config.h"
                     14: #include "http_core.h"
                     15: #include "http_log.h"
                     16: #include "http_main.h"
                     17: #include "http_protocol.h"
                     18: #include "util_script.h"
                     19: #include "ap_md5.h"
                     20: #include "ap_alloc.h"
                     21: 
                     22: #include "pa_httpd.h"
                     23: 
1.13    ! moko       24: volatile const char * IDENT_MOD_PARSER3_C="$Id: 2005-08-09 08:14:53 $" IDENT_PA_HTTPD_H;
        !            25: 
1.2       paf        26: /*
                     27: * Declare ourselves so the configuration routines can find and know us.
                     28: * We'll fill it in at the end of the module.
                     29: */
                     30: extern module MODULE_VAR_EXPORT parser3_module;
                     31: 
                     32: /*
                     33: * Locate our directory configuration record for the current request.
                     34: */
                     35: static Parser_module_config *our_dconfig(request_rec *r) {
                     36:        return (Parser_module_config *) 
                     37:                ap_get_module_config(r->per_dir_config, &parser3_module);
                     38: }
                     39: 
                     40: static const char* cmd_parser_config(cmd_parms *cmd, void *mconfig, char *file_spec) {
                     41:        Parser_module_config *cfg = (Parser_module_config *) mconfig;
                     42:        
                     43:        // remember assigned filespec into cfg
                     44:        cfg->parser_config_filespec=file_spec;
                     45:        
                     46:        return NULL;
                     47: }
                     48: static const char* cmd_parser_status_allowed(cmd_parms *cmd, void *mconfig, char *file_spec) {
                     49:        //_asm int 3;
                     50:        Parser_module_config *cfg = (Parser_module_config *) mconfig;
                     51:        
                     52:        cfg->parser_status_allowed=1;
                     53:        
                     54:        return NULL;
                     55: }
                     56: 
                     57: 
                     58: /*--------------------------------------------------------------------------*/
                     59: /*                                                                          */
                     60: /* Now we declare our content handlers, which are invoked when the server   */
                     61: /* encounters a document which our module is supposed to have a chance to   */
                     62: /* see.  (See mod_mime's SetHandler and AddHandler directives, and the      */
                     63: /* mod_info and mod_status examples, for more details.)                     */
                     64: /*                                                                          */
                     65: /* Since content handlers are dumping data directly into the connexion      */
                     66: /* (using the r*() routines, such as rputs() and rprintf()) without         */
                     67: /* intervention by other parts of the server, they need to make             */
                     68: /* sure any accumulated HTTP headers are sent first.  This is done by       */
                     69: /* calling send_http_header().  Otherwise, no header will be sent at all,   */
                     70: /* and the output sent to the client will actually be HTTP-uncompliant.     */
                     71: /*--------------------------------------------------------------------------*/
                     72: /* 
                     73: * Sample content handler.  All this does is display the call list that has
                     74: * been built up so far.
                     75: *
                     76: * The return value instructs the caller concerning what happened and what to
                     77: * do next:
                     78: *  OK ("we did our thing")
                     79: *  DECLINED ("this isn't something with which we want to get involved")
                     80: *  HTTP_mumble ("an error status should be reported")
                     81: */
                     82: 
                     83: 
                     84: /*--------------------------------------------------------------------------*/
                     85: /*                                                                          */
                     86: /* Now let's declare routines for each of the callback phase in order.      */
                     87: /* (That's the order in which they're listed in the callback list, *not     */
                     88: /* the order in which the server calls them!  See the command_rec           */
                     89: /* declaration near the bottom of this file.)  Note that these may be       */
                     90: /* called for situations that don't relate primarily to our function - in   */
                     91: /* other words, the fixup handler shouldn't assume that the request has     */
                     92: /* to do with "example" stuff.                                              */
                     93: /*                                                                          */
                     94: /* With the exception of the content handler, all of our routines will be   */
                     95: /* called for each request, unless an earlier handler from another module   */
                     96: /* aborted the sequence.                                                    */
                     97: /*                                                                          */
                     98: /* Handlers that are declared as "int" can return the following:            */
                     99: /*                                                                          */
                    100: /*  OK          Handler accepted the request and did its thing with it.     */
                    101: /*  DECLINED    Handler took no action.                                     */
                    102: /*  HTTP_mumble Handler looked at request and found it wanting.             */
                    103: /*                                                                          */
                    104: /* What the server does after calling a module handler depends upon the     */
                    105: /* handler's return value.  In all cases, if the handler returns            */
                    106: /* DECLINED, the server will continue to the next module with an handler    */
                    107: /* for the current phase.  However, if the handler return a non-OK,         */
                    108: /* non-DECLINED status, the server aborts the request right there.  If      */
                    109: /* the handler returns OK, the server's next action is phase-specific;      */
                    110: /* see the individual handler comments below for details.                   */
                    111: /*                                                                          */
                    112: /*--------------------------------------------------------------------------*/
                    113: 
                    114: static int parser_handler(request_rec *ar) {
                    115:        // record clone
                    116:        pa_request_rec lr={
                    117:                ar,
                    118:                ar->pool,
                    119:                ar->header_only,
1.5       paf       120:                &ar->status,
1.2       paf       121:                ar->method,
                    122:                ar->headers_out,
                    123:                ar->subprocess_env,
1.7       paf       124:                &ar->content_type,
1.2       paf       125:                ar->uri,
                    126:                ar->filename,
                    127:                ar->path_info,
                    128:                ar->args,
                    129:                &ar->finfo
                    130:        };
                    131: 
                    132:        // config
                    133:        Parser_module_config *dcfg=our_dconfig(ar);
1.4       paf       134:        
1.2       paf       135:        return pa_parser_handler(&lr, dcfg);
                    136: }
                    137: 
                    138: /* 
                    139: * This function is called during server initialisation.  Any information
                    140: * that needs to be recorded must be in static cells, since there's no
                    141: * configuration record.
                    142: *
                    143: * There is no return value.
                    144: */
                    145: 
1.11      paf       146: static void parser_module_init(server_rec *s, pool *p) {
1.2       paf       147: #if MODULE_MAGIC_NUMBER >= 19980527
                    148:        ap_add_version_component(pa_version());
                    149: #endif 
                    150:        
                    151:        /*
                    152:        * Set up any module cells that ought to be initialised.
                    153:        */
                    154:        pa_setup_module_cells();
                    155: }
                    156: 
1.11      paf       157: /* 
                    158:  * This function is called when an heavy-weight process (such as a child) is
                    159:  * being run down or destroyed.  As with the child-initialisation function,
                    160:  * any information that needs to be recorded must be in static cells, since
                    161:  * there's no configuration record.
                    162:  *
                    163:  * There is no return value.
                    164:  */
                    165: 
                    166: /*
                    167:  * All our process-death routine does is add its trace to the log.
                    168:  */
                    169: static void parser_module_done(server_rec *s, pool *p) {
                    170:        pa_destroy_module_cells();
                    171: }
                    172: 
1.2       paf       173: /*
                    174: * This function gets called to create a per-directory configuration
                    175: * record.  This will be called for the "default" server environment, and for
                    176: * each directory for which the parser finds any of our directives applicable.
                    177: * If a directory doesn't have any of our directives involved (i.e., they
                    178: * aren't in the .htaccess file, or a <Location>, <Directory>, or related
                    179: * block), this routine will *not* be called - the configuration for the
                    180: * closest ancestor is used.
                    181: *
                    182: * The return value is a pointer to the created module-specific
                    183: * structure.
                    184: */
                    185: static void *parser_create_dir_config(pool *p, char *dirspec) {
                    186:        //_asm int 3;
                    187:        /*
                    188:        * Allocate the space for our record from the pool supplied.
                    189:        */
                    190:        Parser_module_config *cfg=
                    191:                (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
                    192:                /*
                    193:                * Now fill in the defaults.  If there are any `parent' configuration
                    194:                * records, they'll get merged as part of a separate callback.
                    195:        */
                    196:        
                    197:        return (void *) cfg;
                    198: }
                    199: 
                    200: /*
                    201: * This function gets called to merge two per-directory configuration
                    202: * records.  This is typically done to cope with things like .htaccess files
                    203: * or <Location> directives for directories that are beneath one for which a
                    204: * configuration record was already created.  The routine has the
                    205: * responsibility of creating a new record and merging the contents of the
                    206: * other two into it appropriately.  If the module doesn't declare a merge
                    207: * routine, the record for the closest ancestor location (that has one) is
                    208: * used exclusively.
                    209: *
                    210: * The routine MUST NOT modify any of its arguments!
                    211: *
                    212: * The return value is a pointer to the created module-specific structure
                    213: * containing the merged values.
                    214: 
                    215:  20011126 paf: noticed, that this is called even on virtual root merge with something "parent",
                    216:  while thought that that is part of merge_server...
                    217:  
                    218: */
                    219: static void *parser_merge_dir_config(pool *p, void *parent_conf,
                    220:                                     void *newloc_conf) {
                    221:        //_asm int 3;
                    222:        Parser_module_config *merged_config = 
                    223:                (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
                    224:        Parser_module_config *pconf = (Parser_module_config *) parent_conf;
                    225:        Parser_module_config *nconf = (Parser_module_config *) newloc_conf;
                    226:        
                    227:        merged_config->parser_config_filespec = ap_pstrdup(p, nconf->parser_config_filespec?
                    228:                nconf->parser_config_filespec:pconf->parser_config_filespec);
                    229:        merged_config->parser_status_allowed=
                    230:                pconf->parser_status_allowed ||
                    231:                nconf->parser_status_allowed;
                    232:        
                    233:                /*
                    234:                * Some things get copied directly from the more-specific record, rather
                    235:                * than getting merged.
                    236:        */
                    237:        
                    238:        return (void *) merged_config;
                    239: }
                    240: 
                    241: /*
                    242: * This function gets called to create a per-server configuration
                    243: * record.  It will always be called for the "default" server.
                    244: *
                    245: * The return value is a pointer to the created module-specific
                    246: * structure.
                    247: */
                    248: static void *parser_create_server_config(pool *p, server_rec *s) {
                    249:        //_asm int 3;
                    250:        /*
                    251:        * As with the parser_create_dir_config() routine, we allocate and fill
                    252:        * in an empty record.
                    253:        */
                    254:        Parser_module_config *cfg=
                    255:                (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
                    256:        
                    257:        return (void *) cfg;
                    258: }
                    259: 
                    260: /*
                    261: * This function gets called to merge two per-server configuration
                    262: * records.  This is typically done to cope with things like virtual hosts and
                    263: * the default server configuration  The routine has the responsibility of
                    264: * creating a new record and merging the contents of the other two into it
                    265: * appropriately.  If the module doesn't declare a merge routine, the more
                    266: * specific existing record is used exclusively.
                    267: *
                    268: * The routine MUST NOT modify any of its arguments!
                    269: *
                    270: * The return value is a pointer to the created module-specific structure
                    271: * containing the merged values.
                    272: */
                    273: static void *parser_merge_server_config(pool *p, void *server1_conf,
                    274:                                        void *server2_conf)
                    275: {
                    276:        //_asm int 3;
                    277:        
                    278:        Parser_module_config *merged_config = 
                    279:                (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
                    280:        Parser_module_config *s1conf = (Parser_module_config *) server1_conf;
                    281:        Parser_module_config *s2conf = (Parser_module_config *) server2_conf;
                    282:        
                    283:        /*
                    284:        * Our inheritance rules are our own, and part of our module's semantics.
                    285:        * Basically, just note whence we came.
                    286:        */
                    287:        merged_config->parser_config_filespec = ap_pstrdup(p, s2conf->parser_config_filespec?
                    288:                s2conf->parser_config_filespec:s1conf->parser_config_filespec);
                    289:        merged_config->parser_status_allowed=
                    290:                s1conf->parser_status_allowed || 
                    291:                s2conf->parser_status_allowed;
                    292:        
                    293:        return (void *) merged_config;
                    294: }
                    295: 
                    296: /*
                    297: * This routine gives our module an opportunity to translate the URI into an
                    298: * actual filename.  If we don't do anything special, the server's default
                    299: * rules (Alias directives and the like) will continue to be followed.
                    300: *
                    301: * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
                    302: * further modules are called for this phase.
                    303: */
                    304: static int parser_translate_handler(request_rec *r) {
                    305:        Parser_module_config *cfg=our_dconfig(r);
                    306:        return DECLINED;
                    307: }
                    308: 
                    309: /*
                    310: * This routine is called to check the authentication information sent with
                    311: * the request (such as looking up the user in a database and verifying that
                    312: * the [encrypted] password sent matches the one in the database).
                    313: *
                    314: * The return value is OK, DECLINED, or some HTTP_mumble error (typically
                    315: * HTTP_UNAUTHORIZED).  If we return OK, no other modules are given a chance
                    316: * at the request during this phase.
                    317: */
                    318: static int parser_check_user_id(request_rec *r) {
                    319:        Parser_module_config *cfg=our_dconfig(r);
                    320:        return DECLINED;
                    321: }
                    322: 
                    323: /*
                    324: * This routine is called to check to see if the resource being requested
                    325: * requires authorisation.
                    326: *
                    327: * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
                    328: * other modules are called during this phase.
                    329: *
                    330: * If *all* modules return DECLINED, the request is aborted with a server
                    331: * error.
                    332: */
                    333: static int parser_auth_checker(request_rec *r) {
                    334:        Parser_module_config *cfg=our_dconfig(r);
                    335:        return DECLINED;
                    336: }
                    337: 
                    338: /*
                    339: * This routine is called to check for any module-specific restrictions placed
                    340: * upon the requested resource.  (See the mod_access module for an example.)
                    341: *
                    342: * The return value is OK, DECLINED, or HTTP_mumble.  All modules with an
                    343: * handler for this phase are called regardless of whether their predecessors
                    344: * return OK or DECLINED.  The first one to return any other status, however,
                    345: * will abort the sequence (and the request) as usual.
                    346: */
                    347: static int parser_access_checker(request_rec *r) {
                    348:        
                    349:        Parser_module_config *cfg=our_dconfig(r);
                    350:        return DECLINED;
                    351: }
                    352: 
                    353: /*--------------------------------------------------------------------------*/
                    354: /*                                                                          */
                    355: /* All of the routines have been declared now.  Here's the list of          */
                    356: /* directives specific to our module, and information about where they      */
                    357: /* may appear and how the command parser should pass them to us for         */
                    358: /* processing.  Note that care must be taken to ensure that there are NO    */
                    359: /* collisions of directive names between modules.                           */
                    360: /*                                                                          */
                    361: /*--------------------------------------------------------------------------*/
                    362: /* 
                    363: * List of directives specific to our module.
                    364: */
                    365: static const command_rec parser_cmds[] =
                    366: {
                    367:        {
                    368:                "ParserConfig",              /* directive name */
                    369:                        (const char* (*)(void))((void *)cmd_parser_config), // config action routine
                    370:                        (void*)0,                   /* argument to include in call */
                    371:                        (int)(OR_OPTIONS),             /* where available */
                    372:                        TAKE1,                /* arguments */
                    373:                        "Parser config filespec" // directive description
                    374:        },
                    375:        {
                    376:                "ParserStatusAllowed",              /* directive name */
                    377:                        (const char* (*)(void))((void *)cmd_parser_status_allowed), // config action routine
                    378:                        (void*)0,                   /* argument to include in call */
                    379:                        (int)(ACCESS_CONF),             /* where available */
                    380:                        NO_ARGS,                /* arguments */
                    381:                        "Parser status class can be used" // directive description
                    382:        },
                    383:        {NULL}
                    384: };
                    385: 
                    386: /*--------------------------------------------------------------------------*/
                    387: /*                                                                          */
                    388: /* Now the list of content handlers available from this module.             */
                    389: /*                                                                          */
                    390: /*--------------------------------------------------------------------------*/
                    391: /* 
                    392: * List of content handlers our module supplies.  Each handler is defined by
                    393: * two parts: a name by which it can be referenced (such as by
                    394: * {Add,Set}Handler), and the actual routine name.  The list is terminated by
                    395: * a NULL block, since it can be of variable length.
                    396: *
                    397: * Note that content-handlers are invoked on a most-specific to least-specific
                    398: * basis; that is, a handler that is declared for "text/plain" will be
                    399: * invoked before one that was declared for "text / *".  Note also that
                    400: * if a content-handler returns anything except DECLINED, no other
                    401: * content-handlers will be called.
                    402: */
                    403: static const handler_rec parser_handlers[] =
                    404: {
                    405:        {"parser3-handler", parser_handler},
                    406:        {NULL}
                    407: };
                    408: 
                    409: /*--------------------------------------------------------------------------*/
                    410: /*                                                                          */
                    411: /* Finally, the list of callback routines and data structures that          */
                    412: /* provide the hooks into our module from the other parts of the server.    */
                    413: /*                                                                          */
                    414: /*--------------------------------------------------------------------------*/
                    415: /* 
                    416: * Module definition for configuration.  If a particular callback is not
                    417: * needed, replace its routine name below with the word NULL.
                    418: *
                    419: * The number in brackets indicates the order in which the routine is called
                    420: * during request processing.  Note that not all routines are necessarily
                    421: * called (such as if a resource doesn't have access restrictions).
                    422: */
                    423: module MODULE_VAR_EXPORT parser3_module =
                    424: {
                    425:        STANDARD_MODULE_STUFF,
1.11      paf       426:        parser_module_init,          /* module initializer */
1.2       paf       427:        parser_create_dir_config,    /* per-directory config creator */
                    428:        parser_merge_dir_config,     /* dir config merger */
                    429:        parser_create_server_config, /* server config creator */
                    430:        parser_merge_server_config,  /* server config merger */
                    431:        parser_cmds,                 /* command table */
                    432:        parser_handlers,             /* [9] list of handlers */
                    433:        parser_translate_handler,    /* [2] filename-to-URI translation */
                    434:        parser_check_user_id,        /* [5] check/validate user_id */
                    435:        parser_auth_checker,         /* [6] check user_id is valid *here* */
                    436:        parser_access_checker,       /* [4] check access by host address */
                    437:        0,                           /* [7] MIME type checker/setter */
                    438:        0,                           /* [8] fixups */
                    439:        0                            /* [10] logger */
1.11      paf       440: #if MODULE_MAGIC_NUMBER >= 19970103
                    441:     ,0      /* [3] header parser */
                    442: #endif
                    443: #if MODULE_MAGIC_NUMBER >= 19970719
                    444:     ,0         /* process initializer */
                    445: #endif
                    446: #if MODULE_MAGIC_NUMBER >= 19970728
                    447:     ,parser_module_done         /* process exit/cleanup */
                    448: #endif
                    449: #if MODULE_MAGIC_NUMBER >= 19970902
                    450:     ,0   /* [1] post read_request handling */
                    451: #endif
1.2       paf       452: };
                    453: 
                    454: #if defined(_MSC_VER)
1.8       paf       455: #      define APACHE_WIN32_SRC "../../../../win32/apache13/src"
1.2       paf       456: #      ifdef _DEBUG
                    457: #              pragma comment(lib, APACHE_WIN32_SRC "/CoreD/ApacheCore.lib")
                    458: #      else
                    459: #              pragma comment(lib, APACHE_WIN32_SRC "/CoreR/ApacheCore.lib")
                    460: #      endif
                    461: #endif
                    462: 
                    463: 
                    464: // interface to C++
                    465: 
                    466: #define        PA_APLOG_EMERG  0       /* system is unusable */
                    467: #define        PA_APLOG_ALERT  1       /* action must be taken immediately */
                    468: #define        PA_APLOG_CRIT   2       /* critical conditions */
                    469: #define        PA_APLOG_ERR    3       /* error conditions */
                    470: #define        PA_APLOG_WARNING        4       /* warning conditions */
                    471: #define        PA_APLOG_NOTICE 5       /* normal but significant condition */
                    472: #define        PA_APLOG_INFO   6       /* informational */
                    473: #define        PA_APLOG_DEBUG  7       /* debug-level messages */
                    474: 
                    475: #define        PA_APLOG_LEVELMASK      7       /* mask off the level value */
                    476: 
                    477: #define PA_APLOG_NOERRNO               (PA_APLOG_LEVELMASK + 1)
                    478: 
                    479: #define PA_APLOG_MARK  __FILE__,__LINE__
                    480: 
                    481: void pa_ap_log_rerror(const char *file, int line, int level,
                    482:                      const pa_request_rec *s, const char *fmt, ...) {
                    483:        const char* str;
                    484:        va_list l;
                    485:        va_start(l, fmt); 
                    486:        str=va_arg(l, const char*);
                    487:        va_end(l); 
                    488: 
                    489:        ap_log_rerror(file, line, level,
                    490:                      (request_rec*)s->real_request_rec, "%s", str);
                    491: }
                    492: 
                    493: 
                    494: void pa_ap_log_error(const char *file, int line, int level,
                    495:                     const pa_server_rec *s, const char *fmt, ...) {
                    496:        const char* str;
                    497:        va_list l;
                    498:        va_start(l, fmt); 
                    499:        str=va_arg(l, const char*);
                    500:        va_end(l); 
                    501: 
                    502:        ap_log_error(file, line, level,
                    503:                      (server_rec*)s, "%s", str);
                    504: }
                    505: 
                    506: // ap_alloc.h
                    507: 
                    508: const char* pa_ap_table_get(const pa_table *t, const char *name) {
                    509:        return ap_table_get((const table*)t, name);
                    510: }
                    511: void pa_ap_table_addn(pa_table *t, const char *name, const char *val) {
                    512:        ap_table_addn((table*)t, name, val);
                    513: }
                    514: 
                    515: int pa_ap_table_size(const pa_table *t) {
                    516:        return ap_table_elts((const table*)t)->nelts;
                    517: }
                    518: 
                    519: void pa_ap_table_do(int (*comp) (void *, const char *, const char *), 
                    520:                    void *rec, const pa_table *t, ...) {
                    521:        ap_table_do(comp, rec, (table*)t, 0);
                    522: }
                    523: 
                    524: char * pa_ap_pstrdup(pa_pool *p, const char *s) {
                    525:        return ap_pstrdup((pool*)p, s);
                    526: }
                    527: 
                    528: // http_protocol.h
                    529: 
                    530: int pa_ap_setup_client_block(pa_request_rec *r, int read_policy) {
                    531:        return ap_setup_client_block((request_rec*)r->real_request_rec,
                    532:                read_policy);
                    533: }
                    534: int pa_ap_should_client_block(pa_request_rec *r) {
                    535:        return ap_should_client_block((request_rec*)r->real_request_rec);
                    536: }
                    537: long pa_ap_get_client_block(pa_request_rec *r, char *buffer, int bufsiz) {
                    538:        return ap_get_client_block((request_rec*)r->real_request_rec,
                    539:                buffer, bufsiz);
                    540: }
                    541: void pa_ap_send_http_header(pa_request_rec *r) {
                    542:        ap_send_http_header((request_rec*)r->real_request_rec);
                    543: }
                    544: int pa_ap_rwrite(const void *buf, int nbyte, pa_request_rec *r) {
                    545:        return ap_rwrite(buf, nbyte, (request_rec*)r->real_request_rec);
                    546: }
                    547: 
                    548: 
                    549: // http_main.h
                    550: 
                    551: void pa_ap_hard_timeout(char *s, pa_request_rec *r) {
                    552:        ap_hard_timeout(s, (request_rec*)r->real_request_rec);
                    553: }
                    554: void pa_ap_reset_timeout(pa_request_rec *r) {
                    555:        ap_reset_timeout((request_rec*)r->real_request_rec);
                    556: }
                    557: void pa_ap_kill_timeout(pa_request_rec *r) {
                    558:        ap_kill_timeout((request_rec*)r->real_request_rec);
                    559: }
                    560: 
                    561: 
                    562: // util_script.h
                    563: 
                    564: void pa_ap_add_cgi_vars(pa_request_rec *r) {
                    565:        ap_add_cgi_vars((request_rec*)r->real_request_rec);
                    566: }
                    567: void pa_ap_add_common_vars(pa_request_rec *r) {
                    568:        ap_add_common_vars((request_rec*)r->real_request_rec);
                    569: }
                    570: 
                    571: 
                    572: // ap_md5.h
                    573: 
                    574: void pa_MD5Init(PA_MD5_CTX *context) { ap_MD5Init((AP_MD5_CTX*)context); }
                    575: void pa_MD5Update(PA_MD5_CTX *context, const unsigned char *input,
                    576:                              unsigned int inputLen) { ap_MD5Update((AP_MD5_CTX *)context, input, inputLen); }
                    577: void pa_MD5Final(unsigned char digest[MD5_DIGESTSIZE],
                    578:                             PA_MD5_CTX *context) { ap_MD5Final(digest, (AP_MD5_CTX *)context); }
                    579: void pa_MD5Encode(const unsigned char *password,
                    580:                              const unsigned char *salt,
                    581:                              char *result, size_t nbytes) { ap_MD5Encode(password, salt, result, nbytes); }
                    582: void pa_to64(char *s, unsigned long v, int n) { ap_to64(s, v, n); }
                    583: 
                    584: 
                    585: // signal.h
                    586: 
                    587: void (*pa_signal (int sig, void (*disp)(int)))(int) {
                    588:        if(sig==PA_SIGPIPE && disp==PA_SIG_IGN)
                    589:                return signal(SIGPIPE, SIG_IGN);
                    590: 
                    591:        return 0;
                    592: }

E-mail: