Annotation of embedaddon/php/ext/mysql/php_mysql.c, revision 1.1.1.5

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.5 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Zeev Suraski <zeev@zend.com>                                |
                     16:    |          Zak Greant <zak@mysql.com>                                  |
                     17:    |          Georg Richter <georg@php.net>                               |
                     18:    +----------------------------------------------------------------------+
                     19: */
                     20: 
1.1.1.2   misho      21: /* $Id$ */
1.1       misho      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)
1.1.1.2   misho     255:        PHP_DEP_FE(mysql_list_dbs,                                                      arginfo__optional_mysql_link)
1.1       misho     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
1.1.1.4   misho     299:        /* for downwards compatibility */
1.1       misho     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: 
1.1.1.2   misho     532: #ifdef MYSQL_USE_MYSQLND
                    533: #include "ext/mysqlnd/mysqlnd_reverse_api.h"
                    534: static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
                    535: {
                    536:        php_mysql_conn *mysql;
                    537: 
                    538:        if (Z_TYPE_P(zv) != IS_RESOURCE) {
                    539:                /* Might be nicer to check resource type, too, but ext/mysql is the only one using resources so emitting an error is not to bad, while usually this hook should be silent */
                    540:                return NULL;
                    541:        }
                    542: 
                    543:        mysql = (php_mysql_conn *)zend_fetch_resource(&zv TSRMLS_CC, -1, "MySQL-Link", NULL, 2, le_link, le_plink);
                    544: 
                    545:        if (!mysql) {
                    546:                return NULL;
                    547:        }
                    548: 
                    549:        return mysql->conn;
                    550: }
                    551: 
                    552: static MYSQLND_REVERSE_API mysql_reverse_api = {
                    553:        &mysql_module_entry,
                    554:        mysql_convert_zv_to_mysqlnd
                    555: };
                    556: #endif
                    557: 
