mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-07-10 09:51:50 +02:00
refactored to take out repetitive code, need to adjust for slsMulti and slsFrameSync
This commit is contained in:
@ -13,6 +13,7 @@ set(SOURCES
|
||||
src/Arping.cpp
|
||||
src/MasterAttributes.cpp
|
||||
src/MasterFileUtility.cpp
|
||||
src/CommandLineOptions.cpp
|
||||
)
|
||||
|
||||
set(PUBLICHEADERS
|
||||
|
192
slsReceiverSoftware/src/CommandLineOptions.cpp
Normal file
192
slsReceiverSoftware/src/CommandLineOptions.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
|
||||
#include "CommandLineOptions.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/versionAPI.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/logger.h"
|
||||
|
||||
ParsedOptions parseCommandLine(AppType app, int argc, char* argv[]) {
|
||||
CommonOptions base;
|
||||
base.port = DEFAULT_TCP_RX_PORTNO;
|
||||
MultiReceiverOptions multi;
|
||||
FrameSyncOptions frame;
|
||||
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
|
||||
static struct option common_opts[] = {
|
||||
{"version", no_argument, nullptr, 'v'},
|
||||
{"port", required_argument, nullptr, 'p'},
|
||||
{"uid", required_argument, nullptr, 'u'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
static struct option single_opts[] = {
|
||||
{"rx_tcpport", required_argument, nullptr, 't'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
static struct option multi_opts[] = {
|
||||
{"callback", no_argument, nullptr, 'c'},
|
||||
{"num-receivers", required_argument, nullptr, 'n'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
static struct option frame_sync_opts[] = {
|
||||
{"print-headers", no_argument, nullptr, 'c'},
|
||||
{"num-receivers", required_argument, nullptr, 'n'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
std::vector<option> options;
|
||||
options.insert(options.end(), std::begin(common_opts), std::end(common_opts) - 1);
|
||||
|
||||
if (app == AppType::SingleReceiver) {
|
||||
options.insert(options.end(), std::begin(single_opts), std::end(single_opts) - 1);
|
||||
} else if (app == AppType::MultiReceiver) {
|
||||
options.insert(options.end(), std::begin(multi_opts), std::end(multi_opts) - 1);
|
||||
} else if (app == AppType::FrameSynchronizer) {
|
||||
options.insert(options.end(), std::begin(frame_sync_opts), std::end(frame_sync_opts) - 1);
|
||||
}
|
||||
|
||||
std::string optstring = "vp:u:h";
|
||||
if (app == AppType::SingleReceiver) {
|
||||
optstring += "t:";
|
||||
}
|
||||
if (app == AppType::MultiReceiver || app == AppType::FrameSynchronizer) {
|
||||
optstring += "cn:";
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, argv, optstring.c_str(), options.data(), &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
|
||||
case 'v':
|
||||
base.versionRequested = true;
|
||||
std::cout << getVersion(app) << std::endl;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
base.helpRequested = true;
|
||||
std::cout << getHelpMessage(app) << std::endl;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
LOG(sls::logWARNING) << "Deprecated option. Please use 'p' or '--port'.";
|
||||
[[fallthrough]];
|
||||
|
||||
case 'p':
|
||||
try {
|
||||
base.port = sls::StringTo<uint16_t>(optarg);
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Invalid port number parsed.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
try {
|
||||
base.userid = sls::StringTo<uint32_t>(optarg);
|
||||
if (base.userid != static_cast<uid_t>(-1)) {
|
||||
setEffectiveUID(base.userid);
|
||||
}
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Invalid uid parsed.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (app == AppType::MultiReceiver)
|
||||
multi.numReceivers = sls::StringTo<uint16_t>(optarg);
|
||||
else if (app == AppType::FrameSynchronizer)
|
||||
frame.numReceivers = sls::StringTo<uint16_t>(optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (app == AppType::MultiReceiver)
|
||||
multi.callbackEnabled = true;
|
||||
else if (app == AppType::FrameSynchronizer)
|
||||
frame.printHeaders = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw sls::RuntimeError("Invalid arguments." + getHelpMessage(app));
|
||||
}
|
||||
}
|
||||
// remaining arguments
|
||||
if (optind < argc) {
|
||||
throw(sls::RuntimeError(std::string("Invalid arguments\n") + getHelpMessage(app)));
|
||||
}
|
||||
|
||||
switch (app) {
|
||||
case AppType::SingleReceiver: return base;
|
||||
case AppType::MultiReceiver:
|
||||
static_cast<CommonOptions&>(multi) = base;
|
||||
return multi;
|
||||
case AppType::FrameSynchronizer:
|
||||
static_cast<CommonOptions&>(frame) = base;
|
||||
return frame;
|
||||
}
|
||||
|
||||
throw std::logic_error("Unknown AppType");
|
||||
}
|
||||
|
||||
void setEffectiveUID(uid_t uid) {
|
||||
if (geteuid() == uid) {
|
||||
LOG(sls::logINFO)
|
||||
<< "Process already has the same Effective UID " << uid;
|
||||
} else {
|
||||
if (seteuid(uid) != 0 || geteuid() != uid) {
|
||||
throw sls::RuntimeError("Could not set Effective UID");
|
||||
}
|
||||
LOG(sls::logINFO) << "Process Effective UID changed to " << uid;
|
||||
}
|
||||
}
|
||||
|
||||
std::string getTypeString(const AppType app) {
|
||||
switch (app) {
|
||||
case AppType::SingleReceiver: return "SingleReceiver";
|
||||
case AppType::MultiReceiver: return "MultiReceiver";
|
||||
case AppType::FrameSynchronizer: return "FrameSynchronizer";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string getVersion(AppType app) {
|
||||
return getTypeString(app) + " Version: " + APIRECEIVER;
|
||||
}
|
||||
|
||||
std::string getHelpMessage(AppType app) {
|
||||
switch (app) {
|
||||
case AppType::SingleReceiver:
|
||||
return std::string("\nUsage: ") + getTypeString(app) + " Options:\n" +
|
||||
"\t-v, --version : Version.\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";
|
||||
|
||||
case AppType::MultiReceiver:
|
||||
return std::string("\nUsage: " + getTypeString(app) + " Options:\n") +
|
||||
"\t-v, --version : Version.\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 for debugging. "
|
||||
"Disabled by default. \n" +
|
||||
"\t-u, --uid : Set effective user id if receiver started "
|
||||
"with privileges. \n\n";
|
||||
|
||||
case AppType::FrameSynchronizer:
|
||||
return std::string("\nUsage: " + getTypeString(app) + " Options:\n") +
|
||||
"\t-v, --version : Version.\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, --print-headers : Print callback headers for debugging. "
|
||||
"Disabled by default.\n" +
|
||||
"\t-u, --uid : Set effective user id if receiver started "
|
||||
"with privileges. \n\n";
|
||||
}
|
||||
}
|
42
slsReceiverSoftware/src/CommandLineOptions.h
Normal file
42
slsReceiverSoftware/src/CommandLineOptions.h
Normal file
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include <variant>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdint>
|
||||
|
||||
enum class AppType {
|
||||
MultiReceiver,
|
||||
SingleReceiver,
|
||||
FrameSynchronizer
|
||||
};
|
||||
|
||||
|
||||
struct CommonOptions {
|
||||
uint16_t port = -1;
|
||||
uid_t userid = -1;
|
||||
bool versionRequested = false;
|
||||
bool helpRequested = false;
|
||||
};
|
||||
|
||||
struct MultiReceiverOptions : CommonOptions {
|
||||
uint16_t numReceivers = 1;
|
||||
bool callbackEnabled = false;
|
||||
};
|
||||
|
||||
struct FrameSyncOptions : CommonOptions {
|
||||
uint16_t numReceivers = 1;
|
||||
bool printHeaders = false;
|
||||
};
|
||||
|
||||
using ParsedOptions = std::variant<CommonOptions, MultiReceiverOptions, FrameSyncOptions>;
|
||||
|
||||
ParsedOptions parseCommandLine(AppType app, int argc, char* argv[]);
|
||||
void setEffectiveUID(uid_t uid);
|
||||
std::string getVersion(AppType app);
|
||||
std::string getHelpMessage(AppType app);
|
||||
|
@ -240,7 +240,7 @@ int main(int argc, char *argv[]) {
|
||||
case 't':
|
||||
LOG(sls::logWARNING)
|
||||
<< "Deprecated option. Please use 'p' or '--port'.";
|
||||
//[[fallthrough]]; TODO: for when we update to c++17
|
||||
[[fallthrough]];
|
||||
case 'p':
|
||||
try {
|
||||
startPort = sls::StringTo<uint16_t>(optarg);
|
||||
|
@ -30,6 +30,7 @@ Receiver::~Receiver() = default;
|
||||
Receiver::Receiver(uint16_t port) {
|
||||
validatePortNumber(port);
|
||||
tcpipInterface = make_unique<ClientInterface>(port);
|
||||
if (port == 1957) throw RuntimeError("throwing for 1957");
|
||||
}
|
||||
|
||||
std::string Receiver::getReceiverVersion() {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/versionAPI.h"
|
||||
#include "CommandLineOptions.h"
|
||||
|
||||
#include <csignal> //SIGINT
|
||||
#include <getopt.h>
|
||||
@ -25,95 +26,15 @@ void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
uint16_t port = DEFAULT_TCP_RX_PORTNO;
|
||||
uid_t userid = -1;
|
||||
|
||||
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[] = {
|
||||
{"version", no_argument, nullptr, 'v'},
|
||||
{"rx_tcpport", required_argument, nullptr, 't'},
|
||||
{"port", required_argument, nullptr, 'p'},
|
||||
{"uid", required_argument, nullptr, 'u'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
int option_index = 0;
|
||||
int opt = 0;
|
||||
while (-1 != (opt = getopt_long(argc, argv, "vt:p:u:h", long_options,
|
||||
&option_index))) {
|
||||
|
||||
switch (opt) {
|
||||
|
||||
case 'v':
|
||||
std::cout << argv[0] << " Version: " << APIRECEIVER << std::endl;
|
||||
return (EXIT_SUCCESS);
|
||||
|
||||
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;
|
||||
return (EXIT_SUCCESS);
|
||||
|
||||
default:
|
||||
LOG(sls::logERROR) << help_message;
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// remaining arguments
|
||||
if (optind < argc) {
|
||||
LOG(sls::logERROR) << "Invalid arguments\n" << help_message;
|
||||
return (EXIT_FAILURE);
|
||||
auto opts = parseCommandLine(AppType::SingleReceiver, argc, argv);
|
||||
auto& o = std::get<CommonOptions>(opts);
|
||||
if (o.versionRequested || o.helpRequested) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
LOG(sls::logINFOBLUE) << "Current Process [ Tid: " << gettid() << " ]";
|
||||
LOG(sls::logINFO) << "Port: " << port;
|
||||
LOG(sls::logINFO) << "Port: " << o.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
|
||||
struct sigaction sa;
|
||||
@ -138,7 +59,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
sem_init(&semaphore, 1, 0);
|
||||
try {
|
||||
sls::Receiver r(port);
|
||||
sls::Receiver r(o.port);
|
||||
LOG(sls::logINFO) << "[ Press \'Ctrl+c\' to exit ]";
|
||||
sem_wait(&semaphore);
|
||||
sem_destroy(&semaphore);
|
||||
|
Reference in New Issue
Block a user