mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
New feature 2524 : Command line utility to work with Trace Service
Source code
This commit is contained in:
parent
ba4e9a8736
commit
9ba34ee2cc
@ -30,8 +30,8 @@
|
||||
#include "iberror.h"
|
||||
#include "../../common/classes/fb_string.h"
|
||||
#include "../../common/StatusArg.h"
|
||||
#include "../../common/utils_proto.h"
|
||||
#include "../../common/UtilSvc.h"
|
||||
#include "../../jrd/ThreadData.h"
|
||||
#include "../../jrd/trace/TraceService.h"
|
||||
|
||||
|
||||
@ -49,33 +49,39 @@ static void usage(UtilSvc* uSvc, const char* message, ...)
|
||||
(Arg::Gds(isc_random) << msg).raise();
|
||||
|
||||
fprintf(stderr, "ERROR: %s.\n\n", msg.c_str());
|
||||
|
||||
fprintf(stderr,
|
||||
"Firebird Trace utility.\n"
|
||||
"Usage: fbtrace <action> [<parameters>]\n"
|
||||
"Usage: fbtracemgr <action> [<parameters>]\n"
|
||||
"\n"
|
||||
"Actions: \n"
|
||||
" -STA[RT] Start trace session\n"
|
||||
" -STO[P] Stop trace session\n"
|
||||
" -S[USPEND] Suspend trace session\n"
|
||||
" -R[ESUME] Resume trace session\n"
|
||||
" -L[IST] List existing trace sessions\n\n"
|
||||
"Parameters: \n"
|
||||
" -N[AME] <string> Session name\n"
|
||||
" -I[D] <number> Session ID\n"
|
||||
" -C[ONFIG] <string> Trace configuration file name\n"
|
||||
" -O[UTPUT] <string> Output file name\n"
|
||||
"\n"
|
||||
"Action parameters: \n"
|
||||
" -N[AME] <string> Session name\n"
|
||||
" -I[D] <number> Session ID\n"
|
||||
" -C[ONFIG] <string> Trace configuration file name\n"
|
||||
"\n"
|
||||
"Connection parameters: \n"
|
||||
" -SE[RVICE] <string> Service name\n"
|
||||
" -U[SER] <string> User name\n"
|
||||
" -P[ASSWORD] <string> Password\n"
|
||||
" -FE[TCH] <string> Fetch password from file\n"
|
||||
" -SE[RVICE] <string> Service name\n\n"
|
||||
"Examples: \n"
|
||||
" fbtrace -START -NAME my_trace -CONFIG my_cfg.txt\n"
|
||||
" fbtrace -START -CONFIG my_cfg.txt -OUTPUT log.txt\n"
|
||||
" fbtrace -STOP -ID 12"
|
||||
" fbtrace -LIST -OUTPUT stdout"
|
||||
" -T[RUSTED] <string> Force trusted authentication\n"
|
||||
"\n"
|
||||
"Examples: \n"
|
||||
" fbtracemgr -LIST\n"
|
||||
" fbtracemgr -START -NAME my_trace -CONFIG my_cfg.txt\n"
|
||||
" fbtracemgr -SUSPEND -ID 2\n"
|
||||
" fbtracemgr -RESUME -ID 2\n"
|
||||
" fbtracemgr -STOP -ID 4\n"
|
||||
"\n"
|
||||
"Notes:\n"
|
||||
" Press CTRL+C to stop interactive trace session"
|
||||
" Press CTRL+C to stop interactive trace session\n"
|
||||
);
|
||||
exit(FINI_ERROR);
|
||||
}
|
||||
@ -131,7 +137,8 @@ static const in_sw_tab_t* findSwitch(const in_sw_tab_t* table, string sw)
|
||||
|
||||
for (const in_sw_tab_t* in_sw_tab = table; in_sw_tab->in_sw_name; in_sw_tab++)
|
||||
{
|
||||
if (switchMatch(sw, in_sw_tab->in_sw_name))
|
||||
if ((sw.length() >= in_sw_tab->in_sw_min_length) &&
|
||||
switchMatch(sw, in_sw_tab->in_sw_name))
|
||||
{
|
||||
return in_sw_tab;
|
||||
}
|
||||
@ -147,8 +154,10 @@ const char TRACE_ERR_PARAM_VAL_MISS[] = "value for switch \"%s\" is missing";
|
||||
const char TRACE_ERR_PARAM_INVALID[] = "invalid value (\"%s\") for switch \"%s\"";
|
||||
const char TRACE_ERR_SWITCH_UNKNOWN[] = "unknown switch \"%s\" encountered";
|
||||
const char TRACE_ERR_SWITCH_SVC_ONLY[] = "switch \"%s\" can be used by service only";
|
||||
const char TRACE_ERR_SWITCH_USER_ONLY[] = "switch \"%s\" can be used by user only";
|
||||
const char TRACE_ERR_SWITCH_PARAM_MISS[] = "mandatory parameter \"%s\" for switch \"%s\" is missing";
|
||||
const char TRACE_ERR_PARAM_ACT_NOTCOMPAT[] = "parameter \"%s\" is incompatible with action \"%s\"";
|
||||
const char TRACE_ERR_MANDATORY_SWITCH_MISS[]= "mandatory switch \"%s\" is missing";
|
||||
|
||||
|
||||
void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
@ -301,6 +310,47 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
usage(uSvc, TRACE_ERR_PARAM_VAL_MISS, sw->in_sw_name);
|
||||
break;
|
||||
|
||||
case IN_SW_TRACE_FETCH_PWD:
|
||||
if (uSvc->isService())
|
||||
usage(uSvc, TRACE_ERR_SWITCH_USER_ONLY, sw->in_sw_name);
|
||||
|
||||
if (!pwd.empty())
|
||||
usage(uSvc, TRACE_ERR_SWITCH_ONCE, sw->in_sw_name);
|
||||
|
||||
argv++;
|
||||
if (argv < end)
|
||||
{
|
||||
const PathName fileName(*argv);
|
||||
const char *s = NULL;
|
||||
switch (fb_utils::fetchPassword(fileName, s))
|
||||
{
|
||||
case fb_utils::FETCH_PASS_OK:
|
||||
pwd = s;
|
||||
break;
|
||||
|
||||
case fb_utils::FETCH_PASS_FILE_OPEN_ERROR:
|
||||
(Arg::Gds(isc_io_error) << Arg::Str("open") << Arg::Str(fileName) <<
|
||||
Arg::Gds(isc_io_open_err) << Arg::OsError()).raise();
|
||||
break;
|
||||
|
||||
case fb_utils::FETCH_PASS_FILE_READ_ERROR:
|
||||
case fb_utils::FETCH_PASS_FILE_EMPTY:
|
||||
(Arg::Gds(isc_io_error) << Arg::Str("read") << Arg::Str(fileName) <<
|
||||
Arg::Gds(isc_io_read_err) << Arg::OsError()).raise();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
usage(uSvc, TRACE_ERR_PARAM_VAL_MISS, sw->in_sw_name);
|
||||
break;
|
||||
|
||||
case IN_SW_TRACE_TRUSTED_AUTH:
|
||||
if (uSvc->isService())
|
||||
usage(uSvc, TRACE_ERR_SWITCH_USER_ONLY, sw->in_sw_name);
|
||||
|
||||
adminRole = true;
|
||||
break;
|
||||
|
||||
case IN_SW_TRACE_TRUSTED_USER:
|
||||
if (!uSvc->isService())
|
||||
usage(uSvc, TRACE_ERR_SWITCH_SVC_ONLY, sw->in_sw_name);
|
||||
@ -334,6 +384,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
svc_name = *argv;
|
||||
else
|
||||
usage(uSvc, TRACE_ERR_PARAM_VAL_MISS, sw->in_sw_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
@ -341,6 +392,10 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
|
||||
}
|
||||
|
||||
// validate missed action's parameters and perform action
|
||||
if (!uSvc->isService() && svc_name.isEmpty()) {
|
||||
usage(uSvc, TRACE_ERR_MANDATORY_SWITCH_MISS, "SERVICE");
|
||||
}
|
||||
|
||||
if (!session.ses_id)
|
||||
{
|
||||
switch (action_sw->in_sw)
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "../../common/config/config.h"
|
||||
#include "../../common/StatusArg.h"
|
||||
#include "../../common/thd.h"
|
||||
#include "../../jrd/ThreadData.h"
|
||||
#include "../../jrd/svc.h"
|
||||
#include "../../jrd/os/guid.h"
|
||||
#include "../../jrd/trace/TraceLog.h"
|
||||
@ -63,9 +62,9 @@ public:
|
||||
virtual void stopSession(ULONG id);
|
||||
virtual void setActive(ULONG id, bool active);
|
||||
virtual void listSessions();
|
||||
virtual void readSession(TraceSession& session);
|
||||
|
||||
private:
|
||||
void readSession(TraceSession& session);
|
||||
bool changeFlags(ULONG id, int setFlags, int clearFlags);
|
||||
bool checkAliveAndFlags(ULONG sesId, int& flags);
|
||||
|
||||
|
@ -54,16 +54,18 @@ const int IN_SW_TRACE_PASSWORD = 10;
|
||||
const int IN_SW_TRACE_TRUSTED_USER = 11;
|
||||
const int IN_SW_TRACE_TRUSTED_ROLE = 12;
|
||||
const int IN_SW_TRACE_SERVICE_NAME = 13;
|
||||
const int IN_SW_TRACE_FETCH_PWD = 14;
|
||||
const int IN_SW_TRACE_TRUSTED_AUTH = 15;
|
||||
|
||||
|
||||
// list of possible actions (services) for use with trace services
|
||||
static const struct in_sw_tab_t trace_action_in_sw_table [] =
|
||||
{
|
||||
{IN_SW_TRACE_LIST, isc_action_svc_trace_list, "LIST", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_RESUME, isc_action_svc_trace_resume, "RESUME", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_STOP, isc_action_svc_trace_stop, "STOP", 0, 0, 0, false, 0, 3, NULL},
|
||||
{IN_SW_TRACE_START, isc_action_svc_trace_start, "START", 0, 0, 0, false, 0, 3, NULL},
|
||||
{IN_SW_TRACE_SUSPEND, isc_action_svc_trace_suspend,"SUSPEND", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_LIST, isc_action_svc_trace_list, "LIST", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_RESUME, isc_action_svc_trace_resume, "RESUME", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_STOP, isc_action_svc_trace_stop, "STOP", 0, 0, 0, false, 0, 3, NULL},
|
||||
{IN_SW_TRACE_START, isc_action_svc_trace_start, "START", 0, 0, 0, false, 0, 3, NULL},
|
||||
{IN_SW_TRACE_SUSPEND, isc_action_svc_trace_suspend, "SUSPEND", 0, 0, 0, false, 0, 1, NULL},
|
||||
{0, 0, NULL, 0, 0, 0, false, 0, 0, NULL} // End of List
|
||||
};
|
||||
|
||||
@ -80,8 +82,10 @@ static const struct in_sw_tab_t trace_option_in_sw_table [] =
|
||||
// authentication switches, common for all utils (services)
|
||||
static const struct in_sw_tab_t trace_auth_in_sw_table [] =
|
||||
{
|
||||
{IN_SW_TRACE_FETCH_PWD, 0, "FETCH_PASSWORD", 0, 0, 0, false, 0, 2, NULL},
|
||||
{IN_SW_TRACE_PASSWORD, 0, PASSWORD_SWITCH, 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_SERVICE_NAME, 0, "SERVICE", 0, 0, 0, false, 0, 2, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_AUTH, 0, "TRUSTED", 0, 0, 0, false, 0, 1, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0, 9, NULL},
|
||||
{IN_SW_TRACE_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, false, 0, 9, NULL},
|
||||
{IN_SW_TRACE_USERNAME, 0, USERNAME_SWITCH, 0, 0, 0, false, 0, 1, NULL},
|
||||
@ -100,7 +104,6 @@ public:
|
||||
virtual void stopSession(ULONG id) = 0;
|
||||
virtual void setActive(ULONG id, bool active) = 0;
|
||||
virtual void listSessions() = 0;
|
||||
virtual void readSession(TraceSession& ) = 0;
|
||||
|
||||
virtual ~TraceSvcIntf() { }
|
||||
};
|
||||
|
342
src/utilities/fbtracemgr/traceMgrMain.cpp
Normal file
342
src/utilities/fbtracemgr/traceMgrMain.cpp
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* PROGRAM: Firebird utilities
|
||||
* MODULE: traceMgrMain.cpp
|
||||
* DESCRIPTION: Trace Manager utility
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Vladyslav Khorsun
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2009 Vladyslav Khorsun <hvlad@users.sourceforge.net>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include <signal.h>
|
||||
|
||||
#include "../../common/classes/auto.h"
|
||||
#include "../../common/classes/ClumpletWriter.h"
|
||||
#include "../../common/utils_proto.h"
|
||||
#include "../../jrd/trace/TraceService.h"
|
||||
#include "../../jrd/ibase.h"
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
class TraceSvcUtil : public TraceSvcIntf
|
||||
{
|
||||
public:
|
||||
TraceSvcUtil();
|
||||
virtual ~TraceSvcUtil();
|
||||
|
||||
virtual void setAttachInfo(const string& service_name, const string& user,
|
||||
const string& pwd, bool isAdmin);
|
||||
|
||||
virtual void startSession(TraceSession& session, bool interactive);
|
||||
virtual void stopSession(ULONG id);
|
||||
virtual void setActive(ULONG id, bool active);
|
||||
virtual void listSessions();
|
||||
|
||||
static void stopRead();
|
||||
|
||||
private:
|
||||
void runService(size_t spbSize, const UCHAR* spb);
|
||||
|
||||
isc_svc_handle m_svcHandle;
|
||||
static bool m_stop;
|
||||
};
|
||||
|
||||
|
||||
const int MAXBUF = 16384;
|
||||
|
||||
bool TraceSvcUtil::m_stop = true;
|
||||
|
||||
TraceSvcUtil::TraceSvcUtil()
|
||||
{
|
||||
m_svcHandle = 0;
|
||||
}
|
||||
|
||||
TraceSvcUtil::~TraceSvcUtil()
|
||||
{
|
||||
if (m_svcHandle)
|
||||
{
|
||||
ISC_STATUS_ARRAY status = {0};
|
||||
isc_service_detach(status, &m_svcHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceSvcUtil::setAttachInfo(const string& service_name, const string& user,
|
||||
const string& pwd, bool isAdmin)
|
||||
{
|
||||
ISC_STATUS_ARRAY status = {0};
|
||||
|
||||
ClumpletWriter spb(ClumpletWriter::SpbAttach, MAXBUF, isc_spb_current_version);
|
||||
|
||||
if (user.isEmpty() && !isAdmin)
|
||||
{
|
||||
string isc_user;
|
||||
if (fb_utils::readenv(ISC_USER, isc_user)) {
|
||||
spb.insertString(isc_spb_user_name, isc_user);
|
||||
}
|
||||
}
|
||||
else if (user.hasData()) {
|
||||
spb.insertString(isc_spb_user_name, user);
|
||||
}
|
||||
|
||||
if (pwd.isEmpty() && !isAdmin)
|
||||
{
|
||||
string isc_pwd;
|
||||
if (fb_utils::readenv(ISC_PASSWORD, isc_pwd)) {
|
||||
spb.insertString(isc_spb_password, isc_pwd);
|
||||
}
|
||||
}
|
||||
else if (pwd.hasData()) {
|
||||
spb.insertString(isc_spb_password, pwd);
|
||||
}
|
||||
|
||||
if (isAdmin) {
|
||||
spb.insertTag(isc_spb_trusted_auth);
|
||||
}
|
||||
|
||||
if (isc_service_attach(status, 0, service_name.c_str(), &m_svcHandle,
|
||||
static_cast<USHORT>(spb.getBufferLength()),
|
||||
reinterpret_cast<const char*>(spb.getBuffer())))
|
||||
{
|
||||
status_exception::raise(status);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceSvcUtil::startSession(TraceSession& session, bool /*interactive*/)
|
||||
{
|
||||
m_stop = false;
|
||||
|
||||
HalfStaticArray<UCHAR, 1024> buff(*getDefaultMemoryPool());
|
||||
UCHAR* p = NULL;
|
||||
long len = 0;
|
||||
|
||||
FILE* file = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
const char* fileName = session.ses_config.c_str();
|
||||
file = fopen(fileName, "rb");
|
||||
if (!file) {
|
||||
(Arg::Gds(isc_io_error) << Arg::Str("fopen") << Arg::Str(fileName) <<
|
||||
Arg::Gds(isc_io_open_err) << Arg::OsError()).raise();
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = ftell(file);
|
||||
if (len == 0) {
|
||||
(Arg::Gds(isc_io_error) << Arg::Str("fread") << Arg::Str(fileName) <<
|
||||
Arg::Gds(isc_io_read_err) << Arg::OsError()).raise();
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_SET);
|
||||
p = buff.getBuffer(len);
|
||||
|
||||
if (fread(p, 1, len, file) != len) {
|
||||
(Arg::Gds(isc_io_error) << Arg::Str("fread") << Arg::Str(fileName) <<
|
||||
Arg::Gds(isc_io_read_err) << Arg::OsError()).raise();
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
if (file)
|
||||
fclose(file);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
ClumpletWriter spb(ClumpletWriter::SpbStart, MAXBUF);
|
||||
|
||||
spb.insertTag(isc_action_svc_trace_start);
|
||||
spb.insertBytes(isc_spb_trc_cfg, p, len);
|
||||
|
||||
if (session.ses_name.hasData())
|
||||
{
|
||||
spb.insertBytes(isc_spb_trc_name,
|
||||
reinterpret_cast<const UCHAR*> (session.ses_name.c_str()),
|
||||
session.ses_name.length());
|
||||
}
|
||||
|
||||
runService(spb.getBufferLength(), spb.getBuffer());
|
||||
}
|
||||
|
||||
void TraceSvcUtil::stopSession(ULONG id)
|
||||
{
|
||||
ClumpletWriter spb(ClumpletWriter::SpbStart, MAXBUF);
|
||||
|
||||
spb.insertTag(isc_action_svc_trace_stop);
|
||||
spb.insertInt(isc_spb_trc_id, id);
|
||||
|
||||
runService(spb.getBufferLength(), spb.getBuffer());
|
||||
}
|
||||
|
||||
void TraceSvcUtil::setActive(ULONG id, bool active)
|
||||
{
|
||||
ClumpletWriter spb(ClumpletWriter::SpbStart, MAXBUF);
|
||||
|
||||
spb.insertTag(active ? isc_action_svc_trace_resume : isc_action_svc_trace_suspend);
|
||||
spb.insertInt(isc_spb_trc_id, id);
|
||||
|
||||
runService(spb.getBufferLength(), spb.getBuffer());
|
||||
}
|
||||
|
||||
void TraceSvcUtil::listSessions()
|
||||
{
|
||||
ClumpletWriter spb(ClumpletWriter::SpbStart, MAXBUF);
|
||||
|
||||
spb.insertTag(isc_action_svc_trace_list);
|
||||
|
||||
runService(spb.getBufferLength(), spb.getBuffer());
|
||||
}
|
||||
|
||||
void TraceSvcUtil::stopRead()
|
||||
{
|
||||
m_stop = true;
|
||||
}
|
||||
|
||||
void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb)
|
||||
{
|
||||
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};
|
||||
const char send[] = {isc_info_svc_timeout, 2, 0, 1, 0, 0, 0, isc_info_end};
|
||||
|
||||
char results[MAXBUF];
|
||||
do
|
||||
{
|
||||
if (isc_service_query(status, &m_svcHandle, 0, sizeof(send), send,
|
||||
sizeof(query), query,
|
||||
sizeof(results) - 1, results))
|
||||
{
|
||||
status_exception::raise(status);
|
||||
}
|
||||
|
||||
char *p = results;
|
||||
bool ignoreTruncation = false;
|
||||
|
||||
while (*p != isc_info_end)
|
||||
{
|
||||
const char item = *p++;
|
||||
switch (item)
|
||||
{
|
||||
case isc_info_svc_to_eof:
|
||||
ignoreTruncation = true;
|
||||
|
||||
case isc_info_svc_line:
|
||||
{
|
||||
unsigned short l = isc_vax_integer (p, sizeof(l));
|
||||
p += sizeof(l);
|
||||
if (l)
|
||||
{
|
||||
char ch = p[l];
|
||||
p[l] = 0;
|
||||
fprintf(stdout, "%s", p);
|
||||
p[l] = ch;
|
||||
p += l;
|
||||
}
|
||||
else
|
||||
m_stop = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_info_truncated:
|
||||
if (!ignoreTruncation)
|
||||
{
|
||||
//printf("%s\n", getMessage(18).c_str());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_info_svc_timeout:
|
||||
m_stop = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
status_exception::raise(Arg::Gds(isc_fbsvcmgr_query_err) <<
|
||||
Arg::Num(static_cast<unsigned char>(p[-1])));
|
||||
}
|
||||
}
|
||||
|
||||
} while (!m_stop);
|
||||
}
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
|
||||
typedef void (*SignalHandlerPointer)(int);
|
||||
|
||||
static SignalHandlerPointer prevCtrlCHandler = NULL;
|
||||
static bool terminated = false;
|
||||
|
||||
static void ctrl_c_handler(int signal)
|
||||
{
|
||||
if (signal == SIGINT)
|
||||
TraceSvcUtil::stopRead();
|
||||
|
||||
if (prevCtrlCHandler)
|
||||
prevCtrlCHandler(signal);
|
||||
}
|
||||
|
||||
|
||||
int CLIB_ROUTINE main(int argc, char* argv[])
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* m a i n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Invoke real nbackup main function
|
||||
*
|
||||
**************************************/
|
||||
|
||||
prevCtrlCHandler = signal(SIGINT, ctrl_c_handler);
|
||||
|
||||
AutoPtr<UtilSvc> uSvc(UtilSvc::createStandalone(argc, argv));
|
||||
try
|
||||
{
|
||||
TraceSvcUtil traceUtil;
|
||||
|
||||
fbtrace(uSvc, &traceUtil);
|
||||
}
|
||||
catch (const Firebird::Exception& ex)
|
||||
{
|
||||
ISC_STATUS_ARRAY temp;
|
||||
|
||||
ex.stuff_exception(temp);
|
||||
isc_print_status(temp);
|
||||
|
||||
return FINI_ERROR;
|
||||
}
|
||||
|
||||
return FINI_OK;
|
||||
}
|
Loading…
Reference in New Issue
Block a user