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 5                                                        |
   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         long res_id;
  35 } ibase_service;
  36 
  37 static int le_service;
  38 
  39 static void _php_ibase_free_service(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
  40 {
  41         ibase_service *sv = (ibase_service *) rsrc->ptr;
  42 
  43         if (isc_service_detach(IB_STATUS, &sv->handle)) {
  44                 _php_ibase_error(TSRMLS_C);
  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_id); _php_ibase_error(TSRMLS_C); } 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() TSRMLS_CC,
 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         ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, "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)"
 166                                         TSRMLS_CC, spb_len);
 167                                 RETURN_FALSE;
 168                         }
 169                         spb_len += chunk;
 170                 }
 171         }
 172 
 173         /* now start the job */
 174         if (isc_service_start(IB_STATUS, &svm->handle, NULL, spb_len, buf)) {
 175                 IBASE_SVC_ERROR(svm);
 176                 RETURN_FALSE;
 177         }
 178 
 179         RETURN_TRUE;
 180 }
 181 /* }}} */
 182 
 183 /* {{{ proto bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 184    Add a user to security database */
 185 PHP_FUNCTION(ibase_add_user)
 186 {
 187         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_add_user);
 188 }
 189 /* }}} */
 190 
 191 /* {{{ proto bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 192    Modify a user in security database */
 193 PHP_FUNCTION(ibase_modify_user)
 194 {
 195         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_modify_user);
 196 }
 197 /* }}} */
 198 
 199 /* {{{ proto bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
 200    Delete a user from security database */
 201 PHP_FUNCTION(ibase_delete_user)
 202 {
 203         _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_delete_user);
 204 }
 205 /* }}} */
 206 
 207 /* {{{ proto resource ibase_service_attach(string host, string dba_username, string dba_password)
 208    Connect to the service manager */
 209 PHP_FUNCTION(ibase_service_attach)
 210 {
 211         int hlen, ulen, plen, spb_len;
 212         ibase_service *svm;
 213         char buf[128], *host, *user, *pass, *loc;
 214         isc_svc_handle handle = NULL;
 215 
 216         RESET_ERRMSG;
 217 
 218         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss",
 219                         &host, &hlen, &user, &ulen, &pass, &plen)) {
 220 
 221                 RETURN_FALSE;
 222         }
 223 
 224         /* construct the spb, hack the service name into it as well */
 225         spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%s" "%s:service_mgr",
 226                 isc_spb_version, isc_spb_current_version, isc_spb_user_name, (char)ulen,
 227                 user, isc_spb_password, (char)plen, pass, host);
 228 
 229         if (spb_len > sizeof(buf) || spb_len == -1) {
 230                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
 231                 RETURN_FALSE;
 232         }
 233 
 234         spb_len -= hlen + 12;
 235         loc = buf + spb_len; /* points to %s:service_mgr part */
 236 
 237         /* attach to the service manager */
 238         if (isc_service_attach(IB_STATUS, 0, loc, &handle, (unsigned short)spb_len, buf)) {
 239                 _php_ibase_error(TSRMLS_C);
 240                 RETURN_FALSE;
 241         }
 242 
 243         svm = (ibase_service*)emalloc(sizeof(ibase_service));
 244         svm->handle = handle;
 245         svm->hostname = estrdup(host);
 246         svm->username = estrdup(user);
 247 
 248         ZEND_REGISTER_RESOURCE(return_value, svm, le_service);
 249         svm->res_id = Z_LVAL_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() TSRMLS_CC, "r", &res)) {
 262                 RETURN_FALSE;
 263         }
 264 
 265         zend_list_delete(Z_LVAL_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         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                                                 RETURN_STRING(heap_buf,0);
 308                                         } else {
 309                                                 RETURN_TRUE;
 310                                         }
 311                                 }
 312                                 if (!heap_buf || (heap_p - heap_buf + line_len +2) > heap_buf_size) {
 313                                         long res_size = heap_buf ? heap_p - heap_buf : 0;
 314 
 315                                         while (heap_buf_size < (res_size + line_len +2)) {
 316                                                 heap_buf_size *= 2;
 317                                         }
 318                                         heap_buf = (char*) erealloc(heap_buf, heap_buf_size);
 319                                         heap_p = heap_buf + res_size;
 320                                 }
 321                                 result += 2;
 322                                 *(result+line_len) = 0;
 323                                 snprintf(heap_p, heap_buf_size - (heap_p - heap_buf), "%s\n", result);
 324                                 heap_p += line_len +1;
 325                                 goto query_loop; /* repeat until result is exhausted */
 326 
 327                         case isc_info_svc_server_version:
 328                         case isc_info_svc_implementation:
 329                         case isc_info_svc_get_env:
 330                         case isc_info_svc_get_env_lock:
 331                         case isc_info_svc_get_env_msg:
 332                         case isc_info_svc_user_dbpath:
 333                                 RETURN_STRINGL(result + 2, isc_vax_integer(result, 2), 1);
 334 
 335                         case isc_info_svc_svr_db_info:
 336                                 array_init(return_value);
 337 
 338                                 do {
 339                                         switch (*result++) {
 340                                                 int len;
 341 
 342                                                 case isc_spb_num_att:
 343                                                         add_assoc_long(return_value, "attachments", isc_vax_integer(result,4));
 344                                                         result += 4;
 345                                                         break;
 346 
 347                                                 case isc_spb_num_db:
 348                                                         add_assoc_long(return_value, "databases", isc_vax_integer(result,4));
 349                                                         result += 4;
 350                                                         break;
 351 
 352                                                 case isc_spb_dbname:
 353                                                         len = isc_vax_integer(result,2);
 354                                                         add_next_index_stringl(return_value, result +2, len, 1);
 355                                                         result += len+2;
 356                                         }
 357                                 } while (*result != isc_info_flag_end);
 358                                 return;
 359 
 360                         case isc_info_svc_get_users: {
 361                                 zval *user;
 362                                 array_init(return_value);
 363 
 364                                 while (*result != isc_info_end) {
 365 
 366                                         switch (*result++) {
 367                                                 int len;
 368 
 369                                                 case isc_spb_sec_username:
 370                                                         /* it appears that the username is always first */
 371                                                         ALLOC_INIT_ZVAL(user);
 372                                                         array_init(user);
 373                                                         add_next_index_zval(return_value, user);
 374 
 375                                                         len = isc_vax_integer(result,2);
 376                                                         add_assoc_stringl(user, "user_name", result +2, len, 1);
 377                                                         result += len+2;
 378                                                         break;
 379 
 380                                                 case isc_spb_sec_firstname:
 381                                                         len = isc_vax_integer(result,2);
 382                                                         add_assoc_stringl(user, "first_name", result +2, len, 1);
 383                                                         result += len+2;
 384                                                         break;
 385 
 386                                                 case isc_spb_sec_middlename:
 387                                                         len = isc_vax_integer(result,2);
 388                                                         add_assoc_stringl(user, "middle_name", result +2, len, 1);
 389                                                         result += len+2;
 390                                                         break;
 391 
 392                                                 case isc_spb_sec_lastname:
 393                                                         len = isc_vax_integer(result,2);
 394                                                         add_assoc_stringl(user, "last_name", result +2, len, 1);
 395                                                         result += len+2;
 396                                                         break;
 397 
 398                                                 case isc_spb_sec_userid:
 399                                                         add_assoc_long(user, "user_id", isc_vax_integer(result, 4));
 400                                                         result += 4;
 401                                                         break;
 402 
 403                                                 case isc_spb_sec_groupid:
 404                                                         add_assoc_long(user, "group_id", isc_vax_integer(result, 4));
 405                                                         result += 4;
 406                                                         break;
 407                                         }
 408                                 }
 409                                 return;
 410                         }
 411                 }
 412         }
 413 }
 414 /* }}} */
 415 
 416 static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */
 417 {
 418         /**
 419          * It appears that the service API is a little bit confused about which flag
 420          * to use for the source and destination in the case of a restore operation.
 421          * When passing the backup file as isc_spb_dbname and the destination db as
 422          * bpk_file, things work well.
 423          */
 424         zval *res;
 425         char *db, *bk, buf[200];
 426         int dblen, bklen, spb_len;
 427         long opts = 0;
 428         zend_bool verbose = 0;
 429         ibase_service *svm;
 430 
 431         RESET_ERRMSG;
 432 
 433         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss|lb",
 434                         &res, &db, &dblen, &bk, &bklen, &opts, &verbose)) {
 435                 RETURN_FALSE;
 436         }
 437 
 438         ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
 439                 "Interbase service manager handle", le_service);
 440 
 441         /* fill the param buffer */
 442         spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%s%c%c%c%c%c",
 443                 operation, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db,
 444                 isc_spb_bkp_file, (char)bklen, (char)(bklen >> 8), bk, isc_spb_options,
 445                 (char)opts,(char)(opts >> 8), (char)(opts >> 16), (char)(opts >> 24));
 446 
 447         if (verbose) {
 448                 buf[spb_len++] = isc_spb_verbose;
 449         }
 450 
 451         if (spb_len > sizeof(buf) || spb_len <= 0) {
 452                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
 453                 RETURN_FALSE;
 454         }
 455 
 456         /* now start the backup/restore job */
 457         if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) {
 458                 IBASE_SVC_ERROR(svm);
 459                 RETURN_FALSE;
 460         }
 461 
 462         if (!verbose) {
 463                 RETURN_TRUE;
 464         } else {
 465                 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line);
 466         }
 467 }
 468 /* }}} */
 469 
 470 /* {{{ proto mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]])
 471    Initiates a backup task in the service manager and returns immediately */
 472 PHP_FUNCTION(ibase_backup)
 473 {
 474         _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_backup);
 475 }
 476 /* }}} */
 477 
 478 /* {{{ proto mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]])
 479    Initiates a restore task in the service manager and returns immediately */
 480 PHP_FUNCTION(ibase_restore)
 481 {
 482         _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_restore);
 483 }
 484 /* }}} */
 485 
 486 static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_action) /* {{{ */
 487 {
 488         zval *res;
 489         char buf[128], *db;
 490         int dblen, spb_len;
 491         long action, argument = 0;
 492         ibase_service *svm;
 493 
 494         RESET_ERRMSG;
 495 
 496         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsl|l",
 497                         &res, &db, &dblen, &action, &argument)) {
 498                 RETURN_FALSE;
 499         }
 500 
 501         ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
 502                 "Interbase service manager handle", le_service);
 503 
 504         if (svc_action == isc_action_svc_db_stats) {
 505                 switch (action) {
 506                         default:
 507                                 goto unknown_option;
 508 
 509                         case isc_spb_sts_data_pages:
 510                         case isc_spb_sts_db_log:
 511                         case isc_spb_sts_hdr_pages:
 512                         case isc_spb_sts_idx_pages:
 513                         case isc_spb_sts_sys_relations:
 514                                 goto options_argument;
 515                 }
 516         } else {
 517                 /* these actions all expect different types of arguments */
 518                 switch (action) {
 519                         default:
 520 unknown_option:
 521                                 _php_ibase_module_error("Unrecognised option (%ld)" TSRMLS_CC, action);
 522                                 RETURN_FALSE;
 523 
 524                         case isc_spb_rpr_check_db:
 525                         case isc_spb_rpr_ignore_checksum:
 526                         case isc_spb_rpr_kill_shadows:
 527                         case isc_spb_rpr_mend_db:
 528                         case isc_spb_rpr_validate_db:
 529                         case isc_spb_rpr_sweep_db:
 530                                 svc_action = isc_action_svc_repair;
 531 
 532                         case isc_spb_prp_activate:
 533                         case isc_spb_prp_db_online:
 534 options_argument:
 535                                 argument |= action;
 536                                 action = isc_spb_options;
 537 
 538                         case isc_spb_prp_page_buffers:
 539                         case isc_spb_prp_sweep_interval:
 540                         case isc_spb_prp_shutdown_db:
 541                         case isc_spb_prp_deny_new_transactions:
 542                         case isc_spb_prp_deny_new_attachments:
 543                         case isc_spb_prp_set_sql_dialect:
 544                                 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%c%c",
 545                                         svc_action, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db,
 546                                         (char)action, (char)argument, (char)(argument >> 8), (char)(argument >> 16),
 547                                         (char)(argument >> 24));
 548                                 break;
 549 
 550                         case isc_spb_prp_reserve_space:
 551                         case isc_spb_prp_write_mode:
 552                         case isc_spb_prp_access_mode:
 553                                 spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c",
 554                                         isc_action_svc_properties, isc_spb_dbname, (char)dblen, (char)(dblen >> 8),
 555                                         db, (char)action, (char)argument);
 556                 }
 557         }
 558 
 559         if (spb_len > sizeof(buf) || spb_len == -1) {
 560                 _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
 561                 RETURN_FALSE;
 562         }
 563 
 564         if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) {
 565                 IBASE_SVC_ERROR(svm);
 566                 RETURN_FALSE;
 567         }
 568 
 569         if (svc_action == isc_action_svc_db_stats) {
 570                 _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line);
 571         } else {
 572                 RETURN_TRUE;
 573         }
 574 }
 575 /* }}} */
 576 
 577 /* {{{ proto bool ibase_maintain_db(resource service_handle, string db, int action [, int argument])
 578    Execute a maintenance command on the database server */
 579 PHP_FUNCTION(ibase_maintain_db)
 580 {
 581         _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_properties);
 582 }
 583 /* }}} */
 584 
 585 /* {{{ proto string ibase_db_info(resource service_handle, string db, int action [, int argument])
 586    Request statistics about a database */
 587 PHP_FUNCTION(ibase_db_info)
 588 {
 589         _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_db_stats);
 590 }
 591 /* }}} */
 592 
 593 /* {{{ proto string ibase_server_info(resource service_handle, int action)
 594    Request information about a database server */
 595 PHP_FUNCTION(ibase_server_info)
 596 {
 597         zval *res;
 598         long action;
 599         ibase_service *svm;
 600 
 601         RESET_ERRMSG;
 602 
 603         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &action)) {
 604                 RETURN_FALSE;
 605         }
 606 
 607         ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
 608                 "Interbase service manager handle", le_service);
 609 
 610         _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action);
 611 }
 612 /* }}} */
 613 
 614 #else
 615 
 616 void php_ibase_register_service_constants(INIT_FUNC_ARGS) { /* nop */ }
 617 
 618 #endif /* HAVE_IBASE */
 619 
 620 /*
 621  * Local variables:
 622  * tab-width: 4
 623  * c-basic-offset: 4
 624  * End:
 625  * vim600: sw=4 ts=4 fdm=marker
 626  * vim<600: sw=4 ts=4
 627  */

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