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

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:    | Copyright (c) 1997-2014 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: 
                     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;
1.1.1.2   misho     322:                                *(result+line_len) = 0;
1.1.1.3   misho     323:                                snprintf(heap_p, heap_buf_size - (heap_p - heap_buf), "%s\n", result);
                    324:                                heap_p += line_len +1;
1.1       misho     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:  */

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