int CLIB_ROUTINE main(int argc, char* argv[]) { /************************************** * * m a i n * ************************************** * * Functional description * Invoke real gsec main function * **************************************/ #ifdef HAVE_LOCALE_H // Pick up the system locale to allow SYSTEM<->UTF8 conversions setlocale(LC_CTYPE, ""); #endif int exitCode = 1; try { Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv)); exitCode = gsec(uSvc); } catch (const Firebird::Exception& ex) { Firebird::StaticStatusVector st; ex.stuffException(st); isc_print_status(st.begin()); } fb_shutdown(0, fb_shutrsn_app_stopped); return exitCode; }
//____________________________________________________________ // // An error returned has been trapped. If the user specified // a status vector, return a status code. Otherwise print the // error code(s) and abort. // static ISC_STATUS error(const Firebird::Exception& ex) { Firebird::StaticStatusVector v; ex.stuffException(v); makePermanentVector(v.begin()); if (UDSQL_error->dsql_user_status) { fb_utils::copyStatus(UDSQL_error->dsql_user_status, ISC_STATUS_LENGTH, v.begin(), v.getCount()); return UDSQL_error->dsql_user_status[1]; } fb_utils::copyStatus(UDSQL_error->dsql_status, ISC_STATUS_LENGTH, v.begin(), v.getCount()); gds__print_status(UDSQL_error->dsql_status); exit(UDSQL_error->dsql_status[1]); return 0; // suppress compiler warning }
void iscLogException(const char* text, const Firebird::Exception& e) { /************************************** * * i s c L o g E x c e p t i o n * ************************************** * * Functional description * Add record about an exception to firebird.log * **************************************/ Firebird::StaticStatusVector s; e.stuffException(s); iscLogStatus(text, s.begin()); }
int CLIB_ROUTINE main(int argc, char* argv[]) { /************************************** * * m a i n * ************************************** * * Functional description * Invoke real trace main function * **************************************/ #ifdef HAVE_LOCALE_H // Pick up the system locale to allow SYSTEM<->UTF8 conversions setlocale(LC_CTYPE, ""); #endif #ifdef WIN_NT int binout = fileno(stdout); _setmode(binout, _O_BINARY); #endif atexit(&atexit_fb_shutdown); AutoPtr<UtilSvc> uSvc(UtilSvc::createStandalone(argc, argv)); try { TraceSvcUtil traceUtil; fbtrace(uSvc, &traceUtil); } catch (const Firebird::Exception& ex) { Firebird::StaticStatusVector temp; ex.stuffException(temp); isc_print_status(temp.begin()); return FINI_ERROR; } return FINI_OK; }
int main(int ac, char** av) { #ifdef HAVE_LOCALE_H // Pick up the system locale to allow SYSTEM<->UTF8 conversions setlocale(LC_CTYPE, ""); #endif if (ac < 2 || (ac == 2 && strcmp(av[1], "-?") == 0)) { usage(ac == 2); return 1; } if (ac == 2 && (strcmp(av[1], "-z") == 0 || strcmp(av[1], "-Z") == 0)) { printMessage(51, SafeArg() << FB_VERSION); return 0; } os_utils::CtrlCHandler ctrlCHandler; atexit(&atexit_fb_shutdown); ISC_STATUS_ARRAY status; try { const int maxbuf = 16384; av++; const char* name = *av; if (name) { av++; } ClumpletWriter spbAtt(ClumpletWriter::spbList, maxbuf); while (populateSpbFromSwitches(av, spbAtt, attSwitch, 0)) ; ClumpletWriter spbStart(ClumpletWriter::SpbStart, maxbuf); ClumpletWriter spbItems(ClumpletWriter::SpbReceiveItems, 256); // single action per one utility run, it may populate info items also populateSpbFromSwitches(av, spbStart, actionSwitch, &spbItems); if (spbStart.getBufferLength() == 0) { while (populateSpbFromSwitches(av, spbItems, infSwitch, 0)) ; } // Here we are over with av parse, look - may be unknown switch left if (*av) { if (strcmp(av[0], "-z") == 0 || strcmp(av[0], "-Z") == 0) { printMessage(51, SafeArg() << FB_VERSION); ++av; } } if (*av) { status_exception::raise(Arg::Gds(isc_fbsvcmgr_switch_unknown) << Arg::Str(*av)); } isc_svc_handle svc_handle = 0; if (isc_service_attach(status, 0, name, &svc_handle, static_cast<USHORT>(spbAtt.getBufferLength()), reinterpret_cast<const char*>(spbAtt.getBuffer()))) { isc_print_status(status); return 1; } if (spbStart.getBufferLength() > 0) { if (isc_service_start(status, &svc_handle, 0, static_cast<USHORT>(spbStart.getBufferLength()), reinterpret_cast<const char*>(spbStart.getBuffer()))) { isc_print_status(status); isc_service_detach(status, &svc_handle); return 1; } } if (spbItems.getBufferLength() > 0) { if (fb_utils::isRunningCheck(spbItems.getBuffer(), spbItems.getBufferLength())) { // running service may request stdin data spbItems.insertTag(isc_info_svc_stdin); } // 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; char results[maxbuf]; UserPrint uPrint; ULONG stdinRequest = 0; Array<char> stdinBuffer; do { char* sendBlock = send; USHORT sendSize = p - send; if (stdinRequest) { --sendSize; FB_SIZE_T len = sendSize; len += (1 + 2 + stdinRequest); if (len > MAX_USHORT - 1) { len = MAX_USHORT - 1; stdinRequest = len - (1 + 2) - sendSize; } sendBlock = stdinBuffer.getBuffer(len + 1); memcpy(sendBlock, send, sendSize); static int binIn = -1; if (binIn == -1) { #ifdef WIN_NT binIn = fileno(stdin); _setmode(binIn, _O_BINARY); #else binIn = 0; #endif } int n = read(binIn, &sendBlock[sendSize + 1 + 2], stdinRequest); if (n < 0) { perror("stdin"); break; } stdinRequest = n; sendBlock[sendSize] = isc_info_svc_line; sendBlock[sendSize + 1] = stdinRequest; sendBlock[sendSize + 2] = stdinRequest >> 8; sendBlock[sendSize + 1 + 2 + stdinRequest] = isc_info_end; sendSize += (1 + 2 + stdinRequest + 1); stdinRequest = 0; } if (isc_service_query(status, &svc_handle, 0, sendSize, sendBlock, static_cast<USHORT>(spbItems.getBufferLength()), reinterpret_cast<const char*>(spbItems.getBuffer()), sizeof(results), results)) { if (!ctrlCHandler.getTerminated()) isc_print_status(status); isc_service_detach(status, &svc_handle); return 1; } } while (printInfo(results, sizeof(results), uPrint, stdinRequest) && !ctrlCHandler.getTerminated()); } if (isc_service_detach(status, &svc_handle)) { if (!ctrlCHandler.getTerminated()) isc_print_status(status); return 1; } return 0; } catch (const Exception& e) { Firebird::StaticStatusVector st; e.stuffException(st); isc_print_status(st.begin()); } return 2; }
int CLIB_ROUTINE main( int argc, char** argv) { /************************************** * * m a i n * ************************************** * * Functional description * Run the server with apollo mailboxes. * **************************************/ try { RemPortPtr port; // We should support 3 modes: // 1. Standalone single-process listener (like SS). // 2. Standalone listener, forking on each packet accepted (look -s switch in CS). // 3. Process spawned by (x)inetd (like CS). bool classic = false; bool standaloneClassic = false; bool super = false; // It's very easy to detect that we are spawned - just check fd 0 to be a socket. const int channel = 0; struct stat stat0; if (fstat(channel, &stat0) == 0 && S_ISSOCK(stat0.st_mode)) { // classic server mode classic = true; } const TEXT* const* const end = argc + argv; argv++; bool debug = false; USHORT INET_SERVER_flag = 0; protocol[0] = 0; bool done = false; while (argv < end) { TEXT c; const TEXT* p = *argv++; if (*p++ == '-') { while (c = *p++) { switch (UPPER(c)) { case 'D': debug = true; break; case 'E': if (argv < end) { if (ISC_set_prefix(p, *argv) == -1) printf("Invalid argument Ignored\n"); else argv++; // do not skip next argument if this one is invalid } else { printf("Missing argument, switch -E ignored\n"); } done = true; break; case 'P': if (argv < end) { if (!classic) { fb_utils::snprintf(protocol, sizeof(protocol), "/%s", *argv++); } else { gds__log("Switch -P ignored in CS mode\n"); } } else { printf("Missing argument, switch -P ignored\n"); } break; case 'H': case '?': printf("Firebird TCP/IP server options are:\n"); printf(" -d : debug on\n"); printf(" -p <port> : specify port to listen on\n"); printf(" -z : print version and exit\n"); printf(" -h|? : print this help\n"); printf("\n"); printf(" (The following -e options used to be -h options)\n"); printf(" -e <firebird_root_dir> : set firebird_root path\n"); printf(" -el <firebird_lock_dir> : set runtime firebird_lock dir\n"); printf(" -em <firebird_msg_dir> : set firebird_msg dir path\n"); exit(FINI_OK); case 'Z': printf("Firebird TCP/IP server version %s\n", FB_VERSION); exit(FINI_OK); default: printf("Unknown switch '%c', ignored\n", c); break; } if (done) break; } } } if (Config::getServerMode() == MODE_CLASSIC) { if (!classic) standaloneClassic = true; } else { if (classic) { gds__log("Server misconfigured - to start it from (x)inetd add ServerMode=Classic to firebird.conf"); Firebird::Syslog::Record(Firebird::Syslog::Error, "Server misconfigured - add ServerMode=Classic to firebird.conf"); exit(STARTUP_ERROR); } INET_SERVER_flag |= SRVR_multi_client; super = true; } { // scope Firebird::MasterInterfacePtr master; master->serverMode(super ? 1 : 0); } if (debug) { INET_SERVER_flag |= SRVR_debug; } // activate paths set with -e family of switches ISC_set_prefix(0, 0); // ignore some signals set_signal(SIGPIPE, signal_handler); set_signal(SIGUSR1, signal_handler); set_signal(SIGUSR2, signal_handler); // First of all change directory to tmp if (chdir(TEMP_DIR)) { // error on changing the directory gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); } #ifdef FB_RAISE_LIMITS #ifdef RLIMIT_NPROC raiseLimit(RLIMIT_NPROC); #endif #if !(defined(DEV_BUILD)) if (Config::getBugcheckAbort()) #endif { // try to force core files creation raiseLimit(RLIMIT_CORE); } #if (defined SOLARIS || defined HPUX || defined LINUX) if (super) { // Increase max open files to hard limit for Unix // platforms which are known to have low soft limits. raiseLimit(RLIMIT_NOFILE); } #endif // Unix platforms #endif // FB_RAISE_LIMITS #ifdef HAVE_LOCALE_H // Pick up the system locale to allow SYSTEM<->UTF8 conversions inside the engine setlocale(LC_CTYPE, ""); #endif if (!(debug || classic)) { int mask = 0; // FD_ZERO(&mask); mask |= 1 << 2; // FD_SET(2, &mask); divorce_terminal(mask); } // check firebird.conf presence - must be for server if (Config::missFirebirdConf()) { Firebird::Syslog::Record(Firebird::Syslog::Error, "Missing master config file firebird.conf"); exit(STARTUP_ERROR); } if (super || standaloneClassic) { try { port = INET_connect(protocol, 0, INET_SERVER_flag, 0, NULL); } catch (const Firebird::Exception& ex) { iscLogException("startup:INET_connect:", ex); Firebird::StaticStatusVector st; ex.stuffException(st); gds__print_status(st.begin()); exit(STARTUP_ERROR); } } if (classic) { port = INET_server(channel); if (!port) { gds__log("Unable to start INET_server"); Firebird::Syslog::Record(Firebird::Syslog::Error, "Unable to start INET_server"); exit(STARTUP_ERROR); } } { // scope for interface ptr Firebird::PluginManagerInterfacePtr pi; Auth::registerSrpServer(pi); } if (super) { // Server tries to attach to security2.fdb to make sure everything is OK // This code fixes bug# 8429 + all other bug of that kind - from // now on the server exits if it cannot attach to the database // (wrong or no license, not enough memory, etc. ISC_STATUS_ARRAY status; isc_db_handle db_handle = 0L; const Firebird::RefPtr<Config> defConf(Config::getDefaultConfig()); const char* path = defConf->getSecurityDatabase(); const char dpb[] = {isc_dpb_version1, isc_dpb_sec_attach, 1, 1, isc_dpb_address_path, 0}; isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb); if (status[0] == 1 && status[1] > 0) { logSecurityDatabaseError(path, status); } isc_detach_database(status, &db_handle); if (status[0] == 1 && status[1] > 0) { logSecurityDatabaseError(path, status); } } // end scope fb_shutdown_callback(NULL, closePort, fb_shut_exit, port); SRVR_multi_thread(port, INET_SERVER_flag); #ifdef DEBUG_GDS_ALLOC // In Debug mode - this will report all server-side memory leaks due to remote access Firebird::PathName name = fb_utils::getPrefix( Firebird::IConfigManager::DIR_LOG, "memdebug.log"); FILE* file = os_utils::fopen(name.c_str(), "w+t"); if (file) { fprintf(file, "Global memory pool allocated objects\n"); getDefaultMemoryPool()->print_contents(file); fclose(file); } #endif // perform atexit shutdown here when all globals in embedded library are active // also sync with possibly already running shutdown in dedicated thread fb_shutdown(10000, fb_shutrsn_exit_called); return FINI_OK; } catch (const Firebird::Exception& ex) { Firebird::StaticStatusVector st; ex.stuffException(st); char s[100]; const ISC_STATUS* status = st.begin(); fb_interpret(s, sizeof(s), &status); iscLogException("Firebird startup error:", ex); Firebird::Syslog::Record(Firebird::Syslog::Error, "Firebird startup error"); Firebird::Syslog::Record(Firebird::Syslog::Error, s); exit(STARTUP_ERROR); } }
void iscLogStatus(const TEXT* text, const Firebird::IStatus* status) { Firebird::StaticStatusVector tmp; tmp.mergeStatus(status); iscLogStatus(text, tmp.begin()); }