Annotation of embedaddon/php/ext/interbase/ibase_service.c, revision 1.1.1.3

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

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