Back to index

php5  5.3.10
ibase_service.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Ard Biesheuvel <a.k.biesheuvel@its.tudelft.nl>              |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: ibase_service.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include "php.h"
00026 
00027 #if HAVE_IBASE
00028 
00029 #include "php_interbase.h"
00030 #include "php_ibase_includes.h"
00031 
00032 typedef struct {
00033        isc_svc_handle handle;
00034        char *hostname;
00035        char *username;
00036        long res_id;
00037 } ibase_service;
00038 
00039 static int le_service;
00040 
00041 static void _php_ibase_free_service(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
00042 {
00043        ibase_service *sv = (ibase_service *) rsrc->ptr;
00044 
00045        if (isc_service_detach(IB_STATUS, &sv->handle)) {
00046               _php_ibase_error(TSRMLS_C);
00047        }
00048 
00049        if (sv->hostname) {
00050               efree(sv->hostname);
00051        }
00052        if (sv->username) {
00053               efree(sv->username);
00054        }
00055 
00056        efree(sv);
00057 }
00058 /* }}} */
00059 
00060 /* the svc api seems to get confused after an error has occurred, 
00061    so invalidate the handle on errors */
00062 #define IBASE_SVC_ERROR(svm) \
00063        do { zend_list_delete(svm->res_id); _php_ibase_error(TSRMLS_C); } while (0)
00064        
00065 
00066 void php_ibase_service_minit(INIT_FUNC_ARGS) /* {{{ */
00067 {
00068        le_service = zend_register_list_destructors_ex(_php_ibase_free_service, NULL, 
00069            "interbase service manager handle", module_number);
00070 
00071        /* backup options */
00072        REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_CHECKSUMS", isc_spb_bkp_ignore_checksums, CONST_PERSISTENT);
00073        REGISTER_LONG_CONSTANT("IBASE_BKP_IGNORE_LIMBO", isc_spb_bkp_ignore_limbo, CONST_PERSISTENT);
00074        REGISTER_LONG_CONSTANT("IBASE_BKP_METADATA_ONLY", isc_spb_bkp_metadata_only, CONST_PERSISTENT);
00075        REGISTER_LONG_CONSTANT("IBASE_BKP_NO_GARBAGE_COLLECT", isc_spb_bkp_no_garbage_collect, CONST_PERSISTENT);
00076        REGISTER_LONG_CONSTANT("IBASE_BKP_OLD_DESCRIPTIONS", isc_spb_bkp_old_descriptions, CONST_PERSISTENT);
00077        REGISTER_LONG_CONSTANT("IBASE_BKP_NON_TRANSPORTABLE", isc_spb_bkp_non_transportable, CONST_PERSISTENT);
00078        REGISTER_LONG_CONSTANT("IBASE_BKP_CONVERT", isc_spb_bkp_convert, CONST_PERSISTENT);
00079 
00080        /* restore options */
00081        REGISTER_LONG_CONSTANT("IBASE_RES_DEACTIVATE_IDX", isc_spb_res_deactivate_idx, CONST_PERSISTENT);
00082        REGISTER_LONG_CONSTANT("IBASE_RES_NO_SHADOW", isc_spb_res_no_shadow, CONST_PERSISTENT);
00083        REGISTER_LONG_CONSTANT("IBASE_RES_NO_VALIDITY", isc_spb_res_no_validity, CONST_PERSISTENT);
00084        REGISTER_LONG_CONSTANT("IBASE_RES_ONE_AT_A_TIME", isc_spb_res_one_at_a_time, CONST_PERSISTENT);
00085        REGISTER_LONG_CONSTANT("IBASE_RES_REPLACE", isc_spb_res_replace, CONST_PERSISTENT);
00086        REGISTER_LONG_CONSTANT("IBASE_RES_CREATE", isc_spb_res_create, CONST_PERSISTENT);
00087        REGISTER_LONG_CONSTANT("IBASE_RES_USE_ALL_SPACE", isc_spb_res_use_all_space, CONST_PERSISTENT);
00088 
00089        /* manage options */
00090        REGISTER_LONG_CONSTANT("IBASE_PRP_PAGE_BUFFERS", isc_spb_prp_page_buffers, CONST_PERSISTENT);
00091        REGISTER_LONG_CONSTANT("IBASE_PRP_SWEEP_INTERVAL", isc_spb_prp_sweep_interval, CONST_PERSISTENT);
00092        REGISTER_LONG_CONSTANT("IBASE_PRP_SHUTDOWN_DB", isc_spb_prp_shutdown_db, CONST_PERSISTENT);
00093        REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_TRANSACTIONS", isc_spb_prp_deny_new_transactions, CONST_PERSISTENT);
00094        REGISTER_LONG_CONSTANT("IBASE_PRP_DENY_NEW_ATTACHMENTS", isc_spb_prp_deny_new_attachments, CONST_PERSISTENT);
00095        REGISTER_LONG_CONSTANT("IBASE_PRP_RESERVE_SPACE", isc_spb_prp_reserve_space, CONST_PERSISTENT);
00096          REGISTER_LONG_CONSTANT("IBASE_PRP_RES_USE_FULL", isc_spb_prp_res_use_full, CONST_PERSISTENT);
00097          REGISTER_LONG_CONSTANT("IBASE_PRP_RES", isc_spb_prp_res, CONST_PERSISTENT);
00098        REGISTER_LONG_CONSTANT("IBASE_PRP_WRITE_MODE", isc_spb_prp_write_mode, CONST_PERSISTENT);
00099          REGISTER_LONG_CONSTANT("IBASE_PRP_WM_ASYNC", isc_spb_prp_wm_async, CONST_PERSISTENT);
00100          REGISTER_LONG_CONSTANT("IBASE_PRP_WM_SYNC", isc_spb_prp_wm_sync, CONST_PERSISTENT);
00101        REGISTER_LONG_CONSTANT("IBASE_PRP_ACCESS_MODE", isc_spb_prp_access_mode, CONST_PERSISTENT);
00102          REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READONLY", isc_spb_prp_am_readonly, CONST_PERSISTENT);
00103          REGISTER_LONG_CONSTANT("IBASE_PRP_AM_READWRITE", isc_spb_prp_am_readwrite, CONST_PERSISTENT);
00104        REGISTER_LONG_CONSTANT("IBASE_PRP_SET_SQL_DIALECT", isc_spb_prp_set_sql_dialect, CONST_PERSISTENT);
00105        REGISTER_LONG_CONSTANT("IBASE_PRP_ACTIVATE", isc_spb_prp_activate, CONST_PERSISTENT);
00106        REGISTER_LONG_CONSTANT("IBASE_PRP_DB_ONLINE", isc_spb_prp_db_online, CONST_PERSISTENT);
00107 
00108        /* repair options */
00109        REGISTER_LONG_CONSTANT("IBASE_RPR_CHECK_DB", isc_spb_rpr_check_db, CONST_PERSISTENT);
00110        REGISTER_LONG_CONSTANT("IBASE_RPR_IGNORE_CHECKSUM", isc_spb_rpr_ignore_checksum, CONST_PERSISTENT);
00111        REGISTER_LONG_CONSTANT("IBASE_RPR_KILL_SHADOWS", isc_spb_rpr_kill_shadows, CONST_PERSISTENT);
00112        REGISTER_LONG_CONSTANT("IBASE_RPR_MEND_DB", isc_spb_rpr_mend_db, CONST_PERSISTENT);
00113        REGISTER_LONG_CONSTANT("IBASE_RPR_VALIDATE_DB", isc_spb_rpr_validate_db, CONST_PERSISTENT);
00114          REGISTER_LONG_CONSTANT("IBASE_RPR_FULL", isc_spb_rpr_full, CONST_PERSISTENT);
00115        REGISTER_LONG_CONSTANT("IBASE_RPR_SWEEP_DB", isc_spb_rpr_sweep_db, CONST_PERSISTENT);
00116 
00117        /* db info arguments */
00118        REGISTER_LONG_CONSTANT("IBASE_STS_DATA_PAGES", isc_spb_sts_data_pages, CONST_PERSISTENT);
00119        REGISTER_LONG_CONSTANT("IBASE_STS_DB_LOG", isc_spb_sts_db_log, CONST_PERSISTENT);
00120        REGISTER_LONG_CONSTANT("IBASE_STS_HDR_PAGES", isc_spb_sts_hdr_pages, CONST_PERSISTENT);
00121        REGISTER_LONG_CONSTANT("IBASE_STS_IDX_PAGES", isc_spb_sts_idx_pages, CONST_PERSISTENT);
00122        REGISTER_LONG_CONSTANT("IBASE_STS_SYS_RELATIONS", isc_spb_sts_sys_relations, CONST_PERSISTENT);
00123 
00124        /* server info arguments */
00125        REGISTER_LONG_CONSTANT("IBASE_SVC_SERVER_VERSION", isc_info_svc_server_version, CONST_PERSISTENT);
00126        REGISTER_LONG_CONSTANT("IBASE_SVC_IMPLEMENTATION", isc_info_svc_implementation, CONST_PERSISTENT);
00127        REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV", isc_info_svc_get_env, CONST_PERSISTENT);
00128        REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_LOCK", isc_info_svc_get_env_lock, CONST_PERSISTENT);
00129        REGISTER_LONG_CONSTANT("IBASE_SVC_GET_ENV_MSG", isc_info_svc_get_env_msg, CONST_PERSISTENT);
00130        REGISTER_LONG_CONSTANT("IBASE_SVC_USER_DBPATH", isc_info_svc_user_dbpath, CONST_PERSISTENT);
00131        REGISTER_LONG_CONSTANT("IBASE_SVC_SVR_DB_INFO", isc_info_svc_svr_db_info, CONST_PERSISTENT);
00132        REGISTER_LONG_CONSTANT("IBASE_SVC_GET_USERS", isc_info_svc_get_users, CONST_PERSISTENT);
00133 }
00134 /* }}} */
00135 
00136 static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */
00137 {
00138        /* user = 0, password = 1, first_name = 2, middle_name = 3, last_name = 4 */
00139        static char const user_flags[] = { isc_spb_sec_username, isc_spb_sec_password, 
00140            isc_spb_sec_firstname, isc_spb_sec_middlename, isc_spb_sec_lastname };
00141        char buf[128], *args[] = { NULL, NULL, NULL, NULL, NULL };
00142        int i, args_len[] = { 0, 0, 0, 0, 0 };
00143        unsigned short spb_len = 1;
00144        zval *res;
00145        ibase_service *svm;
00146 
00147        RESET_ERRMSG;
00148 
00149        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
00150                      (operation == isc_action_svc_delete_user) ? "rs" : "rss|sss",
00151                      &res, &args[0], &args_len[0], &args[1], &args_len[1], &args[2], &args_len[2],
00152                      &args[3], &args_len[3], &args[4], &args_len[4])) {
00153               RETURN_FALSE;
00154        }
00155                      
00156        ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, "Interbase service manager handle",
00157               le_service);
00158 
00159        buf[0] = operation;
00160        
00161        for (i = 0; i < sizeof(user_flags); ++i) {
00162               if (args[i] != NULL) {
00163                      int chunk = slprintf(&buf[spb_len], sizeof(buf) - spb_len, "%c%c%c%s",
00164                             user_flags[i], (char)args_len[i], (char)(args_len[i] >> 8), args[i]);
00165                      
00166                      if ((spb_len + chunk) > sizeof(buf) || chunk <= 0) {
00167                             _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)"
00168                                    TSRMLS_CC, spb_len);
00169                             RETURN_FALSE;
00170                      }
00171                      spb_len += chunk;
00172               }
00173        }
00174 
00175        /* now start the job */
00176        if (isc_service_start(IB_STATUS, &svm->handle, NULL, spb_len, buf)) {
00177               IBASE_SVC_ERROR(svm);
00178               RETURN_FALSE;
00179        }
00180 
00181        RETURN_TRUE;
00182 }
00183 /* }}} */
00184 
00185 /* {{{ proto bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
00186    Add a user to security database */
00187 PHP_FUNCTION(ibase_add_user)
00188 {
00189        _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_add_user);
00190 }
00191 /* }}} */
00192 
00193 /* {{{ proto bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
00194    Modify a user in security database */
00195 PHP_FUNCTION(ibase_modify_user)
00196 {
00197        _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_modify_user);
00198 }
00199 /* }}} */
00200 
00201 /* {{{ proto bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
00202    Delete a user from security database */
00203 PHP_FUNCTION(ibase_delete_user)
00204 {
00205        _php_ibase_user(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_delete_user);
00206 }
00207 /* }}} */
00208 
00209 /* {{{ proto resource ibase_service_attach(string host, string dba_username, string dba_password)
00210    Connect to the service manager */
00211 PHP_FUNCTION(ibase_service_attach)
00212 {
00213        int hlen, ulen, plen, spb_len;
00214        ibase_service *svm;
00215        char buf[128], *host, *user, *pass, *loc;
00216        isc_svc_handle handle = NULL;
00217 
00218        RESET_ERRMSG;
00219 
00220        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss",
00221                      &host, &hlen, &user, &ulen, &pass, &plen)) {
00222 
00223               RETURN_FALSE;
00224        }
00225 
00226        /* construct the spb, hack the service name into it as well */
00227        spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%s" "%s:service_mgr",
00228               isc_spb_version, isc_spb_current_version, isc_spb_user_name, (char)ulen,
00229               user, isc_spb_password, (char)plen, pass, host);
00230 
00231        if (spb_len > sizeof(buf) || spb_len == -1) {
00232               _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
00233               RETURN_FALSE;
00234        }
00235 
00236        spb_len -= hlen + 12;
00237        loc = buf + spb_len; /* points to %s:service_mgr part */
00238 
00239        /* attach to the service manager */
00240        if (isc_service_attach(IB_STATUS, 0, loc, &handle, (unsigned short)spb_len, buf)) {
00241               _php_ibase_error(TSRMLS_C);
00242               RETURN_FALSE;
00243        }
00244 
00245        svm = (ibase_service*)emalloc(sizeof(ibase_service));
00246        svm->handle = handle;
00247        svm->hostname = estrdup(host);
00248        svm->username = estrdup(user);
00249 
00250        ZEND_REGISTER_RESOURCE(return_value, svm, le_service);
00251        svm->res_id = Z_LVAL_P(return_value);
00252 }
00253 /* }}} */
00254 
00255 /* {{{ proto bool ibase_service_detach(resource service_handle)
00256    Disconnect from the service manager */
00257 PHP_FUNCTION(ibase_service_detach)
00258 {
00259        zval *res;
00260 
00261        RESET_ERRMSG;
00262 
00263        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res)) {
00264               RETURN_FALSE;
00265        }
00266 
00267        zend_list_delete(Z_LVAL_P(res));
00268 
00269        RETURN_TRUE;
00270 }
00271 /* }}} */
00272 
00273 static void _php_ibase_service_query(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
00274        ibase_service *svm, char info_action)
00275 {
00276        static char spb[] = { isc_info_svc_timeout, 10, 0, 0, 0 };
00277 
00278        char res_buf[400], *result, *heap_buf = NULL, *heap_p;
00279        long heap_buf_size = 200, line_len;
00280 
00281        /* info about users requires an action first */
00282        if (info_action == isc_info_svc_get_users) {
00283               static char action[] = { isc_action_svc_display_user };
00284 
00285               if (isc_service_start(IB_STATUS, &svm->handle, NULL, sizeof(action), action)) {
00286                      IBASE_SVC_ERROR(svm);
00287                      RETURN_FALSE;
00288               }
00289        }
00290 
00291 query_loop:
00292        result = res_buf;
00293 
00294        if (isc_service_query(IB_STATUS, &svm->handle, NULL, sizeof(spb), spb,
00295                      1, &info_action, sizeof(res_buf), res_buf)) {
00296 
00297               IBASE_SVC_ERROR(svm);
00298               RETURN_FALSE;
00299        }
00300        while (*result != isc_info_end) {
00301               switch (*result++) {
00302                      default:
00303                             RETURN_FALSE;
00304 
00305                      case isc_info_svc_line:
00306                             if (! (line_len = isc_vax_integer(result, 2))) {
00307                                    /* done */
00308                                    if (heap_buf) {
00309                                           RETURN_STRING(heap_buf,0);
00310                                    } else {
00311                                           RETURN_TRUE;
00312                                    }
00313                             }
00314                             if (!heap_buf || (heap_p - heap_buf + line_len +2) > heap_buf_size) {
00315                                    long res_size = heap_buf ? heap_p - heap_buf : 0;
00316 
00317                                    while (heap_buf_size < (res_size + line_len +2)) {
00318                                           heap_buf_size *= 2;
00319                                    }
00320                                    heap_buf = (char*) erealloc(heap_buf, heap_buf_size);
00321                                    heap_p = heap_buf + res_size;
00322                             }
00323                             result += 2;
00324                             snprintf(heap_p, heap_buf_size - (heap_buf - heap_p), "%s\n", result);
00325                             heap_p += line_len +2;
00326                             goto query_loop; /* repeat until result is exhausted */
00327 
00328                      case isc_info_svc_server_version:
00329                      case isc_info_svc_implementation:
00330                      case isc_info_svc_get_env:
00331                      case isc_info_svc_get_env_lock:
00332                      case isc_info_svc_get_env_msg:
00333                      case isc_info_svc_user_dbpath:
00334                             RETURN_STRINGL(result + 2, isc_vax_integer(result, 2), 1);
00335 
00336                      case isc_info_svc_svr_db_info:
00337                             array_init(return_value);
00338 
00339                             do {
00340                                    switch (*result++) {
00341                                           int len;
00342 
00343                                           case isc_spb_num_att:
00344                                                  add_assoc_long(return_value, "attachments", isc_vax_integer(result,4));
00345                                                  result += 4;
00346                                                  break;
00347 
00348                                           case isc_spb_num_db:
00349                                                  add_assoc_long(return_value, "databases", isc_vax_integer(result,4));
00350                                                  result += 4;
00351                                                  break;
00352 
00353                                           case isc_spb_dbname:
00354                                                  len = isc_vax_integer(result,2);
00355                                                  add_next_index_stringl(return_value, result +2, len, 1);
00356                                                  result += len+2;
00357                                    }
00358                             } while (*result != isc_info_flag_end);
00359                             return;
00360 
00361                      case isc_info_svc_get_users: {
00362                             zval *user;
00363                             array_init(return_value);
00364 
00365                             while (*result != isc_info_end) {
00366 
00367                                    switch (*result++) {
00368                                           int len;
00369 
00370                                           case isc_spb_sec_username:
00371                                                  /* it appears that the username is always first */
00372                                                  ALLOC_INIT_ZVAL(user);
00373                                                  array_init(user);
00374                                                  add_next_index_zval(return_value, user);
00375 
00376                                                  len = isc_vax_integer(result,2);
00377                                                  add_assoc_stringl(user, "user_name", result +2, len, 1);
00378                                                  result += len+2;
00379                                                  break;
00380 
00381                                           case isc_spb_sec_firstname:
00382                                                  len = isc_vax_integer(result,2);
00383                                                  add_assoc_stringl(user, "first_name", result +2, len, 1);
00384                                                  result += len+2;
00385                                                  break;
00386 
00387                                           case isc_spb_sec_middlename:
00388                                                  len = isc_vax_integer(result,2);
00389                                                  add_assoc_stringl(user, "middle_name", result +2, len, 1);
00390                                                  result += len+2;
00391                                                  break;
00392 
00393                                           case isc_spb_sec_lastname:
00394                                                  len = isc_vax_integer(result,2);
00395                                                  add_assoc_stringl(user, "last_name", result +2, len, 1);
00396                                                  result += len+2;
00397                                                  break;
00398 
00399                                           case isc_spb_sec_userid:
00400                                                  add_assoc_long(user, "user_id", isc_vax_integer(result, 4));
00401                                                  result += 4;
00402                                                  break;
00403 
00404                                           case isc_spb_sec_groupid:
00405                                                  add_assoc_long(user, "group_id", isc_vax_integer(result, 4));
00406                                                  result += 4;
00407                                                  break;
00408                                    }
00409                             }
00410                             return;
00411                      }
00412               }
00413        }
00414 }
00415 /* }}} */
00416 
00417 static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ */
00418 {
00425        zval *res;
00426        char *db, *bk, buf[200];
00427        int dblen, bklen, spb_len;
00428        long opts = 0;
00429        zend_bool verbose = 0;
00430        ibase_service *svm;
00431 
00432        RESET_ERRMSG;
00433 
00434        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss|lb",
00435                      &res, &db, &dblen, &bk, &bklen, &opts, &verbose)) {
00436               RETURN_FALSE;
00437        }
00438 
00439        ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
00440               "Interbase service manager handle", le_service);
00441 
00442        /* fill the param buffer */
00443        spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%s%c%c%c%c%c",
00444               operation, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db,
00445               isc_spb_bkp_file, (char)bklen, (char)(bklen >> 8), bk, isc_spb_options,
00446               (char)opts,(char)(opts >> 8), (char)(opts >> 16), (char)(opts >> 24));
00447 
00448        if (verbose) {
00449               buf[spb_len++] = isc_spb_verbose;
00450        }
00451 
00452        if (spb_len > sizeof(buf) || spb_len <= 0) {
00453               _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
00454               RETURN_FALSE;
00455        }
00456 
00457        /* now start the backup/restore job */
00458        if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) {
00459               IBASE_SVC_ERROR(svm);
00460               RETURN_FALSE;
00461        }
00462 
00463        if (!verbose) {
00464               RETURN_TRUE;
00465        } else {
00466               _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line);
00467        }
00468 }
00469 /* }}} */
00470 
00471 /* {{{ proto mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]])
00472    Initiates a backup task in the service manager and returns immediately */
00473 PHP_FUNCTION(ibase_backup)
00474 {
00475        _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_backup);
00476 }
00477 /* }}} */
00478 
00479 /* {{{ proto mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]])
00480    Initiates a restore task in the service manager and returns immediately */
00481 PHP_FUNCTION(ibase_restore)
00482 {
00483        _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_restore);
00484 }
00485 /* }}} */
00486 
00487 static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_action) /* {{{ */
00488 {
00489        zval *res;
00490        char buf[128], *db;
00491        int dblen, spb_len;
00492        long action, argument = 0;
00493        ibase_service *svm;
00494 
00495        RESET_ERRMSG;
00496 
00497        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsl|l",
00498                      &res, &db, &dblen, &action, &argument)) {
00499               RETURN_FALSE;
00500        }
00501 
00502        ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
00503               "Interbase service manager handle", le_service);
00504 
00505        if (svc_action == isc_action_svc_db_stats) {
00506               switch (action) {
00507                      default:
00508                             goto unknown_option;
00509 
00510                      case isc_spb_sts_data_pages:
00511                      case isc_spb_sts_db_log:
00512                      case isc_spb_sts_hdr_pages:
00513                      case isc_spb_sts_idx_pages:
00514                      case isc_spb_sts_sys_relations:
00515                             goto options_argument;
00516               }
00517        } else {
00518               /* these actions all expect different types of arguments */
00519               switch (action) {
00520                      default:
00521 unknown_option:
00522                             _php_ibase_module_error("Unrecognised option (%ld)" TSRMLS_CC, action);
00523                             RETURN_FALSE;
00524 
00525                      case isc_spb_rpr_check_db:
00526                      case isc_spb_rpr_ignore_checksum:
00527                      case isc_spb_rpr_kill_shadows:
00528                      case isc_spb_rpr_mend_db:
00529                      case isc_spb_rpr_validate_db:
00530                      case isc_spb_rpr_sweep_db:
00531                             svc_action = isc_action_svc_repair;
00532 
00533                      case isc_spb_prp_activate:
00534                      case isc_spb_prp_db_online:
00535 options_argument:
00536                             argument |= action;
00537                             action = isc_spb_options;
00538 
00539                      case isc_spb_prp_page_buffers:
00540                      case isc_spb_prp_sweep_interval:
00541                      case isc_spb_prp_shutdown_db:
00542                      case isc_spb_prp_deny_new_transactions:
00543                      case isc_spb_prp_deny_new_attachments:
00544                      case isc_spb_prp_set_sql_dialect:
00545                             spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%c%c",
00546                                    svc_action, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db,
00547                                    (char)action, (char)argument, (char)(argument >> 8), (char)(argument >> 16),
00548                                    (char)(argument >> 24));
00549                             break;
00550 
00551                      case isc_spb_prp_reserve_space:
00552                      case isc_spb_prp_write_mode:
00553                      case isc_spb_prp_access_mode:
00554                             spb_len = slprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c",
00555                                    isc_action_svc_properties, isc_spb_dbname, (char)dblen, (char)(dblen >> 8),
00556                                    db, (char)action, (char)argument);
00557               }
00558        }
00559 
00560        if (spb_len > sizeof(buf) || spb_len == -1) {
00561               _php_ibase_module_error("Internal error: insufficient buffer space for SPB (%d)" TSRMLS_CC, spb_len);
00562               RETURN_FALSE;
00563        }
00564 
00565        if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) {
00566               IBASE_SVC_ERROR(svm);
00567               RETURN_FALSE;
00568        }
00569 
00570        if (svc_action == isc_action_svc_db_stats) {
00571               _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, isc_info_svc_line);
00572        } else {
00573               RETURN_TRUE;
00574        }
00575 }
00576 /* }}} */
00577 
00578 /* {{{ proto bool ibase_maintain_db(resource service_handle, string db, int action [, int argument])
00579    Execute a maintenance command on the database server */
00580 PHP_FUNCTION(ibase_maintain_db)
00581 {
00582        _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_properties);
00583 }
00584 /* }}} */
00585 
00586 /* {{{ proto string ibase_db_info(resource service_handle, string db, int action [, int argument])
00587    Request statistics about a database */
00588 PHP_FUNCTION(ibase_db_info)
00589 {
00590        _php_ibase_service_action(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_db_stats);
00591 }
00592 /* }}} */
00593 
00594 /* {{{ proto string ibase_server_info(resource service_handle, int action)
00595    Request information about a database server */
00596 PHP_FUNCTION(ibase_server_info)
00597 {
00598        zval *res;
00599        long action;
00600        ibase_service *svm;
00601 
00602        RESET_ERRMSG;
00603 
00604        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &action)) {
00605               RETURN_FALSE;
00606        }
00607 
00608        ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1,
00609               "Interbase service manager handle", le_service);
00610 
00611        _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action);
00612 }
00613 /* }}} */
00614 
00615 #else
00616 
00617 void php_ibase_register_service_constants(INIT_FUNC_ARGS) { /* nop */ }
00618 
00619 #endif /* HAVE_IBASE */
00620 
00621 /*
00622  * Local variables:
00623  * tab-width: 4
00624  * c-basic-offset: 4
00625  * End:
00626  * vim600: sw=4 ts=4 fdm=marker
00627  * vim<600: sw=4 ts=4
00628  */