ibase_service.c 21 KB

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