void createRestoreBuffer(VALUE file, VALUE database, VALUE options, char **buffer, short *length) { char *offset = NULL; int number = 0; long mask = 0; VALUE cache = rb_hash_aref(options, CACHE_BUFFERS), page = rb_hash_aref(options, PAGE_SIZE), mode = rb_hash_aref(options, ACCESS_MODE), policy = rb_hash_aref(options, RESTORE_MODE); /* Determine the length of the buffer. */ *length = 7; *length += strlen(STR2CSTR(file)) + 3; *length += strlen(STR2CSTR(database)) + 3; if(cache != Qnil) { *length += 5; } if(page != Qnil) { *length += 5; } if(mode != Qnil) { *length += 2; } /* Create and populate the buffer. */ offset = *buffer = ALLOC_N(char, *length); if(buffer == NULL) { rb_raise(rb_eNoMemError, "Memory allocation error preparing database restore."); } memset(*buffer, 8, *length); *offset++ = isc_action_svc_restore; number = strlen(STR2CSTR(file)); *offset++ = isc_spb_bkp_file; ADD_SPB_LENGTH(offset, number); memcpy(offset, STR2CSTR(file), number); offset += number; number = strlen(STR2CSTR(database)); *offset++ = isc_spb_dbname; ADD_SPB_LENGTH(offset, number); memcpy(offset, STR2CSTR(database), number); offset += number; if(cache != Qnil) { long value; value = TYPE(cache) == T_FIXNUM ? FIX2INT(cache) : NUM2INT(cache); *offset++ = isc_spb_res_buffers; ADD_SPB_NUMERIC(offset, value); } if(page != Qnil) { long value; value = TYPE(page) == T_FIXNUM ? FIX2INT(page) : NUM2INT(page); *offset++ = isc_spb_res_page_size; ADD_SPB_NUMERIC(offset, value); } if(mode != Qnil) { *offset++ = isc_spb_res_access_mode; *offset++ = (char)FIX2INT(mode); } mask = FIX2INT(policy); if(rb_hash_aref(options, BUILD_INDICES) == Qfalse) { mask |= isc_spb_res_deactivate_idx; } if(rb_hash_aref(options, NO_SHADOWS) == Qtrue) { mask |= isc_spb_res_no_shadow; } if(rb_hash_aref(options, VALIDITY_CHECKS) == Qfalse) { mask |= isc_spb_res_no_validity; } if(rb_hash_aref(options, COMMIT_TABLES) == Qtrue) { mask |= isc_spb_res_one_at_a_time; } if(rb_hash_aref(options, USE_ALL_SPACE) == Qtrue) { mask |= isc_spb_res_use_all_space; } *offset++ = isc_spb_options; ADD_SPB_NUMERIC(offset, mask); *offset++ = isc_spb_verbose; }
void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb) { os_utils::CtrlCHandler ctrlCHandler; ISC_STATUS_ARRAY status; if (isc_service_start(status, &m_svcHandle, 0, static_cast<USHORT>(spbSize), reinterpret_cast<const char*>(spb))) { status_exception::raise(status); } const char query[] = {isc_info_svc_to_eof, isc_info_end}; // use one second timeout to poll service char send[16]; char* p = send; *p++ = isc_info_svc_timeout; ADD_SPB_LENGTH(p, 4); ADD_SPB_NUMERIC(p, 1); *p++ = isc_info_end; const USHORT sendSize = (p - send); char results[MAXBUF]; bool noData; do { if (isc_service_query(status, &m_svcHandle, 0, sendSize, send, sizeof(query), query, sizeof(results) - 1, results)) { status_exception::raise(status); } p = results; bool ignoreTruncation = false; bool dirty = false; noData = true; while (*p != isc_info_end) { const UCHAR item = *p++; switch (item) { case isc_info_svc_to_eof: ignoreTruncation = true; case isc_info_svc_line: { const unsigned short l = isc_vax_integer(p, sizeof(l)); p += sizeof(l); if (l) { const char ch = p[l]; p[l] = 0; fprintf(stdout, "%s", p); p[l] = ch; p += l; dirty = true; } noData = (l == 0); } break; case isc_info_truncated: if (!ignoreTruncation) return; break; case isc_info_svc_timeout: case isc_info_data_not_ready: noData = false; if (dirty) { fflush(stdout); dirty = false; } break; default: status_exception::raise(Arg::Gds(isc_fbsvcmgr_query_err) << Arg::Num(static_cast<unsigned char>(p[-1]))); } } } while (!(ctrlCHandler.getTerminated() || noData)); }