1/* 2 +----------------------------------------------------------------------+ 3 | PHP Version 5 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2013 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: Ard Biesheuvel <a.k.biesheuvel@its.tudelft.nl> | 16 +----------------------------------------------------------------------+ 17 */ 18 19/* $Id$ */ 20 21#ifdef HAVE_CONFIG_H 22#include "config.h" 23#endif 24 25#include "php.h" 26 27#if HAVE_IBASE 28 29#include "php_interbase.h" 30#include "php_ibase_includes.h" 31 32typedef struct { 33 isc_svc_handle handle; 34 char *hostname; 35 char *username; 36 long res_id; 37} ibase_service; 38 39static int le_service; 40 41static void _php_ibase_free_service(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ 42{ 43 ibase_service *sv = (ibase_service *) rsrc->ptr; 44 45 if (isc_service_detach(IB_STATUS, &sv->handle)) { 46 _php_ibase_error(TSRMLS_C); 47 } 48 49 if (sv->hostname) { 50 efree(sv->hostname); 51 } 52 if (sv->username) { 53 efree(sv->username); 54 } 55 56 efree(sv); 57} 58/* }}} */ 59 60/* the svc api seems to get confused after an error has occurred, 61 so invalidate the handle on errors */ 62#define IBASE_SVC_ERROR(svm) \ 63 do { zend_list_delete(svm->res_id); _php_ibase_error(TSRMLS_C); } while (0) 64 65 66void php_ibase_service_minit(INIT_FUNC_ARGS) /* {{{ */ 67{ 68 le_service = zend_register_list_destructors_ex(_php_ibase_free_service, NULL, 69 "interbase service manager handle", module_number); 70 71 /* backup options */ 72 REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_CHECKSUMS", isc_spb_bkp_ignore_checksums, CONST_PERSISTENT); 73 REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_LIMBO", isc_spb_bkp_ignore_limbo, CONST_PERSISTENT); 74 REGISTER_LONG_CONSTANT("IBASE_BKP_METADATA_ONLY", isc_spb_bkp_metadata_only, CONST_PERSISTENT); 75 REGISTER_LONG_CONSTANT("IBASE_BKP_NO_GARBAGE_COLLECT", isc_spb_bkp_no_garbage_collect, CONST_PERSISTENT); 76 REGISTER_LONG_CONSTANT("IBASE_BKP_OLD_DESCRIPTIONS", isc_spb_bkp_old_descriptions, CONST_PERSISTENT); 77 REGISTER_LONG_CONSTANT("IBASE_BKP_NON_TRANSPORTABLE", isc_spb_bkp_non_transportable, CONST_PERSISTENT); 78 REGISTER_LONG_CONSTANT("IBASE_BKP_CONVERT", isc_spb_bkp_convert, CONST_PERSISTENT); 79 80 /* restore options */ 81 REGISTER_LONG_CONSTANT("IBASE_RES_DEACTIVATE_IDX", isc_spb_res_deactivate_idx, CONST_PERSISTENT); 82 REGISTER_LONG_CONSTANT("IBASE_RES_NO_SHADOW", isc_spb_res_no_shadow, CONST_PERSISTENT); 83 REGISTER_LONG_CONSTANT("IBASE_RES_NO_VALIDITY", isc_spb_res_no_validity, CONST_PERSISTENT); 84 REGISTER_LONG_CONSTANT("IBASE_RES_ONE_AT_A_TIME", isc_spb_res_one_at_a_time, CONST_PERSISTENT); 85 REGISTER_LONG_CONSTANT("IBASE_RES_REPLACE", isc_spb_res_replace, CONST_PERSISTENT); 86 REGISTER_LONG_CONSTANT("IBASE_RES_CREATE", isc_spb_res_create, CONST_PERSISTENT); 87 REGISTER_LONG_CONSTANT("IBASE_RES_USE_ALL_SPACE", isc_spb_res_use_all_space, CONST_PERSISTENT); 88 89 /* manage options */ 90 REGISTER_LONG_CONSTANT("IBASE_PRP_PAGE_BUFFERS", isc_spb_prp_page_buffers, CONST_PERSISTENT); 91 REGISTER_LONG_CONSTANT("IBASE_PRP_SWEEP_INTERVAL", isc_spb_prp_sweep_interval, CONST_PERSISTENT); 92 REGISTER_LONG_CONSTANT("IBASE_PRP_SHUTDOWN_DB", isc_spb_prp_shutdown_db, CONST_PERSISTENT); 93 REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_TRANSACTIONS", isc_spb_prp_deny_new_transactions, CONST_PERSISTENT); 94 REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_ATTACHMENTS", isc_spb_prp_deny_new_attachments, CONST_PERSISTENT); 95 REGISTER_LONG_CONSTANT("IBASE_PRP_RESERVE_SPACE", isc_spb_prp_reserve_space, CONST_PERSISTENT); 96 REGISTER_LONG_CONSTANT("IBASE_PRP_RES_USE_FULL", isc_spb_prp_res_use_full, CONST_PERSISTENT); 97 REGISTER_LONG_CONSTANT("IBASE_PRP_RES", isc_spb_prp_res, CONST_PERSISTENT); 98 REGISTER_LONG_CONSTANT("IBASE_PRP_WRITE_MODE", isc_spb_prp_write_mode, CONST_PERSISTENT); 99 REGISTER_LONG_CONSTANT("IBASE_PRP_WM_ASYNC", isc_spb_prp_wm_async, CONST_PERSISTENT); 100 REGISTER_LONG_CONSTANT("IBASE_PRP_WM_SYNC", isc_spb_prp_wm_sync, CONST_PERSISTENT); 101 REGISTER_LONG_CONSTANT("IBASE_PRP_ACCESS_MODE", isc_spb_prp_access_mode, CONST_PERSISTENT); 102 REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READONLY", isc_spb_prp_am_readonly, CONST_PERSISTENT); 103 REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READWRITE", isc_spb_prp_am_readwrite, CONST_PERSISTENT); 104 REGISTER_LONG_CONSTANT("IBASE_PRP_SET_SQL_DIALECT", isc_spb_prp_set_sql_dialect, CONST_PERSISTENT); 105 REGISTER_LONG_CONSTANT("IBASE_PRP_ACTIVATE", isc_spb_prp_activate, CONST_PERSISTENT); 106 REGISTER_LONG_CONSTANT("IBASE_PRP_DB_ONLINE", isc_spb_prp_db_online, CONST_PERSISTENT); 107 108 /* repair options */ 109 REGISTER_LONG_CONSTANT("IBASE_RPR_CHECK_DB", isc_spb_rpr_check_db, CONST_PERSISTENT); 110 REGISTER_LONG_CONSTANT("IBASE_RPR_IGNORE_CHECKSUM", isc_spb_rpr_ignore_checksum, CONST_PERSISTENT); 111 REGISTER_LONG_CONSTANT("IBASE_RPR_KILL_SHADOWS", isc_spb_rpr_kill_shadows, CONST_PERSISTENT); 112 REGISTER_LONG_CONSTANT("IBASE_RPR_MEND_DB", isc_spb_rpr_mend_db, CONST_PERSISTENT); 113 REGISTER_LONG_CONSTANT("IBASE_RPR_VALIDATE_DB", isc_spb_rpr_validate_db, CONST_PERSISTENT); 114 REGISTER_LONG_CONSTANT("IBASE_RPR_FULL", isc_spb_rpr_full, CONST_PERSISTENT); 115 REGISTER_LONG_CONSTANT("IBASE_RPR_SWEEP_DB", isc_spb_rpr_sweep_db, CONST_PERSISTENT); 116 117 /* db info arguments */ 118 REGISTER_LONG_CONSTANT("IBASE_STS_DATA_PAGES", isc_spb_sts_data_pages, CONST_PERSISTENT); 119 REGISTER_LONG_CONSTANT("IBASE_STS_DB_LOG", isc_spb_sts_db_log, CONST_PERSISTENT); 120 REGISTER_LONG_CONSTANT("IBASE_STS_HDR_PAGES", isc_spb_sts_hdr_pages, CONST_PERSISTENT); 121 REGISTER_LONG_CONSTANT("IBASE_STS_IDX_PAGES", isc_spb_sts_idx_pages, CONST_PERSISTENT); 122 REGISTER_LONG_CONSTANT("IBASE_STS_SYS_RELATIONS", isc_spb_sts_sys_relations, CONST_PERSISTENT); 123 124 /* server info arguments */ 125 REGISTER_LONG_CONSTANT("IBASE_SVC_SERVER_VERSION", isc_info_svc_server_version, CONST_PERSISTENT); 126 REGISTER_LONG_CONSTANT("IBASE_SVC_IMPLEMENTATION", isc_info_svc_implementation, CONST_PERSISTENT); 127 REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV", isc_info_svc_get_env, CONST_PERSISTENT); 128 REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_LOCK", isc_info_svc_get_env_lock, CONST_PERSISTENT); 129 REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_MSG", isc_info_svc_get_env_msg, CONST_PERSISTENT); 130 REGISTER_LONG_CONSTANT("IBASE_SVC_USER_DBPATH", isc_info_svc_user_dbpath, CONST_PERSISTENT); 131 REGISTER_LONG_CONSTANT("IBASE_SVC_SVR_DB_INFO", isc_info_svc_svr_db_info, CONST_PERSISTENT); 132 REGISTER_LONG_CONSTANT("IBASE_SVC_GET_USERS", isc_info_svc_get_users, CONST_PERSISTENT); 133} 134/* }}} */ 135 136static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */ 137{ 138 /* user = 0, password = 1, first_name = 2, middle_name = 3, last_name = 4 */ 139 static char const user_flags[] = { isc_spb_sec_username, isc_spb_sec_password, 140 isc_spb_sec_firstname, isc_spb_sec_middlename, isc_spb_sec_lastname }; 141 char buf[128], *args[] = { NULL, NULL, NULL, NULL, NULL }; 142 int i, args_len[] = { 0, 0, 0, 0, 0 }; 143 unsigned short spb_len = 1; 144 zval *res; 145 ibase_service *svm; 146 147 RESET_ERRMSG; 148 149 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 150 (operation == isc_action_svc_delete_user) ? "rs" : "rss|sss", 151 &res, &args[0], &args_len[0], &args[1], &args_len[1], &args[2], &args_len[2], 152 &args[3], &args_len[3], &args[4], &args_len[4])) { 153 RETURN_FALSE; 154 } 155 156 ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, "Interbase service manager handle", 157 le_service); 158 159 buf[0] = operation; 160 161 for (i = 0; i < sizeof(user_flags); ++i) { 162 if (args[i] != NULL) { 163 int chunk = slprintf(&buf[spb_len], sizeof(buf) - spb_len, "%c%c%c%s", 164 user_flags[i], (char)args_len[i], (char)(args_len[i] >> 8), args[i]); 165 166 if ((spb_len + chunk) > sizeof(buf) || chunk <= 0) { 167 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" 168 TSRMLS_CC, spb_len); 169 RETURN_FALSE; 170 } 171 spb_len += chunk; 172 } 173 } 174 175 /* now start the job */ 176 if (isc_service_start(IB_STATUS, &svm->handle, NULL, spb_len, buf)) { 177 IBASE_SVC_ERROR(svm); 178 RETURN_FALSE; 179 } 180 181 RETURN_TRUE; 182} 183/* }}} */ 184 185/* {{{ proto bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]]) 186 Add a user to security database */ 187PHP_FUNCTION(ibase_add_user) 188{ 189 _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_add_user); 190} 191/* }}} */ 192 193/* {{{ proto bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]]) 194 Modify a user in security database */ 195PHP_FUNCTION(ibase_modify_user) 196{ 197 _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_modify_user); 198} 199/* }}} */ 200 201/* {{{ proto bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]]) 202 Delete a user from security database */ 203PHP_FUNCTION(ibase_delete_user) 204{ 205 _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_delete_user); 206} 207/* }}} */ 208 209/* {{{ proto resource ibase_service_attach(string host, string dba_username, string dba_password) 210 Connect to the service manager */ 211PHP_FUNCTION(ibase_service_attach) 212{ 213 int hlen, ulen, plen, spb_len; 214 ibase_service *svm; 215 char buf[128], *host, *user, *pass, *loc; 216 isc_svc_handle handle = NULL; 217 218 RESET_ERRMSG; 219 220 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", 221 &host, &hlen, &user, &ulen, &pass, &plen)) { 222 223 RETURN_FALSE; 224 } 225 226 /* construct the spb, hack the service name into it as well */ 227 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%s" "%s:service_mgr", 228 isc_spb_version, isc_spb_current_version, isc_spb_user_name, (char)ulen, 229 user, isc_spb_password, (char)plen, pass, host); 230 231 if (spb_len > sizeof(buf) || spb_len == -1) { 232 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len); 233 RETURN_FALSE; 234 } 235 236 spb_len -= hlen + 12; 237 loc = buf + spb_len; /* points to %s:service_mgr part */ 238 239 /* attach to the service manager */ 240 if (isc_service_attach(IB_STATUS, 0, loc, &handle, (unsigned short)spb_len, buf)) { 241 _php_ibase_error(TSRMLS_C); 242 RETURN_FALSE; 243 } 244 245 svm = (ibase_service*)emalloc(sizeof(ibase_service)); 246 svm->handle = handle; 247 svm->hostname = estrdup(host); 248 svm->username = estrdup(user); 249 250 ZEND_REGISTER_RESOURCE(return_value, svm, le_service); 251 svm->res_id = Z_LVAL_P(return_value); 252} 253/* }}} */ 254 255/* {{{ proto bool ibase_service_detach(resource service_handle) 256 Disconnect from the service manager */ 257PHP_FUNCTION(ibase_service_detach) 258{ 259 zval *res; 260 261 RESET_ERRMSG; 262 263 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res)) { 264 RETURN_FALSE; 265 } 266 267 zend_list_delete(Z_LVAL_P(res)); 268 269 RETURN_TRUE; 270} 271/* }}} */ 272 273static void _php_ibase_service_query(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */ 274 ibase_service *svm, char info_action) 275{ 276 static char spb[] = { isc_info_svc_timeout, 10, 0, 0, 0 }; 277 278 char res_buf[400], *result, *heap_buf = NULL, *heap_p; 279 long heap_buf_size = 200, line_len; 280 281 /* info about users requires an action first */ 282 if (info_action == isc_info_svc_get_users) { 283 static char action[] = { isc_action_svc_display_user }; 284 285 if (isc_service_start(IB_STATUS, &svm->handle, NULL, sizeof(action), action)) { 286 IBASE_SVC_ERROR(svm); 287 RETURN_FALSE; 288 } 289 } 290 291query_loop: 292 result = res_buf; 293 294 if (isc_service_query(IB_STATUS, &svm->handle, NULL, sizeof(spb), spb, 295 1, &info_action, sizeof(res_buf), res_buf)) { 296 297 IBASE_SVC_ERROR(svm); 298 RETURN_FALSE; 299 } 300 while (*result != isc_info_end) { 301 switch (*result++) { 302 default: 303 RETURN_FALSE; 304 305 case isc_info_svc_line: 306 if (! (line_len = isc_vax_integer(result, 2))) { 307 /* done */ 308 if (heap_buf) { 309 RETURN_STRING(heap_buf,0); 310 } else { 311 RETURN_TRUE; 312 } 313 } 314 if (!heap_buf || (heap_p - heap_buf + line_len +2) > heap_buf_size) { 315 long res_size = heap_buf ? heap_p - heap_buf : 0; 316 317 while (heap_buf_size < (res_size + line_len +2)) { 318 heap_buf_size *= 2; 319 } 320 heap_buf = (char*) erealloc(heap_buf, heap_buf_size); 321 heap_p = heap_buf + res_size; 322 } 323 result += 2; 324 *(result+line_len) = 0; 325 snprintf(heap_p, heap_buf_size - (heap_p - heap_buf), "%s\n", result); 326 heap_p += line_len +1; 327 goto query_loop; /* repeat until result is exhausted */ 328 329 case isc_info_svc_server_version: 330 case isc_info_svc_implementation: 331 case isc_info_svc_get_env: 332 case isc_info_svc_get_env_lock: 333 case isc_info_svc_get_env_msg: 334 case isc_info_svc_user_dbpath: 335 RETURN_STRINGL(result + 2, isc_vax_integer(result, 2), 1); 336 337 case isc_info_svc_svr_db_info: 338 array_init(return_value); 339 340 do { 341 switch (*result++) { 342 int len; 343 344 case isc_spb_num_att: 345 add_assoc_long(return_value, "attachments", isc_vax_integer(result,4)); 346 result += 4; 347 break; 348 349 case isc_spb_num_db: 350 add_assoc_long(return_value, "databases", isc_vax_integer(result,4)); 351 result += 4; 352 break; 353 354 case isc_spb_dbname: 355 len = isc_vax_integer(result,2); 356 add_next_index_stringl(return_value, result +2, len, 1); 357 result += len+2; 358 } 359 } while (*result != isc_info_flag_end); 360 return; 361 362 case isc_info_svc_get_users: { 363 zval *user; 364 array_init(return_value); 365 366 while (*result != isc_info_end) { 367 368 switch (*result++) { 369 int len; 370 371 case isc_spb_sec_username: 372 /* it appears that the username is always first */ 373 ALLOC_INIT_ZVAL(user); 374 array_init(user); 375 add_next_index_zval(return_value, user); 376 377 len = isc_vax_integer(result,2); 378 add_assoc_stringl(user, "user_name", result +2, len, 1); 379 result += len+2; 380 break; 381 382 case isc_spb_sec_firstname: 383 len = isc_vax_integer(result,2); 384 add_assoc_stringl(user, "first_name", result +2, len, 1); 385 result += len+2; 386 break; 387 388 case isc_spb_sec_middlename: 389 len = isc_vax_integer(result,2); 390 add_assoc_stringl(user, "middle_name", result +2, len, 1); 391 result += len+2; 392 break; 393 394 case isc_spb_sec_lastname: 395 len = isc_vax_integer(result,2); 396 add_assoc_stringl(user, "last_name", result +2, len, 1); 397 result += len+2; 398 break; 399 400 case isc_spb_sec_userid: 401 add_assoc_long(user, "user_id", isc_vax_integer(result, 4)); 402 result += 4; 403 break; 404 405 case isc_spb_sec_groupid: 406 add_assoc_long(user, "group_id", isc_vax_integer(result, 4)); 407 result += 4; 408 break; 409 } 410 } 411 return; 412 } 413 } 414 } 415} 416/* }}} */ 417 418static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */ 419{ 420 /** 421 * It appears that the service API is a little bit confused about which flag 422 * to use for the source and destination in the case of a restore operation. 423 * When passing the backup file as isc_spb_dbname and the destination db as 424 * bpk_file, things work well. 425 */ 426 zval *res; 427 char *db, *bk, buf[200]; 428 int dblen, bklen, spb_len; 429 long opts = 0; 430 zend_bool verbose = 0; 431 ibase_service *svm; 432 433 RESET_ERRMSG; 434 435 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss|lb", 436 &res, &db, &dblen, &bk, &bklen, &opts, &verbose)) { 437 RETURN_FALSE; 438 } 439 440 ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, 441 "Interbase service manager handle", le_service); 442 443 /* fill the param buffer */ 444 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%s%c%c%c%c%c", 445 operation, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db, 446 isc_spb_bkp_file, (char)bklen, (char)(bklen >> 8), bk, isc_spb_options, 447 (char)opts,(char)(opts >> 8), (char)(opts >> 16), (char)(opts >> 24)); 448 449 if (verbose) { 450 buf[spb_len++] = isc_spb_verbose; 451 } 452 453 if (spb_len > sizeof(buf) || spb_len <= 0) { 454 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len); 455 RETURN_FALSE; 456 } 457 458 /* now start the backup/restore job */ 459 if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) { 460 IBASE_SVC_ERROR(svm); 461 RETURN_FALSE; 462 } 463 464 if (!verbose) { 465 RETURN_TRUE; 466 } else { 467 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line); 468 } 469} 470/* }}} */ 471 472/* {{{ proto mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]]) 473 Initiates a backup task in the service manager and returns immediately */ 474PHP_FUNCTION(ibase_backup) 475{ 476 _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_backup); 477} 478/* }}} */ 479 480/* {{{ proto mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]]) 481 Initiates a restore task in the service manager and returns immediately */ 482PHP_FUNCTION(ibase_restore) 483{ 484 _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_restore); 485} 486/* }}} */ 487 488static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_action) /* {{{ */ 489{ 490 zval *res; 491 char buf[128], *db; 492 int dblen, spb_len; 493 long action, argument = 0; 494 ibase_service *svm; 495 496 RESET_ERRMSG; 497 498 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsl|l", 499 &res, &db, &dblen, &action, &argument)) { 500 RETURN_FALSE; 501 } 502 503 ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, 504 "Interbase service manager handle", le_service); 505 506 if (svc_action == isc_action_svc_db_stats) { 507 switch (action) { 508 default: 509 goto unknown_option; 510 511 case isc_spb_sts_data_pages: 512 case isc_spb_sts_db_log: 513 case isc_spb_sts_hdr_pages: 514 case isc_spb_sts_idx_pages: 515 case isc_spb_sts_sys_relations: 516 goto options_argument; 517 } 518 } else { 519 /* these actions all expect different types of arguments */ 520 switch (action) { 521 default: 522unknown_option: 523 _php_ibase_module_error("Unrecognised option (%ld)" TSRMLS_CC, action); 524 RETURN_FALSE; 525 526 case isc_spb_rpr_check_db: 527 case isc_spb_rpr_ignore_checksum: 528 case isc_spb_rpr_kill_shadows: 529 case isc_spb_rpr_mend_db: 530 case isc_spb_rpr_validate_db: 531 case isc_spb_rpr_sweep_db: 532 svc_action = isc_action_svc_repair; 533 534 case isc_spb_prp_activate: 535 case isc_spb_prp_db_online: 536options_argument: 537 argument |= action; 538 action = isc_spb_options; 539 540 case isc_spb_prp_page_buffers: 541 case isc_spb_prp_sweep_interval: 542 case isc_spb_prp_shutdown_db: 543 case isc_spb_prp_deny_new_transactions: 544 case isc_spb_prp_deny_new_attachments: 545 case isc_spb_prp_set_sql_dialect: 546 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%c%c", 547 svc_action, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db, 548 (char)action, (char)argument, (char)(argument >> 8), (char)(argument >> 16), 549 (char)(argument >> 24)); 550 break; 551 552 case isc_spb_prp_reserve_space: 553 case isc_spb_prp_write_mode: 554 case isc_spb_prp_access_mode: 555 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c", 556 isc_action_svc_properties, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), 557 db, (char)action, (char)argument); 558 } 559 } 560 561 if (spb_len > sizeof(buf) || spb_len == -1) { 562 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len); 563 RETURN_FALSE; 564 } 565 566 if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) { 567 IBASE_SVC_ERROR(svm); 568 RETURN_FALSE; 569 } 570 571 if (svc_action == isc_action_svc_db_stats) { 572 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line); 573 } else { 574 RETURN_TRUE; 575 } 576} 577/* }}} */ 578 579/* {{{ proto bool ibase_maintain_db(resource service_handle, string db, int action [, int argument]) 580 Execute a maintenance command on the database server */ 581PHP_FUNCTION(ibase_maintain_db) 582{ 583 _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_properties); 584} 585/* }}} */ 586 587/* {{{ proto string ibase_db_info(resource service_handle, string db, int action [, int argument]) 588 Request statistics about a database */ 589PHP_FUNCTION(ibase_db_info) 590{ 591 _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_db_stats); 592} 593/* }}} */ 594 595/* {{{ proto string ibase_server_info(resource service_handle, int action) 596 Request information about a database server */ 597PHP_FUNCTION(ibase_server_info) 598{ 599 zval *res; 600 long action; 601 ibase_service *svm; 602 603 RESET_ERRMSG; 604 605 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &action)) { 606 RETURN_FALSE; 607 } 608 609 ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, 610 "Interbase service manager handle", le_service); 611 612 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action); 613} 614/* }}} */ 615 616#else 617 618void php_ibase_register_service_constants(INIT_FUNC_ARGS) { /* nop */ } 619 620#endif /* HAVE_IBASE */ 621 622/* 623 * Local variables: 624 * tab-width: 4 625 * c-basic-offset: 4 626 * End: 627 * vim600: sw=4 ts=4 fdm=marker 628 * vim<600: sw=4 ts=4 629 */ 630