1.1       misho     558: /* {{{ PHP_MINIT_FUNCTION
                    559:  */
                    560: ZEND_MODULE_STARTUP_D(mysql)
                    561: {
                    562:        REGISTER_INI_ENTRIES();
                    563:        le_result = zend_register_list_destructors_ex(_free_mysql_result, NULL, "mysql result", module_number);
                    564:        le_link = zend_register_list_destructors_ex(_close_mysql_link, NULL, "mysql link", module_number);
                    565:        le_plink = zend_register_list_destructors_ex(NULL, _close_mysql_plink, "mysql link persistent", module_number);
                    566:        Z_TYPE(mysql_module_entry) = type;
                    567: 
                    568:        REGISTER_LONG_CONSTANT("MYSQL_ASSOC", MYSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
                    569:        REGISTER_LONG_CONSTANT("MYSQL_NUM", MYSQL_NUM, CONST_CS | CONST_PERSISTENT);
                    570:        REGISTER_LONG_CONSTANT("MYSQL_BOTH", MYSQL_BOTH, CONST_CS | CONST_PERSISTENT);
                    571:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
                    572: #if MYSQL_VERSION_ID >= 40000
                    573:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
                    574: #endif
                    575:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
                    576:        REGISTER_LONG_CONSTANT("MYSQL_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
                    577: 
                    578: #ifndef MYSQL_USE_MYSQLND
                    579: #if MYSQL_VERSION_ID >= 40000
                    580:        if (mysql_server_init(0, NULL, NULL)) {
                    581:                return FAILURE;
                    582:        }
                    583: #endif
                    584: #endif
                    585: 
1.1.1.2   misho     586: #ifdef MYSQL_USE_MYSQLND
                    587:        mysqlnd_reverse_api_register_api(&mysql_reverse_api TSRMLS_CC);
                    588: #endif
                    589: 
1.1       misho     590:        return SUCCESS;
                    591: }
                    592: /* }}} */
                    593: 
                    594: /* {{{ PHP_MSHUTDOWN_FUNCTION
                    595:  */
                    596: PHP_MSHUTDOWN_FUNCTION(mysql)
                    597: {
                    598: #ifndef MYSQL_USE_MYSQLND
                    599: #if MYSQL_VERSION_ID >= 40000
                    600: #ifdef PHP_WIN32
                    601:        unsigned long client_ver = mysql_get_client_version();
                    602:        /*
                    603:          Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
                    604:          PHP bug#41350 MySQL bug#25621
                    605:        */
                    606:        if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
                    607:                mysql_server_end();
                    608:        }
                    609: #else
                    610:        mysql_server_end();
                    611: #endif
                    612: #endif
                    613: #endif
                    614: 
                    615:        UNREGISTER_INI_ENTRIES();
                    616:        return SUCCESS;
                    617: }
                    618: /* }}} */
                    619: 
                    620: /* {{{ PHP_RINIT_FUNCTION
                    621:  */
                    622: PHP_RINIT_FUNCTION(mysql)
                    623: {
                    624: #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    625:        if (mysql_thread_init()) {
                    626:                return FAILURE;
                    627:        }
                    628: #endif
                    629:        MySG(default_link)=-1;
                    630:        MySG(num_links) = MySG(num_persistent);
                    631:        /* Reset connect error/errno on every request */
                    632:        MySG(connect_error) = NULL;
                    633:        MySG(connect_errno) =0;
                    634:        MySG(result_allocated) = 0;
                    635: 
                    636:        return SUCCESS;
                    637: }
                    638: /* }}} */
                    639: 
                    640: 
                    641: #if defined(A0) && defined(MYSQL_USE_MYSQLND)
                    642: static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
                    643: {
                    644:        if (le->type == le_plink) {
                    645:                mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn);
                    646:        }
                    647:        return ZEND_HASH_APPLY_KEEP;
                    648: } /* }}} */
                    649: #endif
                    650: 
                    651: 
                    652: /* {{{ PHP_RSHUTDOWN_FUNCTION
                    653:  */
                    654: PHP_RSHUTDOWN_FUNCTION(mysql)
                    655: {
                    656: #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
                    657:        mysql_thread_end();
                    658: #endif
                    659: 
                    660:        if (MySG(trace_mode)) {
                    661:                if (MySG(result_allocated)){
                    662:                        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));
                    663:                }
                    664:        }
                    665: 
                    666:        if (MySG(connect_error)!=NULL) {
                    667:                efree(MySG(connect_error));
                    668:        }
                    669: 
                    670: #if defined(A0) && defined(MYSQL_USE_MYSQLND)
                    671:        zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC);
                    672: #endif
                    673: 
                    674:        return SUCCESS;
                    675: }
                    676: /* }}} */
                    677: 
                    678: /* {{{ PHP_MINFO_FUNCTION
                    679:  */
                    680: PHP_MINFO_FUNCTION(mysql)
                    681: {
                    682:        char buf[32];
                    683: 
                    684:        php_info_print_table_start();
                    685:        php_info_print_table_header(2, "MySQL Support", "enabled");
                    686:        snprintf(buf, sizeof(buf), "%ld", MySG(num_persistent));
                    687:        php_info_print_table_row(2, "Active Persistent Links", buf);
                    688:        snprintf(buf, sizeof(buf), "%ld", MySG(num_links));
                    689:        php_info_print_table_row(2, "Active Links", buf);
                    690:        php_info_print_table_row(2, "Client API version", mysql_get_client_info());
                    691: #if !defined (PHP_WIN32) && !defined (NETWARE) && !defined(MYSQL_USE_MYSQLND)
                    692:        php_info_print_table_row(2, "MYSQL_MODULE_TYPE", PHP_MYSQL_TYPE);
                    693:        php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR);
                    694:        php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE);
                    695:        php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS);
                    696: #endif
                    697: 
                    698:        php_info_print_table_end();
                    699: 
                    700:        DISPLAY_INI_ENTRIES();
                    701: 
                    702: }
                    703: /* }}} */
                    704: 
                    705: /* {{{ php_mysql_do_connect
                    706:  */
                    707: #define MYSQL_DO_CONNECT_CLEANUP()     \
                    708:        if (free_host) {                                \
                    709:                efree(host);                            \
                    710:        }
                    711: 
                    712: #define MYSQL_DO_CONNECT_RETURN_FALSE()                \
                    713:        MYSQL_DO_CONNECT_CLEANUP();                             \
                    714:        RETURN_FALSE;
                    715: 
                    716: #ifdef MYSQL_USE_MYSQLND
                    717: #define MYSQL_PORT 0
                    718: #endif
                    719: 
                    720: static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                    721: {
                    722:        char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL;
1.1.1.3   misho     723:        int  user_len = 0, passwd_len = 0, host_len = 0;
1.1       misho     724:        char *hashed_details=NULL;
                    725:        int hashed_details_length, port = MYSQL_PORT;
                    726:        long client_flags = 0;
                    727:        php_mysql_conn *mysql=NULL;
                    728: #if MYSQL_VERSION_ID <= 32230
                    729:        void (*handler) (int);
                    730: #endif
                    731:        zend_bool free_host=0, new_link=0;
                    732:        long connect_timeout;
                    733: 
                    734: #if !defined(MYSQL_USE_MYSQLND)
                    735:        if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
                    736:                php_error_docref(NULL TSRMLS_CC, E_WARNING,
                    737:                                                "Headers and client library minor version mismatch. Headers:%d Library:%ld",
                    738:                                                MYSQL_VERSION_ID, mysql_get_client_version());
                    739:        }
                    740: #endif
                    741: 
                    742:        connect_timeout = MySG(connect_timeout);
                    743: 
                    744:        socket = MySG(default_socket);
                    745: 
                    746:        if (MySG(default_port) < 0) {
                    747: #if !defined(PHP_WIN32) && !defined(NETWARE)
                    748:                struct servent *serv_ptr;
                    749:                char *env;
                    750: 
                    751:                MySG(default_port) = MYSQL_PORT;
                    752:                if ((serv_ptr = getservbyname("mysql", "tcp"))) {
                    753:                        MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
                    754:                }
                    755:                if ((env = getenv("MYSQL_TCP_PORT"))) {
                    756:                        MySG(default_port) = (uint) atoi(env);
                    757:                }
                    758: #else
                    759:                MySG(default_port) = MYSQL_PORT;
                    760: #endif
                    761:        }
                    762: 
                    763:        if (PG(sql_safe_mode)) {
                    764:                if (ZEND_NUM_ARGS()>0) {
                    765:                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
                    766:                }
                    767:                host_and_port=passwd=NULL;
1.1.1.2   misho     768:                user=php_get_current_user(TSRMLS_C);
1.1       misho     769:                hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user);
                    770:                client_flags = CLIENT_INTERACTIVE;
                    771:        } else {
                    772:                /* mysql_pconnect does not support new_link parameter */
                    773:                if (persistent) {
                    774:                        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len,
                    775:                                                                        &user, &user_len, &passwd, &passwd_len,
                    776:                                                                        &client_flags)==FAILURE) {
                    777:                                return;
                    778:                }
                    779:                } else {
                    780:                        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len,
                    781:                                                                                &user, &user_len, &passwd, &passwd_len,
                    782:                                                                                &new_link, &client_flags)==FAILURE) {
                    783:                                return;
                    784:                        }
                    785:                }
                    786: 
                    787:                if (!host_and_port) {
                    788:                        host_and_port = MySG(default_host);
                    789:                }
                    790:                if (!user) {
                    791:                        user = MySG(default_user);
                    792:                }
                    793:                if (!passwd) {
                    794:                        passwd = MySG(default_password);
                    795:                        passwd_len = passwd? strlen(passwd):0;
                    796:                }
                    797: 
                    798:                /* disable local infile option for open_basedir */
                    799: #if PHP_API_VERSION < 20100412
                    800:                if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
                    801: #else
                    802:                if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) {
                    803: #endif
                    804:                        client_flags ^= CLIENT_LOCAL_FILES;
                    805:                }
                    806: 
                    807: #ifdef CLIENT_MULTI_RESULTS
                    808:                client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
                    809: #endif
                    810: #ifdef CLIENT_MULTI_STATEMENTS
                    811:                client_flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
                    812: #endif
                    813:                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);
                    814:        }
                    815: 
                    816:        /* We cannot use mysql_port anymore in windows, need to use
                    817:         * mysql_real_connect() to set the port.
                    818:         */
                    819:        if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
                    820:                host = estrndup(host_and_port, tmp-host_and_port);
                    821:                free_host = 1;
                    822:                tmp++;
                    823:                if (tmp[0] != '/') {
                    824:                        port = atoi(tmp);
                    825:                        if ((tmp=strchr(tmp, ':'))) {
                    826:                                tmp++;
                    827:                                socket=tmp;
                    828:                        }
                    829:                } else {
                    830:                        socket = tmp;
                    831:                }
                    832:        } else {
                    833:                host = host_and_port;
                    834:                port = MySG(default_port);
                    835:        }
                    836: 
                    837: #if MYSQL_VERSION_ID < 32200
                    838:        mysql_port = port;
                    839: #endif
                    840: 
                    841:        if (!MySG(allow_persistent)) {
                    842:                persistent=0;
                    843:        }
                    844:        if (persistent) {
                    845:                zend_rsrc_list_entry *le;
                    846: 
                    847:                /* try to find if we already have this link in our persistent list */
                    848:                if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
                    849:                        zend_rsrc_list_entry new_le;
                    850: 
                    851:                        if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
                    852:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
                    853:                                efree(hashed_details);
                    854:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    855:                        }
                    856:                        if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) {
                    857:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
                    858:                                efree(hashed_details);
                    859:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    860:                        }
                    861:                        /* create the link */
                    862:                        mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
                    863:                        if (!mysql) {
                    864:                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link");
                    865:                        }
                    866:                        mysql->active_result_id = 0;
                    867: #ifdef CLIENT_MULTI_STATEMENTS
                    868:                        mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
                    869: #else
                    870:                        mysql->multi_query = 0;
                    871: #endif
                    872: 
                    873: #ifndef MYSQL_USE_MYSQLND
                    874:                        mysql->conn = mysql_init(NULL);
                    875: #else
                    876:                        mysql->conn = mysql_init(persistent);
                    877: #endif
                    878: 
                    879:                        if (connect_timeout != -1) {
                    880:                                mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
                    881:                        }
                    882: #ifndef MYSQL_USE_MYSQLND
                    883:                        if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                    884: #else
                    885:                        if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                    886: #endif
                    887:                        {
                    888:                                /* Populate connect error globals so that the error functions can read them */
                    889:                                if (MySG(connect_error) != NULL) {
                    890:                                        efree(MySG(connect_error));
                    891:                                }
                    892:                                MySG(connect_error) = estrdup(mysql_error(mysql->conn));
                    893:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
                    894: #if defined(HAVE_MYSQL_ERRNO)
                    895:                                MySG(connect_errno) = mysql_errno(mysql->conn);
                    896: #endif
                    897:                                free(mysql);
                    898:                                efree(hashed_details);
                    899:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    900:                        }
                    901:                        mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                    902: 
                    903:                        /* hash it up */
                    904:                        Z_TYPE(new_le) = le_plink;
                    905:                        new_le.ptr = mysql;
                    906:                        if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
                    907:                                free(mysql);
                    908:                                efree(hashed_details);
                    909:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    910:                        }
                    911:                        MySG(num_persistent)++;
                    912:                        MySG(num_links)++;
                    913:                } else {  /* The link is in our list of persistent connections */
                    914:                        if (Z_TYPE_P(le) != le_plink) {
                    915:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    916:                        }
                    917:                        mysql = (php_mysql_conn *) le->ptr;
                    918:                        mysql->active_result_id = 0;
                    919: #ifdef CLIENT_MULTI_STATEMENTS
                    920:                        mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
                    921: #else
                    922:                        mysql->multi_query = 0;
                    923: #endif
                    924:                        /* ensure that the link did not die */
                    925: #if defined(A0) && MYSQL_USE_MYSQLND
                    926:                        mysqlnd_end_psession(mysql->conn);
                    927: #endif
                    928:                        if (mysql_ping(mysql->conn)) {
                    929:                                if (mysql_errno(mysql->conn) == 2006) {
                    930: #ifndef MYSQL_USE_MYSQLND
                    931:                                        if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                    932: #else
                    933:                                        if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                    934: #endif
                    935:                                        {
                    936:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
                    937:                                                zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
                    938:                                                efree(hashed_details);
                    939:                                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    940:                                        }
                    941:                                        mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                    942:                                }
                    943:                        } else {
                    944: #ifdef MYSQL_USE_MYSQLND
                    945:                                mysqlnd_restart_psession(mysql->conn);
                    946: #endif
                    947:                        }
                    948:                }
                    949:                ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
                    950:        } else { /* non persistent */
                    951:                zend_rsrc_list_entry *index_ptr, new_index_ptr;
                    952: 
                    953:                /* first we check the hash for the hashed_details key.  if it exists,
                    954:                 * it should point us to the right offset where the actual mysql link sits.
                    955:                 * if it doesn't, open a new mysql link, add it to the resource list,
                    956:                 * and add a pointer to it with hashed_details as the key.
                    957:                 */
                    958:                if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
                    959:                        int type;
                    960:                        long link;
                    961:                        void *ptr;
                    962: 
                    963:                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {
                    964:                                MYSQL_DO_CONNECT_RETURN_FALSE();
                    965:                        }
                    966:                        link = (long) index_ptr->ptr;
                    967:                        ptr = zend_list_find(link,&type);   /* check if the link is still there */
                    968:                        if (ptr && (type==le_link || type==le_plink)) {
                    969:                                zend_list_addref(link);
                    970:                                Z_LVAL_P(return_value) = link;
                    971:                                php_mysql_set_default_link(link TSRMLS_CC);
                    972:                                Z_TYPE_P(return_value) = IS_RESOURCE;
                    973:                                efree(hashed_details);
                    974:                                MYSQL_DO_CONNECT_CLEANUP();
                    975:                                return;
                    976:                        } else {
                    977:                                zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
                    978:                        }
                    979:                }
                    980:                if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
                    981:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
                    982:                        efree(hashed_details);
                    983:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                    984:                }
                    985: 
                    986:                mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
                    987:                mysql->active_result_id = 0;
                    988: #ifdef CLIENT_MULTI_STATEMENTS
                    989:                mysql->multi_query = 1;
                    990: #endif
                    991: 
                    992: #ifndef MYSQL_USE_MYSQLND
                    993:                mysql->conn = mysql_init(NULL);
                    994: #else
                    995:                mysql->conn = mysql_init(persistent);
                    996: #endif
                    997:                if (!mysql->conn) {
                    998:                        MySG(connect_error) = estrdup("OOM");
                    999:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM");
                   1000:                        efree(hashed_details);
                   1001:                        efree(mysql);
                   1002:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                   1003:                }
                   1004: 
                   1005:                if (connect_timeout != -1) {
                   1006:                        mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
                   1007:                }
                   1008: 
                   1009: #ifndef MYSQL_USE_MYSQLND
                   1010:                if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
                   1011: #else
                   1012:                if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
                   1013: #endif
                   1014:                {
                   1015:                        /* Populate connect error globals so that the error functions can read them */
                   1016:                        if (MySG(connect_error) != NULL) {
                   1017:                                efree(MySG(connect_error));
                   1018:                        }
                   1019:                        MySG(connect_error) = estrdup(mysql_error(mysql->conn));
                   1020:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
                   1021: #if defined(HAVE_MYSQL_ERRNO)
                   1022:                        MySG(connect_errno) = mysql_errno(mysql->conn);
                   1023: #endif
                   1024:                        /* free mysql structure */
                   1025: #ifdef MYSQL_USE_MYSQLND
                   1026:                        mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED);
                   1027: #endif
                   1028:                        efree(hashed_details);
                   1029:                        efree(mysql);
                   1030:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                   1031:                }
                   1032:                mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
                   1033: 
                   1034:                /* add it to the list */
                   1035:                ZEND_REGISTER_RESOURCE(return_value, mysql, le_link);
                   1036: 
                   1037:                /* add it to the hash */
                   1038:                new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
                   1039:                Z_TYPE(new_index_ptr) = le_index_ptr;
                   1040:                if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
                   1041:                        efree(hashed_details);
                   1042:                        MYSQL_DO_CONNECT_RETURN_FALSE();
                   1043:                }
                   1044:                MySG(num_links)++;
                   1045:        }
                   1046: 
                   1047:        efree(hashed_details);
                   1048:        php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
                   1049:        MYSQL_DO_CONNECT_CLEANUP();
                   1050: }
                   1051: /* }}} */
                   1052: 
                   1053: /* {{{ php_mysql_get_default_link
                   1054:  */
                   1055: static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
                   1056: {
                   1057:        if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */
                   1058:                ht = 0;
                   1059:                php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1060:        }
                   1061:        return MySG(default_link);
                   1062: }
                   1063: /* }}} */
                   1064: 
                   1065: /* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])
                   1066:    Opens a connection to a MySQL Server */
                   1067: PHP_FUNCTION(mysql_connect)
                   1068: {
                   1069:        php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1070: }
                   1071: /* }}} */
                   1072: 
                   1073: /* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])
                   1074:    Opens a persistent connection to a MySQL Server */
                   1075: PHP_FUNCTION(mysql_pconnect)
                   1076: {
                   1077:        php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   1078: }
                   1079: /* }}} */
                   1080: 
                   1081: /* {{{ proto bool mysql_close([int link_identifier])
                   1082:    Close a MySQL connection */
                   1083: PHP_FUNCTION(mysql_close)
                   1084: {
                   1085:        int resource_id;
                   1086:        zval *mysql_link=NULL;
                   1087:        php_mysql_conn *mysql;
                   1088: 
                   1089:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1090:                return;
                   1091:        }
                   1092: 
                   1093:        if (mysql_link) {
                   1094:                ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink);
                   1095:        } else {
                   1096:                ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink);
                   1097:        }
                   1098: 
                   1099:        resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link);
                   1100:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1101: #ifdef MYSQL_USE_MYSQLND
                   1102:        {
                   1103:                int tmp;
                   1104:                if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) {
                   1105:                        mysqlnd_end_psession(mysql->conn);
                   1106:                }
                   1107:        }
                   1108: #endif
                   1109:        zend_list_delete(resource_id);
                   1110: 
                   1111:        if (!mysql_link
                   1112:                || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) {
                   1113:                MySG(default_link) = -1;
                   1114:                if (mysql_link) {
                   1115:                        /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */
                   1116:                        zend_list_delete(resource_id);
                   1117:                }
                   1118:        }
                   1119: 
                   1120:        RETURN_TRUE;
                   1121: }
                   1122: /* }}} */
                   1123: 
                   1124: /* {{{ proto bool mysql_select_db(string database_name [, int link_identifier])
                   1125:    Selects a MySQL database */
                   1126: PHP_FUNCTION(mysql_select_db)
                   1127: {
                   1128:        char *db;
                   1129:        int db_len;
                   1130:        zval *mysql_link = NULL;
                   1131:        int id = -1;
                   1132:        php_mysql_conn *mysql;
                   1133: 
                   1134:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1135:                return;
                   1136:        }
                   1137: 
                   1138:        if (!mysql_link) {
                   1139:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1140:                CHECK_LINK(id);
                   1141:        }
                   1142: 
                   1143:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1144: 
                   1145:        if (php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1146:                RETURN_TRUE;
                   1147:        } else {
                   1148:                RETURN_FALSE;
                   1149:        }
                   1150: }
                   1151: /* }}} */
                   1152: 
                   1153: #ifdef HAVE_GETINFO_FUNCS
                   1154: 
                   1155: /* {{{ proto string mysql_get_client_info(void)
                   1156:    Returns a string that represents the client library version */
                   1157: PHP_FUNCTION(mysql_get_client_info)
                   1158: {
                   1159:        if (zend_parse_parameters_none() == FAILURE) {
                   1160:                return;
                   1161:        }
                   1162: 
                   1163:        RETURN_STRING((char *)mysql_get_client_info(),1);
                   1164: }
                   1165: /* }}} */
                   1166: 
                   1167: /* {{{ proto string mysql_get_host_info([int link_identifier])
                   1168:    Returns a string describing the type of connection in use, including the server host name */
                   1169: PHP_FUNCTION(mysql_get_host_info)
                   1170: {
                   1171:        zval *mysql_link = NULL;
                   1172:        int id = -1;
                   1173:        php_mysql_conn *mysql;
                   1174: 
                   1175:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1176:                return;
                   1177:        }
                   1178: 
                   1179:        if (!mysql_link) {
                   1180:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1181:                CHECK_LINK(id);
                   1182:        }
                   1183: 
                   1184:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1185: 
                   1186:        RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1);
                   1187: }
                   1188: /* }}} */
                   1189: 
                   1190: /* {{{ proto int mysql_get_proto_info([int link_identifier])
                   1191:    Returns the protocol version used by current connection */
                   1192: PHP_FUNCTION(mysql_get_proto_info)
                   1193: {
                   1194:        zval *mysql_link = NULL;
                   1195:        int id = -1;
                   1196:        php_mysql_conn *mysql;
                   1197: 
                   1198:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1199:                return;
                   1200:        }
                   1201: 
                   1202:        if (!mysql_link) {
                   1203:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1204:                CHECK_LINK(id);
                   1205:        }
                   1206: 
                   1207:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1208: 
                   1209:        RETURN_LONG(mysql_get_proto_info(mysql->conn));
                   1210: }
                   1211: /* }}} */
                   1212: 
                   1213: /* {{{ proto string mysql_get_server_info([int link_identifier])
                   1214:    Returns a string that represents the server version number */
                   1215: PHP_FUNCTION(mysql_get_server_info)
                   1216: {
                   1217:        zval *mysql_link = NULL;
                   1218:        int id = -1;
                   1219:        php_mysql_conn *mysql;
                   1220: 
                   1221:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1222:                return;
                   1223:        }
                   1224: 
                   1225:        if (!mysql_link) {
                   1226:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1227:                CHECK_LINK(id);
                   1228:        }
                   1229: 
                   1230:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1231: 
                   1232:        RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1);
                   1233: }
                   1234: /* }}} */
                   1235: 
                   1236: /* {{{ proto string mysql_info([int link_identifier])
                   1237:    Returns a string containing information about the most recent query */
                   1238: PHP_FUNCTION(mysql_info)
                   1239: {
                   1240:        zval *mysql_link = NULL;
                   1241:        int id = -1;
                   1242:        char *str;
                   1243:        php_mysql_conn *mysql;
                   1244: 
                   1245:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1246:                return;
                   1247:        }
                   1248: 
                   1249:        if (ZEND_NUM_ARGS() == 0) {
                   1250:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1251:                CHECK_LINK(id);
                   1252:        }
                   1253: 
                   1254:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1255: 
                   1256:        if ((str = (char *)mysql_info(mysql->conn))) {
                   1257:                RETURN_STRING(str,1);
                   1258:        } else {
                   1259:                RETURN_FALSE;
                   1260:        }
                   1261: }
                   1262: /* }}} */
                   1263: 
                   1264: /* {{{ proto int mysql_thread_id([int link_identifier])
                   1265:        Returns the thread id of current connection */
                   1266: PHP_FUNCTION(mysql_thread_id)
                   1267: {
                   1268:        zval *mysql_link = NULL;
                   1269:        int  id = -1;
                   1270:        php_mysql_conn *mysql;
                   1271: 
                   1272:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1273:                return;
                   1274:        }
                   1275: 
                   1276:        if (ZEND_NUM_ARGS() == 0) {
                   1277:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1278:                CHECK_LINK(id);
                   1279:        }
                   1280:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1281: 
                   1282:        RETURN_LONG((long) mysql_thread_id(mysql->conn));
                   1283: }
                   1284: /* }}} */
                   1285: 
                   1286: /* {{{ proto string mysql_stat([int link_identifier])
                   1287:        Returns a string containing status information */
                   1288: PHP_FUNCTION(mysql_stat)
                   1289: {
                   1290:        zval *mysql_link = NULL;
                   1291:        int id = -1;
                   1292:        php_mysql_conn *mysql;
                   1293:        char *stat;
                   1294: #ifdef MYSQL_USE_MYSQLND
                   1295:        uint stat_len;
                   1296: #endif
                   1297: 
                   1298:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1299:                return;
                   1300:        }
                   1301: 
                   1302:        if (ZEND_NUM_ARGS() == 0) {
                   1303:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1304:                CHECK_LINK(id);
                   1305:        }
                   1306:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1307: 
                   1308:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1309: #ifndef MYSQL_USE_MYSQLND
                   1310:        if ((stat = (char *)mysql_stat(mysql->conn))) {
                   1311:                RETURN_STRING(stat, 1);
                   1312: #else
                   1313:        if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) {
                   1314:                RETURN_STRINGL(stat, stat_len, 0);
                   1315: #endif
                   1316:        } else {
                   1317:                RETURN_FALSE;
                   1318:        }
                   1319: }
                   1320: /* }}} */
                   1321: 
                   1322: /* {{{ proto string mysql_client_encoding([int link_identifier])
                   1323:        Returns the default character set for the current connection */
                   1324: PHP_FUNCTION(mysql_client_encoding)
                   1325: {
                   1326:        zval *mysql_link = NULL;
                   1327:        int id = -1;
                   1328:        php_mysql_conn *mysql;
                   1329: 
                   1330:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1331:                return;
                   1332:        }
                   1333: 
                   1334:        if (ZEND_NUM_ARGS() == 0) {
                   1335:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1336:                CHECK_LINK(id);
                   1337:        }
                   1338: 
                   1339:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1340:        RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1);
                   1341: }
                   1342: /* }}} */
                   1343: #endif
                   1344: 
                   1345: #ifdef MYSQL_HAS_SET_CHARSET
                   1346: /* {{{ proto bool mysql_set_charset(string csname [, int link_identifier])
                   1347:    sets client character set */
                   1348: PHP_FUNCTION(mysql_set_charset)
                   1349: {
                   1350:        zval *mysql_link = NULL;
                   1351:        char *csname;
                   1352:        int id = -1, csname_len;
                   1353:        php_mysql_conn *mysql;
                   1354: 
                   1355:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
                   1356:                return;
                   1357:        }
                   1358: 
                   1359:        if (ZEND_NUM_ARGS() == 1) {
                   1360:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1361:                CHECK_LINK(id);
                   1362:        }
                   1363: 
                   1364:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1365: 
                   1366:        if (!mysql_set_character_set(mysql->conn, csname)) {
                   1367:                RETURN_TRUE;
                   1368:        } else {
                   1369:                RETURN_FALSE;
                   1370:        }
                   1371: }
                   1372: /* }}} */
                   1373: #endif
                   1374: 
                   1375: #ifndef NETWARE                /* The below two functions not supported on NetWare */
                   1376: #if MYSQL_VERSION_ID < 40000
                   1377: /* {{{ proto bool mysql_create_db(string database_name [, int link_identifier])
                   1378:    Create a MySQL database */
                   1379: PHP_FUNCTION(mysql_create_db)
                   1380: {
                   1381:        char *db;
                   1382:        int db_len;
                   1383:        zval *mysql_link = NULL;
                   1384:        int id = -1;
                   1385:        php_mysql_conn *mysql;
                   1386: 
                   1387:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1388:                return;
                   1389:        }
                   1390: 
                   1391:        if (!mysql_link) {
                   1392:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1393:                CHECK_LINK(id);
                   1394:        }
                   1395: 
                   1396:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1397: 
                   1398:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1399: 
                   1400:        if (mysql_create_db(mysql->conn, db)==0) {
                   1401:                RETURN_TRUE;
                   1402:        } else {
                   1403:                RETURN_FALSE;
                   1404:        }
                   1405: }
                   1406: /* }}} */
                   1407: 
                   1408: /* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier])
                   1409:    Drops (delete) a MySQL database */
                   1410: PHP_FUNCTION(mysql_drop_db)
                   1411: {
                   1412:        char *db;
                   1413:        int db_len;
                   1414:        zval *mysql_link = NULL;
                   1415:        int id = -1;
                   1416:        php_mysql_conn *mysql;
                   1417: 
                   1418:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1419:                return;
                   1420:        }
                   1421: 
                   1422:        if (!mysql_link) {
                   1423:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1424:                CHECK_LINK(id);
                   1425:        }
                   1426: 
                   1427:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1428: 
                   1429:        if (mysql_drop_db(mysql->conn, db)==0) {
                   1430:                RETURN_TRUE;
                   1431:        } else {
                   1432:                RETURN_FALSE;
                   1433:        }
                   1434: }
                   1435: /* }}} */
                   1436: #endif
                   1437: #endif /* NETWARE */
                   1438: 
                   1439: /* {{{ php_mysql_do_query_general
                   1440:  */
                   1441: 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)
                   1442: {
                   1443:        php_mysql_conn *mysql;
                   1444:        MYSQL_RES *mysql_result;
                   1445: 
                   1446:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink);
                   1447: 
                   1448:        if (db) {
                   1449:                if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1450:                        RETURN_FALSE;
                   1451:                }
                   1452:        }
                   1453: 
                   1454:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1455: 
                   1456:        MYSQL_DISABLE_MQ;
                   1457: 
                   1458: #ifndef MYSQL_USE_MYSQLND
                   1459:        /* check explain */
                   1460:        if (MySG(trace_mode)) {
                   1461:                if (!strncasecmp("select", query, 6)){
                   1462:                        MYSQL_ROW       row;
                   1463: 
                   1464:                        char *newquery;
                   1465:                        int newql = spprintf (&newquery, 0, "EXPLAIN %s", query);
                   1466:                        mysql_real_query(mysql->conn, newquery, newql);
                   1467:                        efree (newquery);
                   1468:                        if (mysql_errno(mysql->conn)) {
                   1469:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1470:                                RETURN_FALSE;
                   1471:                        }
                   1472:                        else {
                   1473:                        mysql_result = mysql_use_result(mysql->conn);
                   1474:                                while ((row = mysql_fetch_row(mysql_result))) {
                   1475:                                        if (!strcmp("ALL", row[1])) {
                   1476:                                                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]);
                   1477:                                        } else if (!strcmp("INDEX", row[1])) {
                   1478:                                                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]);
                   1479:                                        }
                   1480:                                }
                   1481:                                mysql_free_result(mysql_result);
                   1482:                        }
                   1483:                }
                   1484:        } /* end explain */
                   1485: #endif
                   1486: 
                   1487:        /* mysql_query is binary unsafe, use mysql_real_query */
                   1488: #if MYSQL_VERSION_ID > 32199
                   1489:        if (mysql_real_query(mysql->conn, query, query_len)!=0) {
                   1490:                /* check possible error */
                   1491:                if (MySG(trace_mode)){
                   1492:                        if (mysql_errno(mysql->conn)){
                   1493:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1494:                        }
                   1495:                }
                   1496:                RETURN_FALSE;
                   1497:        }
                   1498: #else
                   1499:        if (mysql_query(mysql->conn, query)!=0) {
                   1500:                /* check possible error */
                   1501:                if (MySG(trace_mode)){
                   1502:                        if (mysql_errno(mysql->conn)){
                   1503:                                php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
                   1504:                        }
                   1505:                }
                   1506:                RETURN_FALSE;
                   1507:        }
                   1508: #endif
                   1509:        if(use_store == MYSQL_USE_RESULT) {
                   1510:                mysql_result=mysql_use_result(mysql->conn);
                   1511:        } else {
                   1512:                mysql_result=mysql_store_result(mysql->conn);
                   1513:        }
                   1514:        if (!mysql_result) {
                   1515:                if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
                   1516:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
                   1517:                        RETURN_FALSE;
                   1518:                } else {
                   1519:                        RETURN_TRUE;
                   1520:                }
                   1521:        }
                   1522:        MySG(result_allocated)++;
                   1523:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1524:        if (use_store == MYSQL_USE_RESULT) {
                   1525:                mysql->active_result_id = Z_LVAL_P(return_value);
                   1526:        }
                   1527: }
                   1528: /* }}} */
                   1529: 
                   1530: /* {{{ php_mysql_do_query
                   1531:  */
                   1532: static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store)
                   1533: {
                   1534:        char *query;
                   1535:        int query_len;
                   1536:        zval *mysql_link = NULL;
                   1537:        int id = -1;
                   1538: 
                   1539:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) {
                   1540:                return;
                   1541:        }
                   1542: 
                   1543:        if (!mysql_link) {
                   1544:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1545:                CHECK_LINK(id);
                   1546:        }
                   1547: 
                   1548:        php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC);
                   1549: }
                   1550: /* }}} */
                   1551: 
                   1552: /* {{{ proto resource mysql_query(string query [, int link_identifier])
                   1553:    Sends an SQL query to MySQL */
                   1554: PHP_FUNCTION(mysql_query)
                   1555: {
                   1556:        php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
                   1557: }
                   1558: /* }}} */
                   1559: 
                   1560: 
                   1561: /* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
                   1562:    Sends an SQL query to MySQL, without fetching and buffering the result rows */
                   1563: PHP_FUNCTION(mysql_unbuffered_query)
                   1564: {
                   1565:        php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
                   1566: }
                   1567: /* }}} */
                   1568: 
                   1569: 
                   1570: /* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier])
                   1571:    Sends an SQL query to MySQL */
                   1572: PHP_FUNCTION(mysql_db_query)
                   1573: {
                   1574:        char *db, *query;
                   1575:        int db_len, query_len;
                   1576:        zval *mysql_link = NULL;
                   1577:        int id = -1;
                   1578: 
                   1579:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) {
                   1580:                return;
                   1581:        }
                   1582: 
                   1583:        if (!mysql_link) {
                   1584:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1585:                CHECK_LINK(id);
                   1586:        }
                   1587: 
                   1588:        php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead");
                   1589: 
                   1590:        php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC);
                   1591: }
                   1592: /* }}} */
                   1593: 
                   1594: 
                   1595: /* {{{ proto resource mysql_list_dbs([int link_identifier])
                   1596:    List databases available on a MySQL server */
                   1597: PHP_FUNCTION(mysql_list_dbs)
                   1598: {
                   1599:        zval *mysql_link = NULL;
                   1600:        int id = -1;
                   1601:        php_mysql_conn *mysql;
                   1602:        MYSQL_RES *mysql_result;
                   1603: 
                   1604:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1605:                return;
                   1606:        }
                   1607: 
                   1608:        if (!mysql_link) {
                   1609:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1610:                CHECK_LINK(id);
                   1611:        }
