Annotation of embedaddon/php/ext/standard/dl.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:    | Authors: Brian Schaffner <brian@tool.net>                            |
        !            16:    |          Shane Caraveo <shane@caraveo.com>                           |
        !            17:    |          Zeev Suraski <zeev@zend.com>                                |
        !            18:    +----------------------------------------------------------------------+
        !            19: */
        !            20: 
        !            21: /* $Id: dl.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            22: 
        !            23: #include "php.h"
        !            24: #include "dl.h"
        !            25: #include "php_globals.h"
        !            26: #include "php_ini.h"
        !            27: #include "ext/standard/info.h"
        !            28: 
        !            29: #include "SAPI.h"
        !            30: 
        !            31: #if defined(HAVE_LIBDL)
        !            32: #include <stdlib.h>
        !            33: #include <stdio.h>
        !            34: #ifdef HAVE_STRING_H
        !            35: #include <string.h>
        !            36: #else
        !            37: #include <strings.h>
        !            38: #endif
        !            39: #ifdef PHP_WIN32
        !            40: #include "win32/param.h"
        !            41: #include "win32/winutil.h"
        !            42: #define GET_DL_ERROR() php_win_err()
        !            43: #elif defined(NETWARE)
        !            44: #include <sys/param.h>
        !            45: #define GET_DL_ERROR() dlerror()
        !            46: #else
        !            47: #include <sys/param.h>
        !            48: #define GET_DL_ERROR() DL_ERROR()
        !            49: #endif
        !            50: #endif /* defined(HAVE_LIBDL) */
        !            51: 
        !            52: /* {{{ proto int dl(string extension_filename)
        !            53:    Load a PHP extension at runtime */
        !            54: PHPAPI PHP_FUNCTION(dl)
        !            55: {
        !            56:        char *filename;
        !            57:        int filename_len;
        !            58: 
        !            59:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
        !            60:                return;
        !            61:        }
        !            62: 
        !            63:        if (!PG(enable_dl)) {
        !            64:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extensions aren't enabled");
        !            65:                RETURN_FALSE;
        !            66:        } else if (PG(safe_mode)) {
        !            67:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extensions aren't allowed when running in Safe Mode");
        !            68:                RETURN_FALSE;
        !            69:        }
        !            70: 
        !            71:        if (filename_len >= MAXPATHLEN) {
        !            72:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name exceeds the maximum allowed length of %d characters", MAXPATHLEN);
        !            73:                RETURN_FALSE;
        !            74:        }
        !            75: 
        !            76:        if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
        !            77:                (strcmp(sapi_module.name, "cli") != 0) &&
        !            78:                (strncmp(sapi_module.name, "embed", 5) != 0)
        !            79:        ) {
        !            80: #ifdef ZTS
        !            81:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension=%s in your php.ini", filename);
        !            82:                RETURN_FALSE;
        !            83: #else
        !            84:                php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "dl() is deprecated - use extension=%s in your php.ini", filename);
        !            85: #endif
        !            86:        }
        !            87: 
        !            88:        php_dl(filename, MODULE_TEMPORARY, return_value, 0 TSRMLS_CC);
        !            89:        if (Z_LVAL_P(return_value) == 1) {
        !            90:                EG(full_tables_cleanup) = 1;
        !            91:        }
        !            92: }
        !            93: /* }}} */
        !            94: 
        !            95: #if defined(HAVE_LIBDL)
        !            96: 
        !            97: #ifdef ZTS
        !            98: #define USING_ZTS 1
        !            99: #else
        !           100: #define USING_ZTS 0
        !           101: #endif
        !           102: 
        !           103: /* {{{ php_dl
        !           104:  */
        !           105: PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */
        !           106: {
        !           107:        void *handle;
        !           108:        char *libpath;
        !           109:        zend_module_entry *module_entry;
        !           110:        zend_module_entry *(*get_module)(void);
        !           111:        int error_type;
        !           112:        char *extension_dir;
        !           113: 
        !           114:        if (type == MODULE_PERSISTENT) {
        !           115:                extension_dir = INI_STR("extension_dir");
        !           116:        } else {
        !           117:                extension_dir = PG(extension_dir);
        !           118:        }
        !           119: 
        !           120:        if (type == MODULE_TEMPORARY) {
        !           121:                error_type = E_WARNING;
        !           122:        } else {
        !           123:                error_type = E_CORE_WARNING;
        !           124:        }
        !           125: 
        !           126:        /* Check if passed filename contains directory separators */
        !           127:        if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
        !           128:                /* Passing modules with full path is not supported for dynamically loaded extensions */
        !           129:                if (type == MODULE_TEMPORARY) {
        !           130:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
        !           131:                        return FAILURE;
        !           132:                }
        !           133:                libpath = estrdup(filename);
        !           134:        } else if (extension_dir && extension_dir[0]) {
        !           135:                int extension_dir_len = strlen(extension_dir);
        !           136: 
        !           137:                if (IS_SLASH(extension_dir[extension_dir_len-1])) {
        !           138:                        spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
        !           139:                } else {
        !           140:                        spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
        !           141:                }
        !           142:        } else {
        !           143:                return FAILURE; /* Not full path given or extension_dir is not set */
        !           144:        }
        !           145: 
        !           146:        /* load dynamic symbol */
        !           147:        handle = DL_LOAD(libpath);
        !           148:        if (!handle) {
        !           149: #if PHP_WIN32
        !           150:                char *err = GET_DL_ERROR();
        !           151:                if (err && (*err != "")) {
        !           152:                        php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, err);
        !           153:                        LocalFree(err);
        !           154:                } else {
        !           155:                        php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, "Unknown reason");
        !           156:                }
        !           157: #else
        !           158:                php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR());
        !           159:                GET_DL_ERROR(); /* free the buffer storing the error */
        !           160: #endif
        !           161:                efree(libpath);
        !           162:                return FAILURE;
        !           163:        }
        !           164:        efree(libpath);
        !           165: 
        !           166:        get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
        !           167: 
        !           168:        /* Some OS prepend _ to symbol names while their dynamic linker
        !           169:         * does not do that automatically. Thus we check manually for
        !           170:         * _get_module. */
        !           171: 
        !           172:        if (!get_module) {
        !           173:                get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
        !           174:        }
        !           175: 
        !           176:        if (!get_module) {
        !           177:                DL_UNLOAD(handle);
        !           178:                php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
        !           179:                return FAILURE;
        !           180:        }
        !           181:        module_entry = get_module();
        !           182:        if (module_entry->zend_api != ZEND_MODULE_API_NO) {
        !           183:                /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
        !           184:                        struct pre_4_1_0_module_entry {
        !           185:                                char *name;
        !           186:                                zend_function_entry *functions;
        !           187:                                int (*module_startup_func)(INIT_FUNC_ARGS);
        !           188:                                int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
        !           189:                                int (*request_startup_func)(INIT_FUNC_ARGS);
        !           190:                                int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
        !           191:                                void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
        !           192:                                int (*global_startup_func)(void);
        !           193:                                int (*global_shutdown_func)(void);
        !           194:                                int globals_id;
        !           195:                                int module_started;
        !           196:                                unsigned char type;
        !           197:                                void *handle;
        !           198:                                int module_number;
        !           199:                                unsigned char zend_debug;
        !           200:                                unsigned char zts;
        !           201:                                unsigned int zend_api;
        !           202:                        };
        !           203: 
        !           204:                        const char *name;
        !           205:                        int zend_api;
        !           206: 
        !           207:                        if ((((struct pre_4_1_0_module_entry *)module_entry)->zend_api > 20000000) &&
        !           208:                                (((struct pre_4_1_0_module_entry *)module_entry)->zend_api < 20010901)
        !           209:                        ) {
        !           210:                                name            = ((struct pre_4_1_0_module_entry *)module_entry)->name;
        !           211:                                zend_api        = ((struct pre_4_1_0_module_entry *)module_entry)->zend_api;
        !           212:                        } else {
        !           213:                                name            = module_entry->name;
        !           214:                                zend_api        = module_entry->zend_api;
        !           215:                        }
        !           216: 
        !           217:                        php_error_docref(NULL TSRMLS_CC, error_type,
        !           218:                                        "%s: Unable to initialize module\n"
        !           219:                                        "Module compiled with module API=%d\n"
        !           220:                                        "PHP    compiled with module API=%d\n"
        !           221:                                        "These options need to match\n",
        !           222:                                        name, zend_api, ZEND_MODULE_API_NO);
        !           223:                        DL_UNLOAD(handle);
        !           224:                        return FAILURE;
        !           225:        }
        !           226:        if(strcmp(module_entry->build_id, ZEND_MODULE_BUILD_ID)) {
        !           227:                php_error_docref(NULL TSRMLS_CC, error_type,
        !           228:                                "%s: Unable to initialize module\n"
        !           229:                                "Module compiled with build ID=%s\n"
        !           230:                                "PHP    compiled with build ID=%s\n"
        !           231:                                "These options need to match\n",
        !           232:                                module_entry->name, module_entry->build_id, ZEND_MODULE_BUILD_ID);
        !           233:                DL_UNLOAD(handle);
        !           234:                return FAILURE;
        !           235:        }
        !           236:        module_entry->type = type;
        !           237:        module_entry->module_number = zend_next_free_module();
        !           238:        module_entry->handle = handle;
        !           239: 
        !           240:        if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
        !           241:                DL_UNLOAD(handle);
        !           242:                return FAILURE;
        !           243:        }
        !           244: 
        !           245:        if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
        !           246:                DL_UNLOAD(handle);
        !           247:                return FAILURE;
        !           248:        }
        !           249: 
        !           250:        if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) {
        !           251:                if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) {
        !           252:                        php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name);
        !           253:                        DL_UNLOAD(handle);
        !           254:                        return FAILURE;
        !           255:                }
        !           256:        }
        !           257: 
        !           258: #if SUHOSIN_PATCH
        !           259:        if (strncmp("suhosin", module_entry->name, sizeof("suhosin")-1) == 0) {
        !           260:                void *log_func;
        !           261:                /* sucessfully loaded suhosin extension, now check for logging function replacement */
        !           262:                log_func = (void *) DL_FETCH_SYMBOL(handle, "suhosin_log");
        !           263:                if (log_func == NULL) {
        !           264:                        log_func = (void *) DL_FETCH_SYMBOL(handle, "_suhosin_log");
        !           265:                }
        !           266:                if (log_func != NULL) {
        !           267:                        zend_suhosin_log = log_func;
        !           268:                } else {
        !           269:                         zend_suhosin_log(S_MISC, "could not replace logging function");
        !           270:                }
        !           271:        }
        !           272: #endif 
        !           273: 
        !           274:        return SUCCESS;
        !           275: }
        !           276: /* }}} */
        !           277: 
        !           278: /* {{{ php_dl
        !           279:  */
        !           280: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
        !           281: {
        !           282:        /* Load extension */
        !           283:        if (php_load_extension(file, type, start_now TSRMLS_CC) == FAILURE) {
        !           284:                RETVAL_FALSE;
        !           285:        } else {
        !           286:                RETVAL_TRUE;
        !           287:        }
        !           288: }
        !           289: /* }}} */
        !           290: 
        !           291: PHP_MINFO_FUNCTION(dl)
        !           292: {
        !           293:        php_info_print_table_row(2, "Dynamic Library Support", "enabled");
        !           294: }
        !           295: 
        !           296: #else
        !           297: 
        !           298: PHPAPI void php_dl(char *file, int type, zval *return_value, int start_now TSRMLS_DC)
        !           299: {
        !           300:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", file);
        !           301:        RETURN_FALSE;
        !           302: }
        !           303: 
        !           304: PHP_MINFO_FUNCTION(dl)
        !           305: {
        !           306:        PUTS("Dynamic Library support not available<br />.\n");
        !           307: }
        !           308: 
        !           309: #endif
        !           310: 
        !           311: /*
        !           312:  * Local variables:
        !           313:  * tab-width: 4
        !           314:  * c-basic-offset: 4
        !           315:  * End:
        !           316:  * vim600: sw=4 ts=4 fdm=marker
        !           317:  * vim<600: sw=4 ts=4
        !           318:  */

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