Annotation of embedaddon/php/sapi/milter/php_milter.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 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_01.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: Harald Radi <phanto@php.net>                                 |
                     16:    |         Parts based on CGI SAPI Module by                            |
                     17:    |         Rasmus Lerdorf, Stig Bakken and Zeev Suraski                 |
                     18:    +----------------------------------------------------------------------+
                     19: */
                     20: 
1.1.1.2   misho      21: /* $Id$ */
1.1       misho      22: 
                     23: #include "php.h"
                     24: #include "php_globals.h"
                     25: #include "php_variables.h"
                     26: #include "zend_modules.h"
                     27: 
                     28: #ifndef ZTS
                     29: #error SRM sapi module is only useable in thread-safe mode
                     30: #endif
                     31: 
                     32: #include "SAPI.h"
                     33: 
                     34: #include <stdio.h>
                     35: #include "php.h"
                     36: #if HAVE_SYS_TIME_H
                     37: #include <sys/time.h>
                     38: #endif
                     39: #if HAVE_UNISTD_H
                     40: #include <unistd.h>
                     41: #endif
                     42: #if HAVE_SIGNAL_H
                     43: #include <signal.h>
                     44: #endif
                     45: #if HAVE_SETLOCALE
                     46: #include <locale.h>
                     47: #endif
                     48: #include "zend.h"
                     49: #include "zend_extensions.h"
                     50: #include "php_ini.h"
                     51: #include "php_globals.h"
                     52: #include "php_main.h"
                     53: #include "fopen_wrappers.h"
                     54: #include "ext/standard/php_standard.h"
                     55: 
                     56: #ifdef __riscos__
                     57: #include <unixlib/local.h>
                     58: #endif
                     59: 
                     60: #include "zend_compile.h"
                     61: #include "zend_execute.h"
                     62: #include "zend_highlight.h"
                     63: #include "zend_indent.h"
                     64: 
                     65: #include "libmilter/mfapi.h"
                     66: 
                     67: #include "php_getopt.h"
                     68: 
                     69: #define OPTSTRING "ac:d:Def:hnp:vVz:?"
                     70: #define MG(v)  TSRMG(milter_globals_id, zend_milter_globals *, v)
                     71: 
                     72: #define IS_NONE "%s(): This function must not be called outside of a milter callback function's scope"
                     73: #define NOT_EOM "%s(): This function can only be used inside the milter_eom callback's scope"
                     74: #define NOT_INIT "%s(): This function can only be used inside the milter_init callback's scope"
                     75: 
                     76: #define MLFI_NONE              0
                     77: #define MLFI_CONNECT   1
                     78: #define MLFI_HELO              2
                     79: #define MLFI_ENVFROM   3
                     80: #define MLFI_ENVRCPT   4
                     81: #define MLFI_HEADER            5
                     82: #define MLFI_EOH               6
                     83: #define MLFI_BODY              7
                     84: #define MLFI_EOM               8
                     85: #define MLFI_ABORT             9
                     86: #define MLFI_CLOSE             10
                     87: #define MLFI_INIT              11
                     88: 
                     89: /* {{{ globals
                     90:  */
                     91: extern char *ap_php_optarg;
                     92: extern int ap_php_optind;
                     93: 
                     94: static int flag_debug=0;
                     95: static char *filename = NULL;
                     96: 
                     97: /* per thread */
                     98: ZEND_BEGIN_MODULE_GLOBALS(milter)
                     99:        SMFICTX *ctx;
                    100:        int state;
                    101:        int initialized;
                    102: ZEND_END_MODULE_GLOBALS(milter)
                    103: 
                    104: ZEND_DECLARE_MODULE_GLOBALS(milter)
                    105: /* }}} */
                    106: 
                    107: /* this method is called only once when the milter starts */
                    108: /* {{{ Init Milter
                    109: */
                    110: static int mlfi_init()
                    111: {
                    112:        int ret = 0;
                    113:        zend_file_handle file_handle;
                    114:        zval function_name, retval;
                    115:        int status;
                    116:        TSRMLS_FETCH();
                    117: 
                    118:        /* request startup */
                    119:        if (php_request_startup(TSRMLS_C)==FAILURE) {
                    120:                SG(headers_sent) = 1;
                    121:                SG(request_info).no_headers = 1;
                    122:                php_request_shutdown((void *) 0);
                    123: 
                    124:                return -1;
                    125:        }
                    126:        
                    127:        /* disable headers */
                    128:        SG(headers_sent) = 1;
                    129:        SG(request_info).no_headers = 1;
                    130:         
                    131:        if (filename == NULL) {
                    132:                php_printf("No input file specified");
                    133:                return SMFIS_TEMPFAIL;
                    134:        }
                    135: 
                    136:        if (!(file_handle.handle.fp = VCWD_FOPEN(filename, "rb"))) {
                    137:                php_printf("Could not open input file: %s\n", filename);
                    138:                return SMFIS_TEMPFAIL;
                    139:        }
                    140: 
                    141:        file_handle.type = ZEND_HANDLE_FP;
                    142:        file_handle.filename = filename;
                    143:        file_handle.free_filename = 0;
                    144:        file_handle.opened_path = NULL;
                    145: 
                    146:        php_execute_script(&file_handle TSRMLS_CC);
                    147:        
                    148:        /* call userland */
                    149:        INIT_ZVAL(function_name);
                    150: 
                    151:        ZVAL_STRING(&function_name, "milter_init", 0);
                    152: 
                    153:        /* set the milter context for possible use in API functions */
                    154:        MG(state) = MLFI_INIT;
                    155: 
                    156:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC);
                    157: 
                    158:        MG(state) = MLFI_NONE;
                    159:        MG(initialized) = 1;
                    160: 
                    161:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    162:                ret = Z_LVAL(retval);
                    163:        }
                    164:        
                    165:        php_request_shutdown((void *) 0);
                    166:        
                    167:        return ret;
                    168: }
                    169: /* }}} */
                    170: 
                    171: /* {{{ Milter callback functions
                    172:  */
                    173: 
                    174: /* connection info filter, is called whenever sendmail connects to the milter */
                    175: /* {{{ mlfi_connect()
                    176: */
                    177: static sfsistat        mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
                    178: {
                    179:        zend_file_handle file_handle;
                    180:        zval function_name, retval, *param[1];
                    181:        int status;
                    182:        TSRMLS_FETCH();
                    183: 
                    184:        /* request startup */
                    185:        if (php_request_startup(TSRMLS_C)==FAILURE) {
                    186:                SG(headers_sent) = 1;
                    187:                SG(request_info).no_headers = 1;
                    188:                php_request_shutdown((void *) 0);
                    189: 
                    190:                return SMFIS_TEMPFAIL;
                    191:        }
                    192:        
                    193:        /* disable headers */
                    194:        SG(headers_sent) = 1;
                    195:        SG(request_info).no_headers = 1;
                    196:        
                    197:        if (filename == NULL) {
                    198:                php_printf("No input file specified");
                    199:                return SMFIS_TEMPFAIL;
                    200:        }
                    201:        
                    202:        if (!(file_handle.handle.fp = VCWD_FOPEN(filename, "rb"))) {
                    203:                php_printf("Could not open input file: %s\n", filename);
                    204:                return SMFIS_TEMPFAIL;
                    205:        }
                    206: 
                    207:        file_handle.type = ZEND_HANDLE_FP;
                    208:        file_handle.filename = filename;
                    209:        file_handle.free_filename = 0;
                    210:        file_handle.opened_path = NULL;
                    211: 
                    212:        php_execute_script(&file_handle TSRMLS_CC);
                    213:        
                    214:        /* call userland */
                    215:        INIT_ZVAL(function_name);
                    216: 
                    217:        ALLOC_ZVAL(param[0]);
                    218:        INIT_PZVAL(param[0]);
                    219: 
                    220:        ZVAL_STRING(&function_name, "milter_connect", 0);
                    221:        ZVAL_STRING(param[0], hostname, 1);
                    222: 
                    223:        /* set the milter context for possible use in API functions */
                    224:        MG(ctx) = ctx;
                    225:        MG(state) = MLFI_CONNECT;
                    226: 
                    227:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 1, param TSRMLS_CC);
                    228: 
                    229:        MG(state) = MLFI_NONE;
                    230:        zval_ptr_dtor(param);
                    231:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    232:                return Z_LVAL(retval);
                    233:        }
                    234:        
                    235:        return SMFIS_CONTINUE;
                    236: }
                    237: /* }}} */
                    238: 
                    239: /* SMTP HELO command filter */
                    240: /* {{{ mlfi_helo()
                    241: */
                    242: static sfsistat mlfi_helo(SMFICTX *ctx, char *helohost)
                    243: {
                    244:        zval function_name, retval, *param[1];
                    245:        int status;
                    246:        TSRMLS_FETCH();
                    247: 
                    248:        /* call userland */
                    249:        INIT_ZVAL(function_name);
                    250:        
                    251:        ALLOC_ZVAL(param[0]);
                    252:        INIT_PZVAL(param[0]);
                    253: 
                    254:        ZVAL_STRING(&function_name, "milter_helo", 0);
                    255:        ZVAL_STRING(param[0], helohost, 1);
                    256: 
                    257:        /* set the milter context for possible use in API functions */
                    258:        MG(ctx) = ctx;
                    259:        MG(state) = MLFI_HELO;
                    260:        
                    261:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 1, param TSRMLS_CC);
                    262: 
                    263:        MG(state) = MLFI_NONE;
                    264:        zval_ptr_dtor(param);
                    265:        
                    266:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    267:                return Z_LVAL(retval);
                    268:        }
                    269:        
                    270:        return SMFIS_CONTINUE;
                    271: }
                    272: /* }}} */
                    273: 
                    274: /* envelope sender filter */
                    275: /* {{{ mlfi_envform()
                    276: */
                    277: static sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv)
                    278: {
                    279:        zval function_name, retval, *param[1];
                    280:        int status;
                    281:        TSRMLS_FETCH();
                    282: 
                    283:        /* call userland */
                    284:        INIT_ZVAL(function_name);
                    285:        
                    286:        ALLOC_ZVAL(param[0]);
                    287:        INIT_PZVAL(param[0]);
                    288: 
                    289:        ZVAL_STRING(&function_name, "milter_envfrom", 0);
                    290:        array_init(param[0]);
                    291: 
                    292:        while (*argv) {
                    293:                add_next_index_string(param[0], *argv, 1);
                    294:                argv++;
                    295:        }
                    296: 
                    297:        /* set the milter context for possible use in API functions */
                    298:        MG(ctx) = ctx;
                    299:        MG(state) = MLFI_ENVFROM;
                    300:        
                    301:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 1, param TSRMLS_CC);
                    302: 
                    303:        MG(state) = MLFI_NONE;
                    304:        zval_ptr_dtor(param);
                    305:        
                    306:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    307:                return Z_LVAL(retval);
                    308:        }
                    309: 
                    310:        return SMFIS_CONTINUE;
                    311: }
                    312: /* }}} */
                    313: 
                    314: /* envelope recipient filter */
                    315: /* {{{ mlfi_envrcpt()
                    316: */
                    317: static sfsistat mlfi_envrcpt(SMFICTX *ctx, char **argv)
                    318: {
                    319:        zval function_name, retval, *param[1];
                    320:        int status;
                    321:        TSRMLS_FETCH();
                    322: 
                    323:        /* call userland */
                    324:        INIT_ZVAL(function_name);
                    325:        
                    326:        ALLOC_ZVAL(param[0]);
                    327:        INIT_PZVAL(param[0]);
                    328: 
                    329:        ZVAL_STRING(&function_name, "milter_envrcpt", 0);
                    330:        array_init(param[0]);
                    331: 
                    332:        while (*argv) {
                    333:                add_next_index_string(param[0], *argv, 1);
                    334:                argv++;
                    335:        }
                    336: 
                    337:        /* set the milter context for possible use in API functions */
                    338:        MG(ctx) = ctx;
                    339:        MG(state) = MLFI_ENVRCPT;
                    340:        
                    341:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 1, param TSRMLS_CC);
                    342: 
                    343:        MG(state) = MLFI_NONE;
                    344:        
                    345:        zval_ptr_dtor(param);
                    346:        
                    347:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    348:                return Z_LVAL(retval);
                    349:        }
                    350: 
                    351:        return SMFIS_CONTINUE;
                    352: }
                    353: /* }}} */
                    354: 
                    355: /* header filter */
                    356: /* {{{ mlfi_header()
                    357: */
                    358: static sfsistat mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
                    359: {
                    360:        zval function_name, retval, *param[2];
                    361:        int status;
                    362:        TSRMLS_FETCH();
                    363: 
                    364:        /* call userland */
                    365:        INIT_ZVAL(function_name);
                    366:        
                    367:        ALLOC_ZVAL(param[0]);
                    368:        ALLOC_ZVAL(param[1]);
                    369:        INIT_PZVAL(param[0]);
                    370:        INIT_PZVAL(param[1]);
                    371:        
                    372:        ZVAL_STRING(&function_name, "milter_header", 0);
                    373:        ZVAL_STRING(param[0], headerf, 1);
                    374:        ZVAL_STRING(param[1], headerv, 1);
                    375: 
                    376:        /* set the milter context for possible use in API functions */
                    377:        MG(ctx) = ctx;
                    378:        MG(state) = MLFI_HEADER;
                    379:        
                    380:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 2, param TSRMLS_CC);
                    381: 
                    382:        MG(state) = MLFI_NONE;
                    383:        
                    384:        zval_ptr_dtor(&param[0]);
                    385:        zval_ptr_dtor(&param[1]);       
                    386:        
                    387:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    388:                return Z_LVAL(retval);
                    389:        }
                    390:        
                    391:        return SMFIS_CONTINUE;
                    392: }
                    393: /* }}} */
                    394: 
                    395: /* end of header */
                    396: /* {{{ mlfi_eoh()
                    397: */
                    398: static sfsistat mlfi_eoh(SMFICTX *ctx)
                    399: {
                    400:        zval function_name, retval;
                    401:        int status;
                    402:        TSRMLS_FETCH();
                    403: 
                    404:        /* call userland */
                    405:        INIT_ZVAL(function_name);
                    406:        ZVAL_STRING(&function_name, "milter_eoh", 0);
                    407: 
                    408:        /* set the milter context for possible use in API functions */
                    409:        MG(ctx) = ctx;
                    410:        MG(state) = MLFI_EOH;
                    411:        
                    412:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC);
                    413: 
                    414:        MG(state) = MLFI_NONE;
                    415:        
                    416:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    417:                return Z_LVAL(retval);
                    418:        }
                    419: 
                    420:        return SMFIS_CONTINUE;
                    421: }
                    422: /* }}} */
                    423: 
                    424: /* body block */
                    425: /* {{{ mlfi_body()
                    426: */
                    427: static sfsistat mlfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
                    428: {
                    429:        zval function_name, retval, *param[1];
                    430:        int status;
                    431:        TSRMLS_FETCH();
                    432: 
                    433:        /* call userland */
                    434:        INIT_ZVAL(function_name);
                    435:        
                    436:        ALLOC_ZVAL(param[0]);
                    437:        INIT_PZVAL(param[0]);
                    438: 
                    439:        ZVAL_STRING(&function_name, "milter_body", 0);
                    440:        ZVAL_STRINGL(param[0], (char*)bodyp, len, 1); /*alex*/
                    441:        
                    442:        /* set the milter context for possible use in API functions */
                    443:        MG(ctx) = ctx;
                    444:        MG(state) = MLFI_BODY;
                    445:        
                    446:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 1, param TSRMLS_CC);
                    447: 
                    448:        MG(state) = MLFI_NONE;
                    449:        
                    450:        zval_ptr_dtor(param);   
                    451: 
                    452:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    453:                return Z_LVAL(retval);
                    454:        }
                    455: 
                    456:        return SMFIS_CONTINUE;
                    457: }
                    458: /* }}} */
                    459: 
                    460: /* end of message */
                    461: /* {{{ mlfi_eom()
                    462: */
                    463: static sfsistat mlfi_eom(SMFICTX *ctx)
                    464: {
                    465:        zval function_name, retval;
                    466:        int status;
                    467:        TSRMLS_FETCH();
                    468: 
                    469:        /* call userland */
                    470:        INIT_ZVAL(function_name);
                    471:        ZVAL_STRING(&function_name, "milter_eom", 0);
                    472:        
                    473:        /* set the milter context for possible use in API functions */
                    474:        MG(ctx) = ctx;
                    475:        MG(state) = MLFI_EOM;
                    476: 
                    477:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC);
                    478: 
                    479:        MG(state) = MLFI_NONE;
                    480:        
                    481:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    482:                return Z_LVAL(retval);
                    483:        }
                    484: 
                    485:        return SMFIS_CONTINUE;
                    486: }
                    487: /* }}} */
                    488: 
                    489: /* message aborted */
                    490: /* {{{ mlfi_abort()
                    491: */
                    492: static sfsistat mlfi_abort(SMFICTX *ctx)
                    493: {
                    494:        zval function_name, retval;
                    495:        int status;
                    496:        TSRMLS_FETCH();
                    497: 
                    498:        /* call userland */
                    499:        INIT_ZVAL(function_name);
                    500:        ZVAL_STRING(&function_name, "milter_abort", 0);
                    501:        
                    502:        /* set the milter context for possible use in API functions */
                    503:        MG(ctx) = ctx;
                    504:        MG(state) = MLFI_ABORT;
                    505:        
                    506:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC);
                    507: 
                    508:        MG(state) = MLFI_NONE;
                    509:        
                    510:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    511:                return Z_LVAL(retval);
                    512:        }
                    513: 
                    514:        return SMFIS_CONTINUE;
                    515: }
                    516: /* }}} */
                    517: 
                    518: /* connection cleanup */
                    519: /* {{{ mlfi_close()
                    520: */
                    521: static sfsistat mlfi_close(SMFICTX *ctx)
                    522: {
                    523:        int ret = SMFIS_CONTINUE;
                    524:        zval function_name, retval;
                    525:        int status;
                    526:        TSRMLS_FETCH();
                    527: 
                    528:        /* call userland */
                    529:        INIT_ZVAL(function_name);
                    530:        ZVAL_STRING(&function_name, "milter_close", 0);
                    531:        
                    532:        /* set the milter context for possible use in API functions */
                    533:        MG(ctx) = ctx;
                    534:        MG(state) = MLFI_CLOSE;
                    535:        
                    536:        status = call_user_function(CG(function_table), NULL, &function_name, &retval, 0, NULL TSRMLS_CC);
                    537: 
                    538:        MG(state) = MLFI_NONE;
                    539:        
                    540:        if (status == SUCCESS && Z_TYPE(retval) == IS_LONG) {
                    541:                ret = Z_LVAL(retval);
                    542:        }
                    543:        
                    544:        php_request_shutdown((void *) 0);
                    545: 
                    546:        return ret;
                    547: }
                    548: /* }}} */
                    549: /* }}} */
                    550: 
                    551: /* {{{ Milter entry struct
                    552:  */
                    553: struct smfiDesc smfilter = {
                    554:     "php-milter",      /* filter name */
                    555:     SMFI_VERSION,   /* version code -- leave untouched */
                    556:     0,                         /* flags */
                    557:     mlfi_connect,      /* info filter callback */
                    558:     mlfi_helo,         /* HELO filter callback */
                    559:     mlfi_envfrom,      /* envelope filter callback */
                    560:     mlfi_envrcpt,      /* envelope recipient filter callback */
                    561:     mlfi_header,       /* header filter callback */
                    562:     mlfi_eoh,          /* end of header callback */
                    563:     mlfi_body,         /* body filter callback */
                    564:     mlfi_eom,          /* end of message callback */
                    565:     mlfi_abort,                /* message aborted callback */
                    566:     mlfi_close,                /* connection cleanup callback */
                    567: };
                    568: /* }}} */
                    569: 
                    570: /* {{{ PHP Milter API
                    571:  */
                    572: 
                    573: /* {{{ proto void smfi_setflags(long flags)
                    574:    Sets the flags describing the actions the filter may take. */       
                    575: PHP_FUNCTION(smfi_setflags)
                    576: {
                    577:        long flags;
                    578:        
                    579:        /* valid only in the init callback */
                    580:        if (MG(state) != MLFI_INIT) {
                    581:                php_error(E_WARNING, NOT_INIT, get_active_function_name(TSRMLS_C));
                    582:        } else if (zend_parse_parameters(1 TSRMLS_CC, "l", &flags) == SUCCESS) {
                    583:                flags = flags & (SMFIF_ADDHDRS|SMFIF_CHGHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT);
                    584:                smfilter.xxfi_flags = flags;
                    585:        }       
                    586: }
                    587: /* }}} */
                    588: 
                    589: /* {{{ proto void smfi_settimeout(long timeout)
                    590:    Sets the number of seconds libmilter will wait for an MTA connection before timing out a socket. */ 
                    591: PHP_FUNCTION(smfi_settimeout)
                    592: {
                    593:        long timeout;
                    594:        
                    595:        /* valid only in the init callback */
                    596:        if (MG(state) != MLFI_INIT) {
                    597:                php_error(E_WARNING, NOT_INIT, get_active_function_name(TSRMLS_C));
                    598:        } else if (zend_parse_parameters(1 TSRMLS_CC, "l", &timeout) == SUCCESS) {
                    599:                smfi_settimeout(timeout);
                    600:        }       
                    601: }
                    602: /* }}} */
                    603: 
                    604: /* {{{ proto string smfi_getsymval(string macro)
                    605:    Returns the value of the given macro or NULL if the macro is not defined. */        
                    606: PHP_FUNCTION(smfi_getsymval)
                    607: {
                    608:        char *symname, *ret;
                    609:        int len;
                    610: 
                    611:        /* valid in any callback */
                    612:        if (MG(state) == MLFI_NONE) {
                    613:                php_error(E_WARNING, IS_NONE, get_active_function_name(TSRMLS_C));
                    614:        } else if (zend_parse_parameters(1 TSRMLS_CC, "s", &symname, &len) == SUCCESS) {
                    615:                if ((ret = smfi_getsymval(MG(ctx), symname)) != NULL) {
                    616:                        RETURN_STRING(ret, 1);
                    617:                }
                    618:        }
                    619: 
                    620:        RETURN_NULL();
                    621: }
                    622: /* }}} */
                    623: 
                    624: /* {{{ proto bool smfi_setreply(string rcode, string xcode, string message)
                    625:    Directly set the SMTP error reply code for this connection.
                    626:    This code will be used on subsequent error replies resulting from actions taken by this filter. */  
                    627: PHP_FUNCTION(smfi_setreply)
                    628: {
                    629:        char *rcode, *xcode, *message;
                    630:        int len;
                    631:        
                    632:        /* valid in any callback */
                    633:        if (MG(state) == MLFI_NONE) {
                    634:                php_error(E_WARNING, IS_NONE, get_active_function_name(TSRMLS_C));
                    635:        } else if (zend_parse_parameters(3 TSRMLS_CC, "sss", &rcode, &len, &xcode, &len, &message, &len) == SUCCESS) {
                    636:                if (smfi_setreply(MG(ctx), rcode, xcode, message) == MI_SUCCESS) {
                    637:                        RETURN_TRUE;
                    638:                }
                    639:        }
                    640:        
                    641:        RETURN_FALSE;
                    642: }
                    643: /* }}} */
                    644: 
                    645: /* {{{ proto bool smfi_addheader(string headerf, string headerv)
                    646:    Adds a header to the current message. */    
                    647: PHP_FUNCTION(smfi_addheader)
                    648: {
                    649:        char *f, *v;
                    650:        int len;
                    651:        
                    652:        /* valid only in milter_eom */
                    653:        if (MG(state) != MLFI_EOM) {
                    654:                php_error(E_WARNING, NOT_EOM, get_active_function_name(TSRMLS_C));
                    655:        } else if (zend_parse_parameters(2 TSRMLS_CC, "ss", &f, &len, &v, &len) == SUCCESS) {
                    656:                if (smfi_addheader(MG(ctx), f, v) == MI_SUCCESS) {
                    657:                        RETURN_TRUE;
                    658:                }
                    659:        }
                    660:        
                    661:        RETURN_FALSE;
                    662: }
                    663: /* }}} */
                    664: 
                    665: /* {{{ proto bool smfi_chgheader(string headerf, string headerv)
                    666:    Changes a header's value for the current message. */        
                    667: PHP_FUNCTION(smfi_chgheader)
                    668: {
                    669:        char *f, *v;
                    670:        long idx;
                    671:        int len;
                    672:        
                    673:        /* valid only in milter_eom */
                    674:        if (MG(state) != MLFI_EOM) {
                    675:                php_error(E_WARNING, NOT_EOM, get_active_function_name(TSRMLS_C));
                    676:        } else if (zend_parse_parameters(3 TSRMLS_CC, "sls", &f, &len, &idx, &v, &len) == SUCCESS) {
                    677:                if (smfi_chgheader(MG(ctx), f, idx, v) == MI_SUCCESS) {
                    678:                        RETURN_TRUE;
                    679:                }
                    680:        }
                    681:        
                    682:        RETURN_FALSE;
                    683: }
                    684: /* }}} */
                    685: 
                    686: /* {{{ proto bool smfi_addrcpt(string rcpt)
                    687:    Add a recipient to the message envelope. */ 
                    688: PHP_FUNCTION(smfi_addrcpt)
                    689: {
                    690:        char *rcpt;
                    691:        int len;
                    692:        
                    693:        /* valid only in milter_eom */
                    694:        if (MG(state) != MLFI_EOM) {
                    695:                php_error(E_WARNING, NOT_EOM, get_active_function_name(TSRMLS_C));
                    696:        } else if (zend_parse_parameters(1 TSRMLS_CC, "s", &rcpt, &len) == SUCCESS) {
                    697:                if (smfi_addrcpt(MG(ctx), rcpt) == MI_SUCCESS) {
                    698:                        RETURN_TRUE;
                    699:                }
                    700:        }
                    701:        
                    702:        RETURN_FALSE;
                    703: }
                    704: /* }}} */
                    705: 
                    706: /* {{{ proto bool smfi_delrcpt(string rcpt)
                    707:    Removes the named recipient from the current message's envelope. */ 
                    708: PHP_FUNCTION(smfi_delrcpt)
                    709: {
                    710:        char *rcpt;
                    711:        int len;
                    712:        
                    713:        /* valid only in milter_eom */
                    714:        if (MG(state) != MLFI_EOM) {
                    715:                php_error(E_WARNING, NOT_EOM, get_active_function_name(TSRMLS_C));
                    716:        } else if (zend_parse_parameters(1 TSRMLS_CC, "s", &rcpt, &len) == SUCCESS) {
                    717:                if (smfi_delrcpt(MG(ctx), rcpt) == MI_SUCCESS) {
                    718:                        RETURN_TRUE;
                    719:                }
                    720:        }
                    721:        
                    722:        RETURN_FALSE;
                    723: }
                    724: /* }}} */
                    725: 
                    726: /* {{{ proto bool smfi_replacebody(string body)
                    727:    Replaces the body of the current message. If called more than once,
                    728:    subsequent calls result in data being appended to the new body. */  
                    729: PHP_FUNCTION(smfi_replacebody)
                    730: {
                    731:        char *body;
                    732:        int len;
                    733:        
                    734:        /* valid only in milter_eom */
                    735:        if (MG(state) != MLFI_EOM) {
                    736:                php_error(E_WARNING, NOT_EOM, get_active_function_name(TSRMLS_C));
                    737:        } else if (zend_parse_parameters(1 TSRMLS_CC, "s", &body, &len) == SUCCESS) {
                    738:                if (smfi_replacebody(MG(ctx), (u_char*)body, len) == MI_SUCCESS) {
                    739:                        RETURN_TRUE;
                    740:                }
                    741:        }
                    742:        
                    743:        RETURN_FALSE;
                    744: }
                    745: /* }}} */
                    746: 
                    747: /* {{{ PHP_MINIT_FUNCTION
                    748:  */
                    749: PHP_MINIT_FUNCTION(milter)
                    750: {
                    751:        REGISTER_LONG_CONSTANT("SMFIS_CONTINUE",        SMFIS_CONTINUE, CONST_CS | CONST_PERSISTENT);
                    752:        REGISTER_LONG_CONSTANT("SMFIS_REJECT",          SMFIS_REJECT,   CONST_CS | CONST_PERSISTENT);
                    753:        REGISTER_LONG_CONSTANT("SMFIS_DISCARD",         SMFIS_DISCARD,  CONST_CS | CONST_PERSISTENT);
                    754:        REGISTER_LONG_CONSTANT("SMFIS_ACCEPT",          SMFIS_ACCEPT,   CONST_CS | CONST_PERSISTENT);
                    755:        REGISTER_LONG_CONSTANT("SMFIS_TEMPFAIL",        SMFIS_TEMPFAIL, CONST_CS | CONST_PERSISTENT);
                    756: 
                    757:        REGISTER_LONG_CONSTANT("SMFIF_ADDHDRS",         SMFIF_ADDHDRS,  CONST_CS | CONST_PERSISTENT);
                    758:        REGISTER_LONG_CONSTANT("SMFIF_CHGHDRS",         SMFIF_CHGHDRS,  CONST_CS | CONST_PERSISTENT);
                    759:        REGISTER_LONG_CONSTANT("SMFIF_CHGBODY",         SMFIF_CHGBODY,  CONST_CS | CONST_PERSISTENT);
                    760:        REGISTER_LONG_CONSTANT("SMFIF_ADDRCPT",         SMFIF_ADDRCPT,  CONST_CS | CONST_PERSISTENT);
                    761:        REGISTER_LONG_CONSTANT("SMFIF_DELRCPT",         SMFIF_DELRCPT,  CONST_CS | CONST_PERSISTENT);
                    762: 
                    763:        ZEND_INIT_MODULE_GLOBALS(milter, NULL, NULL);
                    764: 
                    765:        MG(state) = MLFI_NONE;
                    766:        MG(initialized) = 0;
                    767:        return SUCCESS;
                    768: }
                    769: /* }}} */
                    770: 
                    771: /* {{{ PHP_MINFO_FUNCTION
                    772:  */
                    773: PHP_MINFO_FUNCTION(milter)
                    774: {
                    775:        php_info_print_table_start();
                    776:        php_info_print_table_header(2, "Milter support", "enabled");
                    777:        php_info_print_table_end();
                    778: }
                    779: /* }}} */
                    780: /* }}} */
                    781: 
                    782: /* {{{ arginfo */
                    783: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_setflags, 0, 0, 1)
                    784:        ZEND_ARG_INFO(0, flags)
                    785: ZEND_END_ARG_INFO()
                    786: 
                    787: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_settimeout, 0, 0, 1)
                    788:        ZEND_ARG_INFO(0, timeout)
                    789: ZEND_END_ARG_INFO()
                    790: 
                    791: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_getsymval, 0, 0, 1)
                    792:        ZEND_ARG_INFO(0, macro)
                    793: ZEND_END_ARG_INFO()
                    794: 
                    795: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_setreply, 0, 0, 3)
                    796:        ZEND_ARG_INFO(0, rcode)
                    797:        ZEND_ARG_INFO(0, xcode)
                    798:        ZEND_ARG_INFO(0, message)
                    799: ZEND_END_ARG_INFO()
                    800: 
                    801: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_addheader, 0, 0, 2)
                    802:        ZEND_ARG_INFO(0, headerf)
                    803:        ZEND_ARG_INFO(0, headerv)
                    804: ZEND_END_ARG_INFO()
                    805: 
                    806: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_chgheader, 0, 0, 2)
                    807:        ZEND_ARG_INFO(0, headerf)
                    808:        ZEND_ARG_INFO(0, headerv)
                    809: ZEND_END_ARG_INFO()
                    810: 
                    811: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_addrcpt, 0, 0, 1)
                    812:        ZEND_ARG_INFO(0, rcpt)
                    813: ZEND_END_ARG_INFO()
                    814: 
                    815: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_delrcpt, 0, 0, 1)
                    816:        ZEND_ARG_INFO(0, rcpt)
                    817: ZEND_END_ARG_INFO()
                    818: 
                    819: ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_replacebody, 0, 0, 1)
                    820:        ZEND_ARG_INFO(0, body)
                    821: ZEND_END_ARG_INFO()
                    822: /* }}} */
                    823: 
                    824: /* {{{ milter_functions[]
                    825: */
                    826: const static zend_function_entry milter_functions[] = {
                    827:        PHP_FE(smfi_setflags,           arginfo_smfi_setflags)
                    828:        PHP_FE(smfi_settimeout,         arginfo_smfi_settimeout)
                    829:        PHP_FE(smfi_getsymval,          arginfo_smfi_getsymval)
                    830:        PHP_FE(smfi_setreply,           arginfo_smfi_setreply)
                    831:        PHP_FE(smfi_addheader,          arginfo_smfi_addheader)
                    832:        PHP_FE(smfi_chgheader,          arginfo_smfi_chgheader)
                    833:        PHP_FE(smfi_addrcpt,            arginfo_smfi_addrcpt)
                    834:        PHP_FE(smfi_delrcpt,            arginfo_smfi_delrcpt)
                    835:        PHP_FE(smfi_replacebody,        arginfo_smfi_replacebody)
                    836:        PHP_FE_END
                    837: };
                    838: /* }}} */
                    839: 
                    840: /* {{{ Zend module entry
                    841: */
                    842: static zend_module_entry php_milter_module = {
                    843:        STANDARD_MODULE_HEADER,
                    844:        "Milter",
                    845:        milter_functions,
                    846:        PHP_MINIT(milter),
                    847:        NULL,
                    848:        NULL,
                    849:        NULL,
                    850:        PHP_MINFO(milter),
                    851:        "0.1.0",
                    852:        STANDARD_MODULE_PROPERTIES
                    853: };
                    854: /* }}} */
                    855: 
                    856: /* {{{ Milter SAPI
                    857: */
                    858: static int sapi_milter_ub_write(const char *str, uint str_length TSRMLS_DC)
                    859: {
                    860:        return str_length;
                    861: }
                    862: 
                    863: static void sapi_milter_flush(void *server_context)
                    864: {
                    865: }
                    866: 
                    867: static void sapi_milter_register_variables(zval *track_vars_array TSRMLS_DC)
                    868: {
                    869:        php_register_variable ("SERVER_SOFTWARE", "Sendmail Milter", track_vars_array TSRMLS_CC);
                    870: }
                    871: 
                    872: static int sapi_milter_post_read(char *buf, uint count_bytes TSRMLS_DC)
                    873: {
                    874:        return 0;
                    875: }
                    876: 
                    877: static char* sapi_milter_read_cookies(TSRMLS_D)
                    878: {
                    879:        return NULL;
                    880: }
                    881: 
                    882: static int sapi_milter_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
                    883: {
                    884:        return SAPI_HEADER_SENT_SUCCESSFULLY;
                    885: }
                    886: 
                    887: static int php_milter_startup(sapi_module_struct *sapi_module)
                    888: {
                    889:        if (php_module_startup(sapi_module, &php_milter_module, 1) == FAILURE) {
                    890:                return FAILURE;
                    891:        }
                    892:        return SUCCESS;
                    893: }
                    894: /* }}} */
                    895: 
                    896: /* {{{ sapi_module_struct milter_sapi_module
                    897: */
                    898: static sapi_module_struct milter_sapi_module = {
                    899:        "milter",                                               /* name */
                    900:        "Sendmail Milter SAPI",                 /* pretty name */
                    901: 
                    902:        php_milter_startup,                             /* startup */
                    903:        php_module_shutdown_wrapper,    /* shutdown */
                    904: 
                    905:        NULL,                                                   /* activate */
                    906:        NULL,                                                   /* deactivate */
                    907: 
                    908:        sapi_milter_ub_write,                   /* unbuffered write */
                    909:        sapi_milter_flush,                              /* flush */
                    910:        NULL,                                                   /* get uid */
                    911:        NULL,                                                   /* getenv */
                    912: 
                    913:        php_error,                                              /* error handler */
                    914: 
                    915:        NULL,                                                   /* header handler */
                    916:        sapi_milter_send_headers,               /* send headers handler */
                    917:        NULL,                                                   /* send header handler */
                    918: 
                    919:        sapi_milter_post_read,                  /* read POST data */
                    920:        sapi_milter_read_cookies,               /* read Cookies */
                    921: 
                    922:        sapi_milter_register_variables, /* register server variables */
                    923:        NULL,                                                   /* Log message */
                    924:        NULL,                                                   /* Get request time */
                    925:        NULL,                                                   /* Child terminate */
                    926: 
                    927:        NULL,                                                   /* Block interruptions */
                    928:        NULL,                                                   /* Unblock interruptions */
                    929: 
                    930:        STANDARD_SAPI_MODULE_PROPERTIES
                    931: };
                    932: /* }}} */
                    933: 
                    934: /****
                    935: * ripped from cli, has to be cleaned up !
                    936: */
                    937: 
                    938: /* {{{ php_milter_usage
                    939: */
                    940: static void php_milter_usage(char *argv0)
                    941: {
                    942:        char *prog;
                    943: 
                    944:        prog = strrchr(argv0, '/');
                    945:        if (prog) {
                    946:                prog++;
                    947:        } else {
                    948:                prog = "php-milter";
                    949:        }
                    950: 
                    951:        printf(     "Usage: %s [options] [-f] <file> [args...]\n"
                    952:                    "       %s [options] [-- args...]\n"
                    953:                                "  -a               Run interactively\n"
                    954:                                "  -c <path>|<file> Look for php.ini file in this directory\n"
                    955:                                "  -n               No php.ini file will be used\n"
                    956:                                "  -d foo[=bar]     Define INI entry foo with value 'bar'\n"
                    957:                                "  -D               run as daemon\n"
                    958:                                "  -e               Generate extended information for debugger/profiler\n"
                    959:                                "  -f <file>        Parse <file>.\n"
                    960:                                "  -h               This help\n"
                    961:                                "  -p <socket>      path to create socket\n"
                    962:                                "  -v               Version number\n"
                    963:                                "  -V <n>           set debug level to n (1 or 2).\n"
                    964:                                "  -z <file>        Load Zend extension <file>.\n"
                    965:                                "  args...          Arguments passed to script. Use -- args when first argument \n"
                    966:                                "                   starts with - or script is read from stdin\n"
                    967:                                , prog, prog);
                    968: }
                    969: /* }}} */
                    970: 
                    971: static void define_command_line_ini_entry(char *arg) /* {{{ */
                    972: {
                    973:        char *name, *value;
                    974: 
                    975:        name = arg;
                    976:        value = strchr(arg, '=');
                    977:        if (value) {
                    978:                *value = 0;
                    979:                value++;
                    980:        } else {
                    981:                value = "1";
                    982:        }
                    983:        zend_alter_ini_entry(name, strlen(name)+1, value, strlen(value), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
                    984: }
                    985: /* }}} */
                    986: 
                    987: /* {{{ main
                    988: */
                    989: int main(int argc, char *argv[])
                    990: {
                    991:     char *sock = NULL;
                    992:        int dofork = 0;
                    993: 
                    994:        int exit_status = SUCCESS;
                    995:        int c;
                    996: /* temporary locals */
                    997:        int orig_optind=ap_php_optind;
                    998:        char *orig_optarg=ap_php_optarg;
                    999:        int interactive=0;
                   1000:        char *param_error=NULL;
                   1001: /* end of temporary locals */
                   1002: 
                   1003:        void ***tsrm_ls;
                   1004: 
                   1005: #ifdef HAVE_SIGNAL_H
                   1006: #if defined(SIGPIPE) && defined(SIG_IGN)
                   1007:        signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
                   1008:                                                                that sockets created via fsockopen()
                   1009:                                                                don't kill PHP if the remote site
                   1010:                                                                closes it.  in apache|apxs mode apache
                   1011:                                                                does that for us!  thies@thieso.net
                   1012:                                                                20000419 */
                   1013: #endif
                   1014: #endif
                   1015: 
                   1016: 
                   1017:        tsrm_startup(1, 1, 0, NULL);
                   1018:        sapi_startup(&milter_sapi_module);
                   1019:        
                   1020:        while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) {
                   1021:                switch (c) {
                   1022:                case 'c':
                   1023:                        milter_sapi_module.php_ini_path_override = strdup(ap_php_optarg);
                   1024:                        break;
                   1025:                case 'n':
                   1026:                        milter_sapi_module.php_ini_ignore = 1;
                   1027:                        break;
                   1028:                }
                   1029:        }
                   1030:        ap_php_optind = orig_optind;
                   1031:        ap_php_optarg = orig_optarg;
                   1032: 
                   1033:        milter_sapi_module.executable_location = argv[0];
                   1034: 
                   1035:        tsrm_ls = ts_resource(0);
                   1036: 
                   1037:        sapi_module.startup(&milter_sapi_module);
                   1038: 
                   1039:        zend_first_try {
                   1040:                while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) {
                   1041:                        switch (c) {
                   1042:                        case '?':
1.1.1.2   misho    1043:                                php_output_tearup();
1.1       misho    1044:                                SG(headers_sent) = 1;
                   1045:                                php_milter_usage(argv[0]);
1.1.1.2   misho    1046:                                php_output_teardown();
1.1       misho    1047:                                exit(1);
                   1048:                                break;
                   1049:                        }
                   1050:                }
                   1051:                ap_php_optind = orig_optind;
                   1052:                ap_php_optarg = orig_optarg;
                   1053: 
                   1054:         /* Set some CLI defaults */
                   1055:                SG(options) |= SAPI_OPTION_NO_CHDIR;
                   1056:                zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
                   1057:                zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
                   1058: 
                   1059:                zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
                   1060: 
                   1061:                while ((c = ap_php_getopt(argc, argv, OPTSTRING)) != -1) {
                   1062:                        switch (c) {
                   1063: 
                   1064:                        case 'a':       /* interactive mode */
                   1065:                                printf("Interactive mode enabled\n\n");
                   1066:                                interactive=1;
                   1067:                                break;
                   1068: 
                   1069:                        case 'C': /* don't chdir to the script directory */
                   1070:                                /* This is default so NOP */
                   1071:                                break;
                   1072:                        case 'd': /* define ini entries on command line */
                   1073:                                define_command_line_ini_entry(ap_php_optarg);
                   1074:                                break;
                   1075: 
                   1076:                        case 'D': /* daemon */
                   1077:                                dofork = 1;
                   1078:                                break;
                   1079: 
                   1080:                        case 'e': /* enable extended info output */
                   1081:                                CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
                   1082:                                break;
                   1083: 
                   1084:                        case 'f': /* parse file */
                   1085:                                filename = ap_php_optarg;
                   1086:                                break;
                   1087: 
                   1088:                        case 'h': /* help & quit */
                   1089:                        case '?':
1.1.1.2   misho    1090:                                php_output_tearup();
1.1       misho    1091:                                SG(headers_sent) = 1;
                   1092:                                php_milter_usage(argv[0]);
1.1.1.2   misho    1093:                                php_output_teardown();
1.1       misho    1094:                                exit(1);
                   1095:                                break;
                   1096: 
                   1097:                        case 'p': /* socket */
                   1098:                                sock = strdup(ap_php_optarg);
                   1099:                                break;
                   1100: 
                   1101:                        case 'v': /* show php version & quit */
                   1102:                                if (php_request_startup(TSRMLS_C)==FAILURE) {
                   1103:                                        zend_ini_deactivate(TSRMLS_C);
                   1104:                                        php_module_shutdown(TSRMLS_C);
                   1105:                                        sapi_shutdown();
                   1106:                                        tsrm_shutdown();
                   1107: 
                   1108:                                        exit(1);
                   1109:                                }
                   1110:                                SG(headers_sent) = 1;
                   1111:                                SG(request_info).no_headers = 1;
1.1.1.4 ! misho    1112:                                php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1.1.1.2   misho    1113:                                php_output_teardown();
1.1       misho    1114:                                exit(1);
                   1115:                                break;
                   1116: 
                   1117:                        case 'V': /* verbose */
                   1118:                                flag_debug = atoi(ap_php_optarg);
                   1119:                                break;
                   1120: 
                   1121:                        case 'z': /* load extension file */
                   1122:                                zend_load_extension(ap_php_optarg);
                   1123:                                break;
                   1124: 
                   1125:                        default:
                   1126:                                break;
                   1127:                        }
                   1128:                }
                   1129: 
                   1130:                if (param_error) {
                   1131:                        SG(headers_sent) = 1;
                   1132:                        SG(request_info).no_headers = 1;
                   1133:                        PUTS(param_error);
                   1134:                        exit(1);
                   1135:                }
                   1136: 
                   1137:                CG(interactive) = interactive;
                   1138: 
                   1139:                /* only set script_file if not set already and not in direct mode and not at end of parameter list */
                   1140:                if (argc > ap_php_optind && !filename) {
                   1141:                        filename=argv[ap_php_optind];
                   1142:                        ap_php_optind++;
                   1143:                }
                   1144: 
                   1145:                /* check if file exists, exit else */
                   1146:                
                   1147:                if (dofork) {
                   1148:                        switch(fork()) {
                   1149:                                case -1: /* Uh-oh, we have a problem forking. */
                   1150:                                        fprintf(stderr, "Uh-oh, couldn't fork!\n");
                   1151:                                        exit(errno);
                   1152:                                        break;
                   1153:                                case 0: /* Child */
                   1154:                                        break;
                   1155:                                default: /* Parent */
                   1156:                                        exit(0);
                   1157:                        }
                   1158:                }
                   1159:                        
                   1160:                if (sock) {
                   1161:                        struct stat junk;
                   1162:                        if (stat(sock,&junk) == 0) unlink(sock);
                   1163:                }
                   1164: 
                   1165:                openlog("php-milter", LOG_PID, LOG_MAIL);
                   1166:                
                   1167:                if ((exit_status = mlfi_init())) {
                   1168:                        syslog(1, "mlfi_init failed.");
                   1169:                        closelog();
                   1170:                        goto err;
                   1171:                }
                   1172: 
                   1173:                smfi_setconn(sock);
                   1174:                if (smfi_register(smfilter) == MI_FAILURE) {
                   1175:                        syslog(1, "smfi_register failed.");
                   1176:                        fprintf(stderr, "smfi_register failed\n");
                   1177:                        closelog();
                   1178:                        goto err;
                   1179:                } else {
                   1180:                        exit_status = smfi_main();
                   1181:                }                       
                   1182: 
                   1183:                closelog();
                   1184: 
                   1185:                if (milter_sapi_module.php_ini_path_override) {
                   1186:                        free(milter_sapi_module.php_ini_path_override);
                   1187:                }
                   1188: 
                   1189:        } zend_catch {
                   1190:                exit_status = EG(exit_status);
                   1191:        } zend_end_try();
                   1192: 
                   1193: err:
                   1194:        php_module_shutdown(TSRMLS_C);
                   1195:        sapi_shutdown();
                   1196:        tsrm_shutdown();
                   1197: 
                   1198:        exit(exit_status);
                   1199: }
                   1200: /* }}} */
                   1201: 
                   1202: /*
                   1203:  * Local variables:
                   1204:  * tab-width: 4
                   1205:  * c-basic-offset: 4
                   1206:  * End:
                   1207:  * vim600: sw=4 ts=4 fdm=marker
                   1208:  * vim<600: sw=4 ts=4
                   1209:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>