1.1.1.2   misho    1612:        php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() with SHOW DATABASES instead");
1.1       misho    1613: 
                   1614:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1615: 
                   1616:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1617: 
1.1.1.2   misho    1618: 
1.1       misho    1619:        if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) {
                   1620:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1621:                RETURN_FALSE;
                   1622:        }
                   1623:        MySG(result_allocated)++;
                   1624:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1625: }
                   1626: /* }}} */
                   1627: 
                   1628: 
                   1629: /* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier])
                   1630:    List tables in a MySQL database */
                   1631: PHP_FUNCTION(mysql_list_tables)
                   1632: {
                   1633:        char *db;
                   1634:        int db_len;
                   1635:        zval *mysql_link = NULL;
                   1636:        int id = -1;
                   1637:        php_mysql_conn *mysql;
                   1638:        MYSQL_RES *mysql_result;
                   1639: 
                   1640:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
                   1641:                return;
                   1642:        }
                   1643: 
                   1644:        if (!mysql_link) {
                   1645:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1646:                CHECK_LINK(id);
                   1647:        }
                   1648: 
                   1649:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1650: 
                   1651:        if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1652:                RETURN_FALSE;
                   1653:        }
                   1654: 
                   1655:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1656: 
                   1657:        if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) {
                   1658:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1659:                RETURN_FALSE;
                   1660:        }
                   1661:        MySG(result_allocated)++;
                   1662:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1663: }
                   1664: /* }}} */
                   1665: 
                   1666: 
                   1667: /* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier])
                   1668:    List MySQL result fields */
                   1669: PHP_FUNCTION(mysql_list_fields)
                   1670: {
                   1671:        char *db, *table;
                   1672:        int db_len, table_len;
                   1673:        zval *mysql_link = NULL;
                   1674:        int id = -1;
                   1675:        php_mysql_conn *mysql;
                   1676:        MYSQL_RES *mysql_result;
                   1677: 
                   1678:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) {
                   1679:                return;
                   1680:        }
                   1681: 
                   1682:        if (!mysql_link) {
                   1683:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1684:                CHECK_LINK(id);
                   1685:        }
                   1686: 
                   1687:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1688: 
                   1689:        if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
                   1690:                RETURN_FALSE;
                   1691:        }
                   1692: 
                   1693:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1694: 
                   1695:        if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) {
                   1696:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1697:                RETURN_FALSE;
                   1698:        }
                   1699:        MySG(result_allocated)++;
                   1700:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1701: }
                   1702: /* }}} */
                   1703: 
                   1704: /* {{{ proto resource mysql_list_processes([int link_identifier])
                   1705:        Returns a result set describing the current server threads */
                   1706: PHP_FUNCTION(mysql_list_processes)
                   1707: {
                   1708:        zval *mysql_link = NULL;
                   1709:        int id = -1;
                   1710:        php_mysql_conn *mysql;
                   1711:        MYSQL_RES *mysql_result;
                   1712: 
                   1713:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1714:                return;
                   1715:        }
                   1716: 
                   1717:        if (ZEND_NUM_ARGS() == 0) {
                   1718:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1719:                CHECK_LINK(id);
                   1720:        }
                   1721: 
                   1722:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1723: 
                   1724:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   1725: 
                   1726:        mysql_result = mysql_list_processes(mysql->conn);
                   1727:        if (mysql_result == NULL) {
                   1728:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
                   1729:                RETURN_FALSE;
                   1730:        }
                   1731: 
                   1732:        MySG(result_allocated)++;
                   1733:        ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
                   1734: }
                   1735: /* }}} */
                   1736: 
                   1737: 
                   1738: /* {{{ proto string mysql_error([int link_identifier])
                   1739:    Returns the text of the error message from previous MySQL operation */
                   1740: PHP_FUNCTION(mysql_error)
                   1741: {
                   1742:        zval *mysql_link = NULL;
                   1743:        int id = -1;
                   1744:        php_mysql_conn *mysql;
                   1745: 
                   1746:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1747:                return;
                   1748:        }
                   1749: 
                   1750:        if (!mysql_link) {
                   1751:                id = MySG(default_link);
                   1752:                if (id==-1) {
                   1753:                        if (MySG(connect_error)!=NULL){
                   1754:                                RETURN_STRING(MySG(connect_error),1);
                   1755:                        } else {
                   1756:                                RETURN_FALSE;
                   1757:                        }
                   1758:                }
                   1759:        }
                   1760: 
                   1761:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1762: 
                   1763:        RETURN_STRING((char *)mysql_error(mysql->conn), 1);
                   1764: }
                   1765: /* }}} */
                   1766: 
                   1767: 
                   1768: /* {{{ proto int mysql_errno([int link_identifier])
                   1769:    Returns the number of the error message from previous MySQL operation */
                   1770: #ifdef HAVE_MYSQL_ERRNO
                   1771: PHP_FUNCTION(mysql_errno)
                   1772: {
                   1773:        zval *mysql_link = NULL;
                   1774:        int id = -1;
                   1775:        php_mysql_conn *mysql;
                   1776: 
                   1777:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1778:                return;
                   1779:        }
                   1780: 
                   1781:        if (!mysql_link) {
                   1782:                id = MySG(default_link);
                   1783:                if (id==-1) {
                   1784:                        if (MySG(connect_errno)!=0){
                   1785:                                RETURN_LONG(MySG(connect_errno));
                   1786:                        } else {
                   1787:                                RETURN_FALSE;
                   1788:                        }
                   1789:                }
                   1790:        }
                   1791: 
                   1792:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1793: 
                   1794:        RETURN_LONG(mysql_errno(mysql->conn));
                   1795: }
                   1796: #endif
                   1797: /* }}} */
                   1798: 
                   1799: 
                   1800: /* {{{ proto int mysql_affected_rows([int link_identifier])
                   1801:    Gets number of affected rows in previous MySQL operation */
                   1802: PHP_FUNCTION(mysql_affected_rows)
                   1803: {
                   1804:        zval *mysql_link = NULL;
                   1805:        int id = -1;
                   1806:        php_mysql_conn *mysql;
                   1807: 
                   1808:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1809:                return;
                   1810:        }
                   1811: 
                   1812:        if (!mysql_link) {
                   1813:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1814:                CHECK_LINK(id);
                   1815:        }
                   1816: 
                   1817:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1818: 
                   1819:        /* conversion from int64 to long happing here */
                   1820:        Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn);
                   1821:        Z_TYPE_P(return_value) = IS_LONG;
                   1822: }
                   1823: /* }}} */
                   1824: 
                   1825: 
                   1826: /* {{{ proto string mysql_escape_string(string to_be_escaped)
                   1827:    Escape string for mysql query */
                   1828: PHP_FUNCTION(mysql_escape_string)
                   1829: {
                   1830:        char *str;
                   1831:        int str_len;
                   1832: 
                   1833:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                   1834:                return;
                   1835:        }
                   1836: 
                   1837:        /* assume worst case situation, which is 2x of the original string.
                   1838:         * we don't realloc() down to the real size since it'd most probably not
                   1839:         * be worth it
                   1840:         */
                   1841: 
                   1842:        Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1);
                   1843:        Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len);
                   1844:        Z_TYPE_P(return_value) = IS_STRING;
                   1845: 
