root/ext/interbase/ibase_service.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _php_ibase_free_service
  2. php_ibase_service_minit
  3. _php_ibase_user
  4. PHP_FUNCTION
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. _php_ibase_service_query
  10. _php_ibase_backup_restore
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. _php_ibase_service_action
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. php_ibase_register_service_constants

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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 #ifdef HAVE_CONFIG_H
  20 #include "config.h"
  21 #endif
  22 
  23 #include "php.h"
  24 
  25 #if HAVE_IBASE
  26 
  27 #include "php_interbase.h"
  28 #include "php_ibase_includes.h"
  29 
  30 typedef struct {
  31         isc_svc_handle handle;
  32         char *hostname;
  33         char *username;
  34         zend_resource *res;
  35 } ibase_service;
  36 
  37 static int le_service;
  38 
  39 static void _php_ibase_free_service(zend_resource *rsrc) /* {{{ */
  40 {
  41         ibase_service *sv = (ibase_service *) rsrc->ptr;
  42 
  43         if (isc_service_detach(IB_STATUS, &sv->handle)) {
  44                 _php_ibase_error();
  45         }
  46 
  47         if (sv->hostname) {
  48                 efree(sv->hostname);
  49         }
  50         if (sv->username) {
  51                 efree(sv->username);
  52         }
  53 
  54         efree(sv);
  55 }
  56 /* }}} */
  57 
  58 /* the svc api seems to get confused after an error has occurred,
  59    so invalidate the handle on errors */
  60 #define IBASE_SVC_ERROR(svm) \
  61         do { zend_list_delete(svm->res); _php_ibase_error(); } while (0)
  62 
  63 
  64 void php_ibase_service_minit(INIT_FUNC_ARGS) /* {{{ */
  65 {
  66         le_service = zend_register_list_destructors_ex(_php_ibase_free_service, NULL,
  67             "interbase service manager handle", module_number);
  68 
  69         /* backup options */
  70         REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_CHECKSUMS", isc_spb_bkp_ignore_checksums, CONST_PERSISTENT);
  71         REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_LIMBO", isc_spb_bkp_ignore_limbo, CONST_PERSISTENT);
  72         REGISTER_LONG_CONSTANT("IBASE_BKP_METADATA_ONLY", isc_spb_bkp_metadata_only, CONST_PERSISTENT);
  73         REGISTER_LONG_CONSTANT("IBASE_BKP_NO_GARBAGE_COLLECT", isc_spb_bkp_no_garbage_collect, CONST_PERSISTENT);
  74         REGISTER_LONG_CONSTANT("IBASE_BKP_OLD_DESCRIPTIONS", isc_spb_bkp_old_descriptions, CONST_PERSISTENT);
  75         REGISTER_LONG_CONSTANT("IBASE_BKP_NON_TRANSPORTABLE", isc_spb_bkp_non_transportable, CONST_PERSISTENT);
  76         REGISTER_LONG_CONSTANT("IBASE_BKP_CONVERT", isc_spb_bkp_convert, CONST_PERSISTENT);
  77 
  78         /* restore options */
  79         REGISTER_LONG_CONSTANT("IBASE_RES_DEACTIVATE_IDX", isc_spb_res_deactivate_idx, CONST_PERSISTENT);
  80         REGISTER_LONG_CONSTANT("IBASE_RES_NO_SHADOW", isc_spb_res_no_shadow, CONST_PERSISTENT);
  81         REGISTER_LONG_CONSTANT("IBASE_RES_NO_VALIDITY", isc_spb_res_no_validity, CONST_PERSISTENT);
  82         REGISTER_LONG_CONSTANT("IBASE_RES_ONE_AT_A_TIME", isc_spb_res_one_at_a_time, CONST_PERSISTENT);
  83         REGISTER_LONG_CONSTANT("IBASE_RES_REPLACE", isc_spb_res_replace, CONST_PERSISTENT);
  84         REGISTER_LONG_CONSTANT("IBASE_RES_CREATE", isc_spb_res_create, CONST_PERSISTENT);
  85         REGISTER_LONG_CONSTANT("IBASE_RES_USE_ALL_SPACE", isc_spb_res_use_all_space, CONST_PERSISTENT);
  86 
  87         /* manage options */
  88         REGISTER_LONG_CONSTANT("IBASE_PRP_PAGE_BUFFERS", isc_spb_prp_page_buffers, CONST_PERSISTENT);
  89         REGISTER_LONG_CONSTANT("IBASE_PRP_SWEEP_INTERVAL", isc_spb_prp_sweep_interval, CONST_PERSISTENT);
  90         REGISTER_LONG_CONSTANT("IBASE_PRP_SHUTDOWN_DB", isc_spb_prp_shutdown_db, CONST_PERSISTENT);
  91         REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_TRANSACTIONS", isc_spb_prp_deny_new_transactions, CONST_PERSISTENT);
  92         REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_ATTACHMENTS", isc_spb_prp_deny_new_attachments, CONST_PERSISTENT);
  93         REGISTER_LONG_CONSTANT("IBASE_PRP_RESERVE_SPACE", isc_spb_prp_reserve_space, CONST_PERSISTENT);
  94           REGISTER_LONG_CONSTANT("IBASE_PRP_RES_USE_FULL", isc_spb_prp_res_use_full, CONST_PERSISTENT);
  95           REGISTER_LONG_CONSTANT("IBASE_PRP_RES", isc_spb_prp_res, CONST_PERSISTENT);
  96         REGISTER_LONG_CONSTANT("IBASE_PRP_WRITE_MODE", isc_spb_prp_write_mode, CONST_PERSISTENT);
  97           REGISTER_LONG_CONSTANT("IBASE_PRP_WM_ASYNC", isc_spb_prp_wm_async, CONST_PERSISTENT);
  98           REGISTER_LONG_CONSTANT("IBASE_PRP_WM_SYNC", isc_spb_prp_wm_sync, CONST_PERSISTENT);
  99         REGISTER_LONG_CONSTANT("IBASE_PRP_ACCESS_MODE", isc_spb_prp_access_mode, CONST_PERSISTENT);
 100           REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READONLY", isc_spb_prp_am_readonly, CONST_PERSISTENT);
 101           REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READWRITE", isc_spb_prp_am_readwrite, CONST_PERSISTENT);
 102         REGISTER_LONG_CONSTANT("IBASE_PRP_SET_SQL_DIALECT", isc_spb_prp_set_sql_dialect, CONST_PERSISTENT);
 103         REGISTER_LONG_CONSTANT("IBASE_PRP_ACTIVATE", isc_spb_prp_activate, CONST_PERSISTENT);
 104         REGISTER_LONG_CONSTANT("IBASE_PRP_DB_ONLINE", isc_spb_prp_db_online, CONST_PERSISTENT);
 105 
 106         /* repair options */
 107         REGISTER_LONG_CONSTANT("IBASE_RPR_CHECK_DB", isc_spb_rpr_check_db, CONST_PERSISTENT);
 108         REGISTER_LONG_CONSTANT("IBASE_RPR_IGNORE_CHECKSUM", isc_spb_rpr_ignore_checksum, CONST_PERSISTENT);
 109         REGISTER_LONG_CONSTANT("IBASE_RPR_KILL_SHADOWS", isc_spb_rpr_kill_shadows, CONST_PERSISTENT);
 110         REGISTER_LONG_CONSTANT("IBASE_RPR_MEND_DB", isc_spb_rpr_mend_db, CONST_PERSISTENT);
 111         REGISTER_LONG_CONSTANT("IBASE_RPR_VALIDATE_DB", isc_spb_rpr_validate_db, CONST_PERSISTENT);
 112           REGISTER_LONG_CONSTANT("IBASE_RPR_FULL", isc_spb_rpr_full, CONST_PERSISTENT);
 113         REGISTER_LONG_CONSTANT("IBASE_RPR_SWEEP_DB", isc_spb_rpr_sweep_db, CONST_PERSISTENT);
 114 
 115         /* db info arguments */
 116         REGISTER_LONG_CONSTANT("IBASE_STS_DATA_PAGES", isc_spb_sts_data_pages, CONST_PERSISTENT);
 117         REGISTER_LONG_CONSTANT("IBASE_STS_DB_LOG", isc_spb_sts_db_log, CONST_PERSISTENT);
 118         REGISTER_LONG_CONSTANT("IBASE_STS_HDR_PAGES", isc_spb_sts_hdr_pages, CONST_PERSISTENT);
 119         REGISTER_LONG_CONSTANT("IBASE_STS_IDX_PAGES", isc_spb_sts_idx_pages, CONST_PERSISTENT);
 120         REGISTER_LONG_CONSTANT("IBASE_STS_SYS_RELATIONS", isc_spb_sts_sys_relations, CONST_PERSISTENT);
 121 
 122         /* server info arguments */
 123         REGISTER_LONG_CONSTANT("IBASE_SVC_SERVER_VERSION", isc_info_svc_server_version, CONST_PERSISTENT);
 124         REGISTER_LONG_CONSTANT("IBASE_SVC_IMPLEMENTATION", isc_info_svc_implementation, CONST_PERSISTENT);
 125         REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV", isc_info_svc_get_env, CONST_PERSISTENT);
 126         REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_LOCK", isc_info_svc_get_env_lock, CONST_PERSISTENT);
 127         REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_MSG", isc_info_svc_get_env_msg, CONST_PERSISTENT);
 128         REGISTER_LONG_CONSTANT("IBASE_SVC_USER_DBPATH", isc_info_svc_user_dbpath, CONST_PERSISTENT);
 129         REGISTER_LONG_CONSTANT("IBASE_SVC_SVR_DB_INFO", isc_info_svc_svr_db_info, CONST_PERSISTENT);
 130         REGISTER_LONG_CONSTANT("IBASE_SVC_GET_USERS", isc_info_svc_get_users, CONST_PERSISTENT);
 131 }
 132 /* }}} */
 133 
 134 static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */
 135 {
 136         /* user = 0, password = 1, first_name = 2, middle_name = 3, last_name = 4 */
 137         static char const user_flags[] = { isc_spb_sec_username, isc_spb_sec_password,
 138             isc_spb_sec_firstname, isc_spb_sec_middlename, isc_spb_sec_lastname };
 139         char buf[128], *args[] = { NULL, NULL, NULL, NULL, NULL };
 140         int i, args_len[] = { 0, 0, 0, 0, 0 };
 141         unsigned short spb_len = 1;
 142         zval *res;
 143         ibase_service *svm;
 144 
 145         RESET_ERRMSG;
 146 
 147         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(),
 148                         (operation == isc_action_svc_delete_user) ? "rs" : "rss|sss",
 149                         &res, &args[0], &args_len[0], &args[1], &args_len[1], &args[2], &args_len[2],
 150                         &args[3], &args_len[3], &args[4], &args_len[4])) {
 151                 RETURN_FALSE;
 152         }
 153 
 154         svm = (ibase_service *)zend_fetch_resource_ex(res, "Interbase service manager handle",
 155                 le_service);
 156 
 157         buf[0] = operation;
 158 
 159         for (i = 0; i < sizeof(user_flags); ++i) {
 160                 if (args[i] != NULL) {
 161                         int chunk = slprintf(&buf[spb_len], sizeof(buf) - spb_len, "%c%c%c%s",
 162                                 user_flags[i], (char)args_len[i], (char)(args_len[i] >> 8), args[i]);
 163 
 164                         if ((spb_len + chunk) > sizeof(buf) || chunk <= 0) {
 165                                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)", spb_len);
 166                                 RETURN_FALSE;
 167                         }
 168                         spb_len += chunk;
 169                 }
 170         }
 171 
 172         /* now start the job */
 173         if (isc_service_start(IB_STATUS, &svm->handle, NULL, spb_len, buf)) {
 174                 IBASE_SVC_ERROR(svm);
 175                 RETURN_FALSE;
 176         }
 177 
 178         RETURN_TRUE;
 179 }
 180 /* }}} */
 181 
 182 /* {{{ proto bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 183    Add a user to security database */
 184 PHP_FUNCTION(ibase_add_user)
 185 {
 186         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_add_user);
 187 }
 188 /* }}} */
 189 
 190 /* {{{ proto bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 191    Modify a user in security database */
 192 PHP_FUNCTION(ibase_modify_user)
 193 {
 194         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_modify_user);
 195 }
 196 /* }}} */
 197 
 198 /* {{{ proto bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 199    Delete a user from security database */
 200 PHP_FUNCTION(ibase_delete_user)
 201 {
 202         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_delete_user);
 203 }
 204 /* }}} */
 205 
 206 /* {{{ proto resource ibase_service_attach(string host, string dba_username, string dba_password)
 207    Connect to the service manager */
 208 PHP_FUNCTION(ibase_service_attach)
 209 {
 210         size_t hlen, ulen, plen, spb_len;
 211         ibase_service *svm;
 212         char buf[128], *host, *user, *pass, *loc;
 213         isc_svc_handle handle = 0;
 214 
 215         RESET_ERRMSG;
 216 
 217         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "sss",
 218                         &host, &hlen, &user, &ulen, &pass, &plen)) {
 219 
 220                 RETURN_FALSE;
 221         }
 222 
 223         /* construct the spb, hack the service name into it as well */
 224         spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%s" "%s:service_mgr",
 225                 isc_spb_version, isc_spb_current_version, isc_spb_user_name, (char)ulen,
 226                 user, isc_spb_password, (char)plen, pass, host);
 227 
 228         if (spb_len > sizeof(buf) || spb_len == -1) {
 229                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)", spb_len);
 230                 RETURN_FALSE;
 231         }
 232 
 233         spb_len -= hlen + 12;
 234         loc = buf + spb_len; /* points to %s:service_mgr part */
 235 
 236         /* attach to the service manager */
 237         if (isc_service_attach(IB_STATUS, 0, loc, &handle, (unsigned short)spb_len, buf)) {
 238                 _php_ibase_error();
 239                 RETURN_FALSE;
 240         }
 241 
 242         svm = (ibase_service*)emalloc(sizeof(ibase_service));
 243         svm->handle = handle;
 244         svm->hostname = estrdup(host);
 245         svm->username = estrdup(user);
 246 
 247         RETVAL_RES(zend_register_resource(svm, le_service));
 248         Z_TRY_ADDREF_P(return_value);
 249         svm->res = Z_RES_P(return_value);
 250 }
 251 /* }}} */
 252 
 253 /* {{{ proto bool ibase_service_detach(resource service_handle)
 254    Disconnect from the service manager */
 255 PHP_FUNCTION(ibase_service_detach)
 256 {
 257         zval *res;
 258 
 259         RESET_ERRMSG;
 260 
 261         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &res)) {
 262                 RETURN_FALSE;
 263         }
 264 
 265         zend_list_delete(Z_RES_P(res));
 266 
 267         RETURN_TRUE;
 268 }
 269 /* }}} */
 270 
 271 static void _php_ibase_service_query(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
 272         ibase_service *svm, char info_action)
 273 {
 274         static char spb[] = { isc_info_svc_timeout, 10, 0, 0, 0 };
 275 
 276         char res_buf[400], *result, *heap_buf = NULL, *heap_p;
 277         zend_long heap_buf_size = 200, line_len;
 278 
 279         /* info about users requires an action first */
 280         if (info_action == isc_info_svc_get_users) {
 281                 static char action[] = { isc_action_svc_display_user };
 282 
 283                 if (isc_service_start(IB_STATUS, &svm->handle, NULL, sizeof(action), action)) {
 284                         IBASE_SVC_ERROR(svm);
 285                         RETURN_FALSE;
 286                 }
 287         }
 288 
 289 query_loop:
 290         result = res_buf;
 291 
 292         if (isc_service_query(IB_STATUS, &svm->handle, NULL, sizeof(spb), spb,
 293                         1, &info_action, sizeof(res_buf), res_buf)) {
 294 
 295                 IBASE_SVC_ERROR(svm);
 296                 RETURN_FALSE;
 297         }
 298         while (*result != isc_info_end) {
 299                 switch (*result++) {
 300                         default:
 301                                 RETURN_FALSE;
 302 
 303                         case isc_info_svc_line:
 304                                 if (! (line_len = isc_vax_integer(result, 2))) {
 305                                         /* done */
 306                                         if (heap_buf) {
 307                                                 RETVAL_STRING(heap_buf);
 308                                                 efree(heap_buf);
 309                                                 return;
 310                                         } else {
 311                                                 RETURN_TRUE;
 312                                         }
 313                                 }
 314                                 if (!heap_buf || (heap_p - heap_buf + line_len +2) > heap_buf_size) {
 315                                         zend_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));
 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);
 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                                                         array_init(&user);
 374                                                         add_next_index_zval(return_value, &user);
 375 
 376                                                         len = isc_vax_integer(result,2);
 377                                                         add_assoc_stringl(&user, "user_name", result +2, len);
 378                                                         result += len+2;
 379                                                         break;
 380 
 381                                                 case isc_spb_sec_firstname:
 382                                                         len = isc_vax_integer(result,2);
 383                                                         add_assoc_stringl(&user, "first_name", result +2, len);
 384                                                         result += len+2;
 385                                                         break;
 386 
 387                                                 case isc_spb_sec_middlename:
 388                                                         len = isc_vax_integer(result,2);
 389                                                         add_assoc_stringl(&user, "middle_name", result +2, len);
 390                                                         result += len+2;
 391                                                         break;
 392 
 393                                                 case isc_spb_sec_lastname:
 394                                                         len = isc_vax_integer(result,2);
 395                                                         add_assoc_stringl(&user, "last_name", result +2, len);
 396                                                         result += len+2;
 397                                                         break;
 398 
 399                                                 case isc_spb_sec_userid:
 400                                                         add_assoc_long(&user, "user_id", isc_vax_integer(result, 4));
 401                                                         result += 4;
 402                                                         break;
 403 
 404                                                 case isc_spb_sec_groupid:
 405                                                         add_assoc_long(&user, "group_id", isc_vax_integer(result, 4));
 406                                                         result += 4;
 407                                                         break;
 408                                         }
 409                                 }
 410                                 return;
 411                         }
 412                 }
 413         }
 414 }
 415 /* }}} */
 416 
 417 static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */
 418 {
 419         /**
 420          * It appears that the service API is a little bit confused about which flag
 421          * to use for the source and destination in the case of a restore operation.
 422          * When passing the backup file as isc_spb_dbname and the destination db as
 423          * bpk_file, things work well.
 424          */
 425         zval *res;
 426         char *db, *bk, buf[200];
 427         size_t dblen, bklen, spb_len;
 428         zend_long opts = 0;
 429         zend_bool verbose = 0;
 430         ibase_service *svm;
 431 
 432         RESET_ERRMSG;
 433 
 434         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rss|lb",
 435                         &res, &db, &dblen, &bk, &bklen, &opts, &verbose)) {
 436                 RETURN_FALSE;
 437         }
 438 
 439         svm = (ibase_service *)zend_fetch_resource_ex(res,
 440                 "Interbase service manager handle", le_service);
 441 
 442         /* fill the param buffer */
 443         spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%s%c%c%c%c%c",
 444                 operation, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db,
 445                 isc_spb_bkp_file, (char)bklen, (char)(bklen >> 8), bk, isc_spb_options,
 446                 (char)opts,(char)(opts >> 8), (char)(opts >> 16), (char)(opts >> 24));
 447 
 448         if (verbose) {
 449                 buf[spb_len++] = isc_spb_verbose;
 450         }
 451 
 452         if (spb_len > sizeof(buf) || spb_len <= 0) {
 453                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)", spb_len);
 454                 RETURN_FALSE;
 455         }
 456 
 457         /* now start the backup/restore job */
 458         if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) {
 459                 IBASE_SVC_ERROR(svm);
 460                 RETURN_FALSE;
 461         }
 462 
 463         if (!verbose) {
 464                 RETURN_TRUE;
 465         } else {
 466                 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line);
 467         }
 468 }
 469 /* }}} */
 470 
 471 /* {{{ proto mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]])
 472    Initiates a backup task in the service manager and returns immediately */
 473 PHP_FUNCTION(ibase_backup)
 474 {
 475         _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_backup);
 476 }
 477 /* }}} */
 478 
 479 /* {{{ proto mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]])
 480    Initiates a restore task in the service manager and returns immediately */
 481 PHP_FUNCTION(ibase_restore)
 482 {
 483         _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_restore);
 484 }
 485 /* }}} */
 486 
 487 static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_action) /* {{{ */
 488 {
 489         zval *res;
 490         char buf[128], *db;
 491         size_t dblen;
 492         int spb_len;
 493         zend_long action, argument = 0;
 494         ibase_service *svm;
 495 
 496         RESET_ERRMSG;
 497 
 498         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rsl|l",
 499                         &res, &db, &dblen, &action, &argument)) {
 500                 RETURN_FALSE;
 501         }
 502 
 503         svm = (ibase_service *)zend_fetch_resource_ex(res,
 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:
 522 unknown_option:
 523                                 _php_ibase_module_error("Unrecognised option (" ZEND_LONG_FMT ")", 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:
 536 options_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)", 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 */
 581 PHP_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 */
 589 PHP_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 */
 597 PHP_FUNCTION(ibase_server_info)
 598 {
 599         zval *res;
 600         zend_long action;
 601         ibase_service *svm;
 602 
 603         RESET_ERRMSG;
 604 
 605         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &res, &action)) {
 606                 RETURN_FALSE;
 607         }
 608 
 609         svm = (ibase_service *)zend_fetch_resource_ex(res,
 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 
 618 void 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  */

/* [<][>][^][v][top][bottom][index][help] */