DRDE/AusRegCliever/server/cliever-md.cpp

221 lines
6.3 KiB
C++

#define MD_MAIN
#include "cliever-md.h"
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
using namespace std;
bool mdHasEPPTk;
const char *mdOrAC; // Process capability based on boolean above
void setSignals();
void signal_handler(int);
void usage();
void md() {
bool daemonized=false;
int i,lfp,rc; // log file pointer
char str[32];
if (thisConfig->daemonized) {
rc = fork();
if (rc < 0) {
puts("Can't initialize process!");
exit(1);
}
if (getpid() == thisConfig->shellProcess)
exit(0);
setsid(); /* obtain a new process group */
for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standard I/O */
umask(027); /* set newly created file permissions */
chdir(RUNNING_DIR); /* change running directory */
lfp=open(MD_LOCK_FILE,O_RDWR|O_CREAT,0640); /* make sure were The MD */
if (lfp<0) {printf("Can't open lockfile(%d)! Ctl-C me."); exit(1);}
if ((rc=lockf(lfp,F_TLOCK,0))<0)
{printf("Can't lock lockfile (%d)! Ctl-C me.",rc); exit(0);}
thisConfig->daemonProcess = getpid();
sprintf(str,"%d\n",getpid());
write(lfp,str,strlen(str)); /* record pid to lockfile */
daemonized = true;
}
setSignals();
try {
theseLogs = new mdLogger();
theseLogs->init(true);
theseLogs->logN(1,MD_NAME " " MD_VERSION " compiled on " __DATE__ " @ " __TIME__ "(%d)",thisConfig->daemonProcess);
if (daemonized) theseLogs->logN(1,"(detached from %d)",thisConfig->shellProcess);
if (mdHasEPPTk) {
theseLogs->logN(0,"AusReg Cliever <- MasterDaemon.");
}
else
theseLogs->logN(0,"Unit testing md without toolkit.");
boost::thread foreground(runMasterDaemon);
boost::thread background(runAPILayer);
if (!foreground.joinable()) {
theseLogs->logN(0,"Fatal Error: couldn't start master daemon!");
exit(1);
}
if (background.joinable()) {
theseLogs->logN(2,"%s %d","Accepting API Requests on Port",thisConfig->clientPort);
background.join(); // normally unreachable
} else
theseLogs->logN(0,"Fatal Error: couldn't start client service layer!");
}
//catch (XmlRpcFault::XmlRpcFault& e)
//{
// theseLogs->logN(1,"xmlrpc_c fault: %s",e.getFaultString().c_str());
// exit(1);
//}
catch (std::exception& e)
{
theseLogs->logN(1,"Exception: %s",e.what());
exit(1);
}
catch (...) {
theseLogs->logN(1,"General Fault!");
exit(1);
}
}
int
main(int const argc,
const char ** const argv) {
char msg[512],*c;
const char *banner = MD_NAME " " MD_VERSION " compiled on " __DATE__ " @ " __TIME__ "(%d)\n";
int mthParm, rc = 0;
thisConfig = new masterDaemonConfig();
thisConfig->shellProcess = getpid();
mdOrAC = (strcspn(argv[0],"./") == strlen(argv[0])) ? argv[0] : strrchr(argv[0],'/') + 1;
mdHasEPPTk = strstr(argv[0],"ausreg-md") ? false : true;
thisConfig->tkScenario = 1;
if (argc < 3 || argc > 7) usage();
thisConfig->servicePort = atoi(argv[1]);
thisConfig->clientPort = atoi(argv[2]);
if (thisConfig->clientPort < 1000 || thisConfig->clientPort > 65535)
{
std::cerr << "The <client-udp-port> value is invalid.\n";
return 1;
}
if (thisConfig->servicePort < 1000 || thisConfig->servicePort > 65535)
{
std::cerr << "The <service-socket-port> value is invalid.\n";
return 1;
}
if (thisConfig->servicePort == thisConfig->clientPort)
{
std::cerr << "The <service-socket-port> and <client-udp-port> cannot be the same.\n";
return 1;
}
for (mthParm=3;mthParm < argc;mthParm++) {
if (*argv[mthParm] == '!') {
thisConfig->daemonized = false;
}
else
if (!strncmp(argv[mthParm],"logs=",4)) {
thisConfig->log_path = std::string(argv[mthParm]+4);
thisConfig->logPath = thisConfig->log_path.c_str();
}
else
if (!strncmp(argv[mthParm],"tk=",2)) {
c = (char *)argv[mthParm]+3;
thisConfig->tkScenario = atoi(c);
}
else
if (!strncmp(argv[mthParm],"cfg=",3)) {
thisConfig->cfg_path = std::string(argv[mthParm]+3);
thisConfig->configPath = thisConfig->cfg_path.c_str();
}
else usage();
}
if (!thisConfig->daemonized) printf(banner,thisConfig->shellProcess);
md();
while(!thisConfig->halt) sleep(5);
}
void setSignals() {
signal(SIGCHLD,SIG_IGN); /* ignore child */
signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
signal(SIGTTOU,SIG_IGN); // both input
signal(SIGTTIN,SIG_IGN); // and output
#ifdef AC_ASSERTIONS
signal(SIGINT, signal_handler); // debug
#endif
signal(SIGSEGV,signal_handler);
signal(SIGUSR1,signal_handler); // commander log messages
signal(SIGUSR2,signal_handler); // reserved
signal(SIGHUP,signal_handler); /* catch hangup signal */
signal(SIGTERM,signal_handler); /* catch kill signal */
}
void signal_handler(int sig)
{ bool waitForGDB=true; long long iSaidWaitBiatch = 100000000000L, i;
switch(sig) {
case SIGSEGV:
theseLogs->logN(0,"SEGV ABEND.");
case SIGINT:
if (waitForGDB) {
for (i = 0;
i < iSaidWaitBiatch;
i++)
{}
}
exit(NOT_OK);
break;
case SIGUSR1:
break;
case SIGUSR2:
break;
case SIGHUP:
theseLogs->logN(0,"hangup signal caught, currently md ignores this.");
break;
case SIGTERM:
theseLogs->logN(0,"terminate signal caught, auc-md will shutdown.");
exit(0);
break;
}
}
void usage() {
std::cerr << "Usage: " << mdOrAC << " <client-udp-port> <service-socket-port> [tk=<n>] [cfg=<path>] [log=<path>] [!] \n\n"
" where tk is the Toolkit Scenario (default ACTK_PROD) \n"
"\nconfig directory defaults to ./etc/toolkit2.conf \n"
"log directory to /tmp \nand ! to not daemonize (for diagnostic purposes)\n\n";
exit(1);
}