1.1.1.2   misho    1846:        php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead.");
1.1       misho    1847: }
                   1848: /* }}} */
                   1849: 
                   1850: /* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier])
                   1851:        Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
                   1852: PHP_FUNCTION(mysql_real_escape_string)
                   1853: {
                   1854:        zval *mysql_link = NULL;
                   1855:        char *str;
                   1856:        char *new_str;
                   1857:        int id = -1, str_len, new_str_len;
                   1858:        php_mysql_conn *mysql;
                   1859: 
                   1860: 
                   1861:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {
                   1862:                return;
                   1863:        }
                   1864: 
                   1865:        if (ZEND_NUM_ARGS() == 1) {
                   1866:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1867:                CHECK_LINK(id);
                   1868:        }
                   1869: 
                   1870:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1871: 
                   1872:        new_str = safe_emalloc(str_len, 2, 1);
                   1873:        new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len);
                   1874:        new_str = erealloc(new_str, new_str_len + 1);
                   1875: 
                   1876:        RETURN_STRINGL(new_str, new_str_len, 0);
                   1877: }
                   1878: /* }}} */
                   1879: 
                   1880: /* {{{ proto int mysql_insert_id([int link_identifier])
                   1881:    Gets the ID generated from the previous INSERT operation */
                   1882: PHP_FUNCTION(mysql_insert_id)
                   1883: {
                   1884:        zval *mysql_link = NULL;
                   1885:        int id = -1;
                   1886:        php_mysql_conn *mysql;
                   1887: 
                   1888:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
                   1889:                return;
                   1890:        }
                   1891: 
                   1892:        if (!mysql_link) {
                   1893:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   1894:                CHECK_LINK(id);
                   1895:        }
                   1896: 
                   1897:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   1898: 
                   1899:        /* conversion from int64 to long happing here */
                   1900:        Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn);
                   1901:        Z_TYPE_P(return_value) = IS_LONG;
                   1902: }
                   1903: /* }}} */
                   1904: 
                   1905: 
                   1906: /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
                   1907:    Gets result data */
                   1908: PHP_FUNCTION(mysql_result)
                   1909: {
                   1910:        zval *result, *field=NULL;
                   1911:        long row;
                   1912:        MYSQL_RES *mysql_result;
                   1913: #ifndef MYSQL_USE_MYSQLND
                   1914:        MYSQL_ROW sql_row;
                   1915:        mysql_row_length_type *sql_row_lengths;
                   1916: #endif
                   1917:        int field_offset=0;
                   1918: 
                   1919: /*
                   1920: johannes TODO:
1.1.1.4   misho    1921: Do 2 zend_parse_parameters calls instead of type "z" and switch below
1.1       misho    1922: Q: String or long first?
                   1923: */
                   1924:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) {
                   1925:                return;
                   1926:        }
                   1927: 
                   1928:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   1929: 
                   1930:        if (row<0 || row>=(int)mysql_num_rows(mysql_result)) {
                   1931:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result));
                   1932:                RETURN_FALSE;
                   1933:        }
                   1934:        mysql_data_seek(mysql_result, row);
                   1935: 
                   1936:        if (field) {
                   1937:                switch(Z_TYPE_P(field)) {
                   1938:                        case IS_STRING: {
                   1939:                                        int i=0;
                   1940:                                        const MYSQL_FIELD *tmp_field;
                   1941:                                        char *table_name, *field_name, *tmp;
                   1942: 
                   1943:                                        if ((tmp=strchr(Z_STRVAL_P(field), '.'))) {
                   1944:                                                table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field));
                   1945:                                                field_name = estrdup(tmp+1);
                   1946:                                        } else {
                   1947:                                                table_name = NULL;
                   1948:                                                field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field));
                   1949:                                        }
                   1950:                                        mysql_field_seek(mysql_result, 0);
                   1951:                                        while ((tmp_field=mysql_fetch_field(mysql_result))) {
                   1952:                                                if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
                   1953:                                                        field_offset = i;
                   1954:                                                        break;
                   1955:                                                }
                   1956:                                                i++;
                   1957:                                        }
                   1958:                                        if (!tmp_field) { /* no match found */
                   1959:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld",
                   1960:                                                                        (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result));
                   1961:                                                efree(field_name);
                   1962:                                                if (table_name) {
                   1963:                                                        efree(table_name);
                   1964:                                                }
                   1965:                                                RETURN_FALSE;
                   1966:                                        }
                   1967:                                        efree(field_name);
                   1968:                                        if (table_name) {
                   1969:                                                efree(table_name);
                   1970:                                        }
                   1971:                                }
                   1972:                                break;
                   1973:                        default:
                   1974:                                convert_to_long_ex(&field);
                   1975:                                field_offset = Z_LVAL_P(field);
                   1976:                                if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) {
                   1977:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
                   1978:                                        RETURN_FALSE;
                   1979:                                }
                   1980:                                break;
                   1981:                }
                   1982:        }
                   1983: 
                   1984: #ifndef MYSQL_USE_MYSQLND
                   1985:        if ((sql_row=mysql_fetch_row(mysql_result))==NULL
                   1986:                || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */
                   1987:                RETURN_FALSE;
                   1988:        }
                   1989:        if (sql_row[field_offset]) {
                   1990:                Z_TYPE_P(return_value) = IS_STRING;
                   1991: 
1.1.1.2   misho    1992: #if PHP_API_VERSION < 20100412         
1.1       misho    1993:                if (PG(magic_quotes_runtime)) {
                   1994:                        Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
                   1995:                } else {
1.1.1.2   misho    1996: #endif                 
1.1       misho    1997:                        Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
                   1998:                        Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
1.1.1.2   misho    1999: #if PHP_API_VERSION < 20100412
1.1       misho    2000:                }
1.1.1.2   misho    2001: #endif         
1.1       misho    2002:        } else {
                   2003:                Z_TYPE_P(return_value) = IS_NULL;
                   2004:        }
                   2005: #else
                   2006:        mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value);
                   2007: #endif
                   2008: }
                   2009: /* }}} */
                   2010: 
                   2011: 
                   2012: /* {{{ proto int mysql_num_rows(resource result)
                   2013:    Gets number of rows in a result */
                   2014: PHP_FUNCTION(mysql_num_rows)
                   2015: {
                   2016:        zval *result;
                   2017:        MYSQL_RES *mysql_result;
                   2018: 
                   2019:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2020:                return;
                   2021:        }
                   2022: 
                   2023:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2024: 
                   2025:        /* conversion from int64 to long happing here */
                   2026:        Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result);
                   2027:        Z_TYPE_P(return_value) = IS_LONG;
                   2028: }
                   2029: /* }}} */
                   2030: 
                   2031: /* {{{ proto int mysql_num_fields(resource result)
                   2032:    Gets number of fields in a result */
                   2033: PHP_FUNCTION(mysql_num_fields)
                   2034: {
                   2035:        zval *result;
                   2036:        MYSQL_RES *mysql_result;
                   2037: 
                   2038:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2039:                return;
                   2040:        }
                   2041: 
                   2042:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2043: 
                   2044:        Z_LVAL_P(return_value) = mysql_num_fields(mysql_result);
                   2045:        Z_TYPE_P(return_value) = IS_LONG;
                   2046: }
                   2047: /* }}} */
                   2048: 
                   2049: /* {{{ php_mysql_fetch_hash
                   2050:  */
                   2051: static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object)
                   2052: {
                   2053:        MYSQL_RES *mysql_result;
                   2054:        zval            *res, *ctor_params = NULL;
                   2055:        zend_class_entry *ce = NULL;
                   2056: #ifndef MYSQL_USE_MYSQLND
                   2057:        int i;
                   2058:        MYSQL_FIELD *mysql_field;
                   2059:        MYSQL_ROW mysql_row;
                   2060:        mysql_row_length_type *mysql_row_lengths;
                   2061: #endif
                   2062: 
                   2063: #ifdef ZEND_ENGINE_2
                   2064:        if (into_object) {
                   2065:                char *class_name = NULL;
                   2066:                int class_name_len = 0;
                   2067: 
                   2068:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) {
                   2069:                        return;
                   2070:                }
                   2071: 
                   2072:                if (ZEND_NUM_ARGS() < 2) {
                   2073:                        ce = zend_standard_class_def;
                   2074:                } else {
                   2075:                        ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
                   2076:                }
                   2077:                if (!ce) {
                   2078:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
                   2079:                        return;
                   2080:                }
                   2081:                result_type = MYSQL_ASSOC;
                   2082:        } else
                   2083: #endif
                   2084:        {
                   2085:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) {
                   2086:                        return;
                   2087:                }
                   2088:                if (!result_type) {
                   2089:                        /* result_type might have been set outside, so only overwrite when not set */
                   2090:                        result_type = MYSQL_BOTH;
                   2091:                }
                   2092:        }
                   2093: 
                   2094:        if (result_type & ~MYSQL_BOTH) {
                   2095:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
                   2096:                result_type = MYSQL_BOTH;
                   2097:        }
                   2098: 
                   2099:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result);
                   2100: 
                   2101: #ifndef MYSQL_USE_MYSQLND
                   2102:        if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL  ||
                   2103:                (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) {
                   2104:                RETURN_FALSE;
                   2105:        }
                   2106: 
                   2107:        array_init(return_value);
                   2108: 
                   2109:        mysql_field_seek(mysql_result, 0);
                   2110:        for (mysql_field = mysql_fetch_field(mysql_result), i = 0;
                   2111:                 mysql_field;
                   2112:                 mysql_field = mysql_fetch_field(mysql_result), i++)
                   2113:        {
                   2114:                if (mysql_row[i]) {
                   2115:                        zval *data;
                   2116: 
                   2117:                        MAKE_STD_ZVAL(data);
                   2118: 
1.1.1.2   misho    2119: #if PHP_API_VERSION < 20100412                 
1.1       misho    2120:                        if (PG(magic_quotes_runtime)) {
                   2121:                                Z_TYPE_P(data) = IS_STRING;
                   2122:                                Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
                   2123:                        } else {
1.1.1.2   misho    2124: #endif                                 
1.1       misho    2125:                                ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
1.1.1.2   misho    2126: #if PHP_API_VERSION < 20100412                         
1.1       misho    2127:                        }
1.1.1.2   misho    2128: #endif                 
1.1       misho    2129: 
                   2130:                        if (result_type & MYSQL_NUM) {
                   2131:                                add_index_zval(return_value, i, data);
                   2132:                        }
                   2133:                        if (result_type & MYSQL_ASSOC) {
                   2134:                                if (result_type & MYSQL_NUM) {
                   2135:                                        Z_ADDREF_P(data);
                   2136:                                }
                   2137:                                add_assoc_zval(return_value, mysql_field->name, data);
                   2138:                        }
                   2139:                } else {
                   2140:                        /* NULL value. */
                   2141:                        if (result_type & MYSQL_NUM) {
                   2142:                                add_index_null(return_value, i);
                   2143:                        }
                   2144: 
                   2145:                        if (result_type & MYSQL_ASSOC) {
                   2146:                                add_assoc_null(return_value, mysql_field->name);
                   2147:                        }
                   2148:                }
                   2149:        }
                   2150: #else
                   2151:        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);
                   2152: #endif
                   2153: 
                   2154: #ifdef ZEND_ENGINE_2
                   2155:        /* mysqlnd might return FALSE if no more rows */
                   2156:        if (into_object && Z_TYPE_P(return_value) != IS_BOOL) {
                   2157:                zval dataset = *return_value;
                   2158:                zend_fcall_info fci;
                   2159:                zend_fcall_info_cache fcc;
                   2160:                zval *retval_ptr;
                   2161: 
                   2162:                object_and_properties_init(return_value, ce, NULL);
                   2163:                zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
                   2164: 
                   2165:                if (ce->constructor) {
                   2166:                        fci.size = sizeof(fci);
                   2167:                        fci.function_table = &ce->function_table;
                   2168:                        fci.function_name = NULL;
                   2169:                        fci.symbol_table = NULL;
                   2170:                        fci.object_ptr = return_value;
                   2171:                        fci.retval_ptr_ptr = &retval_ptr;
                   2172:                        if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
                   2173:                                if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
                   2174:                                        HashTable *htl = Z_ARRVAL_P(ctor_params);
                   2175:                                        Bucket *p;
                   2176: 
                   2177:                                        fci.param_count = 0;
                   2178:                                        fci.params = safe_emalloc(sizeof(zval*), htl->nNumOfElements, 0);
                   2179:                                        p = htl->pListHead;
                   2180:                                        while (p != NULL) {
                   2181:                                                fci.params[fci.param_count++] = (zval**)p->pData;
                   2182:                                                p = p->pListNext;
                   2183:                                        }
                   2184:                                } else {
                   2185:                                        /* Two problems why we throw exceptions here: PHP is typeless
                   2186:                                         * and hence passing one argument that's not an array could be
                   2187:                                         * by mistake and the other way round is possible, too. The
                   2188:                                         * single value is an array. Also we'd have to make that one
                   2189:                                         * argument passed by reference.
                   2190:                                         */
                   2191:                                        zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
                   2192:                                        return;
                   2193:                                }
                   2194:                        } else {
                   2195:                                fci.param_count = 0;
                   2196:                                fci.params = NULL;
                   2197:                        }
                   2198:                        fci.no_separation = 1;
                   2199: 
                   2200:                        fcc.initialized = 1;
                   2201:                        fcc.function_handler = ce->constructor;
                   2202:                        fcc.calling_scope = EG(scope);
                   2203:                        fcc.called_scope = Z_OBJCE_P(return_value);
                   2204:                        fcc.object_ptr = return_value;
                   2205: 
                   2206:                        if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                   2207:                                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);
                   2208:                        } else {
                   2209:                                if (retval_ptr) {
                   2210:                                        zval_ptr_dtor(&retval_ptr);
                   2211:                                }
                   2212:                        }
                   2213:                        if (fci.params) {
                   2214:                                efree(fci.params);
                   2215:                        }
                   2216:                } else if (ctor_params) {
                   2217:                        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);
                   2218:                }
                   2219:        }
                   2220: #endif
                   2221: 
                   2222: }
                   2223: /* }}} */
                   2224: 
                   2225: /* {{{ proto array mysql_fetch_row(resource result)
                   2226:    Gets a result row as an enumerated array */
                   2227: PHP_FUNCTION(mysql_fetch_row)
                   2228: {
                   2229:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0);
                   2230: }
                   2231: /* }}} */
                   2232: 
                   2233: 
                   2234: /* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])
                   2235:    Fetch a result row as an object */
                   2236: PHP_FUNCTION(mysql_fetch_object)
                   2237: {
                   2238:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1);
                   2239: 
                   2240:        if (Z_TYPE_P(return_value) == IS_ARRAY) {
                   2241:                object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
                   2242:        }
                   2243: }
                   2244: /* }}} */
                   2245: 
                   2246: 
                   2247: /* {{{ proto array mysql_fetch_array(resource result [, int result_type])
                   2248:    Fetch a result row as an array (associative, numeric or both) */
                   2249: PHP_FUNCTION(mysql_fetch_array)
                   2250: {
                   2251:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
                   2252: }
                   2253: /* }}} */
                   2254: 
                   2255: 
                   2256: /* {{{ proto array mysql_fetch_assoc(resource result)
                   2257:    Fetch a result row as an associative array */
                   2258: PHP_FUNCTION(mysql_fetch_assoc)
                   2259: {
                   2260:        php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0);
                   2261: }
                   2262: /* }}} */
                   2263: 
                   2264: /* {{{ proto bool mysql_data_seek(resource result, int row_number)
                   2265:    Move internal result pointer */
                   2266: PHP_FUNCTION(mysql_data_seek)
                   2267: {
                   2268:        zval *result;
                   2269:        long offset;
                   2270:        MYSQL_RES *mysql_result;
                   2271: 
                   2272:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) {
                   2273:                return;
                   2274:        }
                   2275: 
                   2276:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2277: 
                   2278:        if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) {
                   2279:                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));
                   2280:                RETURN_FALSE;
                   2281:        }
                   2282:        mysql_data_seek(mysql_result, offset);
                   2283:        RETURN_TRUE;
                   2284: }
                   2285: /* }}} */
                   2286: 
                   2287: 
                   2288: /* {{{ proto array mysql_fetch_lengths(resource result)
                   2289:    Gets max data size of each column in a result */
                   2290: PHP_FUNCTION(mysql_fetch_lengths)
                   2291: {
                   2292:        zval *result;
                   2293:        MYSQL_RES *mysql_result;
                   2294:        mysql_row_length_type *lengths;
                   2295:        int num_fields;
                   2296:        int i;
                   2297: 
                   2298:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2299:                return;
                   2300:        }
                   2301: 
                   2302:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2303: 
                   2304:        if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) {
                   2305:                RETURN_FALSE;
                   2306:        }
                   2307:        array_init(return_value);
                   2308:        num_fields = mysql_num_fields(mysql_result);
                   2309: 
                   2310:        for (i=0; i<num_fields; i++) {
                   2311:                add_index_long(return_value, i, lengths[i]);
                   2312:        }
                   2313: }
                   2314: /* }}} */
                   2315: 
                   2316: /* {{{ php_mysql_get_field_name
                   2317:  */
                   2318: static char *php_mysql_get_field_name(int field_type)
                   2319: {
                   2320:        switch(field_type) {
                   2321:                case FIELD_TYPE_STRING:
                   2322:                case FIELD_TYPE_VAR_STRING:
                   2323:                        return "string";
                   2324:                        break;
                   2325: #if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND)
                   2326:                case MYSQL_TYPE_BIT:
                   2327: #endif
                   2328: #ifdef MYSQL_HAS_TINY
                   2329:                case FIELD_TYPE_TINY:
                   2330: #endif
                   2331:                case FIELD_TYPE_SHORT:
                   2332:                case FIELD_TYPE_LONG:
                   2333:                case FIELD_TYPE_LONGLONG:
                   2334:                case FIELD_TYPE_INT24:
                   2335:                        return "int";
                   2336:                        break;
                   2337:                case FIELD_TYPE_FLOAT:
                   2338:                case FIELD_TYPE_DOUBLE:
                   2339:                case FIELD_TYPE_DECIMAL:
                   2340: #ifdef FIELD_TYPE_NEWDECIMAL
                   2341:                case FIELD_TYPE_NEWDECIMAL:
                   2342: #endif
                   2343:                        return "real";
                   2344:                        break;
                   2345:                case FIELD_TYPE_TIMESTAMP:
                   2346:                        return "timestamp";
                   2347:                        break;
                   2348: #ifdef MYSQL_HAS_YEAR
                   2349:                case FIELD_TYPE_YEAR:
                   2350:                        return "year";
                   2351:                        break;
                   2352: #endif
                   2353:                case FIELD_TYPE_DATE:
                   2354: #ifdef FIELD_TYPE_NEWDATE
                   2355:                case FIELD_TYPE_NEWDATE:
                   2356: #endif
                   2357:                        return "date";
                   2358:                        break;
                   2359:                case FIELD_TYPE_TIME:
                   2360:                        return "time";
                   2361:                        break;
                   2362:                case FIELD_TYPE_SET:
                   2363:                        return "set";
                   2364:                        break;
                   2365:                case FIELD_TYPE_ENUM:
                   2366:                        return "enum";
                   2367:                        break;
                   2368: #ifdef FIELD_TYPE_GEOMETRY
                   2369:                case FIELD_TYPE_GEOMETRY:
                   2370:                        return "geometry";
                   2371:                        break;
                   2372: #endif
                   2373:                case FIELD_TYPE_DATETIME:
                   2374:                        return "datetime";
                   2375:                        break;
                   2376:                case FIELD_TYPE_TINY_BLOB:
                   2377:                case FIELD_TYPE_MEDIUM_BLOB:
                   2378:                case FIELD_TYPE_LONG_BLOB:
                   2379:                case FIELD_TYPE_BLOB:
                   2380:                        return "blob";
                   2381:                        break;
                   2382:                case FIELD_TYPE_NULL:
                   2383:                        return "null";
                   2384:                        break;
                   2385:                default:
                   2386:                        return "unknown";
                   2387:                        break;
                   2388:        }
                   2389: }
                   2390: /* }}} */
                   2391: 
                   2392: /* {{{ proto object mysql_fetch_field(resource result [, int field_offset])
                   2393:    Gets column information from a result and return as an object */
                   2394: PHP_FUNCTION(mysql_fetch_field)
                   2395: {
                   2396:        zval *result;
                   2397:        long field=0;
                   2398:        MYSQL_RES *mysql_result;
                   2399:        const MYSQL_FIELD *mysql_field;
                   2400: 
                   2401:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) {
                   2402:                return;
                   2403:        }
                   2404: 
                   2405:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2406: 
                   2407:        if (ZEND_NUM_ARGS() > 1) {
                   2408:                if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
                   2409:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset");
                   2410:                        RETURN_FALSE;
                   2411:                }
                   2412:                mysql_field_seek(mysql_result, field);
                   2413:        }
                   2414:        if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
                   2415:                RETURN_FALSE;
                   2416:        }
                   2417:        object_init(return_value);
                   2418: 
