From 9b476a67b5e7b79ca37a1c3d4f065a997368d0f7 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 5 May 2024 15:08:00 +0200 Subject: [PATCH] allow commands being injected as well --- src/ebusd/main.cpp | 32 ++++++++++++++++++++++---------- src/ebusd/main.h | 6 +++--- src/ebusd/main_args.cpp | 14 +++++--------- src/ebusd/mainloop.h | 3 ++- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index d362e239..b97b29bd 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -248,13 +248,6 @@ int main(int argc, char* argv[], char* envp[]) { return EINVAL; } - if (s_opt.injectCount > 0) { - if (!s_opt.injectMessages && !(s_opt.checkConfig && s_opt.scanConfig)) { - fprintf(stderr, "invalid inject arguments"); - return EINVAL; - } - } - if (s_opt.logAreas != -1 || s_opt.logLevel != ll_COUNT) { setFacilitiesLogLevel(1 << lf_COUNT, ll_none); setFacilitiesLogLevel(s_opt.logAreas, s_opt.logLevel); @@ -473,14 +466,33 @@ int main(int argc, char* argv[], char* envp[]) { s_scanHelper->loadConfigFiles(!s_opt.scanConfig); // start the MainLoop - if (s_opt.injectMessages) { + if (s_opt.injectCommands) { int scanAdrCount = 0; bool scanAddresses[256] = {}; for (int arg_index = argc - s_opt.injectCount; arg_index < argc; arg_index++) { - // add each passed message + string arg = argv[arg_index]; + if (arg.empty()) { + continue; + } + if (arg.find_first_of(' ') != string::npos || arg.find_first_of('/') == string::npos) { + RequestImpl req(false); + req.add(argv[arg_index]); + bool connected; + RequestMode reqMode; + string user; + bool reload; + ostringstream ostream; + result_t ret = s_mainLoop->decodeRequest(&req, &connected, &reqMode, &user, &reload, &ostream); + if (ret != RESULT_OK) { + string output = ostream.str(); + logError(lf_main, "executing command %s failed: %d", argv[arg_index], output.c_str()); + } + continue; + } + // old style inject message MasterSymbolString master; SlaveSymbolString slave; - if (!s_scanHelper->parseMessage(argv[arg_index], false, &master, &slave)) { + if (!s_scanHelper->parseMessage(arg, false, &master, &slave)) { continue; } s_protocol->injectMessage(master, slave); diff --git a/src/ebusd/main.h b/src/ebusd/main.h index 0747f255..0137514f 100755 --- a/src/ebusd/main.h +++ b/src/ebusd/main.h @@ -60,9 +60,9 @@ typedef struct options { OutputFormat dumpConfig; //!< dump config files, then stop const char* dumpConfigTo; //!< file to dump config to unsigned int pollInterval; //!< poll interval in seconds, 0 to disable [5] - bool injectMessages; //!< inject remaining arguments as already seen messages - bool stopAfterInject; //!< only inject messages once, then stop - int injectCount; //!< number of message arguments to inject, or 0 + bool injectCommands; //!< inject remaining arguments as commands or already seen messages + bool stopAfterInject; //!< only inject arguments once, then stop + int injectCount; //!< number of arguments to inject, or 0 #ifdef HAVE_SSL const char* caFile; //!< the CA file to use (uses defaults if neither caFile nor caPath are set), or "#" for insecure const char* caPath; //!< the path with CA files to use (uses defaults if neither caFile nor caPath are set) diff --git a/src/ebusd/main_args.cpp b/src/ebusd/main_args.cpp index 78f6590f..6c92d73c 100755 --- a/src/ebusd/main_args.cpp +++ b/src/ebusd/main_args.cpp @@ -54,7 +54,7 @@ static const options_t s_default_opt = { .dumpConfig = OF_NONE, .dumpConfigTo = nullptr, .pollInterval = 5, - .injectMessages = false, + .injectCommands = false, .stopAfterInject = false, .injectCount = 0, #ifdef HAVE_SSL @@ -170,9 +170,9 @@ static const argDef argDefs[] = { "Check and dump config files in FORMAT (\"json\" or \"csv\"), then stop"}, {"dumpconfigto", O_DMPCTO, "FILE", 0, "Dump config files to FILE"}, {"pollinterval", O_POLINT, "SEC", 0, "Poll for data every SEC seconds (0=disable) [5]"}, - {"inject", 'i', "stop", af_optional, "Inject remaining arguments as already seen messages (e.g. " + {"inject", 'i', "stop", af_optional, "Inject remaining arguments as commands or already seen messages (e.g. " "\"FF08070400/0AB5454850303003277201\"), optionally stop afterwards"}, - {nullptr, O_INJPOS, "INJECT", af_optional|af_multiple, "Message(s) to inject (if --inject was given)"}, + {nullptr, O_INJPOS, "INJECT", af_optional|af_multiple, "Commands and/or messages to inject (if --inject was given)"}, #ifdef HAVE_SSL {"cafile", O_CAFILE, "FILE", 0, "Use CA FILE for checking certificates (uses defaults," " \"#\" for insecure)"}, @@ -343,7 +343,7 @@ static int parse_opt(int key, char *arg, const argParseOpt *parseOpt, struct opt opt->pollInterval = value; break; case 'i': // --inject[=stop] - opt->injectMessages = true; + opt->injectCommands = true; opt->stopAfterInject = arg && strcmp("stop", arg) == 0; break; #ifdef HAVE_SSL @@ -595,7 +595,7 @@ static int parse_opt(int key, char *arg, const argParseOpt *parseOpt, struct opt default: if (key >= O_INJPOS) { // INJECT - if (!opt->injectMessages || !arg || !arg[0]) { + if (!opt->injectCommands || !arg || !arg[0]) { return ESRCH; } opt->injectCount++; @@ -614,10 +614,6 @@ static int parse_opt(int key, char *arg, const argParseOpt *parseOpt, struct opt argParseError(parseOpt, "scanconfig without polling may lead to invalid files included for certain products!"); return EINVAL; } - if (opt->injectMessages && (opt->checkConfig || opt->dumpConfig)) { - argParseError(parseOpt, "cannot combine inject with checkconfig/dumpconfig"); - return EINVAL; - } return 0; } diff --git a/src/ebusd/mainloop.h b/src/ebusd/mainloop.h index 599df1e7..856ecfb6 100644 --- a/src/ebusd/mainloop.h +++ b/src/ebusd/mainloop.h @@ -128,7 +128,7 @@ class MainLoop : public Thread { void run() override; - private: + public: /** * Decode and execute client request. * @param req the @a Request to decode. @@ -142,6 +142,7 @@ class MainLoop : public Thread { result_t decodeRequest(Request* req, bool* connected, RequestMode* reqMode, string* user, bool* reload, ostringstream* ostream); + private: /** * Parse the hex master message from the remaining arguments. * @param args the arguments passed to the command.