diff --git a/src/alice/alice.cpp b/src/alice/alice.cpp index 3f4578df31..b4d1a0f704 100644 --- a/src/alice/alice.cpp +++ b/src/alice/alice.cpp @@ -24,7 +24,7 @@ // //____________________________________________________________ // -// $Id: alice.cpp,v 1.5 2001-12-24 02:50:47 tamlin Exp $ +// $Id: alice.cpp,v 1.6 2001-12-25 04:53:56 tamlin Exp $ // // 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE" // conditionals, as the engine now fully supports @@ -72,15 +72,15 @@ #endif -static USHORT val_err_table[] = { +static const USHORT val_err_table[] = { 0, - 55, /* msg 55: \n\tNumber of record level errors\t: %ld */ - 56, /* msg 56: \tNumber of Blob page errors\t: %ld */ - 57, /* msg 57: \tNumber of data page errors\t: %ld */ - 58, /* msg 58: \tNumber of index page errors\t: %ld */ - 59, /* msg 59: \tNumber of pointer page errors\t: %ld */ - 60, /* msg 60: \tNumber of transaction page errors\t: %ld */ - 61 /* msg 61: \tNumber of database page errors\t: %ld */ + 55, // msg 55: \n\tNumber of record level errors\t: %ld + 56, // msg 56: \tNumber of Blob page errors\t: %ld + 57, // msg 57: \tNumber of data page errors\t: %ld + 58, // msg 58: \tNumber of index page errors\t: %ld + 59, // msg 59: \tNumber of pointer page errors\t: %ld + 60, // msg 60: \tNumber of transaction page errors\t: %ld + 61 // msg 61: \tNumber of database page errors\t: %ld }; #ifndef NETWARE_386 @@ -89,6 +89,9 @@ struct tgbl *gdgbl; #define ALICE_MSG_FAC 3 +#define EXIT(code) { tdgbl->exit_code = (code); \ + Firebird::status_longjmp_error::raise(1); } + #if defined (WIN95) && !defined (GUI_TOOLS) static BOOL fAnsiCP = FALSE; #define TRANSLATE_CP(a) if (!fAnsiCP) AnsiToOem(a, a) @@ -96,11 +99,11 @@ static BOOL fAnsiCP = FALSE; #define TRANSLATE_CP(a) #endif -static void expand_filename(TEXT *, TEXT *); -static int output_thread(SLONG, UCHAR *); -static int output_main(SLONG, UCHAR *); -static int output_svc(SLONG, UCHAR *); -static void alice_output(CONST SCHAR *, ...); +static void expand_filename(TEXT*, TEXT*); +static int output_thread(SLONG, UCHAR*); +static int output_main(SLONG, UCHAR*); +static int output_svc(SLONG, UCHAR*); +static void alice_output(CONST SCHAR*, ...); @@ -108,19 +111,21 @@ static void alice_output(CONST SCHAR *, ...); //____________________________________________________________ // -// Entry point for GFIX in case of service manager. +// Entry point for GFIX in case of service manager. // int main_gfix(SVC service) { - int exit_code; - - exit_code = ALICE_gfix(service->svc_argc, service->svc_argv, - output_thread, (SLONG) service); + int exit_code = + ALICE_gfix( service->svc_argc, + service->svc_argv, + output_thread, + (SLONG) service); service->svc_handle = 0; - if (service->svc_service->in_use != NULL) + if (service->svc_service->in_use != NULL) { *(service->svc_service->in_use) = FALSE; + } // Mark service thread as finished. // If service is detached, cleanup memory being used by service. @@ -132,7 +137,7 @@ int main_gfix(SVC service) //____________________________________________________________ // -// Routine which is passed to GFIX for calling back when there is output. +// Routine which is passed to GFIX for calling back when there is output. // static int output_thread(SLONG output_data, UCHAR * output_buf) @@ -143,7 +148,8 @@ static int output_thread(SLONG output_data, UCHAR * output_buf) } -#else +#else // SUPERSERVER + #ifndef GUI_TOOLS //____________________________________________________________ @@ -153,9 +159,7 @@ static int output_thread(SLONG output_data, UCHAR * output_buf) int CLIB_ROUTINE main(int argc, char *argv[]) { - int exit_code; - - exit_code = ALICE_gfix(argc, argv, output_main, (SLONG) NULL); + int exit_code = ALICE_gfix(argc, argv, output_main, (SLONG) NULL); return exit_code; } @@ -171,8 +175,9 @@ static int output_main(SLONG output_data, UCHAR * output_buf) ib_fprintf(ib_stderr, "%s", output_buf); return 0; } -#endif -#endif +#endif // !GUI_TOOLS + +#endif // SUPERSERVER //____________________________________________________________ // @@ -193,26 +198,32 @@ static int output_svc(SLONG output_data, UCHAR * output_buf) // Parse switches and do work // -int DLL_EXPORT ALICE_gfix( - int argc, - char *argv[], - OUTPUTPROC output_proc, SLONG output_data) +int DLL_EXPORT ALICE_gfix( int argc, + char* argv[], + OUTPUTPROC output_proc, + SLONG output_data) { - USHORT error, i; IN_SW_TAB table = alice_in_sw_table; - TEXT *database, string[512], *p, *q; - ULONG switches; - SLONG redir_in, redir_out, redir_err; - JMP_BUF env; - USHORT ret; + + USHORT error; + USHORT i; + TEXT* database; + TEXT string[512]; + ULONG switches; + SLONG redir_in; + SLONG redir_out; + SLONG redir_err; + #if defined (WIN95) && !defined (GUI_TOOLS) BOOL fAnsiCP fAnsiCP = (GetConsoleCP() == GetACP()); #endif - VOLATILE tgbl *tdgbl = (struct tgbl *) gds__alloc(sizeof(*tdgbl)); -// NOMEM: return error, FREE: during function exit in the SETJMP - if (tdgbl == NULL) + VOLATILE tgbl* tdgbl = (struct tgbl*) gds__alloc(sizeof(*tdgbl)); + if (!tdgbl) { + // NOMEM: return error, FREE: during function exit in the SETJMP return FINI_ERROR; + } + // TMN #if 0 SET_THREAD_DATA; @@ -221,9 +232,6 @@ int DLL_EXPORT ALICE_gfix( #endif SVC_PUTSPECIFIC_DATA; memset((void *) tdgbl, 0, sizeof(*tdgbl)); -// TMN: I can't for my life understand why the jmp_buf is defined -// as a UCHAR* in ' struct tgbl', but it forces this cast. - tdgbl->alice_env = (UCHAR * volatile) env; tdgbl->output_proc = output_proc; tdgbl->output_data = output_data; tdgbl->ALICE_permanent_pool = NULL; @@ -321,26 +329,35 @@ int DLL_EXPORT ALICE_gfix( continue; } ALICE_down_case(*argv++, string); - if (!string[1]) + if (!string[1]) { continue; - for (table = alice_in_sw_table; TRUE; table++) { - if (!(p = (TEXT *) table->in_sw_name)) { + } + for (table = alice_in_sw_table; TRUE; ++table) + { + const TEXT* p = (TEXT*) table->in_sw_name; + if (!p) { ALICE_print(2, *--argv, 0, 0, 0, 0); /* msg 2: invalid switch %s */ error = TRUE; break; } - q = &string[1]; - while (*q && *p++ == *q) + + TEXT* q = &string[1]; + while (*q && *p++ == *q) { q++; - if (!*q) + } + if (!*q) { break; + } } - if (error) + if (error) { break; - if (*table->in_sw_name == 'x') + } + if (*table->in_sw_name == 'x') { tdgbl->ALICE_data.ua_debug++; - if (table->in_sw_value == sw_z) + } + if (table->in_sw_value == sw_z) { ALICE_print(3, GDS_VERSION, 0, 0, 0, 0); /* msg 3: gfix version %s */ + } if ((table->in_sw_incompatibilities & switches) || (table->in_sw_requires && !(table->in_sw_requires & switches))) { ALICE_print(4, 0, 0, 0, 0, 0); /* msg 4: incompatible switch combination */ @@ -350,130 +367,163 @@ int DLL_EXPORT ALICE_gfix( switches |= table->in_sw_value; if (table->in_sw_value & sw_begin_log) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(5, 0, 0, 0, 0, 0); /* msg 5: replay log pathname required */ + } expand_filename(*argv++, /* TMN: cast away volatile */ (TEXT *) tdgbl->ALICE_data.ua_log_file); } if (table->in_sw_value & (sw_buffers)) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(6, 0, 0, 0, 0, 0); /* msg 6: number of page buffers for cache required */ + } ALICE_down_case(*argv++, string); if ((!(tdgbl->ALICE_data.ua_page_buffers = atoi(string))) && (strcmp(string, "0"))) + { ALICE_error(7, 0, 0, 0, 0, 0); /* msg 7: numeric value required */ - if (tdgbl->ALICE_data.ua_page_buffers < 0) + } + if (tdgbl->ALICE_data.ua_page_buffers < 0) { ALICE_error(8, 0, 0, 0, 0, 0); /* msg 8: positive numeric value required */ + } } if (table->in_sw_value & (sw_housekeeping)) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(9, 0, 0, 0, 0, 0); /* msg 9: number of transactions per sweep required */ + } ALICE_down_case(*argv++, string); if ((!(tdgbl->ALICE_data.ua_sweep_interval = atoi(string))) && (strcmp(string, "0"))) + { ALICE_error(7, 0, 0, 0, 0, 0); /* msg 7: numeric value required */ - if (tdgbl->ALICE_data.ua_sweep_interval < 0) + } + if (tdgbl->ALICE_data.ua_sweep_interval < 0) { ALICE_error(8, 0, 0, 0, 0, 0); /* msg 8: positive numeric value required */ + } } if (table->in_sw_value & (sw_set_db_dialect)) { - if (--argc <= 0) + if (--argc <= 0) { + // TMN: Error in use of error-code. Either the following + // comment is right, or the one 16 lines above, but + // not both. ALICE_error(9, 0, 0, 0, 0, 0); /* msg 9: dialect info is required XXX */ + } ALICE_down_case(*argv++, string); if ((!(tdgbl->ALICE_data.ua_db_SQL_dialect = atoi(string))) && (strcmp(string, "0"))) + { ALICE_error(7, 0, 0, 0, 0, 0); /* msg 7: numeric value required */ + } if (tdgbl->ALICE_data.ua_db_SQL_dialect < 0) + { ALICE_error(8, 0, 0, 0, 0, 0); /* msg 8: positive numeric value required */ + } } if (table->in_sw_value & (sw_commit | sw_rollback | sw_two_phase)) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(10, 0, 0, 0, 0, 0); /* msg 10: transaction number or "all" required */ + } ALICE_down_case(*argv++, string); - if (!(tdgbl->ALICE_data.ua_transaction = atoi(string))) - if (strcmp(string, "all")) + if (!(tdgbl->ALICE_data.ua_transaction = atoi(string))) { + if (strcmp(string, "all")) { ALICE_error(10, 0, 0, 0, 0, 0); /* msg 10: transaction number or "all" required */ - else + } else { switches |= sw_list; + } + } } if (table->in_sw_value & sw_write) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(11, 0, 0, 0, 0, 0); /* msg 11: "sync" or "async" required */ + } ALICE_down_case(*argv++, string); - if (!strcmp(string, ALICE_SW_SYNC)) + if (!strcmp(string, ALICE_SW_SYNC)) { tdgbl->ALICE_data.ua_force = TRUE; - else if (!strcmp(string, ALICE_SW_ASYNC)) + } else if (!strcmp(string, ALICE_SW_ASYNC)) { tdgbl->ALICE_data.ua_force = FALSE; - else + } else { ALICE_error(11, 0, 0, 0, 0, 0); /* msg 11: "sync" or "async" required */ + } } if (table->in_sw_value & sw_use) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(12, 0, 0, 0, 0, 0); /* msg 12: "full" or "reserve" required */ + } ALICE_down_case(*argv++, string); - if (!strcmp(string, "full")) + if (!strcmp(string, "full")) { tdgbl->ALICE_data.ua_use = TRUE; - else if (!strcmp(string, "reserve")) + } else if (!strcmp(string, "reserve")) { tdgbl->ALICE_data.ua_use = FALSE; - else + } else { ALICE_error(12, 0, 0, 0, 0, 0); /* msg 12: "full" or "reserve" required */ + } } if (table->in_sw_value & sw_user) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(13, 0, 0, 0, 0, 0); /* msg 13: user name required */ + } tdgbl->ALICE_data.ua_user = - const_cast < UCHAR * volatile >(reinterpret_cast < - UCHAR * >(*argv++)); + const_cast(reinterpret_cast(*argv++)); } if (table->in_sw_value & sw_password) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(14, 0, 0, 0, 0, 0); /* msg 14: password required */ + } tdgbl->ALICE_data.ua_password = - const_cast < UCHAR * volatile >(reinterpret_cast < - UCHAR * >(*argv++)); + const_cast(reinterpret_cast(*argv++)); } if (table->in_sw_value & sw_disable) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(15, 0, 0, 0, 0, 0); /* msg 15: subsystem name */ + } ALICE_down_case(*argv++, string); - if (strcmp(string, "wal")) + if (strcmp(string, "wal")) { ALICE_error(16, 0, 0, 0, 0, 0); /* msg 16: "wal" required */ + } } if (table->in_sw_value & (sw_attach | sw_force | sw_tran | sw_cache)) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(17, 0, 0, 0, 0, 0); /* msg 17: number of seconds required */ + } ALICE_down_case(*argv++, string); if ((!(tdgbl->ALICE_data.ua_shutdown_delay = atoi(string))) && (strcmp(string, "0"))) + { ALICE_error(7, 0, 0, 0, 0, 0); /* msg 7: numeric value required */ + } if (tdgbl->ALICE_data.ua_shutdown_delay < 0 || tdgbl->ALICE_data.ua_shutdown_delay > 32767) + { ALICE_error(18, 0, 0, 0, 0, 0); /* msg 18: numeric value between 0 and 32767 inclusive required */ + } } if (table->in_sw_value & sw_mode) { - if (--argc <= 0) + if (--argc <= 0) { ALICE_error(110, 0, 0, 0, 0, 0); /* msg 110: "read_only" or "read_write" required */ + } ALICE_down_case(*argv++, string); - if (!strcmp(string, ALICE_SW_MODE_RO)) + if (!strcmp(string, ALICE_SW_MODE_RO)) { tdgbl->ALICE_data.ua_read_only = TRUE; - else if (!strcmp(string, ALICE_SW_MODE_RW)) + } else if (!strcmp(string, ALICE_SW_MODE_RW)) { tdgbl->ALICE_data.ua_read_only = FALSE; - else + } else { ALICE_error(110, 0, 0, 0, 0, 0); /* msg 110: "read_only" or "read_write" required */ + } } } @@ -482,12 +532,15 @@ int DLL_EXPORT ALICE_gfix( // can't use tbl_requires since it only looks backwards on command line if ((switches & sw_shut) && !(switches & ((sw_attach | sw_force | sw_tran | sw_cache)))) + { ALICE_error(19, 0, 0, 0, 0, 0); /* msg 19: must specify type of shutdown */ + } // catch the case where -z is only command line option // switches is unset since sw_z == 0 - if (!switches && !error && table->in_sw_value == sw_z) + if (!switches && !error && table->in_sw_value == sw_z) { EXIT(FINI_OK); + } if (!switches || !(switches & ~(sw_user | sw_password))) { #ifndef SUPERSERVER @@ -511,51 +564,63 @@ int DLL_EXPORT ALICE_gfix( EXIT(FINI_ERROR); } - if (!database) + if (!database) { ALICE_error(23, 0, 0, 0, 0, 0); /* msg 23: please retry, giving a database name */ + } -// generate the database parameter block for the attach, -// based on the various switches + // generate the database parameter block for the attach, + // based on the various switches + + USHORT ret; if (switches & (sw_list | sw_commit | sw_rollback | sw_two_phase)) + { ret = EXE_two_phase(database, switches); - else { + } + else + { ret = EXE_action(database, switches); USHORT count = 0; - for (i = 0; i < MAX_VAL_ERRORS; i++) - if (tdgbl->ALICE_data.ua_val_errors[i]) + for (i = 0; i < MAX_VAL_ERRORS; i++) { + if (tdgbl->ALICE_data.ua_val_errors[i]) { count++; + } + } if ((count) - && !(tdgbl->ALICE_data.ua_val_errors[VAL_INVALID_DB_VERSION])) { + && !(tdgbl->ALICE_data.ua_val_errors[VAL_INVALID_DB_VERSION])) + { ALICE_print(24, 0, 0, 0, 0, 0); /* msg 24: Summary of validation errors\n */ for (i = 0; i < MAX_VAL_ERRORS; i++) + { if (tdgbl->ALICE_data.ua_val_errors[i]) + { ALICE_print(val_err_table[i], reinterpret_cast < char *>(tdgbl->ALICE_data.ua_val_errors[i]), 0, 0, 0, 0); + } + } } } - if (ret == FINI_ERROR) + if (ret == FINI_ERROR) { ALICE_print_status(tdgbl->status); + } EXIT(FINI_OK); } // try catch (...) { - int exit_code; - - /* All calls to EXIT(), normal and error exits, wind up here */ + /* All "calls" to EXIT(), normal and error exits, wind up here */ SVC_STARTED(tdgbl->service_blk); - tdgbl->alice_env = NULL; - exit_code = tdgbl->exit_code; + + int exit_code = tdgbl->exit_code; /* Close the status output file */ if (tdgbl->sw_redirect == TRUE && tdgbl->output_file != NULL) { @@ -567,9 +632,10 @@ int DLL_EXPORT ALICE_gfix( ALLA_fini(); RESTORE_THREAD_DATA; - if (tdgbl != NULL) { - gds__free((SLONG *) tdgbl); - } + + // cast away volatile + gds__free((void*)tdgbl); + #if defined(DEBUG_GDS_ALLOC) && !defined(SUPERSERVER) gds_alloc_report(0, __FILE__, __LINE__); #endif @@ -591,9 +657,9 @@ void ALICE_down_case(TEXT * in, TEXT * out) { TEXT c; - while (c = *in++) + while (c = *in++) { *out++ = (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; - + } *out = 0; } @@ -603,9 +669,12 @@ void ALICE_down_case(TEXT * in, TEXT * out) // Display a formatted error message // -void ALICE_print(USHORT number, - TEXT * arg1, - TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5) +void ALICE_print(USHORT number, + TEXT* arg1, + TEXT* arg2, + TEXT* arg3, + TEXT* arg4, + TEXT* arg5) { TEXT buffer[256]; @@ -622,26 +691,25 @@ void ALICE_print(USHORT number, // to allow redirecting output. // -void ALICE_print_status(STATUS * status_vector) +void ALICE_print_status(STATUS* status_vector) { -#ifdef SUPERSERVER - TGBL tdgbl; - STATUS *status; - int i = 0, j; -#endif - STATUS *vector; - SCHAR s[1024]; + STATUS* vector; + SCHAR s[1024]; - if (status_vector) { + if (status_vector) + { vector = status_vector; #ifdef SUPERSERVER - tdgbl = GET_THREAD_DATA; - status = tdgbl->service_blk->svc_status; + int i = 0, j; + TGBL tdgbl = GET_THREAD_DATA; + STATUS* status = tdgbl->service_blk->svc_status; if (status != status_vector) { - while (*status && (++i < ISC_STATUS_LENGTH)) + while (*status && (++i < ISC_STATUS_LENGTH)) { status++; - for (j = 0; status_vector[j] && (i < ISC_STATUS_LENGTH); j++, i++) + } + for (j = 0; status_vector[j] && (i < ISC_STATUS_LENGTH); j++, i++) { *status++ = status_vector[j]; + } } #endif isc_interprete(s, &vector); @@ -663,26 +731,25 @@ void ALICE_print_status(STATUS * status_vector) // Format and print an error message, then punt. // -void ALICE_error(USHORT number, - TEXT * arg1, - TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5) +void ALICE_error(USHORT number, + TEXT* arg1, + TEXT* arg2, + TEXT* arg3, + TEXT* arg4, + TEXT* arg5) { - TGBL tdgbl; + TGBL tdgbl = GET_THREAD_DATA; TEXT buffer[256]; -#ifdef SUPERSERVER - STATUS *status; -#endif - - tdgbl = GET_THREAD_DATA; #ifdef SUPERSERVER - status = tdgbl->service_blk->svc_status; + STATUS* status = tdgbl->service_blk->svc_status; CMD_UTIL_put_svc_status(status, ALICE_MSG_FAC, number, isc_arg_string, arg1, isc_arg_string, arg2, isc_arg_string, arg3, - isc_arg_string, arg4, isc_arg_string, arg5); + isc_arg_string, arg4, + isc_arg_string, arg5); #endif gds__msg_format(0, ALICE_MSG_FAC, number, sizeof(buffer), buffer, arg1, @@ -703,9 +770,8 @@ static void alice_output(CONST SCHAR * format, ...) va_list arglist; UCHAR buf[1000]; int exit_code; - TGBL tdgbl; - tdgbl = GET_THREAD_DATA; + TGBL tdgbl = GET_THREAD_DATA; if (tdgbl->sw_redirect == NOOUTPUT || format[0] == '\0') { exit_code = @@ -728,8 +794,9 @@ static void alice_output(CONST SCHAR * format, ...) exit_code = tdgbl->output_proc(tdgbl->output_data, buf); } - if (exit_code != 0) + if (exit_code != 0) { EXIT(exit_code); + } } diff --git a/src/alice/alice.h b/src/alice/alice.h index 0f553edb29..6d7ad307f8 100644 --- a/src/alice/alice.h +++ b/src/alice/alice.h @@ -92,7 +92,7 @@ typedef str *STR; /* Transaction block: used to store info about a multidatabase transaction. */ -typedef struct tdr +typedef struct tdr : public pool_alloc { struct tdr *tdr_next; /* next subtransaction */ SLONG tdr_id; /* database-specific transaction id */ @@ -163,7 +163,6 @@ public: STATUS status_vector[ISC_STATUS_LENGTH]; typedef std::vector > pool_vec_t; pool_vec_t pools; - UCHAR* alice_env; int exit_code; OUTPUTPROC output_proc; SLONG output_data; @@ -213,14 +212,6 @@ extern struct tgbl *gdgbl; #define RESTORE_THREAD_DATA #endif -#if defined(__cplusplus) -#define EXIT(code) { tdgbl->exit_code = (code); \ - if (tdgbl->alice_env != NULL) \ - Firebird::status_longjmp_error::raise(1); } -#else -#error Dont do this, it hurts! -#endif // __cplusplus - #define NOOUTPUT 2 #endif // ALICE_ALICE_H diff --git a/src/alice/alice_meta.h b/src/alice/alice_meta.h index afa461e8f2..7b9c37883f 100644 --- a/src/alice/alice_meta.h +++ b/src/alice/alice_meta.h @@ -24,16 +24,9 @@ #ifndef ALICE_ALICE_META_H #define ALICE_ALICE_META_H -#ifdef __cplusplus -extern "C" { -#endif - void MET_disable_wal(STATUS*, isc_db_handle); void MET_get_state(STATUS*, TDR); TDR MET_get_transaction(STATUS*, isc_db_handle, SLONG); void MET_set_capabilities(STATUS*, TDR); -#ifdef __cplusplus -} -#endif -#endif /* ALICE_ALICE_META_H */ +#endif // ALICE_ALICE_META_H