1.1.1.2   misho    2419:        add_property_string(return_value, "name",(mysql_field->name?mysql_field->name:""), 1);
                   2420:        add_property_string(return_value, "table",(mysql_field->table?mysql_field->table:""), 1);
1.1       misho    2421:        add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1);
                   2422:        add_property_long(return_value, "max_length", mysql_field->max_length);
                   2423:        add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
                   2424:        add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
                   2425:        add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
                   2426:        add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
                   2427:        add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0);
                   2428:        add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0);
                   2429:        add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1);
                   2430:        add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
                   2431:        add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
                   2432: }
                   2433: /* }}} */
                   2434: 
                   2435: 
                   2436: /* {{{ proto bool mysql_field_seek(resource result, int field_offset)
                   2437:    Sets result pointer to a specific field offset */
                   2438: PHP_FUNCTION(mysql_field_seek)
                   2439: {
                   2440:        zval *result;
                   2441:        long offset;
                   2442:        MYSQL_RES *mysql_result;
                   2443: 
                   2444:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) {
                   2445:                return;
                   2446:        }
                   2447:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2448: 
                   2449:        if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) {
                   2450:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result));
                   2451:                RETURN_FALSE;
                   2452:        }
                   2453:        mysql_field_seek(mysql_result, offset);
                   2454:        RETURN_TRUE;
                   2455: }
                   2456: /* }}} */
                   2457: 
                   2458: 
                   2459: #define PHP_MYSQL_FIELD_NAME 1
                   2460: #define PHP_MYSQL_FIELD_TABLE 2
                   2461: #define PHP_MYSQL_FIELD_LEN 3
                   2462: #define PHP_MYSQL_FIELD_TYPE 4
                   2463: #define PHP_MYSQL_FIELD_FLAGS 5
                   2464: 
                   2465: /* {{{ php_mysql_field_info
                   2466:  */
                   2467: static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
                   2468: {
                   2469:        zval *result;
                   2470:        long field;
                   2471:        MYSQL_RES *mysql_result;
                   2472:        const MYSQL_FIELD *mysql_field = {0};
                   2473:        char buf[512];
                   2474:        int  len;
                   2475: 
                   2476:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
                   2477:                return;
                   2478:        }
                   2479: 
                   2480:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2481: 
                   2482:        if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
                   2483:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result));
                   2484:                RETURN_FALSE;
                   2485:        }
                   2486:        mysql_field_seek(mysql_result, field);
                   2487:        if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
                   2488:                RETURN_FALSE;
                   2489:        }
                   2490: 
                   2491:        switch (entry_type) {
                   2492:                case PHP_MYSQL_FIELD_NAME:
                   2493:                        Z_STRLEN_P(return_value) = strlen(mysql_field->name);
                   2494:                        Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value));
                   2495:                        Z_TYPE_P(return_value) = IS_STRING;
                   2496:                        break;
                   2497:                case PHP_MYSQL_FIELD_TABLE:
                   2498:                        Z_STRLEN_P(return_value) = strlen(mysql_field->table);
                   2499:                        Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value));
                   2500:                        Z_TYPE_P(return_value) = IS_STRING;
                   2501:                        break;
                   2502:                case PHP_MYSQL_FIELD_LEN:
                   2503:                        Z_LVAL_P(return_value) = mysql_field->length;
                   2504:                        Z_TYPE_P(return_value) = IS_LONG;
                   2505:                        break;
                   2506:                case PHP_MYSQL_FIELD_TYPE:
                   2507:                        Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field));
                   2508:                        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                   2509:                        Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
                   2510:                        Z_TYPE_P(return_value) = IS_STRING;
                   2511:                        break;
                   2512:                case PHP_MYSQL_FIELD_FLAGS:
                   2513:                        memcpy(buf, "", sizeof(""));
                   2514: #ifdef IS_NOT_NULL
                   2515:                        if (IS_NOT_NULL(mysql_field->flags)) {
                   2516:                                strcat(buf, "not_null ");
                   2517:                        }
                   2518: #endif
                   2519: #ifdef IS_PRI_KEY
                   2520:                        if (IS_PRI_KEY(mysql_field->flags)) {
                   2521:                                strcat(buf, "primary_key ");
                   2522:                        }
                   2523: #endif
                   2524: #ifdef UNIQUE_KEY_FLAG
                   2525:                        if (mysql_field->flags&UNIQUE_KEY_FLAG) {
                   2526:                                strcat(buf, "unique_key ");
                   2527:                        }
                   2528: #endif
                   2529: #ifdef MULTIPLE_KEY_FLAG
                   2530:                        if (mysql_field->flags&MULTIPLE_KEY_FLAG) {
                   2531:                                strcat(buf, "multiple_key ");
                   2532:                        }
                   2533: #endif
                   2534: #ifdef IS_BLOB
                   2535:                        if (IS_BLOB(mysql_field->flags)) {
                   2536:                                strcat(buf, "blob ");
                   2537:                        }
                   2538: #endif
                   2539: #ifdef UNSIGNED_FLAG
                   2540:                        if (mysql_field->flags&UNSIGNED_FLAG) {
                   2541:                                strcat(buf, "unsigned ");
                   2542:                        }
                   2543: #endif
                   2544: #ifdef ZEROFILL_FLAG
                   2545:                        if (mysql_field->flags&ZEROFILL_FLAG) {
                   2546:                                strcat(buf, "zerofill ");
                   2547:                        }
                   2548: #endif
                   2549: #ifdef BINARY_FLAG
                   2550:                        if (mysql_field->flags&BINARY_FLAG) {
                   2551:                                strcat(buf, "binary ");
                   2552:                        }
                   2553: #endif
                   2554: #ifdef ENUM_FLAG
                   2555:                        if (mysql_field->flags&ENUM_FLAG) {
                   2556:                                strcat(buf, "enum ");
                   2557:                        }
                   2558: #endif
                   2559: #ifdef SET_FLAG
                   2560:                        if (mysql_field->flags&SET_FLAG) {
                   2561:                                strcat(buf, "set ");
                   2562:                        }
                   2563: #endif
                   2564: #ifdef AUTO_INCREMENT_FLAG
                   2565:                        if (mysql_field->flags&AUTO_INCREMENT_FLAG) {
                   2566:                                strcat(buf, "auto_increment ");
                   2567:                        }
                   2568: #endif
                   2569: #ifdef TIMESTAMP_FLAG
                   2570:                        if (mysql_field->flags&TIMESTAMP_FLAG) {
                   2571:                                strcat(buf, "timestamp ");
                   2572:                        }
                   2573: #endif
                   2574:                        len = strlen(buf);
                   2575:                        /* remove trailing space, if present */
                   2576:                        if (len && buf[len-1] == ' ') {
                   2577:                                buf[len-1] = 0;
                   2578:                                len--;
                   2579:                        }
                   2580: 
                   2581:                        Z_STRLEN_P(return_value) = len;
                   2582:                        Z_STRVAL_P(return_value) = estrndup(buf, len);
                   2583:                        Z_TYPE_P(return_value) = IS_STRING;
                   2584:                        break;
                   2585: 
                   2586:                default:
                   2587:                        RETURN_FALSE;
                   2588:        }
                   2589: }
                   2590: /* }}} */
                   2591: 
                   2592: /* {{{ proto string mysql_field_name(resource result, int field_index)
                   2593:    Gets the name of the specified field in a result */
                   2594: PHP_FUNCTION(mysql_field_name)
                   2595: {
                   2596:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME);
                   2597: }
                   2598: /* }}} */
                   2599: 
                   2600: 
                   2601: /* {{{ proto string mysql_field_table(resource result, int field_offset)
                   2602:    Gets name of the table the specified field is in */
                   2603: PHP_FUNCTION(mysql_field_table)
                   2604: {
                   2605:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE);
                   2606: }
                   2607: /* }}} */
                   2608: 
                   2609: 
                   2610: /* {{{ proto int mysql_field_len(resource result, int field_offset)
                   2611:    Returns the length of the specified field */
                   2612: PHP_FUNCTION(mysql_field_len)
                   2613: {
                   2614:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN);
                   2615: }
                   2616: /* }}} */
                   2617: 
                   2618: 
                   2619: /* {{{ proto string mysql_field_type(resource result, int field_offset)
                   2620:    Gets the type of the specified field in a result */
                   2621: PHP_FUNCTION(mysql_field_type)
                   2622: {
                   2623:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE);
                   2624: }
                   2625: /* }}} */
                   2626: 
                   2627: 
                   2628: /* {{{ proto string mysql_field_flags(resource result, int field_offset)
                   2629:    Gets the flags associated with the specified field in a result */
                   2630: PHP_FUNCTION(mysql_field_flags)
                   2631: {
                   2632:        php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS);
                   2633: }
                   2634: /* }}} */
                   2635: 
                   2636: 
                   2637: /* {{{ proto bool mysql_free_result(resource result)
                   2638:    Free result memory */
                   2639: PHP_FUNCTION(mysql_free_result)
                   2640: {
                   2641:        zval *result;
                   2642:        MYSQL_RES *mysql_result;
                   2643: 
                   2644:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
                   2645:                return;
                   2646:        }
                   2647: 
                   2648:        if (Z_LVAL_P(result)==0) {
                   2649:                RETURN_FALSE;
                   2650:        }
                   2651: 
                   2652:        ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
                   2653: 
                   2654:        zend_list_delete(Z_LVAL_P(result));
                   2655:        RETURN_TRUE;
                   2656: }
                   2657: /* }}} */
                   2658: 
                   2659: /* {{{ proto bool mysql_ping([int link_identifier])
                   2660:    Ping a server connection. If no connection then reconnect. */
                   2661: PHP_FUNCTION(mysql_ping)
                   2662: {
                   2663:        zval           *mysql_link = NULL;
                   2664:        int             id         = -1;
                   2665:        php_mysql_conn *mysql;
                   2666: 
                   2667:        if (0 == ZEND_NUM_ARGS()) {
                   2668:                id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
                   2669:                CHECK_LINK(id);
                   2670:        } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) {
                   2671:                return;
                   2672:        }
                   2673: 
                   2674:        ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
                   2675: 
                   2676:        PHPMY_UNBUFFERED_QUERY_CHECK();
                   2677: 
                   2678:        RETURN_BOOL(! mysql_ping(mysql->conn));
                   2679: }
                   2680: /* }}} */
                   2681: 
                   2682: #endif
                   2683: 
                   2684: /*
                   2685:  * Local variables:
                   2686:  * tab-width: 4
                   2687:  * c-basic-offset: 4
                   2688:  * End:
                   2689:  * vim600: sw=4 ts=4 fdm=marker
                   2690:  * vim<600: sw=4 ts=4
                   2691:  */

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