mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-29 17:40:01 +02:00
proper clean up and versioning of command line arguments for receiver and multi receiver
This commit is contained in:
parent
89726ab3ff
commit
7844216812
@ -13,22 +13,12 @@ class Receiver : private virtual slsDetectorDefs {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* Starts up a Receiver server. Reads configuration file, options, and
|
* Starts up a Receiver server.
|
||||||
* assembles a Receiver using TCP and UDP detector interfaces
|
* Assembles a Receiver using TCP and UDP detector interfaces
|
||||||
* throws an exception in case of failure
|
* throws an exception in case of failure
|
||||||
* @param argc from command line
|
* @param port TCP/IP port number
|
||||||
* @param argv from command line
|
|
||||||
*/
|
*/
|
||||||
Receiver(int argc, char *argv[]);
|
Receiver(uint16_t port = 1954);
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
* Starts up a Receiver server. Reads configuration file, options, and
|
|
||||||
* assembles a Receiver using TCP and UDP detector interfaces
|
|
||||||
* throws an exception in case of failure
|
|
||||||
* @param tcpip_port_no TCP/IP port number
|
|
||||||
*/
|
|
||||||
Receiver(uint16_t tcpip_port_no = 1954);
|
|
||||||
|
|
||||||
~Receiver();
|
~Receiver();
|
||||||
|
|
||||||
|
@ -7,10 +7,12 @@
|
|||||||
#include "sls/container_utils.h"
|
#include "sls/container_utils.h"
|
||||||
#include "sls/logger.h"
|
#include "sls/logger.h"
|
||||||
#include "sls/sls_detector_defs.h"
|
#include "sls/sls_detector_defs.h"
|
||||||
|
#include "sls/sls_detector_exceptions.h"
|
||||||
#include "sls/versionAPI.h"
|
#include "sls/versionAPI.h"
|
||||||
|
|
||||||
#include <csignal> //SIGINT
|
#include <csignal> //SIGINT
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <getopt.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <sys/wait.h> //wait
|
#include <sys/wait.h> //wait
|
||||||
@ -29,28 +31,6 @@
|
|||||||
|
|
||||||
sem_t semaphore;
|
sem_t semaphore;
|
||||||
|
|
||||||
/**
|
|
||||||
* Control+C Interrupt Handler
|
|
||||||
* to let all the processes know to exit properly
|
|
||||||
*/
|
|
||||||
void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* prints usage of this example program
|
|
||||||
*/
|
|
||||||
std::string getHelpMessage() {
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "\nUsage:\n\n"
|
|
||||||
<< "./slsMultiReceiver --version or -v\n"
|
|
||||||
<< "\t - Gets the slsMultiReceiver version\n\n"
|
|
||||||
<< "./slsMultiReceiver [start tcp port] [num recevers] [call back "
|
|
||||||
"option (optional)]\n"
|
|
||||||
<< "\t - tcp port has to be non-zero and 16 bit\n"
|
|
||||||
<< "\t - call back option is 0 (disabled) by default, 1 prints frame "
|
|
||||||
"header for debugging\n";
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start Acquisition Call back (slsMultiReceiver writes data if file write
|
* Start Acquisition Call back (slsMultiReceiver writes data if file write
|
||||||
* enabled) if registerCallBackRawDataReady or
|
* enabled) if registerCallBackRawDataReady or
|
||||||
@ -153,6 +133,60 @@ void GetData(slsDetectorDefs::sls_receiver_header &header,
|
|||||||
imageSize = 26000;
|
imageSize = 26000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control+C Interrupt Handler
|
||||||
|
* to let all the processes know to exit properly
|
||||||
|
*/
|
||||||
|
void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
||||||
|
|
||||||
|
void GetDeprecatedCommandLineOptions(int argc, char *argv[],
|
||||||
|
uint16_t &startPort,
|
||||||
|
uint16_t &numReceivers,
|
||||||
|
bool &callbackEnabled) {
|
||||||
|
std::string deprecatedMessage =
|
||||||
|
"Detected deprecated Options. Please update.\n";
|
||||||
|
if (argc > 1) {
|
||||||
|
try {
|
||||||
|
if (argc == 3 || argc == 4) {
|
||||||
|
startPort = sls::StringTo<uint16_t>(argv[1]);
|
||||||
|
numReceivers = sls::StringTo<uint16_t>(argv[2]);
|
||||||
|
if (numReceivers > 1024) {
|
||||||
|
LOG(sls::logWARNING) << deprecatedMessage;
|
||||||
|
LOG(sls::logERROR)
|
||||||
|
<< "Did you mix up the order of the arguments?";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (numReceivers == 0) {
|
||||||
|
LOG(sls::logWARNING) << deprecatedMessage;
|
||||||
|
LOG(sls::logERROR) << "Invalid number of receivers.";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (argc == 4) {
|
||||||
|
callbackEnabled = sls::StringTo<bool>(argv[3]);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
throw std::runtime_error("Invalid number of arguments");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LOG(sls::logWARNING) << deprecatedMessage;
|
||||||
|
LOG(sls::logERROR) << e.what();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getHelpMessage() {
|
||||||
|
std::string name = "slsMultiReceiver";
|
||||||
|
return "\nUsage: " + name + " Options:\n" +
|
||||||
|
"\t-v, --version : Version of " + name + ".\n" +
|
||||||
|
"\t-n, --num-receivers : Number of receivers.\n" +
|
||||||
|
"\t-p, --port : TCP port to communicate with client for "
|
||||||
|
"configuration. Non-zero and 16 bit.\n" +
|
||||||
|
"\t-c, --callback : Enable dummy callbacks. Disabled (0) by "
|
||||||
|
"default. Prints frame header for debugging.\n" +
|
||||||
|
"\t-u, --uid : Set effective user id if receiver started "
|
||||||
|
"with privileges. \n\n";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example of main program using the Receiver class
|
* Example of main program using the Receiver class
|
||||||
*
|
*
|
||||||
@ -161,60 +195,109 @@ void GetData(slsDetectorDefs::sls_receiver_header &header,
|
|||||||
* - Default Start TCP port is 1954
|
* - Default Start TCP port is 1954
|
||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
uint16_t startPort = DEFAULT_TCP_RX_PORTNO;
|
||||||
|
uint16_t numReceivers = 1;
|
||||||
|
bool callbackEnabled = false;
|
||||||
|
uid_t userid = -1;
|
||||||
|
|
||||||
// version
|
std::string help_message = getHelpMessage();
|
||||||
if (argc == 2) {
|
|
||||||
std::string sargv1 = std::string(argv[1]);
|
static struct option long_options[] = {
|
||||||
if (sargv1 == "--version" || sargv1 == "-v") {
|
{"help", no_argument, nullptr, 'h'},
|
||||||
std::cout << "slsMultiReceiver Version: " << APIRECEIVER
|
{"version", no_argument, nullptr, 'v'},
|
||||||
<< std::endl;
|
{"num-receivers", required_argument, nullptr, 'n'},
|
||||||
|
{"rx_tcpport", required_argument, nullptr, 't'},
|
||||||
|
{"port", required_argument, nullptr, 'p'},
|
||||||
|
{"callback", required_argument, nullptr, 'c'},
|
||||||
|
{"uid", required_argument, nullptr, 'u'},
|
||||||
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
|
int option_index = 0;
|
||||||
|
int opt = 0;
|
||||||
|
while (-1 != (opt = getopt_long(argc, argv, "hvn:t:p:u:c:", long_options,
|
||||||
|
&option_index))) {
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
try {
|
||||||
|
numReceivers = sls::StringTo<uint16_t>(optarg);
|
||||||
|
if (numReceivers == 0 || numReceivers > 100) {
|
||||||
|
throw std::runtime_error("Invalid argument.");
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Invalid number of receivers." +
|
||||||
|
help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
LOG(sls::logWARNING)
|
||||||
|
<< "Deprecated option. Please use 'p' or '--port'.";
|
||||||
|
case 'p':
|
||||||
|
try {
|
||||||
|
startPort = sls::StringTo<uint16_t>(optarg);
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Could not scan port number." +
|
||||||
|
help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
try {
|
||||||
|
callbackEnabled = sls::StringTo<bool>(optarg);
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Invalid callback enable." +
|
||||||
|
help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
try {
|
||||||
|
userid = sls::StringTo<uint32_t>(optarg);
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Invalid uid." + help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
std::cout << help_message << std::endl;
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
default:
|
||||||
|
// maintain backward compatibility of [startport] [num-receivers]
|
||||||
|
// [callback]
|
||||||
|
GetDeprecatedCommandLineOptions(argc, argv, startPort, numReceivers,
|
||||||
|
callbackEnabled);
|
||||||
|
throw sls::RuntimeError(help_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** - set default values */
|
LOG(sls::logINFOBLUE) << "Current Process [ Tid: " << gettid() << ']';
|
||||||
int numReceivers = 1;
|
LOG(sls::logINFO) << "Number of Receivers: " << numReceivers;
|
||||||
uint16_t startTCPPort = DEFAULT_TCP_RX_PORTNO;
|
LOG(sls::logINFO) << "Start TCP Port: " << startPort;
|
||||||
int withCallback = 0;
|
LOG(sls::logINFO) << "Callback Enable: " << callbackEnabled;
|
||||||
sem_init(&semaphore, 1, 0);
|
|
||||||
|
|
||||||
/** - get number of receivers and start tcp port from command line
|
// set effective id if provided
|
||||||
* arguments */
|
if (userid != static_cast<uid_t>(-1)) {
|
||||||
if (argc > 1) {
|
if (geteuid() == userid) {
|
||||||
try {
|
LOG(sls::logINFO)
|
||||||
if (argc == 3 || argc == 4) {
|
<< "Process already has the same Effective UID " << userid;
|
||||||
startTCPPort = sls::StringTo<uint16_t>(argv[1]);
|
} else {
|
||||||
if (startTCPPort == 0) {
|
if (seteuid(userid) != 0) {
|
||||||
throw std::runtime_error("Invalid start tcp port");
|
std::ostringstream oss;
|
||||||
}
|
oss << "Could not set Effective UID to " << userid;
|
||||||
numReceivers = std::stoi(argv[2]);
|
throw sls::RuntimeError(oss.str());
|
||||||
if (numReceivers > 1024) {
|
}
|
||||||
cprintf(RED,
|
if (geteuid() != userid) {
|
||||||
"Did you mix up the order of the arguments?\n%s\n",
|
std::ostringstream oss;
|
||||||
getHelpMessage().c_str());
|
oss << "Could not set Effective UID to " << userid << ". Got "
|
||||||
return EXIT_FAILURE;
|
<< geteuid();
|
||||||
}
|
throw sls::RuntimeError(oss.str());
|
||||||
if (numReceivers == 0) {
|
}
|
||||||
cprintf(RED, "Invalid number of receivers.\n%s\n",
|
LOG(sls::logINFO) << "Process Effective UID changed to " << userid;
|
||||||
getHelpMessage().c_str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if (argc == 4) {
|
|
||||||
withCallback = std::stoi(argv[3]);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
throw std::runtime_error("Invalid number of arguments");
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
cprintf(RED, "Error: %s\n%s\n", e.what(), getHelpMessage().c_str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n", (long)gettid());
|
|
||||||
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
|
|
||||||
cprintf(RESET, "Start TCP Port: %hu\n", startTCPPort);
|
|
||||||
cprintf(RESET, "Callback Enable: %d\n", withCallback);
|
|
||||||
|
|
||||||
/** - Catch signal SIGINT to close files and call destructors properly */
|
/** - Catch signal SIGINT to close files and call destructors properly */
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_flags = 0; // no flags
|
sa.sa_flags = 0; // no flags
|
||||||
@ -222,7 +305,7 @@ int main(int argc, char *argv[]) {
|
|||||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
|
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
|
||||||
// of handler
|
// of handler
|
||||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
LOG(sls::logERROR) << "Could not set handler function for SIGINT";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
|
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
|
||||||
@ -234,10 +317,11 @@ int main(int argc, char *argv[]) {
|
|||||||
sigemptyset(&asa.sa_mask); // dont block additional signals during
|
sigemptyset(&asa.sa_mask); // dont block additional signals during
|
||||||
// invocation of handler
|
// invocation of handler
|
||||||
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
|
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
|
||||||
cprintf(RED, "Could not set handler function for SIGPIPE\n");
|
LOG(sls::logERROR) << "Could not set handler function for SIGPIPE";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** - loop over number of receivers */
|
/** - loop over number of receivers */
|
||||||
|
sem_init(&semaphore, 1, 0);
|
||||||
for (int i = 0; i < numReceivers; ++i) {
|
for (int i = 0; i < numReceivers; ++i) {
|
||||||
|
|
||||||
/** - fork process to create child process */
|
/** - fork process to create child process */
|
||||||
@ -246,35 +330,38 @@ int main(int argc, char *argv[]) {
|
|||||||
/** - if fork failed, raise SIGINT and properly destroy all child
|
/** - if fork failed, raise SIGINT and properly destroy all child
|
||||||
* processes */
|
* processes */
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
cprintf(RED, "fork() failed. Killing all the receiver objects\n");
|
LOG(sls::logERROR)
|
||||||
|
<< "fork() failed. Killing all the receiver objects";
|
||||||
raise(SIGINT);
|
raise(SIGINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** - if child process */
|
/** - if child process */
|
||||||
else if (pid == 0) {
|
else if (pid == 0) {
|
||||||
cprintf(BLUE, "Child process %d [ Tid: %ld ]\n", i, (long)gettid());
|
LOG(sls::logINFOBLUE)
|
||||||
|
<< "Child process " << i << " [ Tid: " << gettid() << ']';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
uint16_t port = startTCPPort + i;
|
uint16_t port = startPort + i;
|
||||||
sls::Receiver receiver(port);
|
sls::Receiver receiver(port);
|
||||||
|
|
||||||
/** - register callbacks. remember to set file write enable
|
/** - register callbacks. remember to set file write enable
|
||||||
* to 0 (using the client) if we should not write files and you
|
* to 0 (using the client) if we should not write files and you
|
||||||
* will write data using the callbacks */
|
* will write data using the callbacks */
|
||||||
if (withCallback) {
|
if (callbackEnabled) {
|
||||||
|
|
||||||
/** - Call back for start acquisition */
|
/** - Call back for start acquisition */
|
||||||
cprintf(BLUE, "Registering StartAcq()\n");
|
LOG(sls::logINFOBLUE) << "Registering StartAcq()";
|
||||||
receiver.registerCallBackStartAcquisition(StartAcq,
|
receiver.registerCallBackStartAcquisition(StartAcq,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
/** - Call back for acquisition finished */
|
/** - Call back for acquisition finished */
|
||||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
LOG(sls::logINFOBLUE)
|
||||||
|
<< "Registering AcquisitionFinished()";
|
||||||
receiver.registerCallBackAcquisitionFinished(
|
receiver.registerCallBackAcquisitionFinished(
|
||||||
AcquisitionFinished, nullptr);
|
AcquisitionFinished, nullptr);
|
||||||
|
|
||||||
/* - Call back for raw data */
|
/* - Call back for raw data */
|
||||||
cprintf(BLUE, "Registering GetData() \n");
|
LOG(sls::logINFOBLUE) << "Registering GetData()";
|
||||||
receiver.registerCallBackRawDataReady(GetData, nullptr);
|
receiver.registerCallBackRawDataReady(GetData, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,8 +375,8 @@ int main(int argc, char *argv[]) {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
|
LOG(sls::logINFOBLUE)
|
||||||
(long)gettid());
|
<< "Exiting Child Process [ Tid: " << gettid() << ']';
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,12 +388,12 @@ int main(int argc, char *argv[]) {
|
|||||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
|
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
|
||||||
// of handler
|
// of handler
|
||||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
LOG(sls::logERROR) << "Could not set handler function for SIGINT";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** - Print Ready and Instructions how to exit */
|
/** - Print Ready and Instructions how to exit */
|
||||||
std::cout << "Ready ... \n";
|
std::cout << "Ready ... \n";
|
||||||
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
|
LOG(sls::logINFO) << "\n[ Press \'Ctrl+c\' to exit ]";
|
||||||
|
|
||||||
/** - Parent process waits for all child processes to exit */
|
/** - Parent process waits for all child processes to exit */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -315,18 +402,19 @@ int main(int argc, char *argv[]) {
|
|||||||
// no child closed
|
// no child closed
|
||||||
if (childPid == -1) {
|
if (childPid == -1) {
|
||||||
if (errno == ECHILD) {
|
if (errno == ECHILD) {
|
||||||
cprintf(GREEN, "All Child Processes have been closed\n");
|
LOG(sls::logINFOGREEN)
|
||||||
|
<< "All Child Processes have been closed";
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
cprintf(RED, "Unexpected error from waitpid(): (%s)\n",
|
LOG(sls::logERROR)
|
||||||
strerror(errno));
|
<< "Unexpected error from waitpid(): " << strerror(errno);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// child closed
|
// child closed
|
||||||
cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
|
LOG(sls::logINFOBLUE)
|
||||||
(long int)childPid);
|
<< "Exiting Child Process [ Tid: " << childPid << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Goodbye!\n";
|
std::cout << "Goodbye!\n";
|
||||||
|
@ -27,106 +27,9 @@ namespace sls {
|
|||||||
|
|
||||||
Receiver::~Receiver() = default;
|
Receiver::~Receiver() = default;
|
||||||
|
|
||||||
Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) {
|
Receiver::Receiver(uint16_t port) {
|
||||||
|
validatePortNumber(port);
|
||||||
// options
|
tcpipInterface = make_unique<ClientInterface>(port);
|
||||||
uint16_t tcpip_port_no = 1954;
|
|
||||||
uid_t userid = -1;
|
|
||||||
|
|
||||||
// parse command line for config
|
|
||||||
static struct option long_options[] = {
|
|
||||||
// These options set a flag.
|
|
||||||
//{"verbose", no_argument, &verbose_flag, 1},
|
|
||||||
// These options don’t set a flag. We distinguish them by their indices.
|
|
||||||
{"rx_tcpport", required_argument, nullptr,
|
|
||||||
't'}, // TODO change or backward compatible to "port, p"?
|
|
||||||
{"uid", required_argument, nullptr, 'u'},
|
|
||||||
{"version", no_argument, nullptr, 'v'},
|
|
||||||
{"help", no_argument, nullptr, 'h'},
|
|
||||||
{nullptr, 0, nullptr, 0}};
|
|
||||||
|
|
||||||
// initialize global optind variable (required when instantiating multiple
|
|
||||||
// receivers in the same process)
|
|
||||||
optind = 1;
|
|
||||||
// getopt_long stores the option index here.
|
|
||||||
int option_index = 0;
|
|
||||||
int c = 0;
|
|
||||||
|
|
||||||
std::string help_message =
|
|
||||||
"\nUsage: " + std::string(argv[0]) + " [arguments]\n" +
|
|
||||||
"Possible arguments are:\n" +
|
|
||||||
"\t-t, --rx_tcpport <port> : TCP Communication Port with "
|
|
||||||
"client. Non-zero and 16 bit.\n" +
|
|
||||||
"\t-u, --uid <user id> : Set effective user id if receiver "
|
|
||||||
"\n" +
|
|
||||||
"\t started with privileges. \n\n";
|
|
||||||
|
|
||||||
while (c != -1) {
|
|
||||||
c = getopt_long(argc, argv, "hvt:u:", long_options, &option_index);
|
|
||||||
|
|
||||||
// Detect the end of the options.
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
|
|
||||||
case 't':
|
|
||||||
try {
|
|
||||||
tcpip_port_no = sls::StringTo<uint16_t>(optarg);
|
|
||||||
validatePortNumber(tcpip_port_no);
|
|
||||||
} catch (...) {
|
|
||||||
throw RuntimeError("Could not scan TCP port number." +
|
|
||||||
help_message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'u':
|
|
||||||
if (sscanf(optarg, "%u", &userid) != 1) {
|
|
||||||
throw RuntimeError("Could not scan uid" + help_message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
std::cout << "slsReceiver Version: " << APIRECEIVER << std::endl;
|
|
||||||
LOG(logINFOBLUE) << "Exiting [ Tid: " << gettid() << " ]";
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
std::cout << help_message << std::endl;
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
default:
|
|
||||||
throw RuntimeError(help_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set effective id if provided
|
|
||||||
if (userid != static_cast<uid_t>(-1)) {
|
|
||||||
if (geteuid() == userid) {
|
|
||||||
LOG(logINFO) << "Process already has the same Effective UID "
|
|
||||||
<< userid;
|
|
||||||
} else {
|
|
||||||
if (seteuid(userid) != 0) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Could not set Effective UID to " << userid;
|
|
||||||
throw RuntimeError(oss.str());
|
|
||||||
}
|
|
||||||
if (geteuid() != userid) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Could not set Effective UID to " << userid << ". Got "
|
|
||||||
<< geteuid();
|
|
||||||
throw RuntimeError(oss.str());
|
|
||||||
}
|
|
||||||
LOG(logINFO) << "Process Effective UID changed to " << userid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// might throw an exception
|
|
||||||
tcpipInterface = make_unique<ClientInterface>(tcpip_port_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
Receiver::Receiver(uint16_t tcpip_port_no) {
|
|
||||||
// might throw an exception
|
|
||||||
tcpipInterface = make_unique<ClientInterface>(tcpip_port_no);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Receiver::getReceiverVersion() {
|
std::string Receiver::getReceiverVersion() {
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
/* slsReceiver */
|
/* slsReceiver */
|
||||||
#include "sls/Receiver.h"
|
#include "sls/Receiver.h"
|
||||||
|
#include "sls/ToString.h"
|
||||||
#include "sls/container_utils.h"
|
#include "sls/container_utils.h"
|
||||||
#include "sls/logger.h"
|
#include "sls/logger.h"
|
||||||
#include "sls/sls_detector_defs.h"
|
#include "sls/sls_detector_defs.h"
|
||||||
|
|
||||||
#include <csignal> //SIGINT
|
#include <csignal> //SIGINT
|
||||||
|
#include <getopt.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -22,9 +24,84 @@ void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
sem_init(&semaphore, 1, 0);
|
uint16_t port = DEFAULT_TCP_RX_PORTNO;
|
||||||
|
uid_t userid = -1;
|
||||||
|
|
||||||
LOG(sls::logINFOBLUE) << "Created [ Tid: " << gettid() << " ]";
|
std::string help_message =
|
||||||
|
"\nUsage: " + std::string(argv[0]) + " Options:\n" +
|
||||||
|
"\t-v, --version : Version of " + std::string(argv[0]) + ".\n" +
|
||||||
|
"\t-p, --port : TCP port to communicate with client for "
|
||||||
|
"configuration. Non-zero and 16 bit.\n" +
|
||||||
|
"\t-u, --uid : Set effective user id if receiver started "
|
||||||
|
"with privileges. \n\n";
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, nullptr, 'h'},
|
||||||
|
{"version", no_argument, nullptr, 'v'},
|
||||||
|
{"rx_tcpport", required_argument, nullptr, 't'},
|
||||||
|
{"port", required_argument, nullptr, 'p'},
|
||||||
|
{"uid", required_argument, nullptr, 'u'},
|
||||||
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
|
int option_index = 0;
|
||||||
|
int opt = 0;
|
||||||
|
while (-1 != (opt = getopt_long(argc, argv, "hvt:p:u:", long_options,
|
||||||
|
&option_index))) {
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
LOG(sls::logWARNING)
|
||||||
|
<< "Deprecated option. Please use 'p' or '--port'.";
|
||||||
|
//[[fallthrough]]; TODO: for when we update to c++17
|
||||||
|
case 'p':
|
||||||
|
try {
|
||||||
|
port = sls::StringTo<uint16_t>(optarg);
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Could not scan port number." +
|
||||||
|
help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
try {
|
||||||
|
userid = sls::StringTo<uint32_t>(optarg);
|
||||||
|
} catch (...) {
|
||||||
|
throw sls::RuntimeError("Invalid uid." + help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
std::cout << help_message << std::endl;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
default:
|
||||||
|
throw sls::RuntimeError(help_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(sls::logINFOBLUE) << "Current Process [ Tid: " << gettid() << " ]";
|
||||||
|
LOG(sls::logINFO) << "Port: " << port;
|
||||||
|
|
||||||
|
// set effective id if provided
|
||||||
|
if (userid != static_cast<uid_t>(-1)) {
|
||||||
|
if (geteuid() == userid) {
|
||||||
|
LOG(sls::logINFO)
|
||||||
|
<< "Process already has the same Effective UID " << userid;
|
||||||
|
} else {
|
||||||
|
if (seteuid(userid) != 0) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Could not set Effective UID to " << userid;
|
||||||
|
throw sls::RuntimeError(oss.str());
|
||||||
|
}
|
||||||
|
if (geteuid() != userid) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Could not set Effective UID to " << userid << ". Got "
|
||||||
|
<< geteuid();
|
||||||
|
throw sls::RuntimeError(oss.str());
|
||||||
|
}
|
||||||
|
LOG(sls::logINFO) << "Process Effective UID changed to " << userid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Catch signal SIGINT to close files and call destructors properly
|
// Catch signal SIGINT to close files and call destructors properly
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
@ -47,8 +124,9 @@ int main(int argc, char *argv[]) {
|
|||||||
LOG(sls::logERROR) << "Could not set handler function for SIGPIPE";
|
LOG(sls::logERROR) << "Could not set handler function for SIGPIPE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sem_init(&semaphore, 1, 0);
|
||||||
try {
|
try {
|
||||||
sls::Receiver r(argc, argv);
|
sls::Receiver r(port);
|
||||||
LOG(sls::logINFO) << "[ Press \'Ctrl+c\' to exit ]";
|
LOG(sls::logINFO) << "[ Press \'Ctrl+c\' to exit ]";
|
||||||
sem_wait(&semaphore);
|
sem_wait(&semaphore);
|
||||||
sem_destroy(&semaphore);
|
sem_destroy(&semaphore);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user