summaryrefslogtreecommitdiffstats
path: root/src/detection/command/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/detection/command/command.c')
-rw-r--r--src/detection/command/command.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/detection/command/command.c b/src/detection/command/command.c
new file mode 100644
index 0000000..28c6f4b
--- /dev/null
+++ b/src/detection/command/command.c
@@ -0,0 +1,58 @@
+#include "detection/command/command.h"
+#include "common/processing.h"
+#include "common/FFstrbuf.h"
+
+typedef struct FFCommandResultBundle {
+ FFProcessHandle handle;
+ const char* error;
+} FFCommandResultBundle;
+
+// FIFO, non-thread-safe list of running commands
+static FFlist commandQueue;
+
+static const char* spawnProcess(FFCommandOptions* options, FFProcessHandle* handle) {
+ if (options->text.length == 0) {
+ return "No command text specified";
+ }
+
+ return ffProcessSpawn(options->param.length ? (char* const[]) {
+ options->shell.chars,
+ options->param.chars,
+ options->text.chars,
+ NULL }
+ : (char* const[]) { options->shell.chars, options->text.chars, NULL },
+ options->useStdErr,
+ handle);
+}
+
+bool ffPrepareCommand(FFCommandOptions* options) {
+ if (!options->parallel) {
+ return false;
+ }
+
+ FFCommandResultBundle* bundle = FF_LIST_ADD(FFCommandResultBundle, commandQueue);
+ bundle->error = spawnProcess(options, &bundle->handle);
+
+ return true;
+}
+
+const char* ffDetectCommand(FFCommandOptions* options, FFstrbuf* result) {
+ FFCommandResultBundle bundle = {};
+ if (!options->parallel) {
+ bundle.error = spawnProcess(options, &bundle.handle);
+ } else if (!FF_LIST_SHIFT(commandQueue, &bundle)) {
+ return "[BUG] command queue is empty";
+ }
+
+ if (bundle.error) {
+ return bundle.error;
+ }
+
+ bundle.error = ffProcessReadOutput(&bundle.handle, result);
+ if (bundle.error) {
+ return bundle.error;
+ }
+
+ ffStrbufTrimRightSpace(result);
+ return NULL;
+}