Annotation of embedaddon/php/ext/standard/dl.c, revision 1.1.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>