Annotation of embedaddon/php/ext/mysql/php_mysql.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: Zeev Suraski <zeev@zend.com>                                |
                     16:    |          Zak Greant <zak@mysql.com>                                  |
                     17:    |          Georg Richter <georg@php.net>                               |
                     18:    +----------------------------------------------------------------------+
                     19: */
                     20: 
                     21: /* $Id: php_mysql.c 321634 2012-01-01 13:15:04Z felipe $ */
                     22: 
                     23: /* TODO:
                     24:  *
                     25:  * ? Safe mode implementation
                     26:  */
                     27: 
                     28: #ifdef HAVE_CONFIG_H
                     29: # include "config.h"
                     30: #endif
                     31: 
                     32: #include "php.h"
                     33: #include "php_globals.h"
                     34: #include "ext/standard/info.h"
                     35: #include "ext/standard/php_string.h"
                     36: #include "ext/standard/basic_functions.h"
                     37: 
                     38: #ifdef ZEND_ENGINE_2
                     39: # include "zend_exceptions.h"
                     40: #else
                     41:   /* PHP 4 compat */
                     42: # define OnUpdateLong  OnUpdateInt
                     43: # define E_STRICT              E_NOTICE
                     44: #endif
                     45: 
                     46: #if HAVE_MYSQL
                     47: 
                     48: #ifdef PHP_WIN32
                     49: # include <winsock2.h>
                     50: # define signal(a, b) NULL
                     51: #elif defined(NETWARE)
                     52: # include <sys/socket.h>
                     53: # define signal(a, b) NULL
                     54: #else
                     55: # if HAVE_SIGNAL_H
                     56: #  include <signal.h>
                     57: # endif
                     58: # if HAVE_SYS_TYPES_H
                     59: #  include <sys/types.h>
                     60: # endif
                     61: # include <netdb.h>
                     62: # include <netinet/in.h>
                     63: # if HAVE_ARPA_INET_H
                     64: #  include <arpa/inet.h>
                     65: # endif
                     66: #endif
                     67: 
                     68: #include "php_ini.h"
                     69: #include "php_mysql_structs.h"
                     70: 
                     71: /* True globals, no need for thread safety */
                     72: static int le_result, le_link, le_plink;
                     73: 
                     74: #ifdef HAVE_MYSQL_REAL_CONNECT
                     75: # ifdef HAVE_ERRMSG_H
                     76: #  include <errmsg.h>
                     77: # endif
                     78: #endif
                     79: 
                     80: #define SAFE_STRING(s) ((s)?(s):"")
                     81: 
                     82: #if MYSQL_VERSION_ID > 32199 || defined(MYSQL_USE_MYSQLND)
                     83: # define mysql_row_length_type unsigned long
                     84: # define HAVE_MYSQL_ERRNO
                     85: #else
                     86: # define mysql_row_length_type unsigned int
                     87: # ifdef mysql_errno
                     88: #  define HAVE_MYSQL_ERRNO
                     89: # endif
                     90: #endif
                     91: 
                     92: #if MYSQL_VERSION_ID >= 32032 || defined(MYSQL_USE_MYSQLND)
                     93: #define HAVE_GETINFO_FUNCS
                     94: #endif
                     95: 
                     96: #if MYSQL_VERSION_ID > 32133 || defined(FIELD_TYPE_TINY)
                     97: #define MYSQL_HAS_TINY
                     98: #endif
                     99: 
                    100: #if MYSQL_VERSION_ID >= 32200
                    101: #define MYSQL_HAS_YEAR
                    102: #endif
                    103: 
                    104: #define MYSQL_ASSOC            1<<0
                    105: #define MYSQL_NUM              1<<1
                    106: #define MYSQL_BOTH             (MYSQL_ASSOC|MYSQL_NUM)
                    107: 
                    108: #define MYSQL_USE_RESULT       0
                    109: #define MYSQL_STORE_RESULT     1
                    110: 
                    111: #if MYSQL_VERSION_ID < 32224
                    112: #define PHP_MYSQL_VALID_RESULT(mysql)          \
                    113:        (mysql_num_fields(mysql)>0)
                    114: #else
                    115: #define PHP_MYSQL_VALID_RESULT(mysql)          \
                    116:        (mysql_field_count(mysql)>0)
                    117: #endif
                    118: 
                    119: ZEND_DECLARE_MODULE_GLOBALS(mysql)
                    120: static PHP_GINIT_FUNCTION(mysql);
                    121: 
                    122: typedef struct _php_mysql_conn {
                    123:        MYSQL *conn;
                    124:        int active_result_id;
                    125:        int multi_query;
                    126: } php_mysql_conn;
                    127: 
                    128: 
                    129: #if MYSQL_VERSION_ID >= 40101
                    130: #define MYSQL_DISABLE_MQ if (mysql->multi_query) { \
                    131:        mysql_set_server_option(mysql->conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
                    132:        mysql->multi_query = 0; \
                    133: }
                    134: #else
                    135: #define MYSQL_DISABLE_MQ
                    136: #endif
                    137: 
                    138: /* {{{ arginfo */
                    139: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_connect, 0, 0, 0)
                    140:        ZEND_ARG_INFO(0, hostname)
                    141:        ZEND_ARG_INFO(0, username)
                    142:        ZEND_ARG_INFO(0, password)
                    143:        ZEND_ARG_INFO(0, new)
                    144:        ZEND_ARG_INFO(0, flags)
                    145: ZEND_END_ARG_INFO()
                    146: 
                    147: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_pconnect, 0, 0, 0)
                    148:        ZEND_ARG_INFO(0, hostname)
                    149:        ZEND_ARG_INFO(0, username)
                    150:        ZEND_ARG_INFO(0, password)
                    151:        ZEND_ARG_INFO(0, flags)
                    152: ZEND_END_ARG_INFO()
                    153: 
                    154: ZEND_BEGIN_ARG_INFO_EX(arginfo__optional_mysql_link, 0, 0, 0)
                    155:        ZEND_ARG_INFO(0, link_identifier)
                    156: ZEND_END_ARG_INFO()
                    157: 
                    158: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_select_db, 0, 0, 1)
                    159:        ZEND_ARG_INFO(0, database_name)
                    160:        ZEND_ARG_INFO(0, link_identifier)
                    161: ZEND_END_ARG_INFO()
                    162: 
                    163: ZEND_BEGIN_ARG_INFO(arginfo__void_mysql_arg, 0)
                    164: ZEND_END_ARG_INFO()
                    165: 
                    166: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_set_charset, 0, 0, 1)
                    167:        ZEND_ARG_INFO(0, charset_name)
                    168:        ZEND_ARG_INFO(0, link_identifier)
                    169: ZEND_END_ARG_INFO()
                    170: 
                    171: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_query, 0, 0, 1)
                    172:        ZEND_ARG_INFO(0, query)
                    173:        ZEND_ARG_INFO(0, link_identifier)
                    174: ZEND_END_ARG_INFO()
                    175: 
                    176: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_db_query, 0, 0, 2)
                    177:        ZEND_ARG_INFO(0, database_name)
                    178:        ZEND_ARG_INFO(0, query)
                    179:        ZEND_ARG_INFO(0, link_identifier)
                    180: ZEND_END_ARG_INFO()
                    181: 
                    182: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_list_fields, 0, 0, 2)
                    183:        ZEND_ARG_INFO(0, database_name)
                    184:        ZEND_ARG_INFO(0, table_name)
                    185:        ZEND_ARG_INFO(0, link_identifier)
                    186: ZEND_END_ARG_INFO()
                    187: 
                    188: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_escape_string, 0, 0, 1)
                    189:        ZEND_ARG_INFO(0, string)
                    190: ZEND_END_ARG_INFO()
                    191: 
                    192: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_real_escape_string, 0, 0, 1)
                    193:        ZEND_ARG_INFO(0, string)
                    194:        ZEND_ARG_INFO(0, link_identifier)
                    195: ZEND_END_ARG_INFO()
                    196: 
                    197: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_result, 0, 0, 2)
                    198:        ZEND_ARG_INFO(0, result)
                    199:        ZEND_ARG_INFO(0, row)
                    200:        ZEND_ARG_INFO(0, field)
                    201: ZEND_END_ARG_INFO()
                    202: 
                    203: ZEND_BEGIN_ARG_INFO_EX(arginfo__result_mysql_arg, 0, 0, 1)
                    204:        ZEND_ARG_INFO(0, result)
                    205: ZEND_END_ARG_INFO()
                    206: 
                    207: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_object, 0, 0, 1)
                    208:        ZEND_ARG_INFO(0, result)
                    209:        ZEND_ARG_INFO(0, class_name)
                    210:        ZEND_ARG_INFO(0, ctor_params)
                    211: ZEND_END_ARG_INFO()
                    212: 
                    213: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_array, 0, 0, 1)
                    214:        ZEND_ARG_INFO(0, result)
                    215:        ZEND_ARG_INFO(0, result_type)
                    216: ZEND_END_ARG_INFO()
                    217: 
                    218: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_data_seek, 0, 0, 2)
                    219:        ZEND_ARG_INFO(0, result)
                    220:        ZEND_ARG_INFO(0, row_number)
                    221: ZEND_END_ARG_INFO()
                    222: 
                    223: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_field, 0, 0, 1)
                    224:        ZEND_ARG_INFO(0, result)
                    225:        ZEND_ARG_INFO(0, field_offset)
                    226: ZEND_END_ARG_INFO()
                    227: 
                    228: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_seek, 0, 0, 2)
                    229:        ZEND_ARG_INFO(0, result)
                    230:        ZEND_ARG_INFO(0, field_offset)
                    231: ZEND_END_ARG_INFO()
                    232: 
                    233: ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_name, 0, 0, 2)
                    234:        ZEND_ARG_INFO(0, result)
                    235:        ZEND_ARG_INFO(0, field_index)
                    236: ZEND_END_ARG_INFO()
                    237: /* }}} */
                    238: 
                    239: /* {{{ mysql_functions[]
                    240:  */
                    241: static const zend_function_entry mysql_functions[] = {
                    242:        PHP_FE(mysql_connect,                                                           arginfo_mysql_connect)
                    243:        PHP_FE(mysql_pconnect,                                                          arginfo_mysql_pconnect)
                    244:        PHP_FE(mysql_close,                                                                     arginfo__optional_mysql_link)
                    245:        PHP_FE(mysql_select_db,                                                         arginfo_mysql_select_db)
                    246: #ifndef NETWARE                /* The below two functions not supported on NetWare */
                    247: #if MYSQL_VERSION_ID < 40000
                    248:        PHP_DEP_FE(mysql_create_db,                                                     arginfo_mysql_select_db)
                    249:        PHP_DEP_FE(mysql_drop_db,                                                       arginfo_mysql_select_db)
                    250: #endif
                    251: #endif /* NETWARE */
                    252:        PHP_FE(mysql_query,                                                                     arginfo_mysql_query)
                    253:        PHP_FE(mysql_unbuffered_query,                                          arginfo_mysql_query)
                    254:        PHP_DEP_FE(mysql_db_query,                                                      arginfo_mysql_db_query)
                    255:        PHP_FE(mysql_list_dbs,                                                          arginfo__optional_mysql_link)
                    256:        PHP_DEP_FE(mysql_list_tables,                                           arginfo_mysql_select_db)
                    257:        PHP_FE(mysql_list_fields,                                                       arginfo_mysql_list_fields)
                    258:        PHP_FE(mysql_list_processes,                                            arginfo__optional_mysql_link)
                    259:        PHP_FE(mysql_error,                                                                     arginfo__optional_mysql_link)
                    260: #ifdef HAVE_MYSQL_ERRNO
                    261:        PHP_FE(mysql_errno,                                                                     arginfo__optional_mysql_link)
                    262: #endif
                    263:        PHP_FE(mysql_affected_rows,                                                     arginfo__optional_mysql_link)
                    264:        PHP_FE(mysql_insert_id,                                                         arginfo__optional_mysql_link)
                    265:        PHP_FE(mysql_result,                                                            arginfo_mysql_result)
                    266:        PHP_FE(mysql_num_rows,                                                          arginfo__result_mysql_arg)
                    267:        PHP_FE(mysql_num_fields,                                                        arginfo__result_mysql_arg)
                    268:        PHP_FE(mysql_fetch_row,                                                         arginfo__result_mysql_arg)
                    269:        PHP_FE(mysql_fetch_array,                                                       arginfo_mysql_fetch_array)
                    270:        PHP_FE(mysql_fetch_assoc,                                                       arginfo__result_mysql_arg)
                    271:        PHP_FE(mysql_fetch_object,                                                      arginfo_mysql_fetch_object)
                    272:        PHP_FE(mysql_data_seek,                                                         arginfo_mysql_data_seek)
                    273:        PHP_FE(mysql_fetch_lengths,                                                     arginfo__result_mysql_arg)
                    274:        PHP_FE(mysql_fetch_field,                                                       arginfo_mysql_fetch_field)
                    275:        PHP_FE(mysql_field_seek,                                                        arginfo_mysql_field_seek)
                    276:        PHP_FE(mysql_free_result,                                                       arginfo__result_mysql_arg)
                    277:        PHP_FE(mysql_field_name,                                                        arginfo_mysql_field_name)
                    278:        PHP_FE(mysql_field_table,                                                       arginfo_mysql_field_seek)
                    279:        PHP_FE(mysql_field_len,                                                         arginfo_mysql_field_seek)
                    280:        PHP_FE(mysql_field_type,                                                        arginfo_mysql_field_seek)
                    281:        PHP_FE(mysql_field_flags,                                                       arginfo_mysql_field_seek)
                    282:        PHP_FE(mysql_escape_string,                                                     arginfo_mysql_escape_string)
                    283:        PHP_FE(mysql_real_escape_string,                                        arginfo_mysql_real_escape_string)
                    284:        PHP_FE(mysql_stat,                                                                      arginfo__optional_mysql_link)
                    285:        PHP_FE(mysql_thread_id,                                                         arginfo__optional_mysql_link)
                    286:        PHP_FE(mysql_client_encoding,                                           arginfo__optional_mysql_link)
                    287:        PHP_FE(mysql_ping,                                                                      arginfo__optional_mysql_link)
                    288: #ifdef HAVE_GETINFO_FUNCS
                    289:        PHP_FE(mysql_get_client_info,                                           arginfo__void_mysql_arg)
                    290:        PHP_FE(mysql_get_host_info,                                                     arginfo__optional_mysql_link)
                    291:        PHP_FE(mysql_get_proto_info,                                            arginfo__optional_mysql_link)
                    292:        PHP_FE(mysql_get_server_info,                                           arginfo__optional_mysql_link)
                    293: #endif
                    294: 
                    295:        PHP_FE(mysql_info,                                                                      arginfo__optional_mysql_link)
                    296: #ifdef MYSQL_HAS_SET_CHARSET
                    297:        PHP_FE(mysql_set_charset,                                                       arginfo_mysql_set_charset)
                    298: #endif
                    299:        /* for downwards compatability */
                    300:        PHP_FALIAS(mysql,                               mysql_db_query,         arginfo_mysql_db_query)
                    301:        PHP_FALIAS(mysql_fieldname,             mysql_field_name,       arginfo_mysql_field_name)
                    302:        PHP_FALIAS(mysql_fieldtable,    mysql_field_table,      arginfo_mysql_field_seek)
                    303:        PHP_FALIAS(mysql_fieldlen,              mysql_field_len,        arginfo_mysql_field_seek)
                    304:        PHP_FALIAS(mysql_fieldtype,             mysql_field_type,       arginfo_mysql_field_seek)
                    305:        PHP_FALIAS(mysql_fieldflags,    mysql_field_flags,      arginfo_mysql_field_seek)
                    306:        PHP_FALIAS(mysql_selectdb,              mysql_select_db,        arginfo_mysql_select_db)
                    307: #ifndef NETWARE                /* The below two functions not supported on NetWare */
                    308: #if MYSQL_VERSION_ID < 40000
                    309:        PHP_DEP_FALIAS(mysql_createdb,  mysql_create_db,        arginfo_mysql_select_db)
                    310:        PHP_DEP_FALIAS(mysql_dropdb,    mysql_drop_db,          arginfo_mysql_select_db)
                    311: #endif
                    312: #endif /* NETWARE */
                    313:        PHP_FALIAS(mysql_freeresult,    mysql_free_result,      arginfo__result_mysql_arg)
                    314:        PHP_FALIAS(mysql_numfields,             mysql_num_fields,       arginfo__result_mysql_arg)
                    315:        PHP_FALIAS(mysql_numrows,               mysql_num_rows,         arginfo__result_mysql_arg)
                    316:        PHP_FALIAS(mysql_listdbs,               mysql_list_dbs,         arginfo__optional_mysql_link)
                    317:        PHP_DEP_FALIAS(mysql_listtables,mysql_list_tables,      arginfo_mysql_select_db)
                    318:        PHP_FALIAS(mysql_listfields,    mysql_list_fields,      arginfo_mysql_list_fields)
                    319:        PHP_FALIAS(mysql_db_name,               mysql_result,           arginfo_mysql_result)
                    320:        PHP_FALIAS(mysql_dbname,                mysql_result,           arginfo_mysql_result)
                    321:        PHP_FALIAS(mysql_tablename,             mysql_result,           arginfo_mysql_result)
                    322:        PHP_FALIAS(mysql_table_name,    mysql_result,           arginfo_mysql_result)
                    323:        PHP_FE_END
                    324: };
                    325: /* }}} */
                    326: 
                    327: /* Dependancies */
                    328: static const zend_module_dep mysql_deps[] = {
                    329: #if defined(MYSQL_USE_MYSQLND)
                    330:        ZEND_MOD_REQUIRED("mysqlnd")
                    331: #endif
                    332:        ZEND_MOD_END
                    333: };
                    334: 
                    335: /* {{{ mysql_module_entry
                    336:  */
                    337: zend_module_entry mysql_module_entry = {
                    338: #if ZEND_MODULE_API_NO >= 20050922
                    339:        STANDARD_MODULE_HEADER_EX, NULL,
                    340:        mysql_deps,
                    341: #elif ZEND_MODULE_API_NO >= 20010901
                    342:        STANDARD_MODULE_HEADER,
                    343: #endif
                    344:        "mysql",
                    345:        mysql_functions,
                    346:        ZEND_MODULE_STARTUP_N(mysql),
                    347:        PHP_MSHUTDOWN(mysql),
                    348:        PHP_RINIT(mysql),
                    349:        PHP_RSHUTDOWN(mysql),
                    350:        PHP_MINFO(mysql),
                    351:        "1.0",
                    352:        PHP_MODULE_GLOBALS(mysql),
                    353:        PHP_GINIT(mysql),
                    354:        NULL,
                    355:        NULL,
                    356:        STANDARD_MODULE_PROPERTIES_EX
                    357: };
                    358: /* }}} */
                    359: 
                    360: #ifdef COMPILE_DL_MYSQL
                    361: ZEND_GET_MODULE(mysql)
                    362: #endif
                    363: 
                    364: void timeout(int sig);
                    365: 
                    366: #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
                    367: 
                    368: #if defined(MYSQL_USE_MYSQLND)
                    369: #define PHPMY_UNBUFFERED_QUERY_CHECK() \
                    370: {\
                    371:        if (mysql->active_result_id) { \
                    372:                do {                                    \
                    373:                        int type;                       \
                    374:                        MYSQL_RES *_mysql_result;       \
                    375:                                                        \
                    376:                        _mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type);   \
                    377:                        if (_mysql_result && type==le_result) {                                         \
                    378:                                if (mysql_result_is_unbuffered(_mysql_result) && !mysql_eof(_mysql_result)) { \
                    379:                                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
                    380:                                }                                               \
                    381:                                zend_list_delete(mysql->active_result_id);      \
                    382:                                mysql->active_result_id = 0;                    \
                    383:                        } \
                    384:                } while(0); \
                    385:        }\
                    386: }
                    387: #else
                    388: #define PHPMY_UNBUFFERED_QUERY_CHECK()                 \
                    389: {                                                      \
                    390:        if (mysql->active_result_id) {                  \
                    391:                do {                                    \
                    392:                        int type;                       \
                    393:                        MYSQL_RES *mysql_result;        \
                    394:                                                        \
                    395:                        mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type);    \
                    396:                        if (mysql_result && type==le_result) {                                          \
                    397:                                if (!mysql_eof(mysql_result)) {                                         \
                    398:                                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
                    399:                                        while (mysql_fetch_row(mysql_result));  \
                    400:                                }                                               \
                    401:                                zend_list_delete(mysql->active_result_id);      \
                    402:                                mysql->active_result_id = 0;                    \
                    403:                        }                                                       \
                    404:                } while(0);                                                     \
                    405:        }                                                                       \
                    406: }
                    407: #endif
                    408: 
                    409: /* {{{ _free_mysql_result
                    410:  * This wrapper is required since mysql_free_result() returns an integer, and
                    411:  * thus, cannot be used directly
                    412:  */
                    413: static void _free_mysql_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
                    414: {
                    415:        MYSQL_RES *mysql_result = (MYSQL_RES *)rsrc->ptr;
                    416: 
                    417:        mysql_free_result(mysql_result);
                    418:        MySG(result_allocated)--;
                    419: }
                    420: /* }}} */
                    421: 
                    422: /* {{{ php_mysql_set_default_link
                    423:  */
                    424: static void php_mysql_set_default_link(int id TSRMLS_DC)
                    425: {
                    426:        if (MySG(default_link) != -1) {
                    427:                zend_list_delete(MySG(default_link));
                    428:        }
                    429:        MySG(default_link) = id;
                    430:        zend_list_addref(id);
                    431: }
                    432: /* }}} */
                    433: 
                    434: /* {{{ php_mysql_select_db
                    435: */
                    436: static int php_mysql_select_db(php_mysql_conn *mysql, char *db TSRMLS_DC)
                    437: {
                    438:        PHPMY_UNBUFFERED_QUERY_CHECK();
                    439: 
                    440:        if (mysql_select_db(mysql->conn, db) != 0) {
                    441:                return 0;
                    442:        } else {
                    443:                return 1;
                    444:        }
                    445: }
                    446: /* }}} */
                    447: 
                    448: /* {{{ _close_mysql_link
                    449:  */
                    450: static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
                    451: {
                    452:        php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
                    453:        void (*handler) (int);
                    454: 
                    455:        handler = signal(SIGPIPE, SIG_IGN);
                    456:        mysql_close(link->conn);
                    457:        signal(SIGPIPE, handler);
                    458:        efree(link);
                    459:        MySG(num_links)--;
                    460: }
                    461: /* }}} */
                    462: 
                    463: /* {{{ _close_mysql_plink
                    464:  */
                    465: static void _close_mysql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
                    466: {
                    467:        php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
                    468:        void (*handler) (int);
                    469: 
                    470:        handler = signal(SIGPIPE, SIG_IGN);
                    471:        mysql_close(link->conn);
                    472:        signal(SIGPIPE, handler);
                    473: 
                    474:        free(link);
                    475:        MySG(num_persistent)--;
                    476:        MySG(num_links)--;
                    477: }
                    478: /* }}} */
                    479: 
                    480: /* {{{ PHP_INI_MH
                    481:  */
                    482: static PHP_INI_MH(OnMySQLPort)
                    483: {
                    484:        if (new_value != NULL) { /* default port */
                    485:                MySG(default_port) = atoi(new_value);
                    486:        } else {
                    487:                MySG(default_port) = -1;
                    488:        }
                    489: 
                    490:        return SUCCESS;
                    491: }
                    492: /* }}} */
                    493: 
                    494: /* {{{ PHP_INI */
                    495: PHP_INI_BEGIN()
                    496:        STD_PHP_INI_BOOLEAN("mysql.allow_persistent",   "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_persistent,       zend_mysql_globals,             mysql_globals)
                    497:        STD_PHP_INI_ENTRY_EX("mysql.max_persistent",    "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_persistent,         zend_mysql_globals,             mysql_globals,  display_link_numbers)
                    498:        STD_PHP_INI_ENTRY_EX("mysql.max_links",                 "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_links,                      zend_mysql_globals,             mysql_globals,  display_link_numbers)
                    499:        STD_PHP_INI_ENTRY("mysql.default_host",                 NULL,   PHP_INI_ALL,            OnUpdateString,         default_host,           zend_mysql_globals,             mysql_globals)
                    500:        STD_PHP_INI_ENTRY("mysql.default_user",                 NULL,   PHP_INI_ALL,            OnUpdateString,         default_user,           zend_mysql_globals,             mysql_globals)
                    501:        STD_PHP_INI_ENTRY("mysql.default_password",             NULL,   PHP_INI_ALL,            OnUpdateString,         default_password,       zend_mysql_globals,             mysql_globals)
                    502:        PHP_INI_ENTRY("mysql.default_port",                             NULL,   PHP_INI_ALL,            OnMySQLPort)
                    503: #ifdef MYSQL_UNIX_ADDR
                    504:        STD_PHP_INI_ENTRY("mysql.default_socket",               MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty,      default_socket, zend_mysql_globals,             mysql_globals)
                    505: #else
                    506:        STD_PHP_INI_ENTRY("mysql.default_socket",               NULL,   PHP_INI_ALL,            OnUpdateStringUnempty,  default_socket, zend_mysql_globals,             mysql_globals)
                    507: #endif
                    508:        STD_PHP_INI_ENTRY("mysql.connect_timeout",              "60",   PHP_INI_ALL,            OnUpdateLong,           connect_timeout,        zend_mysql_globals,             mysql_globals)
                    509:        STD_PHP_INI_BOOLEAN("mysql.trace_mode",                 "0",    PHP_INI_ALL,            OnUpdateLong,           trace_mode,             zend_mysql_globals,             mysql_globals)
                    510:        STD_PHP_INI_BOOLEAN("mysql.allow_local_infile", "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_local_infile, zend_mysql_globals,         mysql_globals)
                    511: PHP_INI_END()
                    512: /* }}} */
                    513: 
                    514: /* {{{ PHP_GINIT_FUNCTION
                    515:  */
                    516: static PHP_GINIT_FUNCTION(mysql)
                    517: {
                    518:        mysql_globals->num_persistent = 0;
                    519:        mysql_globals->default_socket = NULL;
                    520:        mysql_globals->default_host = NULL;
                    521:        mysql_globals->default_user = NULL;
                    522:        mysql_globals->default_password = NULL;
                    523:        mysql_globals->connect_errno = 0;
                    524:        mysql_globals->connect_error = NULL;
                    525:        mysql_globals->connect_timeout = 0;
                    526:        mysql_globals->trace_mode = 0;
                    527:        mysql_globals->allow_local_infile = 1;
                    528:        mysql_globals->result_allocated = 0;
                    529: }
                    530: /* }}} */
                    531: 
                    532: /* {{{ PHP_MINIT_FUNCTION
                    533:  */
                    534: ZEND_MODULE_STARTUP_D(mysql)
                    535: {
                    536:        REGISTER_INI_ENTRIES();
                    537:        le_result = zend_register_list_destructors_ex(_free_mysql_result, NULL, "mysql result", module_number);
                    538:        le_link = zend_register_list_destructors_ex(_close_mysql_link, NULL, "mysql link", module_number);
                    539:        le_plink = zend_register_list_destructors_ex(NULL, _close_mysql_plink, "mysql link persistent", module_number);
                    540:        Z_TYPE(mysql_module_entry) = type;
                    541: 
                    542:        REGISTER_LONG_CONSTANT("MYSQL_ASSOC", MYSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
                    543:        REGISTER_LONG_CONSTANT("MYSQL_NUM", MYSQL_NUM, CONST_CS | CONST_PERSISTENT);
                    544:        REGISTER_LONG_CONSTANT("MYSQL_BOTH", MYSQL_BOTH, CONST_CS | CONST_PERSISTENT);
                    545:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
                    546: #if MYSQL_VERSION_ID >= 40000
                    547:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
                    548: #endif
                    549:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
                    550:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
                    551: 
                    552: #ifndef MYSQL_USE_MYSQLND
                    553: #if MYSQL_VERSION_ID >= 40000
                    554:        if (mysql_server_init(0, NULL, NULL)) {
                    555:                return FAILURE;
                    556:        }
                    557: #endif
                    558: #endif
                    559: 
                    560:        return SUCCESS;
                    561: }
                    562: /* }}} */
                    563: 
                    564: /* {{{ PHP_MSHUTDOWN_FUNCTION
                    565:  */
                    566: PHP_MSHUTDOWN_FUNCTION(mysql)
                    567: {
                    568: #ifndef MYSQL_USE_MYSQLND
                    569: #if MYSQL_VERSION_ID >= 40000
                    570: #ifdef PHP_WIN32
                    571:        unsigned long client_ver = mysql_get_client_version();
                    572:        /*
                    573:          Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
                    574:          PHP bug#41350 MySQL bug#25621
                    575:        */
                    576:        if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
                    577:                mysql_server_end();
                    578:        }
                    579: #else
                    580:        mysql_server_end();
                    581: #endif
                    582: #endif
                    583: #endif
                    584: 
                    585:        UNREGISTER_INI_ENTRIES();
                    586:        return SUCCESS;
                    587: }
                    588: /* }}} */
                    589: 
                    590: /* {{{ PHP_RINIT_FUNCTION
                    591:  */
                    592: PHP_RINIT_FUNCTION(mysql)
                    593: {
                    594: #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    595:        if (mysql_thread_init()) {
                    596:                return FAILURE;
                    597:        }
                    598: #endif
                    599:        MySG(default_link)=-1;
                    600:        MySG(num_links) = MySG(num_persistent);
                    601:        /* Reset connect error/errno on every request */
                    602:        MySG(connect_error) = NULL;
                    603:        MySG(connect_errno) =0;
                    604:        MySG(result_allocated) = 0;
                    605: 
                    606:        return SUCCESS;
                    607: }
                    608: /* }}} */
                    609: 
                    610: 
                    611: #if defined(A0) && defined(MYSQL_USE_MYSQLND)
                    612: static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
                    613: {
                    614:        if (le->type == le_plink) {
                    615:                mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn);
                    616:        }
                    617:        return ZEND_HASH_APPLY_KEEP;
                    618: } /* }}} */
                    619: #endif
                    620: 
                    621: 
                    622: /* {{{ PHP_RSHUTDOWN_FUNCTION
                    623:  */
                    624: PHP_RSHUTDOWN_FUNCTION(mysql)
                    625: {
                    626: #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    627:        mysql_thread_end();
                    628: #endif
                    629: 
                    630:        if (MySG(trace_mode)) {
                    631:                if (MySG(result_allocated)){
                    632:                        php_error_docref("function.mysql-free-result" TSRMLS_CC, E_WARNING, "%lu result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query()", MySG(result_allocated));
                    633:                }
                    634:        }
                    635: 
                    636:        if (MySG(connect_error)!=NULL) {
                    637:                efree(MySG(connect_error));
                    638:        }
                    639: 
                    640: #if defined(A0) && defined(MYSQL_USE_MYSQLND)
                    641:        zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC);
                    642: #endif
                    643: 
                    644:        return SUCCESS;
                    645: }
                    646: /* }}} */
                    647: 
                    648: /* {{{ PHP_MINFO_FUNCTION
                    649:  */
                    650: PHP_MINFO_FUNCTION(mysql)
                    651: {
                    652:        char buf[32];
                    653: 
                    654:        php_info_print_table_start();
                    655:        php_info_print_table_header(2, "MySQL Support", "enabled");
                    656:        snprintf(buf, sizeof(buf), "%ld", MySG(num_persistent));
                    657:        php_info_print_table_row(2, "Active Persistent Links", buf);
                    658:        snprintf(buf, sizeof(buf), "%ld", MySG(num_links));
                    659:        php_info_print_table_row(2, "Active Links", buf);
                    660:        php_info_print_table_row(2, "Client API version", mysql_get_client_info());
                    661: #if !defined (PHP_WIN32) && !defined (NETWARE) && !defined(MYSQL_USE_MYSQLND)
                    662:        php_info_print_table_row(2, "MYSQL_MODULE_TYPE", PHP_MYSQL_TYPE);
                    663:        php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR);
                    664:        php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE);
                    665:        php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS);
                    666: #endif
                    667: 
                    668:        php_info_print_table_end();
                    669: 
                    670:        DISPLAY_INI_ENTRIES();
                    671: 
                    672: }
                    673: /* }}} */
                    674: 
                    675: /* {{{ php_mysql_do_connect
                    676:  */
                    677: #define MYSQL_DO_CONNECT_CLEANUP()     \
                    678:        if (free_host) {                                \
                    679:                efree(host);                            \
                    680:        }
                    681: 
                    682: #define MYSQL_DO_CONNECT_RETURN_FALSE()                \
                    683:        MYSQL_DO_CONNECT_CLEANUP();                             \
                    684:        RETURN_FALSE;
                    685: 
                    686: #ifdef MYSQL_USE_MYSQLND
                    687: #define MYSQL_PORT 0
                    688: #endif
                    689: 
                    690: static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                    691: {
                    692:        char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL;
                    693:        int  user_len, passwd_len, host_len;
                    694:        char *hashed_details=NULL;
                    695:        int hashed_details_length, port = MYSQL_PORT;
                    696:        long client_flags = 0;
                    697:        php_mysql_conn *mysql=NULL;
                    698: #if MYSQL_VERSION_ID <= 32230
                    699:        void (*handler) (int);
                    700: #endif
                    701:        zend_bool free_host=0, new_link=0;
                    702:        long connect_timeout;
                    703: 
                    704: #if !defined(MYSQL_USE_MYSQLND)
                    705:        if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
                    706:                php_error_docref(NULL TSRMLS_CC, E_WARNING,
                    707:                                                "Headers and client library minor version mismatch. Headers:%d Library:%ld",
                    708:                                                MYSQL_VERSION_ID, mysql_get_client_version());
                    709:        }
                    710: #endif
                    711: 
                    712:        connect_timeout = MySG(connect_timeout);
                    713: 
                    714:        socket = MySG(default_socket);
                    715: 
                    716:        if (MySG(default_port) < 0) {
                    717: #if !defined(PHP_WIN32) && !defined(NETWARE)
                    718:                struct servent *serv_ptr;
                    719:                char *env;
                    720: 
                    721:                MySG(default_port) = MYSQL_PORT;
                    722:                if ((serv_ptr = getservbyname("mysql", "tcp"))) {
                    723:                        MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
                    724:                }
                    725:                if ((env = getenv("MYSQL_TCP_PORT"))) {
                    726:                        MySG(default_port) = (uint) atoi(env);
                    727:                }
                    728: #else
                    729:                MySG(default_port) = MYSQL_PORT;
                    730: #endif
                    731:        }
                    732: 
                    733:        if (PG(sql_safe_mode)) {
                    734:                if (ZEND_NUM_ARGS()>0) {
                    735:                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
                    736:                }
                    737:                host_and_port=passwd=NULL;
                    738:                user=php_get_current_user();
                    739:                hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user);
                    740:                client_flags = CLIENT_INTERACTIVE;
                    741:        } else {
                    742:                /* mysql_pconnect does not support new_link parameter */
                    743:                if (persistent) {
                    744:                        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len,
                    745:                                                                        &user, &user_len, &passwd, &passwd_len,
                    746:                                                                        &client_flags)==FAILURE) {
                    747:                                return;
                    748:                }
                    749:                } else {
                    750:                        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len,
                    751:                                                                                &user, &user_len, &passwd, &passwd_len,
                    752:                                                                                &new_link, &client_flags)==FAILURE) {
                    753:                                return;
                    754:                        }
                    755:                }
                    756: 
                    757:                if (!host_and_port) {
                    758:                        host_and_port = MySG(default_host);
                    759:                }
                    760:                if (!user) {
                    761:                        user = MySG(default_user);
                    762:                }
                    763:                if (!passwd) {
                    764:                        passwd = MySG(default_password);
                    765:                        passwd_len = passwd? strlen(passwd):0;
                    766:                }
                    767: 
                    768:                /* disable local infile option for open_basedir */
                    769: #if PHP_API_VERSION < 20100412
                    770:                if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
                    771: #else
                    772:                if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) {
                    773: #endif
                    774:                        client_flags ^= CLIENT_LOCAL_FILES;
                    775:                }
                    776: 
                    777: #ifdef CLIENT_MULTI_RESULTS
                    778:                client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
                    779: #endif
                    780: #ifdef CLIENT_MULTI_STATEMENTS
                    781:                client_flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
                    782: #endif
                    783:                hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags);
                    784:        }
                    785: 
                    786:        /* We cannot use mysql_port anymore in windows, need to use
                    787:         * mysql_real_connect() to set the port.
                    788:         */
                    789:        if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
                    790:                host = estrndup(host_and_port, tmp-host_and_port);
                    791:                free_host = 1;
                    792:                tmp++;
                    793:                if (tmp[0] != '/') {
                    794:                        port = atoi(tmp);
                    795:                        if ((tmp=strchr(tmp, ':'))) {
                    796:                                tmp++;
                    797:                                socket=tmp;
                    798:                        }
                    799:                } else {
                    800:                        socket = tmp;
                    801:                }
                    802:        } else {
                    803:                host = host_and_port;
                    804:                port = MySG(default_port);
                    805:        }
                    806: 
                    807: #if MYSQL_VERSION_ID < 32200
                    808:        mysql_port = port;
                    809: #endif
                    810: 
                    811:        if (!MySG(allow_persistent)) {
                    812:                persistent=0;
                    813:        }
                    814:        if (persistent) {
                    815:                zend_rsrc_list_entry *le;
                    816: 
                    817:                /* try to find if we already have this link in our persistent list */
                    818:                if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
                    819:                        zend_rsrc_list_entry new_le;
                    820: 
                    821:                        if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
                    822:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
                    823:                                efree(hashed_details);
                    824:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    825:                        }
                    826:                        if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) {
                    827:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
                    828:                                efree(hashed_details);
                    829:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    830:                        }
                    831:                        /* create the link */
                    832:                        mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
                    833:                        if (!mysql) {
                    834:                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link");
                    835:                        }
                    836:                        mysql->active_result_id = 0;
                    837: #ifdef CLIENT_MULTI_STATEMENTS
                    838:                        mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
                    839: #else
                    840:                        mysql->multi_query = 0;
                    841: #endif
                    842: 
                    843: #ifndef MYSQL_USE_MYSQLND
                    844:                        mysql->conn = mysql_init(NULL);
                    845: #else
                    846:                        mysql->conn = mysql_init(persistent);
                    847: #endif
                    848: 
                    849:                        if (connect_timeout != -1) {
                    850:                                mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
                    851:                        }
                    852: #ifndef MYSQL_USE_MYSQLND
                    853:                        if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                    854: #else
                    855:                        if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                    856: #endif
                    857:                        {
                    858:                                /* Populate connect error globals so that the error functions can read them */
                    859:                                if (MySG(connect_error) != NULL) {
                    860:                                        efree(MySG(connect_error));
                    861:                                }
                    862:                                MySG(connect_error) = estrdup(mysql_error(mysql->conn));
                    863:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
                    864: #if defined(HAVE_MYSQL_ERRNO)
                    865:                                MySG(connect_errno) = mysql_errno(mysql->conn);
                    866: #endif
                    867:                                free(mysql);
                    868:                                efree(hashed_details);
                    869:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    870:                        }
                    871:                        mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                    872: 
                    873:                        /* hash it up */
                    874:                        Z_TYPE(new_le) = le_plink;
                    875:                        new_le.ptr = mysql;
                    876:                        if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
                    877:                                free(mysql);
                    878:                                efree(hashed_details);
                    879:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    880:                        }
                    881:                        MySG(num_persistent)++;
                    882:                        MySG(num_links)++;
                    883:                } else {  /* The link is in our list of persistent connections */
                    884:                        if (Z_TYPE_P(le) != le_plink) {
                    885:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    886:                        }
                    887:                        mysql = (php_mysql_conn *) le->ptr;
                    888:                        mysql->active_result_id = 0;
                    889: #ifdef CLIENT_MULTI_STATEMENTS
                    890:                        mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
                    891: #else
                    892:                        mysql->multi_query = 0;
                    893: #endif
                    894:                        /* ensure that the link did not die */
                    895: #if defined(A0) && MYSQL_USE_MYSQLND
                    896:                        mysqlnd_end_psession(mysql->conn);
                    897: #endif
                    898:                        if (mysql_ping(mysql->conn)) {
                    899:                                if (mysql_errno(mysql->conn) == 2006) {
                    900: #ifndef MYSQL_USE_MYSQLND
                    901:                                        if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                    902: #else
                    903:                                        if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                    904: #endif
                    905:                                        {
                    906:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
                    907:                                                zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
                    908:                                                efree(hashed_details);
                    909:                                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    910:                                        }
                    911:                                        mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                    912:                                }
                    913:                        } else {
                    914: #ifdef MYSQL_USE_MYSQLND
                    915:                                mysqlnd_restart_psession(mysql->conn);
                    916: #endif
                    917:                        }
                    918:                }
                    919:                ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
                    920:        } else { /* non persistent */
                    921:                zend_rsrc_list_entry *index_ptr, new_index_ptr;
                    922: 
                    923:                /* first we check the hash for the hashed_details key.  if it exists,
                    924:                 * it should point us to the right offset where the actual mysql link sits.
                    925:                 * if it doesn't, open a new mysql link, add it to the resource list,
                    926:                 * and add a pointer to it with hashed_details as the key.
                    927:                 */
                    928:                if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
                    929:                        int type;
                    930:                        long link;
                    931:                        void *ptr;
                    932: 
                    933:                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {
                    934:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    935:                        }
                    936:                        link = (long) index_ptr->ptr;
                    937:                        ptr = zend_list_find(link,&type);   /* check if the link is still there */
                    938:                        if (ptr && (type==le_link || type==le_plink)) {
                    939:                                zend_list_addref(link);
                    940:                                Z_LVAL_P(return_value) = link;
                    941:                                php_mysql_set_default_link(link TSRMLS_CC);
                    942:                                Z_TYPE_P(return_value) = IS_RESOURCE;
                    943:                                efree(hashed_details);
                    944:                                MYSQL_DO_CONNECT_CLEANUP();
                    945:                                return;
                    946:                        } else {
                    947:                                zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
                    948:                        }
                    949:                }
                    950:                if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
                    951:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
                    952:                        efree(hashed_details);
                    953:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                    954:                }
                    955: 
                    956:                mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
                    957:                mysql->active_result_id = 0;
                    958: #ifdef CLIENT_MULTI_STATEMENTS
                    959:                mysql->multi_query = 1;
                    960: #endif
                    961: 
                    962: #ifndef MYSQL_USE_MYSQLND
                    963:                mysql->conn = mysql_init(NULL);
                    964: #else
                    965:                mysql->conn = mysql_init(persistent);
                    966: #endif
                    967:                if (!mysql->conn) {
                    968:                        MySG(connect_error) = estrdup("OOM");
                    969:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM");
                    970:                        efree(hashed_details);
                    971:                        efree(mysql);
                    972:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                    973:                }
                    974: 
                    975:                if (connect_timeout != -1) {
                    976:                        mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
                    977:                }
                    978: 
                    979: #ifndef MYSQL_USE_MYSQLND
                    980:                if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                    981: #else
                    982:                if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                    983: #endif
                    984:                {
                    985:                        /* Populate connect error globals so that the error functions can read them */
                    986:                        if (MySG(connect_error) != NULL) {
                    987:                                efree(MySG(connect_error));
                    988:                        }
                    989:                        MySG(connect_error) = estrdup(mysql_error(mysql->conn));
                    990:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
                    991: #if defined(HAVE_MYSQL_ERRNO)
                    992:                        MySG(connect_errno) = mysql_errno(mysql->conn);
                    993: #endif
                    994:                        /* free mysql structure */
                    995: #ifdef MYSQL_USE_MYSQLND
                    996:                        mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED);
                    997: #endif
                    998:                        efree(hashed_details);
                    999:                        efree(mysql);
                   1000:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                   1001:                }
                   1002:                mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                   1003: 
                   1004:                /* add it to the list */
                   1005:                ZEND_REGISTER_RESOURCE(return_value, mysql, le_link);
                   1006: 
                   1007:                /* add it to the hash */
                   1008:                new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
                   1009:                Z_TYPE(new_index_ptr) = le_index_ptr;
                   1010:                if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
                   1011:                        efree(hashed_details);
                   1012:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                   1013:                }
                   1014:                MySG(num_links)++;
                   1015:        }
                   1016: 
                   1017:        efree(hashed_details);
                   1018:        php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
                   1019:        MYSQL_DO_CONNECT_CLEANUP();
                   1020: }
                   1021: /* }}} */
                   1022: 
                   1023: /* {{{ php_mysql_get_default_link
                   1024:  */
                   1025: static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
                   1026: {
                   1027:        if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */
                   1028:                ht = 0;
                   1029:                php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1030:        }
                   1031:        return MySG(default_link);
                   1032: }
                   1033: /* }}} */
                   1034: 
                   1035: /* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])
                   1036:    Opens a connection to a MySQL Server */
                   1037: PHP_FUNCTION(mysql_connect)
                   1038: {
                   1039:        php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1040: }
                   1041: /* }}} */
                   1042: 
                   1043: /* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])
                   1044:    Opens a persistent connection to a MySQL Server */
                   1045: PHP_FUNCTION(mysql_pconnect)
                   1046: {
                   1047:        php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   1048: }
                   1049: /* }}} */
                   1050: 
                   1051: /* {{{ proto bool mysql_close([int link_identifier])
                   1052:    Close a MySQL connection */
                   1053: PHP_FUNCTION(mysql_close)
                   1054: {
                   1055:        int resource_id;
                   1056:        zval *mysql_link=NULL;
                   1057:        php_mysql_conn *mysql;
                   1058: 
                   1059:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1060:                return;
                   1061:        }
                   1062: 
                   1063:        if (mysql_link) {
                   1064:                ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink);
                   1065:        } else {
                   1066:                ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink);
                   1067:        }
                   1068: 
                   1069:        resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link);
                   1070:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1071: #ifdef MYSQL_USE_MYSQLND
                   1072:        {
                   1073:                int tmp;
                   1074:                if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) {
                   1075:                        mysqlnd_end_psession(mysql->conn);
                   1076:                }
                   1077:        }
                   1078: #endif
                   1079:        zend_list_delete(resource_id);
                   1080: 
                   1081:        if (!mysql_link
                   1082:                || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) {
                   1083:                MySG(default_link) = -1;
                   1084:                if (mysql_link) {
                   1085:                        /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */
                   1086:                        zend_list_delete(resource_id);
                   1087:                }
                   1088:        }
                   1089: 
                   1090:        RETURN_TRUE;
                   1091: }
                   1092: /* }}} */
                   1093: 
                   1094: /* {{{ proto bool mysql_select_db(string database_name [, int link_identifier])
                   1095:    Selects a MySQL database */
                   1096: PHP_FUNCTION(mysql_select_db)
                   1097: {
                   1098:        char *db;
                   1099:        int db_len;
                   1100:        zval *mysql_link = NULL;
                   1101:        int id = -1;
                   1102:        php_mysql_conn *mysql;
                   1103: 
                   1104:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1105:                return;
                   1106:        }
                   1107: 
                   1108:        if (!mysql_link) {
                   1109:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1110:                CHECK_LINK(id);
                   1111:        }
                   1112: 
                   1113:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1114: 
                   1115:        if (php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1116:                RETURN_TRUE;
                   1117:        } else {
                   1118:                RETURN_FALSE;
                   1119:        }
                   1120: }
                   1121: /* }}} */
                   1122: 
                   1123: #ifdef HAVE_GETINFO_FUNCS
                   1124: 
                   1125: /* {{{ proto string mysql_get_client_info(void)
                   1126:    Returns a string that represents the client library version */
                   1127: PHP_FUNCTION(mysql_get_client_info)
                   1128: {
                   1129:        if (zend_parse_parameters_none() == FAILURE) {
                   1130:                return;
                   1131:        }
                   1132: 
                   1133:        RETURN_STRING((char *)mysql_get_client_info(),1);
                   1134: }
                   1135: /* }}} */
                   1136: 
                   1137: /* {{{ proto string mysql_get_host_info([int link_identifier])
                   1138:    Returns a string describing the type of connection in use, including the server host name */
                   1139: PHP_FUNCTION(mysql_get_host_info)
                   1140: {
                   1141:        zval *mysql_link = NULL;
                   1142:        int id = -1;
                   1143:        php_mysql_conn *mysql;
                   1144: 
                   1145:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1146:                return;
                   1147:        }
                   1148: 
                   1149:        if (!mysql_link) {
                   1150:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1151:                CHECK_LINK(id);
                   1152:        }
                   1153: 
                   1154:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1155: 
                   1156:        RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1);
                   1157: }
                   1158: /* }}} */
                   1159: 
                   1160: /* {{{ proto int mysql_get_proto_info([int link_identifier])
                   1161:    Returns the protocol version used by current connection */
                   1162: PHP_FUNCTION(mysql_get_proto_info)
                   1163: {
                   1164:        zval *mysql_link = NULL;
                   1165:        int id = -1;
                   1166:        php_mysql_conn *mysql;
                   1167: 
                   1168:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1169:                return;
                   1170:        }
                   1171: 
                   1172:        if (!mysql_link) {
                   1173:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1174:                CHECK_LINK(id);
                   1175:        }
                   1176: 
                   1177:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1178: 
                   1179:        RETURN_LONG(mysql_get_proto_info(mysql->conn));
                   1180: }
                   1181: /* }}} */
                   1182: 
                   1183: /* {{{ proto string mysql_get_server_info([int link_identifier])
                   1184:    Returns a string that represents the server version number */
                   1185: PHP_FUNCTION(mysql_get_server_info)
                   1186: {
                   1187:        zval *mysql_link = NULL;
                   1188:        int id = -1;
                   1189:        php_mysql_conn *mysql;
                   1190: 
                   1191:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1192:                return;
                   1193:        }
                   1194: 
                   1195:        if (!mysql_link) {
                   1196:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1197:                CHECK_LINK(id);
                   1198:        }
                   1199: 
                   1200:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1201: 
                   1202:        RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1);
                   1203: }
                   1204: /* }}} */
                   1205: 
                   1206: /* {{{ proto string mysql_info([int link_identifier])
                   1207:    Returns a string containing information about the most recent query */
                   1208: PHP_FUNCTION(mysql_info)
                   1209: {
                   1210:        zval *mysql_link = NULL;
                   1211:        int id = -1;
                   1212:        char *str;
                   1213:        php_mysql_conn *mysql;
                   1214: 
                   1215:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1216:                return;
                   1217:        }
                   1218: 
                   1219:        if (ZEND_NUM_ARGS() == 0) {
                   1220:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1221:                CHECK_LINK(id);
                   1222:        }
                   1223: 
                   1224:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1225: 
                   1226:        if ((str = (char *)mysql_info(mysql->conn))) {
                   1227:                RETURN_STRING(str,1);
                   1228:        } else {
                   1229:                RETURN_FALSE;
                   1230:        }
                   1231: }
                   1232: /* }}} */
                   1233: 
                   1234: /* {{{ proto int mysql_thread_id([int link_identifier])
                   1235:        Returns the thread id of current connection */
                   1236: PHP_FUNCTION(mysql_thread_id)
                   1237: {
                   1238:        zval *mysql_link = NULL;
                   1239:        int  id = -1;
                   1240:        php_mysql_conn *mysql;
                   1241: 
                   1242:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1243:                return;
                   1244:        }
                   1245: 
                   1246:        if (ZEND_NUM_ARGS() == 0) {
                   1247:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1248:                CHECK_LINK(id);
                   1249:        }
                   1250:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1251: 
                   1252:        RETURN_LONG((long) mysql_thread_id(mysql->conn));
                   1253: }
                   1254: /* }}} */
                   1255: 
                   1256: /* {{{ proto string mysql_stat([int link_identifier])
                   1257:        Returns a string containing status information */
                   1258: PHP_FUNCTION(mysql_stat)
                   1259: {
                   1260:        zval *mysql_link = NULL;
                   1261:        int id = -1;
                   1262:        php_mysql_conn *mysql;
                   1263:        char *stat;
                   1264: #ifdef MYSQL_USE_MYSQLND
                   1265:        uint stat_len;
                   1266: #endif
                   1267: 
                   1268:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1269:                return;
                   1270:        }
                   1271: 
                   1272:        if (ZEND_NUM_ARGS() == 0) {
                   1273:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1274:                CHECK_LINK(id);
                   1275:        }
                   1276:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1277: 
                   1278:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1279: #ifndef MYSQL_USE_MYSQLND
                   1280:        if ((stat = (char *)mysql_stat(mysql->conn))) {
                   1281:                RETURN_STRING(stat, 1);
                   1282: #else
                   1283:        if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) {
                   1284:                RETURN_STRINGL(stat, stat_len, 0);
                   1285: #endif
                   1286:        } else {
                   1287:                RETURN_FALSE;
                   1288:        }
                   1289: }
                   1290: /* }}} */
                   1291: 
                   1292: /* {{{ proto string mysql_client_encoding([int link_identifier])
                   1293:        Returns the default character set for the current connection */
                   1294: PHP_FUNCTION(mysql_client_encoding)
                   1295: {
                   1296:        zval *mysql_link = NULL;
                   1297:        int id = -1;
                   1298:        php_mysql_conn *mysql;
                   1299: 
                   1300:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1301:                return;
                   1302:        }
                   1303: 
                   1304:        if (ZEND_NUM_ARGS() == 0) {
                   1305:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1306:                CHECK_LINK(id);
                   1307:        }
                   1308: 
                   1309:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1310:        RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1);
                   1311: }
                   1312: /* }}} */
                   1313: #endif
                   1314: 
                   1315: #ifdef MYSQL_HAS_SET_CHARSET
                   1316: /* {{{ proto bool mysql_set_charset(string csname [, int link_identifier])
                   1317:    sets client character set */
                   1318: PHP_FUNCTION(mysql_set_charset)
                   1319: {
                   1320:        zval *mysql_link = NULL;
                   1321:        char *csname;
                   1322:        int id = -1, csname_len;
                   1323:        php_mysql_conn *mysql;
                   1324: 
                   1325:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
                   1326:                return;
                   1327:        }
                   1328: 
                   1329:        if (ZEND_NUM_ARGS() == 1) {
                   1330:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1331:                CHECK_LINK(id);
                   1332:        }
                   1333: 
                   1334:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1335: 
                   1336:        if (!mysql_set_character_set(mysql->conn, csname)) {
                   1337:                RETURN_TRUE;
                   1338:        } else {
                   1339:                RETURN_FALSE;
                   1340:        }
                   1341: }
                   1342: /* }}} */
                   1343: #endif
                   1344: 
                   1345: #ifndef NETWARE                /* The below two functions not supported on NetWare */
                   1346: #if MYSQL_VERSION_ID < 40000
                   1347: /* {{{ proto bool mysql_create_db(string database_name [, int link_identifier])
                   1348:    Create a MySQL database */
                   1349: PHP_FUNCTION(mysql_create_db)
                   1350: {
                   1351:        char *db;
                   1352:        int db_len;
                   1353:        zval *mysql_link = NULL;
                   1354:        int id = -1;
                   1355:        php_mysql_conn *mysql;
                   1356: 
                   1357:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1358:                return;
                   1359:        }
                   1360: 
                   1361:        if (!mysql_link) {
                   1362:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1363:                CHECK_LINK(id);
                   1364:        }
                   1365: 
                   1366:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1367: 
                   1368:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1369: 
                   1370:        if (mysql_create_db(mysql->conn, db)==0) {
                   1371:                RETURN_TRUE;
                   1372:        } else {
                   1373:                RETURN_FALSE;
                   1374:        }
                   1375: }
                   1376: /* }}} */
                   1377: 
                   1378: /* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier])
                   1379:    Drops (delete) a MySQL database */
                   1380: PHP_FUNCTION(mysql_drop_db)
                   1381: {
                   1382:        char *db;
                   1383:        int db_len;
                   1384:        zval *mysql_link = NULL;
                   1385:        int id = -1;
                   1386:        php_mysql_conn *mysql;
                   1387: 
                   1388:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1389:                return;
                   1390:        }
                   1391: 
                   1392:        if (!mysql_link) {
                   1393:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1394:                CHECK_LINK(id);
                   1395:        }
                   1396: 
                   1397:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1398: 
                   1399:        if (mysql_drop_db(mysql->conn, db)==0) {
                   1400:                RETURN_TRUE;
                   1401:        } else {
                   1402:                RETURN_FALSE;
                   1403:        }
                   1404: }
                   1405: /* }}} */
                   1406: #endif
                   1407: #endif /* NETWARE */
                   1408: 
                   1409: /* {{{ php_mysql_do_query_general
                   1410:  */
                   1411: static void php_mysql_do_query_general(char *query, int query_len, zval *mysql_link, int link_id, char *db, int use_store, zval *return_value TSRMLS_DC)
                   1412: {
                   1413:        php_mysql_conn *mysql;
                   1414:        MYSQL_RES *mysql_result;
                   1415: 
                   1416:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink);
                   1417: 
                   1418:        if (db) {
                   1419:                if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1420:                        RETURN_FALSE;
                   1421:                }
                   1422:        }
                   1423: 
                   1424:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1425: 
                   1426:        MYSQL_DISABLE_MQ;
                   1427: 
                   1428: #ifndef MYSQL_USE_MYSQLND
                   1429:        /* check explain */
                   1430:        if (MySG(trace_mode)) {
                   1431:                if (!strncasecmp("select", query, 6)){
                   1432:                        MYSQL_ROW       row;
                   1433: 
                   1434:                        char *newquery;
                   1435:                        int newql = spprintf (&newquery, 0, "EXPLAIN %s", query);
                   1436:                        mysql_real_query(mysql->conn, newquery, newql);
                   1437:                        efree (newquery);
                   1438:                        if (mysql_errno(mysql->conn)) {
                   1439:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1440:                                RETURN_FALSE;
                   1441:                        }
                   1442:                        else {
                   1443:                        mysql_result = mysql_use_result(mysql->conn);
                   1444:                                while ((row = mysql_fetch_row(mysql_result))) {
                   1445:                                        if (!strcmp("ALL", row[1])) {
                   1446:                                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full tablescan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
                   1447:                                        } else if (!strcmp("INDEX", row[1])) {
                   1448:                                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full indexscan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
                   1449:                                        }
                   1450:                                }
                   1451:                                mysql_free_result(mysql_result);
                   1452:                        }
                   1453:                }
                   1454:        } /* end explain */
                   1455: #endif
                   1456: 
                   1457:        /* mysql_query is binary unsafe, use mysql_real_query */
                   1458: #if MYSQL_VERSION_ID > 32199
                   1459:        if (mysql_real_query(mysql->conn, query, query_len)!=0) {
                   1460:                /* check possible error */
                   1461:                if (MySG(trace_mode)){
                   1462:                        if (mysql_errno(mysql->conn)){
                   1463:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1464:                        }
                   1465:                }
                   1466:                RETURN_FALSE;
                   1467:        }
                   1468: #else
                   1469:        if (mysql_query(mysql->conn, query)!=0) {
                   1470:                /* check possible error */
                   1471:                if (MySG(trace_mode)){
                   1472:                        if (mysql_errno(mysql->conn)){
                   1473:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1474:                        }
                   1475:                }
                   1476:                RETURN_FALSE;
                   1477:        }
                   1478: #endif
                   1479:        if(use_store == MYSQL_USE_RESULT) {
                   1480:                mysql_result=mysql_use_result(mysql->conn);
                   1481:        } else {
                   1482:                mysql_result=mysql_store_result(mysql->conn);
                   1483:        }
                   1484:        if (!mysql_result) {
                   1485:                if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
                   1486:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
                   1487:                        RETURN_FALSE;
                   1488:                } else {
                   1489:                        RETURN_TRUE;
                   1490:                }
                   1491:        }
                   1492:        MySG(result_allocated)++;
                   1493:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1494:        if (use_store == MYSQL_USE_RESULT) {
                   1495:                mysql->active_result_id = Z_LVAL_P(return_value);
                   1496:        }
                   1497: }
                   1498: /* }}} */
                   1499: 
                   1500: /* {{{ php_mysql_do_query
                   1501:  */
                   1502: static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store)
                   1503: {
                   1504:        char *query;
                   1505:        int query_len;
                   1506:        zval *mysql_link = NULL;
                   1507:        int id = -1;
                   1508: 
                   1509:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) {
                   1510:                return;
                   1511:        }
                   1512: 
                   1513:        if (!mysql_link) {
                   1514:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1515:                CHECK_LINK(id);
                   1516:        }
                   1517: 
                   1518:        php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC);
                   1519: }
                   1520: /* }}} */
                   1521: 
                   1522: /* {{{ proto resource mysql_query(string query [, int link_identifier])
                   1523:    Sends an SQL query to MySQL */
                   1524: PHP_FUNCTION(mysql_query)
                   1525: {
                   1526:        php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
                   1527: }
                   1528: /* }}} */
                   1529: 
                   1530: 
                   1531: /* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
                   1532:    Sends an SQL query to MySQL, without fetching and buffering the result rows */
                   1533: PHP_FUNCTION(mysql_unbuffered_query)
                   1534: {
                   1535:        php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
                   1536: }
                   1537: /* }}} */
                   1538: 
                   1539: 
                   1540: /* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier])
                   1541:    Sends an SQL query to MySQL */
                   1542: PHP_FUNCTION(mysql_db_query)
                   1543: {
                   1544:        char *db, *query;
                   1545:        int db_len, query_len;
                   1546:        zval *mysql_link = NULL;
                   1547:        int id = -1;
                   1548: 
                   1549:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) {
                   1550:                return;
                   1551:        }
                   1552: 
                   1553:        if (!mysql_link) {
                   1554:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1555:                CHECK_LINK(id);
                   1556:        }
                   1557: 
                   1558:        php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead");
                   1559: 
                   1560:        php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC);
                   1561: }
                   1562: /* }}} */
                   1563: 
                   1564: 
                   1565: /* {{{ proto resource mysql_list_dbs([int link_identifier])
                   1566:    List databases available on a MySQL server */
                   1567: PHP_FUNCTION(mysql_list_dbs)
                   1568: {
                   1569:        zval *mysql_link = NULL;
                   1570:        int id = -1;
                   1571:        php_mysql_conn *mysql;
                   1572:        MYSQL_RES *mysql_result;
                   1573: 
                   1574:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1575:                return;
                   1576:        }
                   1577: 
                   1578:        if (!mysql_link) {
                   1579:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1580:                CHECK_LINK(id);
                   1581:        }
                   1582: 
                   1583:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1584: 
                   1585:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1586: 
                   1587:        if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) {
                   1588:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1589:                RETURN_FALSE;
                   1590:        }
                   1591:        MySG(result_allocated)++;
                   1592:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1593: }
                   1594: /* }}} */
                   1595: 
                   1596: 
                   1597: /* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier])
                   1598:    List tables in a MySQL database */
                   1599: PHP_FUNCTION(mysql_list_tables)
                   1600: {
                   1601:        char *db;
                   1602:        int db_len;
                   1603:        zval *mysql_link = NULL;
                   1604:        int id = -1;
                   1605:        php_mysql_conn *mysql;
                   1606:        MYSQL_RES *mysql_result;
                   1607: 
                   1608:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1609:                return;
                   1610:        }
                   1611: 
                   1612:        if (!mysql_link) {
                   1613:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1614:                CHECK_LINK(id);
                   1615:        }
                   1616: 
                   1617:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1618: 
                   1619:        if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1620:                RETURN_FALSE;
                   1621:        }
                   1622: 
                   1623:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1624: 
                   1625:        if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) {
                   1626:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1627:                RETURN_FALSE;
                   1628:        }
                   1629:        MySG(result_allocated)++;
                   1630:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1631: }
                   1632: /* }}} */
                   1633: 
                   1634: 
                   1635: /* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier])
                   1636:    List MySQL result fields */
                   1637: PHP_FUNCTION(mysql_list_fields)
                   1638: {
                   1639:        char *db, *table;
                   1640:        int db_len, table_len;
                   1641:        zval *mysql_link = NULL;
                   1642:        int id = -1;
                   1643:        php_mysql_conn *mysql;
                   1644:        MYSQL_RES *mysql_result;
                   1645: 
                   1646:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) {
                   1647:                return;
                   1648:        }
                   1649: 
                   1650:        if (!mysql_link) {
                   1651:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1652:                CHECK_LINK(id);
                   1653:        }
                   1654: 
                   1655:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1656: 
                   1657:        if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1658:                RETURN_FALSE;
                   1659:        }
                   1660: 
                   1661:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1662: 
                   1663:        if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) {
                   1664:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1665:                RETURN_FALSE;
                   1666:        }
                   1667:        MySG(result_allocated)++;
                   1668:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1669: }
                   1670: /* }}} */
                   1671: 
                   1672: /* {{{ proto resource mysql_list_processes([int link_identifier])
                   1673:        Returns a result set describing the current server threads */
                   1674: PHP_FUNCTION(mysql_list_processes)
                   1675: {
                   1676:        zval *mysql_link = NULL;
                   1677:        int id = -1;
                   1678:        php_mysql_conn *mysql;
                   1679:        MYSQL_RES *mysql_result;
                   1680: 
                   1681:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1682:                return;
                   1683:        }
                   1684: 
                   1685:        if (ZEND_NUM_ARGS() == 0) {
                   1686:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1687:                CHECK_LINK(id);
                   1688:        }
                   1689: 
                   1690:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1691: 
                   1692:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1693: 
                   1694:        mysql_result = mysql_list_processes(mysql->conn);
                   1695:        if (mysql_result == NULL) {
                   1696:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1697:                RETURN_FALSE;
                   1698:        }
                   1699: 
                   1700:        MySG(result_allocated)++;
                   1701:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1702: }
                   1703: /* }}} */
                   1704: 
                   1705: 
                   1706: /* {{{ proto string mysql_error([int link_identifier])
                   1707:    Returns the text of the error message from previous MySQL operation */
                   1708: PHP_FUNCTION(mysql_error)
                   1709: {
                   1710:        zval *mysql_link = NULL;
                   1711:        int id = -1;
                   1712:        php_mysql_conn *mysql;
                   1713: 
                   1714:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1715:                return;
                   1716:        }
                   1717: 
                   1718:        if (!mysql_link) {
                   1719:                id = MySG(default_link);
                   1720:                if (id==-1) {
                   1721:                        if (MySG(connect_error)!=NULL){
                   1722:                                RETURN_STRING(MySG(connect_error),1);
                   1723:                        } else {
                   1724:                                RETURN_FALSE;
                   1725:                        }
                   1726:                }
                   1727:        }
                   1728: 
                   1729:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1730: 
                   1731:        RETURN_STRING((char *)mysql_error(mysql->conn), 1);
                   1732: }
                   1733: /* }}} */
                   1734: 
                   1735: 
                   1736: /* {{{ proto int mysql_errno([int link_identifier])
                   1737:    Returns the number of the error message from previous MySQL operation */
                   1738: #ifdef HAVE_MYSQL_ERRNO
                   1739: PHP_FUNCTION(mysql_errno)
                   1740: {
                   1741:        zval *mysql_link = NULL;
                   1742:        int id = -1;
                   1743:        php_mysql_conn *mysql;
                   1744: 
                   1745:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1746:                return;
                   1747:        }
                   1748: 
                   1749:        if (!mysql_link) {
                   1750:                id = MySG(default_link);
                   1751:                if (id==-1) {
                   1752:                        if (MySG(connect_errno)!=0){
                   1753:                                RETURN_LONG(MySG(connect_errno));
                   1754:                        } else {
                   1755:                                RETURN_FALSE;
                   1756:                        }
                   1757:                }
                   1758:        }
                   1759: 
                   1760:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1761: 
                   1762:        RETURN_LONG(mysql_errno(mysql->conn));
                   1763: }
                   1764: #endif
                   1765: /* }}} */
                   1766: 
                   1767: 
                   1768: /* {{{ proto int mysql_affected_rows([int link_identifier])
                   1769:    Gets number of affected rows in previous MySQL operation */
                   1770: PHP_FUNCTION(mysql_affected_rows)
                   1771: {
                   1772:        zval *mysql_link = NULL;
                   1773:        int id = -1;
                   1774:        php_mysql_conn *mysql;
                   1775: 
                   1776:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1777:                return;
                   1778:        }
                   1779: 
                   1780:        if (!mysql_link) {
                   1781:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1782:                CHECK_LINK(id);
                   1783:        }
                   1784: 
                   1785:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1786: 
                   1787:        /* conversion from int64 to long happing here */
                   1788:        Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn);
                   1789:        Z_TYPE_P(return_value) = IS_LONG;
                   1790: }
                   1791: /* }}} */
                   1792: 
                   1793: 
                   1794: /* {{{ proto string mysql_escape_string(string to_be_escaped)
                   1795:    Escape string for mysql query */
                   1796: PHP_FUNCTION(mysql_escape_string)
                   1797: {
                   1798:        char *str;
                   1799:        int str_len;
                   1800: 
                   1801:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                   1802:                return;
                   1803:        }
                   1804: 
                   1805:        /* assume worst case situation, which is 2x of the original string.
                   1806:         * we don't realloc() down to the real size since it'd most probably not
                   1807:         * be worth it
                   1808:         */
                   1809: 
                   1810:        Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1);
                   1811:        Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len);
                   1812:        Z_TYPE_P(return_value) = IS_STRING;
                   1813: 
                   1814:        if (MySG(trace_mode)){
                   1815:                php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead.");
                   1816:        }
                   1817: }
                   1818: /* }}} */
                   1819: 
                   1820: /* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier])
                   1821:        Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
                   1822: PHP_FUNCTION(mysql_real_escape_string)
                   1823: {
                   1824:        zval *mysql_link = NULL;
                   1825:        char *str;
                   1826:        char *new_str;
                   1827:        int id = -1, str_len, new_str_len;
                   1828:        php_mysql_conn *mysql;
                   1829: 
                   1830: 
                   1831:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {
                   1832:                return;
                   1833:        }
                   1834: 
                   1835:        if (ZEND_NUM_ARGS() == 1) {
                   1836:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1837:                CHECK_LINK(id);
                   1838:        }
                   1839: 
                   1840:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1841: 
                   1842:        new_str = safe_emalloc(str_len, 2, 1);
                   1843:        new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len);
                   1844:        new_str = erealloc(new_str, new_str_len + 1);
                   1845: 
                   1846:        RETURN_STRINGL(new_str, new_str_len, 0);
                   1847: }
                   1848: /* }}} */
                   1849: 
                   1850: /* {{{ proto int mysql_insert_id([int link_identifier])
                   1851:    Gets the ID generated from the previous INSERT operation */
                   1852: PHP_FUNCTION(mysql_insert_id)
                   1853: {
                   1854:        zval *mysql_link = NULL;
                   1855:        int id = -1;
                   1856:        php_mysql_conn *mysql;
                   1857: 
                   1858:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1859:                return;
                   1860:        }
                   1861: 
                   1862:        if (!mysql_link) {
                   1863:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1864:                CHECK_LINK(id);
                   1865:        }
                   1866: 
                   1867:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1868: 
                   1869:        /* conversion from int64 to long happing here */
                   1870:        Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn);
                   1871:        Z_TYPE_P(return_value) = IS_LONG;
                   1872: }
                   1873: /* }}} */
                   1874: 
                   1875: 
                   1876: /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
                   1877:    Gets result data */
                   1878: PHP_FUNCTION(mysql_result)
                   1879: {
                   1880:        zval *result, *field=NULL;
                   1881:        long row;
                   1882:        MYSQL_RES *mysql_result;
                   1883: #ifndef MYSQL_USE_MYSQLND
                   1884:        MYSQL_ROW sql_row;
                   1885:        mysql_row_length_type *sql_row_lengths;
                   1886: #endif
                   1887:        int field_offset=0;
                   1888: 
                   1889: /*
                   1890: johannes TODO:
                   1891: Do 2 zend_parse_paramters calls instead of type "z" and switch below
                   1892: Q: String or long first?
                   1893: */
                   1894:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) {
                   1895:                return;
                   1896:        }
                   1897: 
                   1898:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   1899: 
                   1900:        if (row<0 || row>=(int)mysql_num_rows(mysql_result)) {
                   1901:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result));
                   1902:                RETURN_FALSE;
                   1903:        }
                   1904:        mysql_data_seek(mysql_result, row);
                   1905: 
                   1906:        if (field) {
                   1907:                switch(Z_TYPE_P(field)) {
                   1908:                        case IS_STRING: {
                   1909:                                        int i=0;
                   1910:                                        const MYSQL_FIELD *tmp_field;
                   1911:                                        char *table_name, *field_name, *tmp;
                   1912: 
                   1913:                                        if ((tmp=strchr(Z_STRVAL_P(field), '.'))) {
                   1914:                                                table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field));
                   1915:                                                field_name = estrdup(tmp+1);
                   1916:                                        } else {
                   1917:                                                table_name = NULL;
                   1918:                                                field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field));
                   1919:                                        }
                   1920:                                        mysql_field_seek(mysql_result, 0);
                   1921:                                        while ((tmp_field=mysql_fetch_field(mysql_result))) {
                   1922:                                                if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
                   1923:                                                        field_offset = i;
                   1924:                                                        break;
                   1925:                                                }
                   1926:                                                i++;
                   1927:                                        }
                   1928:                                        if (!tmp_field) { /* no match found */
                   1929:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld",
                   1930:                                                                        (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result));
                   1931:                                                efree(field_name);
                   1932:                                                if (table_name) {
                   1933:                                                        efree(table_name);
                   1934:                                                }
                   1935:                                                RETURN_FALSE;
                   1936:                                        }
                   1937:                                        efree(field_name);
                   1938:                                        if (table_name) {
                   1939:                                                efree(table_name);
                   1940:                                        }
                   1941:                                }
                   1942:                                break;
                   1943:                        default:
                   1944:                                convert_to_long_ex(&field);
                   1945:                                field_offset = Z_LVAL_P(field);
                   1946:                                if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) {
                   1947:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
                   1948:                                        RETURN_FALSE;
                   1949:                                }
                   1950:                                break;
                   1951:                }
                   1952:        }
                   1953: 
                   1954: #ifndef MYSQL_USE_MYSQLND
                   1955:        if ((sql_row=mysql_fetch_row(mysql_result))==NULL
                   1956:                || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */
                   1957:                RETURN_FALSE;
                   1958:        }
                   1959:        if (sql_row[field_offset]) {
                   1960:                Z_TYPE_P(return_value) = IS_STRING;
                   1961: 
                   1962:                if (PG(magic_quotes_runtime)) {
                   1963:                        Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
                   1964:                } else {
                   1965:                        Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
                   1966:                        Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
                   1967:                }
                   1968:        } else {
                   1969:                Z_TYPE_P(return_value) = IS_NULL;
                   1970:        }
                   1971: #else
                   1972:        mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value);
                   1973: #endif
                   1974: }
                   1975: /* }}} */
                   1976: 
                   1977: 
                   1978: /* {{{ proto int mysql_num_rows(resource result)
                   1979:    Gets number of rows in a result */
                   1980: PHP_FUNCTION(mysql_num_rows)
                   1981: {
                   1982:        zval *result;
                   1983:        MYSQL_RES *mysql_result;
                   1984: 
                   1985:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   1986:                return;
                   1987:        }
                   1988: 
                   1989:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   1990: 
                   1991:        /* conversion from int64 to long happing here */
                   1992:        Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result);
                   1993:        Z_TYPE_P(return_value) = IS_LONG;
                   1994: }
                   1995: /* }}} */
                   1996: 
                   1997: /* {{{ proto int mysql_num_fields(resource result)
                   1998:    Gets number of fields in a result */
                   1999: PHP_FUNCTION(mysql_num_fields)
                   2000: {
                   2001:        zval *result;
                   2002:        MYSQL_RES *mysql_result;
                   2003: 
                   2004:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2005:                return;
                   2006:        }
                   2007: 
                   2008:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2009: 
                   2010:        Z_LVAL_P(return_value) = mysql_num_fields(mysql_result);
                   2011:        Z_TYPE_P(return_value) = IS_LONG;
                   2012: }
                   2013: /* }}} */
                   2014: 
                   2015: /* {{{ php_mysql_fetch_hash
                   2016:  */
                   2017: static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object)
                   2018: {
                   2019:        MYSQL_RES *mysql_result;
                   2020:        zval            *res, *ctor_params = NULL;
                   2021:        zend_class_entry *ce = NULL;
                   2022: #ifndef MYSQL_USE_MYSQLND
                   2023:        int i;
                   2024:        MYSQL_FIELD *mysql_field;
                   2025:        MYSQL_ROW mysql_row;
                   2026:        mysql_row_length_type *mysql_row_lengths;
                   2027: #endif
                   2028: 
                   2029: #ifdef ZEND_ENGINE_2
                   2030:        if (into_object) {
                   2031:                char *class_name = NULL;
                   2032:                int class_name_len = 0;
                   2033: 
                   2034:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) {
                   2035:                        return;
                   2036:                }
                   2037: 
                   2038:                if (ZEND_NUM_ARGS() < 2) {
                   2039:                        ce = zend_standard_class_def;
                   2040:                } else {
                   2041:                        ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
                   2042:                }
                   2043:                if (!ce) {
                   2044:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
                   2045:                        return;
                   2046:                }
                   2047:                result_type = MYSQL_ASSOC;
                   2048:        } else
                   2049: #endif
                   2050:        {
                   2051:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) {
                   2052:                        return;
                   2053:                }
                   2054:                if (!result_type) {
                   2055:                        /* result_type might have been set outside, so only overwrite when not set */
                   2056:                        result_type = MYSQL_BOTH;
                   2057:                }
                   2058:        }
                   2059: 
                   2060:        if (result_type & ~MYSQL_BOTH) {
                   2061:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
                   2062:                result_type = MYSQL_BOTH;
                   2063:        }
                   2064: 
                   2065:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result);
                   2066: 
                   2067: #ifndef MYSQL_USE_MYSQLND
                   2068:        if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL  ||
                   2069:                (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) {
                   2070:                RETURN_FALSE;
                   2071:        }
                   2072: 
                   2073:        array_init(return_value);
                   2074: 
                   2075:        mysql_field_seek(mysql_result, 0);
                   2076:        for (mysql_field = mysql_fetch_field(mysql_result), i = 0;
                   2077:                 mysql_field;
                   2078:                 mysql_field = mysql_fetch_field(mysql_result), i++)
                   2079:        {
                   2080:                if (mysql_row[i]) {
                   2081:                        zval *data;
                   2082: 
                   2083:                        MAKE_STD_ZVAL(data);
                   2084: 
                   2085:                        if (PG(magic_quotes_runtime)) {
                   2086:                                Z_TYPE_P(data) = IS_STRING;
                   2087:                                Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
                   2088:                        } else {
                   2089:                                ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
                   2090:                        }
                   2091: 
                   2092:                        if (result_type & MYSQL_NUM) {
                   2093:                                add_index_zval(return_value, i, data);
                   2094:                        }
                   2095:                        if (result_type & MYSQL_ASSOC) {
                   2096:                                if (result_type & MYSQL_NUM) {
                   2097:                                        Z_ADDREF_P(data);
                   2098:                                }
                   2099:                                add_assoc_zval(return_value, mysql_field->name, data);
                   2100:                        }
                   2101:                } else {
                   2102:                        /* NULL value. */
                   2103:                        if (result_type & MYSQL_NUM) {
                   2104:                                add_index_null(return_value, i);
                   2105:                        }
                   2106: 
                   2107:                        if (result_type & MYSQL_ASSOC) {
                   2108:                                add_assoc_null(return_value, mysql_field->name);
                   2109:                        }
                   2110:                }
                   2111:        }
                   2112: #else
                   2113:        mysqlnd_fetch_into(mysql_result, ((result_type & MYSQL_NUM)? MYSQLND_FETCH_NUM:0) | ((result_type & MYSQL_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQL);
                   2114: #endif
                   2115: 
                   2116: #ifdef ZEND_ENGINE_2
                   2117:        /* mysqlnd might return FALSE if no more rows */
                   2118:        if (into_object && Z_TYPE_P(return_value) != IS_BOOL) {
                   2119:                zval dataset = *return_value;
                   2120:                zend_fcall_info fci;
                   2121:                zend_fcall_info_cache fcc;
                   2122:                zval *retval_ptr;
                   2123: 
                   2124:                object_and_properties_init(return_value, ce, NULL);
                   2125:                zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
                   2126: 
                   2127:                if (ce->constructor) {
                   2128:                        fci.size = sizeof(fci);
                   2129:                        fci.function_table = &ce->function_table;
                   2130:                        fci.function_name = NULL;
                   2131:                        fci.symbol_table = NULL;
                   2132:                        fci.object_ptr = return_value;
                   2133:                        fci.retval_ptr_ptr = &retval_ptr;
                   2134:                        if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
                   2135:                                if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
                   2136:                                        HashTable *htl = Z_ARRVAL_P(ctor_params);
                   2137:                                        Bucket *p;
                   2138: 
                   2139:                                        fci.param_count = 0;
                   2140:                                        fci.params = safe_emalloc(sizeof(zval*), htl->nNumOfElements, 0);
                   2141:                                        p = htl->pListHead;
                   2142:                                        while (p != NULL) {
                   2143:                                                fci.params[fci.param_count++] = (zval**)p->pData;
                   2144:                                                p = p->pListNext;
                   2145:                                        }
                   2146:                                } else {
                   2147:                                        /* Two problems why we throw exceptions here: PHP is typeless
                   2148:                                         * and hence passing one argument that's not an array could be
                   2149:                                         * by mistake and the other way round is possible, too. The
                   2150:                                         * single value is an array. Also we'd have to make that one
                   2151:                                         * argument passed by reference.
                   2152:                                         */
                   2153:                                        zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
                   2154:                                        return;
                   2155:                                }
                   2156:                        } else {
                   2157:                                fci.param_count = 0;
                   2158:                                fci.params = NULL;
                   2159:                        }
                   2160:                        fci.no_separation = 1;
                   2161: 
                   2162:                        fcc.initialized = 1;
                   2163:                        fcc.function_handler = ce->constructor;
                   2164:                        fcc.calling_scope = EG(scope);
                   2165:                        fcc.called_scope = Z_OBJCE_P(return_value);
                   2166:                        fcc.object_ptr = return_value;
                   2167: 
                   2168:                        if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                   2169:                                zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
                   2170:                        } else {
                   2171:                                if (retval_ptr) {
                   2172:                                        zval_ptr_dtor(&retval_ptr);
                   2173:                                }
                   2174:                        }
                   2175:                        if (fci.params) {
                   2176:                                efree(fci.params);
                   2177:                        }
                   2178:                } else if (ctor_params) {
                   2179:                        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
                   2180:                }
                   2181:        }
                   2182: #endif
                   2183: 
                   2184: }
                   2185: /* }}} */
                   2186: 
                   2187: /* {{{ proto array mysql_fetch_row(resource result)
                   2188:    Gets a result row as an enumerated array */
                   2189: PHP_FUNCTION(mysql_fetch_row)
                   2190: {
                   2191:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0);
                   2192: }
                   2193: /* }}} */
                   2194: 
                   2195: 
                   2196: /* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])
                   2197:    Fetch a result row as an object */
                   2198: PHP_FUNCTION(mysql_fetch_object)
                   2199: {
                   2200:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1);
                   2201: 
                   2202:        if (Z_TYPE_P(return_value) == IS_ARRAY) {
                   2203:                object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
                   2204:        }
                   2205: }
                   2206: /* }}} */
                   2207: 
                   2208: 
                   2209: /* {{{ proto array mysql_fetch_array(resource result [, int result_type])
                   2210:    Fetch a result row as an array (associative, numeric or both) */
                   2211: PHP_FUNCTION(mysql_fetch_array)
                   2212: {
                   2213:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
                   2214: }
                   2215: /* }}} */
                   2216: 
                   2217: 
                   2218: /* {{{ proto array mysql_fetch_assoc(resource result)
                   2219:    Fetch a result row as an associative array */
                   2220: PHP_FUNCTION(mysql_fetch_assoc)
                   2221: {
                   2222:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0);
                   2223: }
                   2224: /* }}} */
                   2225: 
                   2226: /* {{{ proto bool mysql_data_seek(resource result, int row_number)
                   2227:    Move internal result pointer */
                   2228: PHP_FUNCTION(mysql_data_seek)
                   2229: {
                   2230:        zval *result;
                   2231:        long offset;
                   2232:        MYSQL_RES *mysql_result;
                   2233: 
                   2234:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) {
                   2235:                return;
                   2236:        }
                   2237: 
                   2238:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2239: 
                   2240:        if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) {
                   2241:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset %ld is invalid for MySQL result index %ld (or the query data is unbuffered)", offset, Z_LVAL_P(result));
                   2242:                RETURN_FALSE;
                   2243:        }
                   2244:        mysql_data_seek(mysql_result, offset);
                   2245:        RETURN_TRUE;
                   2246: }
                   2247: /* }}} */
                   2248: 
                   2249: 
                   2250: /* {{{ proto array mysql_fetch_lengths(resource result)
                   2251:    Gets max data size of each column in a result */
                   2252: PHP_FUNCTION(mysql_fetch_lengths)
                   2253: {
                   2254:        zval *result;
                   2255:        MYSQL_RES *mysql_result;
                   2256:        mysql_row_length_type *lengths;
                   2257:        int num_fields;
                   2258:        int i;
                   2259: 
                   2260:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2261:                return;
                   2262:        }
                   2263: 
                   2264:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2265: 
                   2266:        if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) {
                   2267:                RETURN_FALSE;
                   2268:        }
                   2269:        array_init(return_value);
                   2270:        num_fields = mysql_num_fields(mysql_result);
                   2271: 
                   2272:        for (i=0; i<num_fields; i++) {
                   2273:                add_index_long(return_value, i, lengths[i]);
                   2274:        }
                   2275: }
                   2276: /* }}} */
                   2277: 
                   2278: /* {{{ php_mysql_get_field_name
                   2279:  */
                   2280: static char *php_mysql_get_field_name(int field_type)
                   2281: {
                   2282:        switch(field_type) {
                   2283:                case FIELD_TYPE_STRING:
                   2284:                case FIELD_TYPE_VAR_STRING:
                   2285:                        return "string";
                   2286:                        break;
                   2287: #if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND)
                   2288:                case MYSQL_TYPE_BIT:
                   2289: #endif
                   2290: #ifdef MYSQL_HAS_TINY
                   2291:                case FIELD_TYPE_TINY:
                   2292: #endif
                   2293:                case FIELD_TYPE_SHORT:
                   2294:                case FIELD_TYPE_LONG:
                   2295:                case FIELD_TYPE_LONGLONG:
                   2296:                case FIELD_TYPE_INT24:
                   2297:                        return "int";
                   2298:                        break;
                   2299:                case FIELD_TYPE_FLOAT:
                   2300:                case FIELD_TYPE_DOUBLE:
                   2301:                case FIELD_TYPE_DECIMAL:
                   2302: #ifdef FIELD_TYPE_NEWDECIMAL
                   2303:                case FIELD_TYPE_NEWDECIMAL:
                   2304: #endif
                   2305:                        return "real";
                   2306:                        break;
                   2307:                case FIELD_TYPE_TIMESTAMP:
                   2308:                        return "timestamp";
                   2309:                        break;
                   2310: #ifdef MYSQL_HAS_YEAR
                   2311:                case FIELD_TYPE_YEAR:
                   2312:                        return "year";
                   2313:                        break;
                   2314: #endif
                   2315:                case FIELD_TYPE_DATE:
                   2316: #ifdef FIELD_TYPE_NEWDATE
                   2317:                case FIELD_TYPE_NEWDATE:
                   2318: #endif
                   2319:                        return "date";
                   2320:                        break;
                   2321:                case FIELD_TYPE_TIME:
                   2322:                        return "time";
                   2323:                        break;
                   2324:                case FIELD_TYPE_SET:
                   2325:                        return "set";
                   2326:                        break;
                   2327:                case FIELD_TYPE_ENUM:
                   2328:                        return "enum";
                   2329:                        break;
                   2330: #ifdef FIELD_TYPE_GEOMETRY
                   2331:                case FIELD_TYPE_GEOMETRY:
                   2332:                        return "geometry";
                   2333:                        break;
                   2334: #endif
                   2335:                case FIELD_TYPE_DATETIME:
                   2336:                        return "datetime";
                   2337:                        break;
                   2338:                case FIELD_TYPE_TINY_BLOB:
                   2339:                case FIELD_TYPE_MEDIUM_BLOB:
                   2340:                case FIELD_TYPE_LONG_BLOB:
                   2341:                case FIELD_TYPE_BLOB:
                   2342:                        return "blob";
                   2343:                        break;
                   2344:                case FIELD_TYPE_NULL:
                   2345:                        return "null";
                   2346:                        break;
                   2347:                default:
                   2348:                        return "unknown";
                   2349:                        break;
                   2350:        }
                   2351: }
                   2352: /* }}} */
                   2353: 
                   2354: /* {{{ proto object mysql_fetch_field(resource result [, int field_offset])
                   2355:    Gets column information from a result and return as an object */
                   2356: PHP_FUNCTION(mysql_fetch_field)
                   2357: {
                   2358:        zval *result;
                   2359:        long field=0;
                   2360:        MYSQL_RES *mysql_result;
                   2361:        const MYSQL_FIELD *mysql_field;
                   2362: 
                   2363:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) {
                   2364:                return;
                   2365:        }
                   2366: 
                   2367:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2368: 
                   2369:        if (ZEND_NUM_ARGS() > 1) {
                   2370:                if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
                   2371:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset");
                   2372:                        RETURN_FALSE;
                   2373:                }
                   2374:                mysql_field_seek(mysql_result, field);
                   2375:        }
                   2376:        if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
                   2377:                RETURN_FALSE;
                   2378:        }
                   2379:        object_init(return_value);
                   2380: 
                   2381:        add_property_string(return_value, "name", (char *) (mysql_field->name?mysql_field->name:""), 1);
                   2382:        add_property_string(return_value, "table",(char *) (mysql_field->table?mysql_field->table:""), 1);
                   2383:        add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1);
                   2384:        add_property_long(return_value, "max_length", mysql_field->max_length);
                   2385:        add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
                   2386:        add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
                   2387:        add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
                   2388:        add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
                   2389:        add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0);
                   2390:        add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0);
                   2391:        add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1);
                   2392:        add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
                   2393:        add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
                   2394: }
                   2395: /* }}} */
                   2396: 
                   2397: 
                   2398: /* {{{ proto bool mysql_field_seek(resource result, int field_offset)
                   2399:    Sets result pointer to a specific field offset */
                   2400: PHP_FUNCTION(mysql_field_seek)
                   2401: {
                   2402:        zval *result;
                   2403:        long offset;
                   2404:        MYSQL_RES *mysql_result;
                   2405: 
                   2406:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) {
                   2407:                return;
                   2408:        }
                   2409:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2410: 
                   2411:        if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) {
                   2412:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result));
                   2413:                RETURN_FALSE;
                   2414:        }
                   2415:        mysql_field_seek(mysql_result, offset);
                   2416:        RETURN_TRUE;
                   2417: }
                   2418: /* }}} */
                   2419: 
                   2420: 
                   2421: #define PHP_MYSQL_FIELD_NAME 1
                   2422: #define PHP_MYSQL_FIELD_TABLE 2
                   2423: #define PHP_MYSQL_FIELD_LEN 3
                   2424: #define PHP_MYSQL_FIELD_TYPE 4
                   2425: #define PHP_MYSQL_FIELD_FLAGS 5
                   2426: 
                   2427: /* {{{ php_mysql_field_info
                   2428:  */
                   2429: static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
                   2430: {
                   2431:        zval *result;
                   2432:        long field;
                   2433:        MYSQL_RES *mysql_result;
                   2434:        const MYSQL_FIELD *mysql_field = {0};
                   2435:        char buf[512];
                   2436:        int  len;
                   2437: 
                   2438:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
                   2439:                return;
                   2440:        }
                   2441: 
                   2442:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2443: 
                   2444:        if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
                   2445:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result));
                   2446:                RETURN_FALSE;
                   2447:        }
                   2448:        mysql_field_seek(mysql_result, field);
                   2449:        if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
                   2450:                RETURN_FALSE;
                   2451:        }
                   2452: 
                   2453:        switch (entry_type) {
                   2454:                case PHP_MYSQL_FIELD_NAME:
                   2455:                        Z_STRLEN_P(return_value) = strlen(mysql_field->name);
                   2456:                        Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value));
                   2457:                        Z_TYPE_P(return_value) = IS_STRING;
                   2458:                        break;
                   2459:                case PHP_MYSQL_FIELD_TABLE:
                   2460:                        Z_STRLEN_P(return_value) = strlen(mysql_field->table);
                   2461:                        Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value));
                   2462:                        Z_TYPE_P(return_value) = IS_STRING;
                   2463:                        break;
                   2464:                case PHP_MYSQL_FIELD_LEN:
                   2465:                        Z_LVAL_P(return_value) = mysql_field->length;
                   2466:                        Z_TYPE_P(return_value) = IS_LONG;
                   2467:                        break;
                   2468:                case PHP_MYSQL_FIELD_TYPE:
                   2469:                        Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field));
                   2470:                        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                   2471:                        Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
                   2472:                        Z_TYPE_P(return_value) = IS_STRING;
                   2473:                        break;
                   2474:                case PHP_MYSQL_FIELD_FLAGS:
                   2475:                        memcpy(buf, "", sizeof(""));
                   2476: #ifdef IS_NOT_NULL
                   2477:                        if (IS_NOT_NULL(mysql_field->flags)) {
                   2478:                                strcat(buf, "not_null ");
                   2479:                        }
                   2480: #endif
                   2481: #ifdef IS_PRI_KEY
                   2482:                        if (IS_PRI_KEY(mysql_field->flags)) {
                   2483:                                strcat(buf, "primary_key ");
                   2484:                        }
                   2485: #endif
                   2486: #ifdef UNIQUE_KEY_FLAG
                   2487:                        if (mysql_field->flags&UNIQUE_KEY_FLAG) {
                   2488:                                strcat(buf, "unique_key ");
                   2489:                        }
                   2490: #endif
                   2491: #ifdef MULTIPLE_KEY_FLAG
                   2492:                        if (mysql_field->flags&MULTIPLE_KEY_FLAG) {
                   2493:                                strcat(buf, "multiple_key ");
                   2494:                        }
                   2495: #endif
                   2496: #ifdef IS_BLOB
                   2497:                        if (IS_BLOB(mysql_field->flags)) {
                   2498:                                strcat(buf, "blob ");
                   2499:                        }
                   2500: #endif
                   2501: #ifdef UNSIGNED_FLAG
                   2502:                        if (mysql_field->flags&UNSIGNED_FLAG) {
                   2503:                                strcat(buf, "unsigned ");
                   2504:                        }
                   2505: #endif
                   2506: #ifdef ZEROFILL_FLAG
                   2507:                        if (mysql_field->flags&ZEROFILL_FLAG) {
                   2508:                                strcat(buf, "zerofill ");
                   2509:                        }
                   2510: #endif
                   2511: #ifdef BINARY_FLAG
                   2512:                        if (mysql_field->flags&BINARY_FLAG) {
                   2513:                                strcat(buf, "binary ");
                   2514:                        }
                   2515: #endif
                   2516: #ifdef ENUM_FLAG
                   2517:                        if (mysql_field->flags&ENUM_FLAG) {
                   2518:                                strcat(buf, "enum ");
                   2519:                        }
                   2520: #endif
                   2521: #ifdef SET_FLAG
                   2522:                        if (mysql_field->flags&SET_FLAG) {
                   2523:                                strcat(buf, "set ");
                   2524:                        }
                   2525: #endif
                   2526: #ifdef AUTO_INCREMENT_FLAG
                   2527:                        if (mysql_field->flags&AUTO_INCREMENT_FLAG) {
                   2528:                                strcat(buf, "auto_increment ");
                   2529:                        }
                   2530: #endif
                   2531: #ifdef TIMESTAMP_FLAG
                   2532:                        if (mysql_field->flags&TIMESTAMP_FLAG) {
                   2533:                                strcat(buf, "timestamp ");
                   2534:                        }
                   2535: #endif
                   2536:                        len = strlen(buf);
                   2537:                        /* remove trailing space, if present */
                   2538:                        if (len && buf[len-1] == ' ') {
                   2539:                                buf[len-1] = 0;
                   2540:                                len--;
                   2541:                        }
                   2542: 
                   2543:                        Z_STRLEN_P(return_value) = len;
                   2544:                        Z_STRVAL_P(return_value) = estrndup(buf, len);
                   2545:                        Z_TYPE_P(return_value) = IS_STRING;
                   2546:                        break;
                   2547: 
                   2548:                default:
                   2549:                        RETURN_FALSE;
                   2550:        }
                   2551: }
                   2552: /* }}} */
                   2553: 
                   2554: /* {{{ proto string mysql_field_name(resource result, int field_index)
                   2555:    Gets the name of the specified field in a result */
                   2556: PHP_FUNCTION(mysql_field_name)
                   2557: {
                   2558:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME);
                   2559: }
                   2560: /* }}} */
                   2561: 
                   2562: 
                   2563: /* {{{ proto string mysql_field_table(resource result, int field_offset)
                   2564:    Gets name of the table the specified field is in */
                   2565: PHP_FUNCTION(mysql_field_table)
                   2566: {
                   2567:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE);
                   2568: }
                   2569: /* }}} */
                   2570: 
                   2571: 
                   2572: /* {{{ proto int mysql_field_len(resource result, int field_offset)
                   2573:    Returns the length of the specified field */
                   2574: PHP_FUNCTION(mysql_field_len)
                   2575: {
                   2576:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN);
                   2577: }
                   2578: /* }}} */
                   2579: 
                   2580: 
                   2581: /* {{{ proto string mysql_field_type(resource result, int field_offset)
                   2582:    Gets the type of the specified field in a result */
                   2583: PHP_FUNCTION(mysql_field_type)
                   2584: {
                   2585:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE);
                   2586: }
                   2587: /* }}} */
                   2588: 
                   2589: 
                   2590: /* {{{ proto string mysql_field_flags(resource result, int field_offset)
                   2591:    Gets the flags associated with the specified field in a result */
                   2592: PHP_FUNCTION(mysql_field_flags)
                   2593: {
                   2594:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS);
                   2595: }
                   2596: /* }}} */
                   2597: 
                   2598: 
                   2599: /* {{{ proto bool mysql_free_result(resource result)
                   2600:    Free result memory */
                   2601: PHP_FUNCTION(mysql_free_result)
                   2602: {
                   2603:        zval *result;
                   2604:        MYSQL_RES *mysql_result;
                   2605: 
                   2606:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2607:                return;
                   2608:        }
                   2609: 
                   2610:        if (Z_LVAL_P(result)==0) {
                   2611:                RETURN_FALSE;
                   2612:        }
                   2613: 
                   2614:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2615: 
                   2616:        zend_list_delete(Z_LVAL_P(result));
                   2617:        RETURN_TRUE;
                   2618: }
                   2619: /* }}} */
                   2620: 
                   2621: /* {{{ proto bool mysql_ping([int link_identifier])
                   2622:    Ping a server connection. If no connection then reconnect. */
                   2623: PHP_FUNCTION(mysql_ping)
                   2624: {
                   2625:        zval           *mysql_link = NULL;
                   2626:        int             id         = -1;
                   2627:        php_mysql_conn *mysql;
                   2628: 
                   2629:        if (0 == ZEND_NUM_ARGS()) {
                   2630:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   2631:                CHECK_LINK(id);
                   2632:        } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) {
                   2633:                return;
                   2634:        }
                   2635: 
                   2636:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   2637: 
                   2638:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   2639: 
                   2640:        RETURN_BOOL(! mysql_ping(mysql->conn));
                   2641: }
                   2642: /* }}} */
                   2643: 
                   2644: #endif
                   2645: 
                   2646: /*
                   2647:  * Local variables:
                   2648:  * tab-width: 4
                   2649:  * c-basic-offset: 4
                   2650:  * End:
                   2651:  * vim600: sw=4 ts=4 fdm=marker
                   2652:  * vim<600: sw=4 ts=4
                   2653:  */

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