Annotation of embedaddon/php/ext/interbase/interbase.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Authors: Jouni Ahto <jouni.ahto@exdec.fi>                            |
        !            16:    |          Andrew Avdeev <andy@rsc.mv.ru>                              |
        !            17:    |          Ard Biesheuvel <a.k.biesheuvel@ewi.tudelft.nl>              |
        !            18:    +----------------------------------------------------------------------+
        !            19:  */
        !            20: 
        !            21: /* $Id: interbase.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            22: 
        !            23: #ifdef HAVE_CONFIG_H
        !            24: #include "config.h"
        !            25: #endif
        !            26: 
        !            27: #define _GNU_SOURCE
        !            28: 
        !            29: #include "php.h"
        !            30: 
        !            31: #if HAVE_IBASE
        !            32: 
        !            33: #include "php_ini.h"
        !            34: #include "ext/standard/php_standard.h"
        !            35: #include "ext/standard/md5.h"
        !            36: #include "php_interbase.h"
        !            37: #include "php_ibase_includes.h"
        !            38: #include "SAPI.h"
        !            39: 
        !            40: #include <time.h>
        !            41: 
        !            42: #define ROLLBACK               0
        !            43: #define COMMIT                 1
        !            44: #define RETAIN                 2
        !            45: 
        !            46: #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; } }
        !            47: 
        !            48: ZEND_DECLARE_MODULE_GLOBALS(ibase)
        !            49: static PHP_GINIT_FUNCTION(ibase);
        !            50: 
        !            51: /* {{{ arginfo */
        !            52: ZEND_BEGIN_ARG_INFO(arginfo_ibase_errmsg, 0)
        !            53: ZEND_END_ARG_INFO()
        !            54: 
        !            55: ZEND_BEGIN_ARG_INFO(arginfo_ibase_errcode, 0)
        !            56: ZEND_END_ARG_INFO()
        !            57: 
        !            58: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_connect, 0, 0, 1)
        !            59:        ZEND_ARG_INFO(0, database)
        !            60:        ZEND_ARG_INFO(0, username)
        !            61:        ZEND_ARG_INFO(0, password)
        !            62:        ZEND_ARG_INFO(0, charset)
        !            63:        ZEND_ARG_INFO(0, buffers)
        !            64:        ZEND_ARG_INFO(0, dialect)
        !            65:        ZEND_ARG_INFO(0, role)
        !            66: ZEND_END_ARG_INFO()
        !            67: 
        !            68: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_pconnect, 0, 0, 1)
        !            69:        ZEND_ARG_INFO(0, database)
        !            70:        ZEND_ARG_INFO(0, username)
        !            71:        ZEND_ARG_INFO(0, password)
        !            72:        ZEND_ARG_INFO(0, charset)
        !            73:        ZEND_ARG_INFO(0, buffers)
        !            74:        ZEND_ARG_INFO(0, dialect)
        !            75:        ZEND_ARG_INFO(0, role)
        !            76: ZEND_END_ARG_INFO()
        !            77: 
        !            78: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_close, 0, 0, 0)
        !            79:        ZEND_ARG_INFO(0, link_identifier)
        !            80: ZEND_END_ARG_INFO()
        !            81: 
        !            82: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_drop_db, 0, 0, 0)
        !            83:        ZEND_ARG_INFO(0, link_identifier)
        !            84: ZEND_END_ARG_INFO()
        !            85: 
        !            86: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_trans, 0, 0, 0)
        !            87:        ZEND_ARG_INFO(0, trans_args)
        !            88:        ZEND_ARG_INFO(0, link_identifier)
        !            89:        ZEND_ARG_INFO(0, trans_args)
        !            90:        ZEND_ARG_INFO(0, link_identifier)
        !            91: ZEND_END_ARG_INFO()
        !            92: 
        !            93: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit, 0, 0, 1)
        !            94:        ZEND_ARG_INFO(0, link_identifier)
        !            95: ZEND_END_ARG_INFO()
        !            96: 
        !            97: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback, 0, 0, 1)
        !            98:        ZEND_ARG_INFO(0, link_identifier)
        !            99: ZEND_END_ARG_INFO()
        !           100: 
        !           101: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit_ret, 0, 0, 1)
        !           102:        ZEND_ARG_INFO(0, link_identifier)
        !           103: ZEND_END_ARG_INFO()
        !           104: 
        !           105: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback_ret, 0, 0, 1)
        !           106:        ZEND_ARG_INFO(0, link_identifier)
        !           107: ZEND_END_ARG_INFO()
        !           108: 
        !           109: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_gen_id, 0, 0, 1)
        !           110:        ZEND_ARG_INFO(0, generator)
        !           111:        ZEND_ARG_INFO(0, increment)
        !           112:        ZEND_ARG_INFO(0, link_identifier)
        !           113: ZEND_END_ARG_INFO()
        !           114: 
        !           115: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_create, 0, 0, 0)
        !           116:        ZEND_ARG_INFO(0, link_identifier)
        !           117: ZEND_END_ARG_INFO()
        !           118: 
        !           119: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_open, 0, 0, 0)
        !           120:        ZEND_ARG_INFO(0, link_identifier)
        !           121:        ZEND_ARG_INFO(0, blob_id)
        !           122: ZEND_END_ARG_INFO()
        !           123: 
        !           124: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_add, 0, 0, 2)
        !           125:        ZEND_ARG_INFO(0, blob_handle)
        !           126:        ZEND_ARG_INFO(0, data)
        !           127: ZEND_END_ARG_INFO()
        !           128: 
        !           129: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_get, 0, 0, 2)
        !           130:        ZEND_ARG_INFO(0, blob_handle)
        !           131:        ZEND_ARG_INFO(0, len)
        !           132: ZEND_END_ARG_INFO()
        !           133: 
        !           134: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_close, 0, 0, 1)
        !           135:        ZEND_ARG_INFO(0, blob_handle)
        !           136: ZEND_END_ARG_INFO()
        !           137: 
        !           138: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_cancel, 0, 0, 1)
        !           139:        ZEND_ARG_INFO(0, blob_handle)
        !           140: ZEND_END_ARG_INFO()
        !           141: 
        !           142: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_info, 0, 0, 0)
        !           143:        ZEND_ARG_INFO(0, link_identifier)
        !           144:        ZEND_ARG_INFO(0, blob_id)
        !           145: ZEND_END_ARG_INFO()
        !           146: 
        !           147: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_echo, 0, 0, 0)
        !           148:        ZEND_ARG_INFO(0, link_identifier)
        !           149:        ZEND_ARG_INFO(0, blob_id)
        !           150: ZEND_END_ARG_INFO()
        !           151: 
        !           152: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_import, 0, 0, 0)
        !           153:        ZEND_ARG_INFO(0, link_identifier)
        !           154:        ZEND_ARG_INFO(0, file)
        !           155: ZEND_END_ARG_INFO()
        !           156: 
        !           157: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_query, 0, 0, 0)
        !           158:        ZEND_ARG_INFO(0, link_identifier)
        !           159:        ZEND_ARG_INFO(0, link_identifier)
        !           160:        ZEND_ARG_INFO(0, query)
        !           161:        ZEND_ARG_INFO(0, bind_arg)
        !           162:        ZEND_ARG_INFO(0, bind_arg)
        !           163: ZEND_END_ARG_INFO()
        !           164: 
        !           165: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_affected_rows, 0, 0, 0)
        !           166:        ZEND_ARG_INFO(0, link_identifier)
        !           167: ZEND_END_ARG_INFO()
        !           168: 
        !           169: #if abies_0
        !           170: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_rows, 0, 0, 1)
        !           171:        ZEND_ARG_INFO(0, result_identifier)
        !           172: ZEND_END_ARG_INFO()
        !           173: #endif
        !           174: 
        !           175: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_row, 0, 0, 1)
        !           176:        ZEND_ARG_INFO(0, result)
        !           177:        ZEND_ARG_INFO(0, fetch_flags)
        !           178: ZEND_END_ARG_INFO()
        !           179: 
        !           180: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_assoc, 0, 0, 1)
        !           181:        ZEND_ARG_INFO(0, result)
        !           182:        ZEND_ARG_INFO(0, fetch_flags)
        !           183: ZEND_END_ARG_INFO()
        !           184: 
        !           185: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_object, 0, 0, 1)
        !           186:        ZEND_ARG_INFO(0, result)
        !           187:        ZEND_ARG_INFO(0, fetch_flags)
        !           188: ZEND_END_ARG_INFO()
        !           189: 
        !           190: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_name_result, 0, 0, 2)
        !           191:        ZEND_ARG_INFO(0, result)
        !           192:        ZEND_ARG_INFO(0, name)
        !           193: ZEND_END_ARG_INFO()
        !           194: 
        !           195: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_result, 0, 0, 1)
        !           196:        ZEND_ARG_INFO(0, result)
        !           197: ZEND_END_ARG_INFO()
        !           198: 
        !           199: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_prepare, 0, 0, 0)
        !           200:        ZEND_ARG_INFO(0, link_identifier)
        !           201:        ZEND_ARG_INFO(0, query)
        !           202: ZEND_END_ARG_INFO()
        !           203: 
        !           204: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_execute, 0, 0, 1)
        !           205:        ZEND_ARG_INFO(0, query)
        !           206:        ZEND_ARG_INFO(0, bind_arg)
        !           207:        ZEND_ARG_INFO(0, bind_arg)
        !           208: ZEND_END_ARG_INFO()
        !           209: 
        !           210: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_query, 0, 0, 1)
        !           211:        ZEND_ARG_INFO(0, query)
        !           212: ZEND_END_ARG_INFO()
        !           213: 
        !           214: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_fields, 0, 0, 1)
        !           215:        ZEND_ARG_INFO(0, query_result)
        !           216: ZEND_END_ARG_INFO()
        !           217: 
        !           218: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_field_info, 0, 0, 2)
        !           219:        ZEND_ARG_INFO(0, query_result)
        !           220:        ZEND_ARG_INFO(0, field_number)
        !           221: ZEND_END_ARG_INFO()
        !           222: 
        !           223: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_params, 0, 0, 1)
        !           224:        ZEND_ARG_INFO(0, query)
        !           225: ZEND_END_ARG_INFO()
        !           226: 
        !           227: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_param_info, 0, 0, 2)
        !           228:        ZEND_ARG_INFO(0, query)
        !           229:        ZEND_ARG_INFO(0, field_number)
        !           230: ZEND_END_ARG_INFO()
        !           231: 
        !           232: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_add_user, 0, 0, 3)
        !           233:        ZEND_ARG_INFO(0, service_handle)
        !           234:        ZEND_ARG_INFO(0, user_name)
        !           235:        ZEND_ARG_INFO(0, password)
        !           236:        ZEND_ARG_INFO(0, first_name)
        !           237:        ZEND_ARG_INFO(0, middle_name)
        !           238:        ZEND_ARG_INFO(0, last_name)
        !           239: ZEND_END_ARG_INFO()
        !           240: 
        !           241: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_modify_user, 0, 0, 3)
        !           242:        ZEND_ARG_INFO(0, service_handle)
        !           243:        ZEND_ARG_INFO(0, user_name)
        !           244:        ZEND_ARG_INFO(0, password)
        !           245:        ZEND_ARG_INFO(0, first_name)
        !           246:        ZEND_ARG_INFO(0, middle_name)
        !           247:        ZEND_ARG_INFO(0, last_name)
        !           248: ZEND_END_ARG_INFO()
        !           249: 
        !           250: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_delete_user, 0, 0, 3)
        !           251:        ZEND_ARG_INFO(0, service_handle)
        !           252:        ZEND_ARG_INFO(0, user_name)
        !           253:        ZEND_ARG_INFO(0, password)
        !           254:        ZEND_ARG_INFO(0, first_name)
        !           255:        ZEND_ARG_INFO(0, middle_name)
        !           256:        ZEND_ARG_INFO(0, last_name)
        !           257: ZEND_END_ARG_INFO()
        !           258: 
        !           259: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_attach, 0, 0, 3)
        !           260:        ZEND_ARG_INFO(0, host)
        !           261:        ZEND_ARG_INFO(0, dba_username)
        !           262:        ZEND_ARG_INFO(0, dba_password)
        !           263: ZEND_END_ARG_INFO()
        !           264: 
        !           265: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_detach, 0, 0, 1)
        !           266:        ZEND_ARG_INFO(0, service_handle)
        !           267: ZEND_END_ARG_INFO()
        !           268: 
        !           269: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_backup, 0, 0, 3)
        !           270:        ZEND_ARG_INFO(0, service_handle)
        !           271:        ZEND_ARG_INFO(0, source_db)
        !           272:        ZEND_ARG_INFO(0, dest_file)
        !           273:        ZEND_ARG_INFO(0, options)
        !           274:        ZEND_ARG_INFO(0, verbose)
        !           275: ZEND_END_ARG_INFO()
        !           276: 
        !           277: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_restore, 0, 0, 3)
        !           278:        ZEND_ARG_INFO(0, service_handle)
        !           279:        ZEND_ARG_INFO(0, source_file)
        !           280:        ZEND_ARG_INFO(0, dest_db)
        !           281:        ZEND_ARG_INFO(0, options)
        !           282:        ZEND_ARG_INFO(0, verbose)
        !           283: ZEND_END_ARG_INFO()
        !           284: 
        !           285: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_maintain_db, 0, 0, 3)
        !           286:        ZEND_ARG_INFO(0, service_handle)
        !           287:        ZEND_ARG_INFO(0, db)
        !           288:        ZEND_ARG_INFO(0, action)
        !           289:        ZEND_ARG_INFO(0, argument)
        !           290: ZEND_END_ARG_INFO()
        !           291: 
        !           292: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_db_info, 0, 0, 3)
        !           293:        ZEND_ARG_INFO(0, service_handle)
        !           294:        ZEND_ARG_INFO(0, db)
        !           295:        ZEND_ARG_INFO(0, action)
        !           296:        ZEND_ARG_INFO(0, argument)
        !           297: ZEND_END_ARG_INFO()
        !           298: 
        !           299: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_server_info, 0, 0, 2)
        !           300:        ZEND_ARG_INFO(0, service_handle)
        !           301:        ZEND_ARG_INFO(0, action)
        !           302: ZEND_END_ARG_INFO()
        !           303: 
        !           304: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_wait_event, 0, 0, 1)
        !           305:        ZEND_ARG_INFO(0, link_identifier)
        !           306:        ZEND_ARG_INFO(0, event)
        !           307:        ZEND_ARG_INFO(0, event2)
        !           308: ZEND_END_ARG_INFO()
        !           309: 
        !           310: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_set_event_handler, 0, 0, 2)
        !           311:        ZEND_ARG_INFO(0, link_identifier)
        !           312:        ZEND_ARG_INFO(0, handler)
        !           313:        ZEND_ARG_INFO(0, event)
        !           314:        ZEND_ARG_INFO(0, event2)
        !           315: ZEND_END_ARG_INFO()
        !           316: 
        !           317: ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_event_handler, 0, 0, 1)
        !           318:        ZEND_ARG_INFO(0, event)
        !           319: ZEND_END_ARG_INFO()
        !           320: /* }}} */
        !           321: 
        !           322: /* {{{ extension definition structures */
        !           323: const zend_function_entry ibase_functions[] = {
        !           324:        PHP_FE(ibase_connect,           arginfo_ibase_connect)
        !           325:        PHP_FE(ibase_pconnect,          arginfo_ibase_pconnect)
        !           326:        PHP_FE(ibase_close,             arginfo_ibase_close)
        !           327:        PHP_FE(ibase_drop_db,           arginfo_ibase_drop_db)
        !           328:        PHP_FE(ibase_query,             arginfo_ibase_query)
        !           329:        PHP_FE(ibase_fetch_row,         arginfo_ibase_fetch_row)
        !           330:        PHP_FE(ibase_fetch_assoc,       arginfo_ibase_fetch_assoc)
        !           331:        PHP_FE(ibase_fetch_object,      arginfo_ibase_fetch_object)
        !           332:        PHP_FE(ibase_free_result,       arginfo_ibase_free_result)
        !           333:        PHP_FE(ibase_name_result,       arginfo_ibase_name_result)
        !           334:        PHP_FE(ibase_prepare,           arginfo_ibase_prepare)
        !           335:        PHP_FE(ibase_execute,           arginfo_ibase_execute)
        !           336:        PHP_FE(ibase_free_query,        arginfo_ibase_free_query)
        !           337:        PHP_FE(ibase_gen_id,            arginfo_ibase_gen_id)
        !           338:        PHP_FE(ibase_num_fields,        arginfo_ibase_num_fields)
        !           339:        PHP_FE(ibase_num_params,        arginfo_ibase_num_params)
        !           340: #if abies_0
        !           341:        PHP_FE(ibase_num_rows,          arginfo_ibase_num_rows)
        !           342: #endif
        !           343:        PHP_FE(ibase_affected_rows, arginfo_ibase_affected_rows)
        !           344:        PHP_FE(ibase_field_info,        arginfo_ibase_field_info)
        !           345:        PHP_FE(ibase_param_info,        arginfo_ibase_param_info)
        !           346: 
        !           347:        PHP_FE(ibase_trans,             arginfo_ibase_trans)
        !           348:        PHP_FE(ibase_commit,            arginfo_ibase_commit)
        !           349:        PHP_FE(ibase_rollback,          arginfo_ibase_rollback)
        !           350:        PHP_FE(ibase_commit_ret,        arginfo_ibase_commit_ret)
        !           351:        PHP_FE(ibase_rollback_ret,      arginfo_ibase_rollback_ret)
        !           352: 
        !           353:        PHP_FE(ibase_blob_info,         arginfo_ibase_blob_info)
        !           354:        PHP_FE(ibase_blob_create,       arginfo_ibase_blob_create)
        !           355:        PHP_FE(ibase_blob_add,          arginfo_ibase_blob_add)
        !           356:        PHP_FE(ibase_blob_cancel,       arginfo_ibase_blob_cancel)
        !           357:        PHP_FE(ibase_blob_close,        arginfo_ibase_blob_close)
        !           358:        PHP_FE(ibase_blob_open,         arginfo_ibase_blob_open)
        !           359:        PHP_FE(ibase_blob_get,          arginfo_ibase_blob_get)
        !           360:        PHP_FE(ibase_blob_echo,         arginfo_ibase_blob_echo)
        !           361:        PHP_FE(ibase_blob_import,       arginfo_ibase_blob_import)
        !           362:        PHP_FE(ibase_errmsg,            arginfo_ibase_errmsg)
        !           363:        PHP_FE(ibase_errcode,           arginfo_ibase_errcode)
        !           364: 
        !           365:        PHP_FE(ibase_add_user,          arginfo_ibase_add_user)
        !           366:        PHP_FE(ibase_modify_user,       arginfo_ibase_modify_user)
        !           367:        PHP_FE(ibase_delete_user,       arginfo_ibase_delete_user)
        !           368: 
        !           369:        PHP_FE(ibase_service_attach, arginfo_ibase_service_attach)
        !           370:        PHP_FE(ibase_service_detach, arginfo_ibase_service_detach)
        !           371:        PHP_FE(ibase_backup,            arginfo_ibase_backup)
        !           372:        PHP_FE(ibase_restore,           arginfo_ibase_restore)
        !           373:        PHP_FE(ibase_maintain_db,       arginfo_ibase_maintain_db)
        !           374:        PHP_FE(ibase_db_info,           arginfo_ibase_db_info)
        !           375:        PHP_FE(ibase_server_info,       arginfo_ibase_server_info)
        !           376: 
        !           377:        PHP_FE(ibase_wait_event,                        arginfo_ibase_wait_event)
        !           378:        PHP_FE(ibase_set_event_handler,         arginfo_ibase_set_event_handler)
        !           379:        PHP_FE(ibase_free_event_handler,        arginfo_ibase_free_event_handler)
        !           380: 
        !           381:        /**
        !           382:        * These aliases are provided in order to maintain forward compatibility. As Firebird
        !           383:        * and InterBase are developed independently, functionality might be different between
        !           384:        * the two branches in future versions.
        !           385:        * Firebird users should use the aliases, so future InterBase-specific changes will
        !           386:        * not affect their code
        !           387:        */
        !           388:        PHP_FALIAS(fbird_connect,               ibase_connect,          arginfo_ibase_connect)
        !           389:        PHP_FALIAS(fbird_pconnect,              ibase_pconnect,         arginfo_ibase_pconnect)
        !           390:        PHP_FALIAS(fbird_close,                 ibase_close,            arginfo_ibase_close)
        !           391:        PHP_FALIAS(fbird_drop_db,               ibase_drop_db,          arginfo_ibase_drop_db)
        !           392:        PHP_FALIAS(fbird_query,                 ibase_query,            arginfo_ibase_query)
        !           393:        PHP_FALIAS(fbird_fetch_row,             ibase_fetch_row,        arginfo_ibase_fetch_row)
        !           394:        PHP_FALIAS(fbird_fetch_assoc,   ibase_fetch_assoc,      arginfo_ibase_fetch_assoc)
        !           395:        PHP_FALIAS(fbird_fetch_object,  ibase_fetch_object, arginfo_ibase_fetch_object)
        !           396:        PHP_FALIAS(fbird_free_result,   ibase_free_result,      arginfo_ibase_free_result)
        !           397:        PHP_FALIAS(fbird_name_result,   ibase_name_result,      arginfo_ibase_name_result)
        !           398:        PHP_FALIAS(fbird_prepare,               ibase_prepare,          arginfo_ibase_prepare)
        !           399:        PHP_FALIAS(fbird_execute,               ibase_execute,          arginfo_ibase_execute)
        !           400:        PHP_FALIAS(fbird_free_query,    ibase_free_query,       arginfo_ibase_free_query)
        !           401:        PHP_FALIAS(fbird_gen_id,                ibase_gen_id,           arginfo_ibase_gen_id)
        !           402:        PHP_FALIAS(fbird_num_fields,    ibase_num_fields,       arginfo_ibase_num_fields)
        !           403:        PHP_FALIAS(fbird_num_params,    ibase_num_params,       arginfo_ibase_num_params)
        !           404: #if abies_0
        !           405:        PHP_FALIAS(fbird_num_rows,              ibase_num_rows,         arginfo_ibase_num_rows)
        !           406: #endif
        !           407:        PHP_FALIAS(fbird_affected_rows, ibase_affected_rows, arginfo_ibase_affected_rows)
        !           408:        PHP_FALIAS(fbird_field_info,    ibase_field_info,       arginfo_ibase_field_info)
        !           409:        PHP_FALIAS(fbird_param_info,    ibase_param_info,       arginfo_ibase_param_info)
        !           410: 
        !           411:        PHP_FALIAS(fbird_trans,                 ibase_trans,            arginfo_ibase_trans)
        !           412:        PHP_FALIAS(fbird_commit,                ibase_commit,           arginfo_ibase_commit)
        !           413:        PHP_FALIAS(fbird_rollback,              ibase_rollback,         arginfo_ibase_rollback)
        !           414:        PHP_FALIAS(fbird_commit_ret,    ibase_commit_ret,       arginfo_ibase_commit_ret)
        !           415:        PHP_FALIAS(fbird_rollback_ret,  ibase_rollback_ret, arginfo_ibase_rollback_ret)
        !           416: 
        !           417:        PHP_FALIAS(fbird_blob_info,             ibase_blob_info,        arginfo_ibase_blob_info)
        !           418:        PHP_FALIAS(fbird_blob_create,   ibase_blob_create,      arginfo_ibase_blob_create)
        !           419:        PHP_FALIAS(fbird_blob_add,              ibase_blob_add,         arginfo_ibase_blob_add)
        !           420:        PHP_FALIAS(fbird_blob_cancel,   ibase_blob_cancel,      arginfo_ibase_blob_cancel)
        !           421:        PHP_FALIAS(fbird_blob_close,    ibase_blob_close,       arginfo_ibase_blob_close)
        !           422:        PHP_FALIAS(fbird_blob_open,             ibase_blob_open,        arginfo_ibase_blob_open)
        !           423:        PHP_FALIAS(fbird_blob_get,              ibase_blob_get,         arginfo_ibase_blob_get)
        !           424:        PHP_FALIAS(fbird_blob_echo,             ibase_blob_echo,        arginfo_ibase_blob_echo)
        !           425:        PHP_FALIAS(fbird_blob_import,   ibase_blob_import,      arginfo_ibase_blob_import)
        !           426:        PHP_FALIAS(fbird_errmsg,                ibase_errmsg,           arginfo_ibase_errmsg)
        !           427:        PHP_FALIAS(fbird_errcode,               ibase_errcode,          arginfo_ibase_errcode)
        !           428: 
        !           429:        PHP_FALIAS(fbird_add_user,              ibase_add_user,         arginfo_ibase_add_user)
        !           430:        PHP_FALIAS(fbird_modify_user,   ibase_modify_user,      arginfo_ibase_modify_user)
        !           431:        PHP_FALIAS(fbird_delete_user,   ibase_delete_user,      arginfo_ibase_delete_user)
        !           432: 
        !           433:        PHP_FALIAS(fbird_service_attach,        ibase_service_attach, arginfo_ibase_service_attach)
        !           434:        PHP_FALIAS(fbird_service_detach,        ibase_service_detach, arginfo_ibase_service_detach)
        !           435:        PHP_FALIAS(fbird_backup,                ibase_backup,           arginfo_ibase_backup)
        !           436:        PHP_FALIAS(fbird_restore,               ibase_restore,          arginfo_ibase_restore)
        !           437:        PHP_FALIAS(fbird_maintain_db,   ibase_maintain_db,      arginfo_ibase_maintain_db)
        !           438:        PHP_FALIAS(fbird_db_info,               ibase_db_info,          arginfo_ibase_db_info)
        !           439:        PHP_FALIAS(fbird_server_info,   ibase_server_info,      arginfo_ibase_server_info)
        !           440: 
        !           441:        PHP_FALIAS(fbird_wait_event,    ibase_wait_event,       arginfo_ibase_wait_event)
        !           442:        PHP_FALIAS(fbird_set_event_handler,     ibase_set_event_handler,        arginfo_ibase_set_event_handler)
        !           443:        PHP_FALIAS(fbird_free_event_handler,    ibase_free_event_handler, arginfo_ibase_free_event_handler)
        !           444:        PHP_FE_END
        !           445: };
        !           446: 
        !           447: zend_module_entry ibase_module_entry = {
        !           448:        STANDARD_MODULE_HEADER,
        !           449:        "interbase",
        !           450:        ibase_functions,
        !           451:        PHP_MINIT(ibase),
        !           452:        PHP_MSHUTDOWN(ibase),
        !           453:        NULL,
        !           454:        PHP_RSHUTDOWN(ibase),
        !           455:        PHP_MINFO(ibase),
        !           456:        NO_VERSION_YET,
        !           457:        PHP_MODULE_GLOBALS(ibase),
        !           458:        PHP_GINIT(ibase),
        !           459:        NULL,
        !           460:        NULL,
        !           461:        STANDARD_MODULE_PROPERTIES_EX
        !           462: };
        !           463: 
        !           464: #ifdef COMPILE_DL_INTERBASE
        !           465: ZEND_GET_MODULE(ibase)
        !           466: #endif
        !           467: 
        !           468: /* True globals, no need for thread safety */
        !           469: int le_link, le_plink, le_trans;
        !           470: 
        !           471: /* }}} */
        !           472: 
        !           473: /* error handling ---------------------------- */
        !           474: 
        !           475: /* {{{ proto string ibase_errmsg(void) 
        !           476:    Return error message */
        !           477: PHP_FUNCTION(ibase_errmsg)
        !           478: {
        !           479:        if (zend_parse_parameters_none() == FAILURE) {
        !           480:                return;
        !           481:        }
        !           482: 
        !           483:        if (IBG(sql_code) != 0) {
        !           484:                RETURN_STRING(IBG(errmsg), 1);
        !           485:        }
        !           486: 
        !           487:        RETURN_FALSE;
        !           488: }
        !           489: /* }}} */
        !           490: 
        !           491: /* {{{ proto int ibase_errcode(void) 
        !           492:    Return error code */
        !           493: PHP_FUNCTION(ibase_errcode)
        !           494: {
        !           495:        if (zend_parse_parameters_none() == FAILURE) {
        !           496:                return;
        !           497:        }
        !           498: 
        !           499:        if (IBG(sql_code) != 0) {
        !           500:                RETURN_LONG(IBG(sql_code));
        !           501:        }
        !           502:        RETURN_FALSE;
        !           503: }
        !           504: /* }}} */
        !           505: 
        !           506: /* print interbase error and save it for ibase_errmsg() */
        !           507: void _php_ibase_error(TSRMLS_D) /* {{{ */
        !           508: {
        !           509:        char *s = IBG(errmsg);
        !           510:        ISC_STATUS *statusp = IB_STATUS;
        !           511: 
        !           512:        IBG(sql_code) = isc_sqlcode(IB_STATUS);
        !           513:        
        !           514:        while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
        !           515:                strcat(IBG(errmsg), " ");
        !           516:                s = IBG(errmsg) + strlen(IBG(errmsg));
        !           517:        }
        !           518: 
        !           519:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
        !           520: }
        !           521: /* }}} */
        !           522: 
        !           523: /* print php interbase module error and save it for ibase_errmsg() */
        !           524: void _php_ibase_module_error(char *msg TSRMLS_DC, ...) /* {{{ */
        !           525: {
        !           526:        va_list ap;
        !           527: 
        !           528: #ifdef ZTS
        !           529:        va_start(ap, TSRMLS_C);
        !           530: #else
        !           531:        va_start(ap, msg);
        !           532: #endif
        !           533: 
        !           534:        /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
        !           535:        vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap);
        !           536:        va_end(ap);
        !           537: 
        !           538:        IBG(sql_code) = -999; /* no SQL error */
        !           539: 
        !           540:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
        !           541: }
        !           542: /* }}} */
        !           543: 
        !           544: /* {{{ internal macros, functions and structures */
        !           545: typedef struct {
        !           546:        isc_db_handle *db_ptr;
        !           547:        long tpb_len;
        !           548:        char *tpb_ptr;
        !           549: } ISC_TEB;
        !           550: 
        !           551: /* }}} */
        !           552: 
        !           553: /* Fill ib_link and trans with the correct database link and transaction. */
        !           554: void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
        !           555:        zval **link_id, ibase_db_link **ib_link, ibase_trans **trans)
        !           556: {
        !           557:        int type;
        !           558: 
        !           559:        IBDEBUG("Transaction or database link?");
        !           560:        if (zend_list_find(Z_LVAL_PP(link_id), &type)) {
        !           561:                if (type == le_trans) {
        !           562:                        /* Transaction resource: make sure it refers to one link only, then 
        !           563:                           fetch it; database link is stored in ib_trans->db_link[]. */
        !           564:                        IBDEBUG("Type is le_trans");
        !           565:                        ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
        !           566:                        if ((*trans)->link_cnt > 1) {
        !           567:                                _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
        !           568:                                        TSRMLS_CC);
        !           569:                                return;
        !           570:                        }                               
        !           571:                        *ib_link = (*trans)->db_link[0];
        !           572:                        return;
        !           573:                }
        !           574:        } 
        !           575:        IBDEBUG("Type is le_[p]link or id not found");
        !           576:        /* Database link resource, use default transaction. */
        !           577:        *trans = NULL;
        !           578:        ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
        !           579: }
        !           580: /* }}} */      
        !           581: 
        !           582: /* destructors ---------------------- */
        !           583: 
        !           584: static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC) /* {{{ */
        !           585: {
        !           586:        unsigned short i = 0, j;
        !           587:        ibase_tr_list *l;
        !           588:        ibase_event *e;
        !           589:        IBDEBUG("Checking transactions to close...");
        !           590: 
        !           591:        for (l = link->tr_list; l != NULL; ++i) {
        !           592:                ibase_tr_list *p = l;
        !           593:                if (p->trans != NULL) {
        !           594:                        if (i == 0) {
        !           595:                                if (p->trans->handle != NULL) {
        !           596:                                        IBDEBUG("Committing default transaction...");
        !           597:                                        if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) {
        !           598:                                                _php_ibase_error(TSRMLS_C);
        !           599:                                        }
        !           600:                                }
        !           601:                                efree(p->trans); /* default transaction is not a registered resource: clean up */
        !           602:                        } else {
        !           603:                                if (p->trans->handle != NULL) { 
        !           604:                                        /* non-default trans might have been rolled back by other call of this dtor */
        !           605:                                        IBDEBUG("Rolling back other transactions...");
        !           606:                                        if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) {
        !           607:                                                _php_ibase_error(TSRMLS_C);
        !           608:                                        }
        !           609:                                }
        !           610:                                /* set this link pointer to NULL in the transaction */
        !           611:                                for (j = 0; j < p->trans->link_cnt; ++j) {
        !           612:                                        if (p->trans->db_link[j] == link) {
        !           613:                                                p->trans->db_link[j] = NULL;
        !           614:                                                break;
        !           615:                                        }
        !           616:                                }
        !           617:                        }
        !           618:                }
        !           619:                l = l->next;
        !           620:                efree(p);
        !           621:        }
        !           622:        link->tr_list = NULL;
        !           623:        
        !           624:        for (e = link->event_head; e; e = e->event_next) {
        !           625:                _php_ibase_free_event(e TSRMLS_CC);
        !           626:                e->link = NULL;
        !           627:        }
        !           628: }
        !           629: 
        !           630: /* }}} */
        !           631: 
        !           632: static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
        !           633: {
        !           634:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
        !           635: 
        !           636:        _php_ibase_commit_link(link TSRMLS_CC);
        !           637: }
        !           638: /* }}} */
        !           639: 
        !           640: static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
        !           641: {
        !           642:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
        !           643: 
        !           644:        _php_ibase_commit_link(link TSRMLS_CC);
        !           645:        if (link->handle != NULL) {
        !           646:                IBDEBUG("Closing normal link...");
        !           647:                isc_detach_database(IB_STATUS, &link->handle);
        !           648:        }
        !           649:        IBG(num_links)--;
        !           650:        efree(link);
        !           651: }
        !           652: /* }}} */
        !           653: 
        !           654: static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
        !           655: {
        !           656:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
        !           657: 
        !           658:        _php_ibase_commit_link(link TSRMLS_CC);
        !           659:        IBDEBUG("Closing permanent link...");
        !           660:        if (link->handle != NULL) {
        !           661:                isc_detach_database(IB_STATUS, &link->handle);
        !           662:        }
        !           663:        IBG(num_persistent)--;
        !           664:        IBG(num_links)--;
        !           665:        free(link);
        !           666: }
        !           667: /* }}} */
        !           668: 
        !           669: static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
        !           670: {
        !           671:        ibase_trans *trans = (ibase_trans *)rsrc->ptr;
        !           672:        unsigned short i;
        !           673:        
        !           674:        IBDEBUG("Cleaning up transaction resource...");
        !           675:        if (trans->handle != NULL) {
        !           676:                IBDEBUG("Rolling back unhandled transaction...");
        !           677:                if (isc_rollback_transaction(IB_STATUS, &trans->handle)) {
        !           678:                        _php_ibase_error(TSRMLS_C);
        !           679:                }
        !           680:        }
        !           681: 
        !           682:        /* now remove this transaction from all the connection-transaction lists */
        !           683:        for (i = 0; i < trans->link_cnt; ++i) {
        !           684:                if (trans->db_link[i] != NULL) {
        !           685:                        ibase_tr_list **l;
        !           686:                        for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) {
        !           687:                                if ( (*l)->trans == trans) {
        !           688:                                        ibase_tr_list *p = *l;
        !           689:                                        *l = p->next;
        !           690:                                        efree(p);
        !           691:                                        break;
        !           692:                                }
        !           693:                        }
        !           694:                }
        !           695:        }
        !           696:        efree(trans);
        !           697: }
        !           698: /* }}} */
        !           699: 
        !           700: /* TODO this function should be part of either Zend or PHP API */
        !           701: static PHP_INI_DISP(php_ibase_password_displayer_cb)
        !           702: {
        !           703:        TSRMLS_FETCH();
        !           704: 
        !           705:        if ((type == PHP_INI_DISPLAY_ORIG && ini_entry->orig_value) 
        !           706:                        || (type == PHP_INI_DISPLAY_ACTIVE && ini_entry->value)) {
        !           707:                PUTS("********");
        !           708:        } else if (!sapi_module.phpinfo_as_text) {
        !           709:                PUTS("<i>no value</i>");
        !           710:        } else {
        !           711:                PUTS("no value");
        !           712:        }
        !           713: }
        !           714: 
        !           715: /* {{{ startup, shutdown and info functions */
        !           716: PHP_INI_BEGIN()
        !           717:        PHP_INI_ENTRY_EX("ibase.allow_persistent", "1", PHP_INI_SYSTEM, NULL, zend_ini_boolean_displayer_cb)
        !           718:        PHP_INI_ENTRY_EX("ibase.max_persistent", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
        !           719:        PHP_INI_ENTRY_EX("ibase.max_links", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
        !           720:        PHP_INI_ENTRY("ibase.default_db", NULL, PHP_INI_SYSTEM, NULL)
        !           721:        PHP_INI_ENTRY("ibase.default_user", NULL, PHP_INI_ALL, NULL)
        !           722:        PHP_INI_ENTRY_EX("ibase.default_password", NULL, PHP_INI_ALL, NULL, php_ibase_password_displayer_cb)
        !           723:        PHP_INI_ENTRY("ibase.default_charset", NULL, PHP_INI_ALL, NULL)
        !           724:        PHP_INI_ENTRY("ibase.timestampformat", IB_DEF_DATE_FMT " " IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
        !           725:        PHP_INI_ENTRY("ibase.dateformat", IB_DEF_DATE_FMT, PHP_INI_ALL, NULL)
        !           726:        PHP_INI_ENTRY("ibase.timeformat", IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
        !           727: PHP_INI_END()
        !           728: 
        !           729: static PHP_GINIT_FUNCTION(ibase)
        !           730: {
        !           731:        ibase_globals->num_persistent = ibase_globals->num_links = 0;
        !           732:        ibase_globals->sql_code = *ibase_globals->errmsg = 0;
        !           733:        ibase_globals->default_link = -1;
        !           734: }
        !           735: 
        !           736: PHP_MINIT_FUNCTION(ibase)
        !           737: {
        !           738:        REGISTER_INI_ENTRIES();
        !           739: 
        !           740:        le_link = zend_register_list_destructors_ex(_php_ibase_close_link, NULL, LE_LINK, module_number);
        !           741:        le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, LE_PLINK, module_number);
        !           742:        le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, LE_TRANS, module_number);
        !           743: 
        !           744:        REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT);
        !           745:        REGISTER_LONG_CONSTANT("IBASE_CREATE", PHP_IBASE_CREATE, CONST_PERSISTENT);
        !           746:        REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */
        !           747:        REGISTER_LONG_CONSTANT("IBASE_FETCH_BLOBS", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT);
        !           748:        REGISTER_LONG_CONSTANT("IBASE_FETCH_ARRAYS", PHP_IBASE_FETCH_ARRAYS, CONST_PERSISTENT);
        !           749:        REGISTER_LONG_CONSTANT("IBASE_UNIXTIME", PHP_IBASE_UNIXTIME, CONST_PERSISTENT);
        !           750: 
        !           751:        /* transactions */
        !           752:        REGISTER_LONG_CONSTANT("IBASE_WRITE", PHP_IBASE_WRITE, CONST_PERSISTENT);
        !           753:        REGISTER_LONG_CONSTANT("IBASE_READ", PHP_IBASE_READ, CONST_PERSISTENT);
        !           754:        REGISTER_LONG_CONSTANT("IBASE_COMMITTED", PHP_IBASE_COMMITTED, CONST_PERSISTENT);
        !           755:        REGISTER_LONG_CONSTANT("IBASE_CONSISTENCY", PHP_IBASE_CONSISTENCY, CONST_PERSISTENT);
        !           756:        REGISTER_LONG_CONSTANT("IBASE_CONCURRENCY", PHP_IBASE_CONCURRENCY, CONST_PERSISTENT);
        !           757:        REGISTER_LONG_CONSTANT("IBASE_REC_VERSION", PHP_IBASE_REC_VERSION, CONST_PERSISTENT);
        !           758:        REGISTER_LONG_CONSTANT("IBASE_REC_NO_VERSION", PHP_IBASE_REC_NO_VERSION, CONST_PERSISTENT);
        !           759:        REGISTER_LONG_CONSTANT("IBASE_NOWAIT", PHP_IBASE_NOWAIT, CONST_PERSISTENT);
        !           760:        REGISTER_LONG_CONSTANT("IBASE_WAIT", PHP_IBASE_WAIT, CONST_PERSISTENT);
        !           761: 
        !           762:        php_ibase_query_minit(INIT_FUNC_ARGS_PASSTHRU);
        !           763:        php_ibase_blobs_minit(INIT_FUNC_ARGS_PASSTHRU);
        !           764:        php_ibase_events_minit(INIT_FUNC_ARGS_PASSTHRU);
        !           765:        php_ibase_service_minit(INIT_FUNC_ARGS_PASSTHRU);
        !           766:        
        !           767:        return SUCCESS;          
        !           768: }                            
        !           769:                              
        !           770: PHP_MSHUTDOWN_FUNCTION(ibase)
        !           771: {
        !           772: #ifndef PHP_WIN32
        !           773:        /**
        !           774:         * When the Interbase client API library libgds.so is first loaded, it registers a call to 
        !           775:         * gds__cleanup() with atexit(), in order to clean up after itself when the process exits.
        !           776:         * This means that the library is called at process shutdown, and cannot be unloaded beforehand.
        !           777:         * PHP tries to unload modules after every request [dl()'ed modules], and right before the 
        !           778:         * process shuts down [modules loaded from php.ini]. This results in a segfault for this module.
        !           779:         * By NULLing the dlopen() handle in the module entry, Zend omits the call to dlclose(),
        !           780:         * ensuring that the module will remain present until the process exits. However, the functions
        !           781:         * and classes exported by the module will not be available until the module is 'reloaded'. 
        !           782:         * When reloaded, dlopen() will return the handle of the already loaded module. The module will
        !           783:         * be unloaded automatically when the process exits.
        !           784:         */
        !           785:        zend_module_entry *ibase_entry;
        !           786:        if (SUCCESS == zend_hash_find(&module_registry, ibase_module_entry.name,
        !           787:                        strlen(ibase_module_entry.name) +1, (void*) &ibase_entry)) {
        !           788:                ibase_entry->handle = NULL;
        !           789:        }
        !           790: #endif
        !           791:        UNREGISTER_INI_ENTRIES();
        !           792:        return SUCCESS;
        !           793: }
        !           794: 
        !           795: PHP_RSHUTDOWN_FUNCTION(ibase)
        !           796: {
        !           797:        IBG(num_links) = IBG(num_persistent);
        !           798:        IBG(default_link)= -1;
        !           799: 
        !           800:        RESET_ERRMSG;
        !           801: 
        !           802:        return SUCCESS;
        !           803: } 
        !           804:  
        !           805: PHP_MINFO_FUNCTION(ibase)
        !           806: {
        !           807:        char tmp[64], *s;
        !           808: 
        !           809:        php_info_print_table_start();
        !           810:        php_info_print_table_row(2, "Firebird/InterBase Support", 
        !           811: #ifdef COMPILE_DL_INTERBASE
        !           812:                "dynamic");
        !           813: #else
        !           814:                "static");
        !           815: #endif
        !           816: 
        !           817: #ifdef FB_API_VER
        !           818:        snprintf( (s = tmp), sizeof(tmp), "Firebird API version %d", FB_API_VER);
        !           819: #elif (SQLDA_CURRENT_VERSION > 1)
        !           820:        s =  "Interbase 7.0 and up";
        !           821: #elif !defined(DSC_null)
        !           822:        s = "Interbase 6";
        !           823: #else
        !           824:        s = "Firebird 1.0";
        !           825: #endif
        !           826:        php_info_print_table_row(2, "Compile-time Client Library Version", s);
        !           827: 
        !           828: #if defined(__GNUC__) || defined(PHP_WIN32)
        !           829:        do {
        !           830:                info_func_t info_func = NULL;
        !           831: #ifdef __GNUC__
        !           832:                info_func = (info_func_t)dlsym(RTLD_DEFAULT, "isc_get_client_version");
        !           833: #else
        !           834:                HMODULE l = GetModuleHandle("fbclient");
        !           835: 
        !           836:                if (!l && !(l = GetModuleHandle("gds32"))) {
        !           837:                        break;
        !           838:                }
        !           839:                info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version");
        !           840: #endif
        !           841:                if (info_func) {
        !           842:                        info_func(s = tmp);
        !           843:                } else {
        !           844:                        s = "Firebird 1.0/Interbase 6";
        !           845:                }
        !           846:                php_info_print_table_row(2, "Run-time Client Library Version", s);
        !           847:        } while (0);
        !           848: #endif                 
        !           849:        php_info_print_table_end();
        !           850: 
        !           851:        DISPLAY_INI_ENTRIES();
        !           852: 
        !           853: }
        !           854: /* }}} */
        !           855: 
        !           856: enum connect_args { DB = 0, USER = 1, PASS = 2, CSET = 3, ROLE = 4, BUF = 0, DLECT = 1, SYNC = 2 };
        !           857:        
        !           858: static char const dpb_args[] = { 
        !           859:        0, isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name, 0
        !           860: };
        !           861:        
        !           862: int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC)
        !           863: {
        !           864:        short i, dpb_len, buf_len = 257-2;  /* version byte at the front, and a null at the end */
        !           865:        char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb;
        !           866: 
        !           867:        dpb = dpb_buffer + 1;
        !           868: 
        !           869:        for (i = 0; i < sizeof(dpb_args); ++i) {
        !           870:                if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
        !           871:                        dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
        !           872:                        dpb += dpb_len;
        !           873:                        buf_len -= dpb_len;
        !           874:                }
        !           875:        }
        !           876:        if (largs[BUF] && buf_len > 0) {
        !           877:                dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers, 
        !           878:                        (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
        !           879:                dpb += dpb_len;
        !           880:                buf_len -= dpb_len;
        !           881:        }
        !           882:        if (largs[SYNC] && buf_len > 0) {
        !           883:                dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync ? 1 : 0);
        !           884:                dpb += dpb_len;
        !           885:                buf_len -= dpb_len;
        !           886:        }
        !           887:        if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
        !           888:                _php_ibase_error(TSRMLS_C);
        !           889:                return FAILURE;
        !           890:        }
        !           891:        return SUCCESS;
        !           892: }
        !           893: /* }}} */
        !           894: 
        !           895: static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */
        !           896: {
        !           897:        char *c, hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL };
        !           898:        int i, len[] = { 0, 0, 0, 0, 0 };
        !           899:        long largs[] = { 0, 0, 0 };
        !           900:        PHP_MD5_CTX hash_context;
        !           901:        zend_rsrc_list_entry new_index_ptr, *le;
        !           902:        isc_db_handle db_handle = NULL;
        !           903:        ibase_db_link *ib_link;
        !           904: 
        !           905:        RESET_ERRMSG;
        !           906: 
        !           907:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssllsl",
        !           908:                        &args[DB], &len[DB], &args[USER], &len[USER], &args[PASS], &len[PASS],
        !           909:                        &args[CSET], &len[CSET], &largs[BUF], &largs[DLECT], &args[ROLE], &len[ROLE],
        !           910:                        &largs[SYNC])) {
        !           911:                RETURN_FALSE;
        !           912:        }
        !           913:        
        !           914:        /* restrict to the server/db in the .ini if in safe mode */
        !           915:        if ((!len[DB] || PG(sql_safe_mode)) && (c = INI_STR("ibase.default_db"))) { 
        !           916:                args[DB] = c;
        !           917:                len[DB] = strlen(c);
        !           918:        }
        !           919:        if (!len[USER] && (c = INI_STR("ibase.default_user"))) {
        !           920:                args[USER] = c;
        !           921:                len[USER] = strlen(c);
        !           922:        }
        !           923:        if (!len[PASS] && (c = INI_STR("ibase.default_password"))) {
        !           924:                args[PASS] = c;
        !           925:                len[PASS] = strlen(c);
        !           926:        }
        !           927:        if (!len[CSET] && (c = INI_STR("ibase.default_charset"))) {
        !           928:                args[CSET] = c;
        !           929:                len[CSET] = strlen(c);
        !           930:        }
        !           931:        
        !           932:        /* don't want usernames and passwords floating around */
        !           933:        PHP_MD5Init(&hash_context);
        !           934:        for (i = 0; i < sizeof(args)/sizeof(char*); ++i) {
        !           935:                PHP_MD5Update(&hash_context,args[i],len[i]);
        !           936:        }
        !           937:        for (i = 0; i < sizeof(largs)/sizeof(long); ++i) {
        !           938:                PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long));
        !           939:        }
        !           940:        PHP_MD5Final(hash, &hash_context);
        !           941:        
        !           942:        /* try to reuse a connection */
        !           943:        if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) {
        !           944:                long xlink;
        !           945:                int type;
        !           946: 
        !           947:                if (Z_TYPE_P(le) != le_index_ptr) {
        !           948:                        RETURN_FALSE;
        !           949:                }
        !           950:                        
        !           951:                xlink = (long) le->ptr;
        !           952:                if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) {
        !           953:                        zend_list_addref(xlink);
        !           954:                        RETURN_RESOURCE(IBG(default_link) = xlink);
        !           955:                } else {
        !           956:                        zend_hash_del(&EG(regular_list), hash, sizeof(hash));
        !           957:                }
        !           958:        }               
        !           959: 
        !           960:        /* ... or a persistent one */
        !           961:        switch (zend_hash_find(&EG(persistent_list), hash, sizeof(hash), (void *) &le)) {
        !           962:                long l;
        !           963:                
        !           964:                static char info[] = { isc_info_base_level, isc_info_end };
        !           965:                char result[8];
        !           966:                ISC_STATUS status[20];
        !           967: 
        !           968:        case SUCCESS:
        !           969: 
        !           970:                if (Z_TYPE_P(le) != le_plink) {
        !           971:                        RETURN_FALSE;
        !           972:                }
        !           973:                /* check if connection has timed out */
        !           974:                ib_link = (ibase_db_link *) le->ptr;
        !           975:                if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
        !           976:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
        !           977:                        break;
        !           978:                }
        !           979:                zend_hash_del(&EG(persistent_list), hash, sizeof(hash));
        !           980:        
        !           981:        default:
        !           982: 
        !           983:                /* no link found, so we have to open one */
        !           984:        
        !           985:                if ((l = INI_INT("ibase.max_links")) != -1 && IBG(num_links) >= l) {
        !           986:                        _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links));
        !           987:                        RETURN_FALSE;
        !           988:                }
        !           989:        
        !           990:                /* create the ib_link */
        !           991:                if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle TSRMLS_CC)) {
        !           992:                        RETURN_FALSE;
        !           993:                }
        !           994:        
        !           995:                /* use non-persistent if allowed number of persistent links is exceeded */
        !           996:                if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
        !           997:                        ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
        !           998:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
        !           999:                } else {
        !          1000:                        zend_rsrc_list_entry new_le;
        !          1001: 
        !          1002:                        ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
        !          1003:                        if (!ib_link) {
        !          1004:                                RETURN_FALSE;
        !          1005:                        }
        !          1006: 
        !          1007:                        /* hash it up */
        !          1008:                        Z_TYPE(new_le) = le_plink;
        !          1009:                        new_le.ptr = ib_link;
        !          1010:                        if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash),
        !          1011:                                        (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)) {
        !          1012:                                free(ib_link);
        !          1013:                                RETURN_FALSE;
        !          1014:                        }
        !          1015:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
        !          1016:                        ++IBG(num_persistent);
        !          1017:                }
        !          1018:                ib_link->handle = db_handle;
        !          1019:                ib_link->dialect = largs[DLECT] ? (unsigned short)largs[DLECT] : SQL_DIALECT_CURRENT;
        !          1020:                ib_link->tr_list = NULL;
        !          1021:                ib_link->event_head = NULL;
        !          1022:        
        !          1023:                ++IBG(num_links);
        !          1024:        }
        !          1025: 
        !          1026:        /* add it to the hash */
        !          1027:        new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
        !          1028:        Z_TYPE(new_index_ptr) = le_index_ptr;
        !          1029:        if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash),
        !          1030:                        (void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)) {
        !          1031:                RETURN_FALSE;
        !          1032:        }
        !          1033:        zend_list_addref(IBG(default_link) = Z_LVAL_P(return_value));
        !          1034: }
        !          1035: /* }}} */
        !          1036: 
        !          1037: /* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
        !          1038:    Open a connection to an InterBase database */
        !          1039: PHP_FUNCTION(ibase_connect)
        !          1040: {
        !          1041:        _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
        !          1042: }
        !          1043: /* }}} */
        !          1044: 
        !          1045: /* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
        !          1046:    Open a persistent connection to an InterBase database */
        !          1047: PHP_FUNCTION(ibase_pconnect)
        !          1048: {
        !          1049:        _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INI_INT("ibase.allow_persistent"));
        !          1050: }
        !          1051: /* }}} */
        !          1052: 
        !          1053: /* {{{ proto bool ibase_close([resource link_identifier])
        !          1054:    Close an InterBase connection */
        !          1055: PHP_FUNCTION(ibase_close)
        !          1056: {
        !          1057:        zval *link_arg = NULL;
        !          1058:        ibase_db_link *ib_link;
        !          1059:        int link_id;
        !          1060: 
        !          1061:        RESET_ERRMSG;
        !          1062:        
        !          1063:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
        !          1064:                return;
        !          1065:        }
        !          1066:        
        !          1067:        if (ZEND_NUM_ARGS() == 0) {
        !          1068:                link_id = IBG(default_link);
        !          1069:                CHECK_LINK(link_id);
        !          1070:                IBG(default_link) = -1;
        !          1071:        } else {
        !          1072:                link_id = Z_RESVAL_P(link_arg);
        !          1073:        }
        !          1074: 
        !          1075:        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
        !          1076:        zend_list_delete(link_id);
        !          1077:        RETURN_TRUE;
        !          1078: }
        !          1079: /* }}} */
        !          1080: 
        !          1081: /* {{{ proto bool ibase_drop_db([resource link_identifier])
        !          1082:    Drop an InterBase database */
        !          1083: PHP_FUNCTION(ibase_drop_db)
        !          1084: {
        !          1085:        zval *link_arg = NULL;
        !          1086:        ibase_db_link *ib_link;
        !          1087:        ibase_tr_list *l;
        !          1088:        int link_id;
        !          1089: 
        !          1090:        RESET_ERRMSG;
        !          1091:        
        !          1092:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
        !          1093:                return;
        !          1094:        }
        !          1095:        
        !          1096:        if (ZEND_NUM_ARGS() == 0) {
        !          1097:                link_id = IBG(default_link);
        !          1098:                CHECK_LINK(link_id);
        !          1099:                IBG(default_link) = -1;
        !          1100:        } else {
        !          1101:                link_id = Z_RESVAL_P(link_arg);
        !          1102:        }
        !          1103:        
        !          1104:        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
        !          1105: 
        !          1106:        if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
        !          1107:                _php_ibase_error(TSRMLS_C);
        !          1108:                RETURN_FALSE;
        !          1109:        }
        !          1110: 
        !          1111:        /* isc_drop_database() doesn't invalidate the transaction handles */
        !          1112:        for (l = ib_link->tr_list; l != NULL; l = l->next) {
        !          1113:                if (l->trans != NULL) l->trans->handle = NULL;
        !          1114:        }
        !          1115: 
        !          1116:        zend_list_delete(link_id);
        !          1117:        RETURN_TRUE;
        !          1118: }
        !          1119: /* }}} */
        !          1120: 
        !          1121: /* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
        !          1122:    Start a transaction over one or several databases */
        !          1123: 
        !          1124: #define TPB_MAX_SIZE (8*sizeof(char))
        !          1125: 
        !          1126: PHP_FUNCTION(ibase_trans)
        !          1127: {
        !          1128:        unsigned short i, argn, link_cnt = 0, tpb_len = 0;
        !          1129:        char last_tpb[TPB_MAX_SIZE];
        !          1130:        ibase_db_link **ib_link = NULL;
        !          1131:        ibase_trans *ib_trans;
        !          1132:        isc_tr_handle tr_handle = NULL;
        !          1133:        ISC_STATUS result;
        !          1134:        
        !          1135:        RESET_ERRMSG;
        !          1136: 
        !          1137:        argn = ZEND_NUM_ARGS();
        !          1138: 
        !          1139:        /* (1+argn) is an upper bound for the number of links this trans connects to */
        !          1140:        ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0);
        !          1141:        
        !          1142:        if (argn > 0) {
        !          1143:                long trans_argl = 0;
        !          1144:                char *tpb;
        !          1145:                ISC_TEB *teb;
        !          1146:                zval ***args = NULL;
        !          1147: 
        !          1148:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) {
        !          1149:                        efree(args);
        !          1150:                        efree(ib_link);
        !          1151:                        RETURN_FALSE;
        !          1152:                }
        !          1153: 
        !          1154:                teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0);
        !          1155:                tpb = (char *) safe_emalloc(TPB_MAX_SIZE,argn,0);
        !          1156: 
        !          1157:                /* enumerate all the arguments: assume every non-resource argument 
        !          1158:                   specifies modifiers for the link ids that follow it */
        !          1159:                for (i = 0; i < argn; ++i) {
        !          1160:                        
        !          1161:                        if (Z_TYPE_PP(args[i]) == IS_RESOURCE) {
        !          1162:                                
        !          1163:                                if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) {
        !          1164:                                        efree(teb);
        !          1165:                                        efree(tpb);
        !          1166:                                        efree(ib_link);
        !          1167:                                        efree(args);
        !          1168:                                        RETURN_FALSE;
        !          1169:                                }
        !          1170:        
        !          1171:                                /* copy the most recent modifier string into tbp[] */
        !          1172:                                memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, TPB_MAX_SIZE);
        !          1173: 
        !          1174:                                /* add a database handle to the TEB with the most recently specified set of modifiers */
        !          1175:                                teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle;
        !          1176:                                teb[link_cnt].tpb_len = tpb_len;
        !          1177:                                teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
        !          1178:                                
        !          1179:                                ++link_cnt;
        !          1180:                                
        !          1181:                        } else {
        !          1182:                                
        !          1183:                                tpb_len = 0;
        !          1184: 
        !          1185:                                convert_to_long_ex(args[i]);
        !          1186:                                trans_argl = Z_LVAL_PP(args[i]);
        !          1187: 
        !          1188:                                if (trans_argl != PHP_IBASE_DEFAULT) {
        !          1189:                                        last_tpb[tpb_len++] = isc_tpb_version3;
        !          1190: 
        !          1191:                                        /* access mode */
        !          1192:                                        if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) {
        !          1193:                                                last_tpb[tpb_len++] = isc_tpb_read;
        !          1194:                                        } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) {
        !          1195:                                                last_tpb[tpb_len++] = isc_tpb_write;
        !          1196:                                        }
        !          1197: 
        !          1198:                                        /* isolation level */
        !          1199:                                        if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) {
        !          1200:                                                last_tpb[tpb_len++] = isc_tpb_read_committed;
        !          1201:                                                if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) {
        !          1202:                                                        last_tpb[tpb_len++] = isc_tpb_rec_version;
        !          1203:                                                } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) {
        !          1204:                                                        last_tpb[tpb_len++] = isc_tpb_no_rec_version; 
        !          1205:                                                }       
        !          1206:                                        } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) {
        !          1207:                                                last_tpb[tpb_len++] = isc_tpb_consistency;
        !          1208:                                        } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) {
        !          1209:                                                last_tpb[tpb_len++] = isc_tpb_concurrency;
        !          1210:                                        }
        !          1211:                                        
        !          1212:                                        /* lock resolution */
        !          1213:                                        if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) {
        !          1214:                                                last_tpb[tpb_len++] = isc_tpb_nowait;
        !          1215:                                        } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) {
        !          1216:                                                last_tpb[tpb_len++] = isc_tpb_wait;
        !          1217:                                        }
        !          1218:                                }
        !          1219:                        }
        !          1220:                }       
        !          1221:                                        
        !          1222:                if (link_cnt > 0) {
        !          1223:                        result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb);
        !          1224:                }
        !          1225: 
        !          1226:                efree(args);
        !          1227:                efree(tpb);
        !          1228:                efree(teb);
        !          1229:        }
        !          1230: 
        !          1231:        if (link_cnt == 0) {
        !          1232:                link_cnt = 1;
        !          1233:                if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
        !          1234:                        efree(ib_link);
        !          1235:                        RETURN_FALSE;
        !          1236:                }
        !          1237:                result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb);
        !          1238:        }
        !          1239:        
        !          1240:        /* start the transaction */
        !          1241:        if (result) {
        !          1242:                _php_ibase_error(TSRMLS_C);
        !          1243:                efree(ib_link);
        !          1244:                RETURN_FALSE;
        !          1245:        }
        !          1246: 
        !          1247:        /* register the transaction in our own data structures */
        !          1248:        ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans));
        !          1249:        ib_trans->handle = tr_handle;
        !          1250:        ib_trans->link_cnt = link_cnt;
        !          1251:        ib_trans->affected_rows = 0;
        !          1252:        for (i = 0; i < link_cnt; ++i) {
        !          1253:                ibase_tr_list **l;
        !          1254:                ib_trans->db_link[i] = ib_link[i];
        !          1255:                
        !          1256:                /* the first item in the connection-transaction list is reserved for the default transaction */
        !          1257:                if (ib_link[i]->tr_list == NULL) {
        !          1258:                        ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
        !          1259:                        ib_link[i]->tr_list->trans = NULL;
        !          1260:                        ib_link[i]->tr_list->next = NULL;
        !          1261:                }
        !          1262: 
        !          1263:                /* link the transaction into the connection-transaction list */
        !          1264:                for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next);
        !          1265:                *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
        !          1266:                (*l)->trans = ib_trans;
        !          1267:                (*l)->next = NULL;
        !          1268:        }
        !          1269:        efree(ib_link);
        !          1270:        ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
        !          1271: }
        !          1272: /* }}} */
        !          1273: 
        !          1274: int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC) /* {{{ */
        !          1275: {
        !          1276:        if (ib_link == NULL) {
        !          1277:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link");
        !          1278:                return FAILURE;
        !          1279:        }
        !          1280: 
        !          1281:        /* the first item in the connection-transaction list is reserved for the default transaction */
        !          1282:        if (ib_link->tr_list == NULL) {
        !          1283:                ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
        !          1284:                ib_link->tr_list->trans = NULL;
        !          1285:                ib_link->tr_list->next = NULL;
        !          1286:        }
        !          1287: 
        !          1288:        if (*trans == NULL) {
        !          1289:                ibase_trans *tr = ib_link->tr_list->trans;
        !          1290: 
        !          1291:                if (tr == NULL) {
        !          1292:                        tr = (ibase_trans *) emalloc(sizeof(ibase_trans));
        !          1293:                        tr->handle = NULL;
        !          1294:                        tr->link_cnt = 1;
        !          1295:                        tr->affected_rows = 0;
        !          1296:                        tr->db_link[0] = ib_link;
        !          1297:                        ib_link->tr_list->trans = tr;
        !          1298:                }
        !          1299:                if (tr->handle == NULL) {
        !          1300:                        if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) {
        !          1301:                                _php_ibase_error(TSRMLS_C);
        !          1302:                                return FAILURE;
        !          1303:                        }
        !          1304:                }
        !          1305:                *trans = tr;
        !          1306:        }
        !          1307:        return SUCCESS;
        !          1308: }
        !          1309: /* }}} */
        !          1310: 
        !          1311: static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */
        !          1312: {
        !          1313:        ibase_trans *trans = NULL;
        !          1314:        int res_id = 0;
        !          1315:        ISC_STATUS result;
        !          1316:        ibase_db_link *ib_link;
        !          1317:        zval *arg = NULL;
        !          1318:        int type;
        !          1319: 
        !          1320:        RESET_ERRMSG;
        !          1321:        
        !          1322:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
        !          1323:                return;
        !          1324:        }
        !          1325: 
        !          1326:        if (ZEND_NUM_ARGS() == 0) {
        !          1327:                ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
        !          1328:                if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
        !          1329:                        /* this link doesn't have a default transaction */
        !          1330:                        _php_ibase_module_error("Default link has no default transaction" TSRMLS_CC);
        !          1331:                        RETURN_FALSE;
        !          1332:                }
        !          1333:                trans = ib_link->tr_list->trans;
        !          1334:        } else {
        !          1335:                /* one id was passed, could be db or trans id */
        !          1336:                if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) {
        !          1337:                        ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans);
        !          1338:                        res_id = Z_RESVAL_P(arg);
        !          1339:                } else {
        !          1340:                        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink);
        !          1341: 
        !          1342:                        if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
        !          1343:                                /* this link doesn't have a default transaction */
        !          1344:                                _php_ibase_module_error("Link has no default transaction" TSRMLS_CC);
        !          1345:                                RETURN_FALSE;
        !          1346:                        }
        !          1347:                        trans = ib_link->tr_list->trans;
        !          1348:                }
        !          1349:        }
        !          1350: 
        !          1351:        switch (commit) {
        !          1352:                default: /* == case ROLLBACK: */
        !          1353:                        result = isc_rollback_transaction(IB_STATUS, &trans->handle);
        !          1354:                        break;
        !          1355:                case COMMIT:
        !          1356:                        result = isc_commit_transaction(IB_STATUS, &trans->handle);
        !          1357:                        break;
        !          1358:                case (ROLLBACK | RETAIN):
        !          1359:                        result = isc_rollback_retaining(IB_STATUS, &trans->handle);
        !          1360:                        break;
        !          1361:                case (COMMIT | RETAIN):
        !          1362:                        result = isc_commit_retaining(IB_STATUS, &trans->handle);
        !          1363:                        break;
        !          1364:        }
        !          1365:        
        !          1366:        if (result) {
        !          1367:                _php_ibase_error(TSRMLS_C);
        !          1368:                RETURN_FALSE;
        !          1369:        }
        !          1370: 
        !          1371:        /* Don't try to destroy implicitly opened transaction from list... */
        !          1372:        if ((commit & RETAIN) == 0 && res_id != 0) {
        !          1373:                zend_list_delete(res_id);
        !          1374:        }
        !          1375:        RETURN_TRUE;
        !          1376: }
        !          1377: /* }}} */
        !          1378: 
        !          1379: /* {{{ proto bool ibase_commit( resource link_identifier )
        !          1380:    Commit transaction */
        !          1381: PHP_FUNCTION(ibase_commit)
        !          1382: {
        !          1383:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
        !          1384: }
        !          1385: /* }}} */
        !          1386: 
        !          1387: /* {{{ proto bool ibase_rollback( resource link_identifier )
        !          1388:    Rollback transaction */
        !          1389: PHP_FUNCTION(ibase_rollback)
        !          1390: {
        !          1391:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
        !          1392: }
        !          1393: /* }}} */
        !          1394: 
        !          1395: /* {{{ proto bool ibase_commit_ret( resource link_identifier )
        !          1396:    Commit transaction and retain the transaction context */
        !          1397: PHP_FUNCTION(ibase_commit_ret)
        !          1398: {
        !          1399:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN);
        !          1400: }
        !          1401: /* }}} */
        !          1402: 
        !          1403: /* {{{ proto bool ibase_rollback_ret( resource link_identifier )
        !          1404:    Rollback transaction and retain the transaction context */
        !          1405: PHP_FUNCTION(ibase_rollback_ret)
        !          1406: {
        !          1407:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN);
        !          1408: }
        !          1409: /* }}} */
        !          1410: 
        !          1411: /* {{{ proto int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])
        !          1412:    Increments the named generator and returns its new value */
        !          1413: PHP_FUNCTION(ibase_gen_id)
        !          1414: {
        !          1415:        zval *link = NULL;
        !          1416:        char query[128], *generator;
        !          1417:        int gen_len;
        !          1418:        long inc = 1;
        !          1419:        ibase_db_link *ib_link;
        !          1420:        ibase_trans *trans = NULL;
        !          1421:        XSQLDA out_sqlda;
        !          1422:        ISC_INT64 result;
        !          1423: 
        !          1424:        RESET_ERRMSG;
        !          1425: 
        !          1426:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &generator, &gen_len,
        !          1427:                        &inc, &link)) {
        !          1428:                RETURN_FALSE;
        !          1429:        }
        !          1430:        
        !          1431:        if (gen_len > 31) {
        !          1432:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid generator name");
        !          1433:                RETURN_FALSE;
        !          1434:        }
        !          1435: 
        !          1436:        PHP_IBASE_LINK_TRANS(link, ib_link, trans);
        !          1437:        
        !          1438:        snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc);
        !          1439: 
        !          1440:        /* allocate a minimal descriptor area */
        !          1441:        out_sqlda.sqln = out_sqlda.sqld = 1;
        !          1442:        out_sqlda.version = SQLDA_CURRENT_VERSION;
        !          1443:        
        !          1444:        /* allocate the field for the result */
        !          1445:        out_sqlda.sqlvar[0].sqltype = SQL_INT64;
        !          1446:        out_sqlda.sqlvar[0].sqlscale = 0;
        !          1447:        out_sqlda.sqlvar[0].sqllen = sizeof(result);
        !          1448:        out_sqlda.sqlvar[0].sqldata = (void*) &result;
        !          1449: 
        !          1450:        /* execute the query */
        !          1451:        if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query,
        !          1452:                        SQL_DIALECT_CURRENT, NULL, &out_sqlda)) {
        !          1453:                _php_ibase_error(TSRMLS_C);
        !          1454:                RETURN_FALSE;
        !          1455:        }
        !          1456: 
        !          1457:        /* don't return the generator value as a string unless it doesn't fit in a long */
        !          1458: #if SIZEOF_LONG < 8
        !          1459:        if (result < LONG_MIN || result > LONG_MAX) {
        !          1460:                char *res;
        !          1461:                int l;
        !          1462: 
        !          1463:                l = spprintf(&res, 0, "%" LL_MASK "d", result);
        !          1464:                RETURN_STRINGL(res, l, 0);
        !          1465:        }
        !          1466: #endif
        !          1467:        RETURN_LONG((long)result);
        !          1468: }
        !          1469: 
        !          1470: /* }}} */
        !          1471:     
        !          1472: #endif /* HAVE_IBASE */
        !          1473: 
        !          1474: /*
        !          1475:  * Local variables:
        !          1476:  * tab-width: 4
        !          1477:  * c-basic-offset: 4
        !          1478:  * End:
        !          1479:  * vim600: sw=4 ts=4 fdm=marker
        !          1480:  * vim<600: sw=4 ts=4
        !          1481:  */

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