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

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             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: 
        !            21: /* $Id: php_milter.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            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 '?':
        !          1043:                                php_output_startup();
        !          1044:                                php_output_activate(TSRMLS_C);
        !          1045:                                SG(headers_sent) = 1;
        !          1046:                                php_milter_usage(argv[0]);
        !          1047:                                php_end_ob_buffers(1 TSRMLS_CC);
        !          1048:                                exit(1);
        !          1049:                                break;
        !          1050:                        }
        !          1051:                }
        !          1052:                ap_php_optind = orig_optind;
        !          1053:                ap_php_optarg = orig_optarg;
        !          1054: 
        !          1055:         /* Set some CLI defaults */
        !          1056:                SG(options) |= SAPI_OPTION_NO_CHDIR;
        !          1057:                zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
        !          1058:                zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
        !          1059: 
        !          1060:                zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
        !          1061: 
        !          1062:                while ((c = ap_php_getopt(argc, argv, OPTSTRING)) != -1) {
        !          1063:                        switch (c) {
        !          1064: 
        !          1065:                        case 'a':       /* interactive mode */
        !          1066:                                printf("Interactive mode enabled\n\n");
        !          1067:                                interactive=1;
        !          1068:                                break;
        !          1069: 
        !          1070:                        case 'C': /* don't chdir to the script directory */
        !          1071:                                /* This is default so NOP */
        !          1072:                                break;
        !          1073:                        case 'd': /* define ini entries on command line */
        !          1074:                                define_command_line_ini_entry(ap_php_optarg);
        !          1075:                                break;
        !          1076: 
        !          1077:                        case 'D': /* daemon */
        !          1078:                                dofork = 1;
        !          1079:                                break;
        !          1080: 
        !          1081:                        case 'e': /* enable extended info output */
        !          1082:                                CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
        !          1083:                                break;
        !          1084: 
        !          1085:                        case 'f': /* parse file */
        !          1086:                                filename = ap_php_optarg;
        !          1087:                                break;
        !          1088: 
        !          1089:                        case 'h': /* help & quit */
        !          1090:                        case '?':
        !          1091:                                php_output_startup();
        !          1092:                                php_output_activate(TSRMLS_C);
        !          1093:                                SG(headers_sent) = 1;
        !          1094:                                php_milter_usage(argv[0]);
        !          1095:                                php_end_ob_buffers(1 TSRMLS_CC);
        !          1096:                                exit(1);
        !          1097:                                break;
        !          1098: 
        !          1099:                        case 'p': /* socket */
        !          1100:                                sock = strdup(ap_php_optarg);
        !          1101:                                break;
        !          1102: 
        !          1103:                        case 'v': /* show php version & quit */
        !          1104:                                if (php_request_startup(TSRMLS_C)==FAILURE) {
        !          1105:                                        zend_ini_deactivate(TSRMLS_C);
        !          1106:                                        php_module_shutdown(TSRMLS_C);
        !          1107:                                        sapi_shutdown();
        !          1108:                                        tsrm_shutdown();
        !          1109: 
        !          1110:                                        exit(1);
        !          1111:                                }
        !          1112:                                SG(headers_sent) = 1;
        !          1113:                                SG(request_info).no_headers = 1;
        !          1114: #if SUHOSIN_PATCH
        !          1115:                                php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
        !          1116: #else
        !          1117:                                php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
        !          1118: #endif
        !          1119:                                php_end_ob_buffers(1 TSRMLS_CC);
        !          1120:                                exit(1);
        !          1121:                                break;
        !          1122: 
        !          1123:                        case 'V': /* verbose */
        !          1124:                                flag_debug = atoi(ap_php_optarg);
        !          1125:                                break;
        !          1126: 
        !          1127:                        case 'z': /* load extension file */
        !          1128:                                zend_load_extension(ap_php_optarg);
        !          1129:                                break;
        !          1130: 
        !          1131:                        default:
        !          1132:                                break;
        !          1133:                        }
        !          1134:                }
        !          1135: 
        !          1136:                if (param_error) {
        !          1137:                        SG(headers_sent) = 1;
        !          1138:                        SG(request_info).no_headers = 1;
        !          1139:                        PUTS(param_error);
        !          1140:                        exit(1);
        !          1141:                }
        !          1142: 
        !          1143:                CG(interactive) = interactive;
        !          1144: 
        !          1145:                /* only set script_file if not set already and not in direct mode and not at end of parameter list */
        !          1146:                if (argc > ap_php_optind && !filename) {
        !          1147:                        filename=argv[ap_php_optind];
        !          1148:                        ap_php_optind++;
        !          1149:                }
        !          1150: 
        !          1151:                /* check if file exists, exit else */
        !          1152:                
        !          1153:                if (dofork) {
        !          1154:                        switch(fork()) {
        !          1155:                                case -1: /* Uh-oh, we have a problem forking. */
        !          1156:                                        fprintf(stderr, "Uh-oh, couldn't fork!\n");
        !          1157:                                        exit(errno);
        !          1158:                                        break;
        !          1159:                                case 0: /* Child */
        !          1160:                                        break;
        !          1161:                                default: /* Parent */
        !          1162:                                        exit(0);
        !          1163:                        }
        !          1164:                }
        !          1165:                        
        !          1166:                if (sock) {
        !          1167:                        struct stat junk;
        !          1168:                        if (stat(sock,&junk) == 0) unlink(sock);
        !          1169:                }
        !          1170: 
        !          1171:                openlog("php-milter", LOG_PID, LOG_MAIL);
        !          1172:                
        !          1173:                if ((exit_status = mlfi_init())) {
        !          1174:                        syslog(1, "mlfi_init failed.");
        !          1175:                        closelog();
        !          1176:                        goto err;
        !          1177:                }
        !          1178: 
        !          1179:                smfi_setconn(sock);
        !          1180:                if (smfi_register(smfilter) == MI_FAILURE) {
        !          1181:                        syslog(1, "smfi_register failed.");
        !          1182:                        fprintf(stderr, "smfi_register failed\n");
        !          1183:                        closelog();
        !          1184:                        goto err;
        !          1185:                } else {
        !          1186:                        exit_status = smfi_main();
        !          1187:                }                       
        !          1188: 
        !          1189:                closelog();
        !          1190: 
        !          1191:                if (milter_sapi_module.php_ini_path_override) {
        !          1192:                        free(milter_sapi_module.php_ini_path_override);
        !          1193:                }
        !          1194: 
        !          1195:        } zend_catch {
        !          1196:                exit_status = EG(exit_status);
        !          1197:        } zend_end_try();
        !          1198: 
        !          1199: err:
        !          1200:        php_module_shutdown(TSRMLS_C);
        !          1201:        sapi_shutdown();
        !          1202:        tsrm_shutdown();
        !          1203: 
        !          1204:        exit(exit_status);
        !          1205: }
        !          1206: /* }}} */
        !          1207: 
        !          1208: /*
        !          1209:  * Local variables:
        !          1210:  * tab-width: 4
        !          1211:  * c-basic-offset: 4
        !          1212:  * End:
        !          1213:  * vim600: sw=4 ts=4 fdm=marker
        !          1214:  * vim<600: sw=4 ts=4
        !          1215:  */

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