summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2023-07-08 16:33:24 +0200
committercbdev <cb@cbcdn.com>2023-07-08 16:33:24 +0200
commit24c97f5b1fe1b666a3c53e8d36b0bea0ede307e0 (patch)
tree23d8c9b846402ea47cfcb67180db67b18c8c6f5f
parent7891f4f491873e9063c02d4d4fafbd51242b4a43 (diff)
downloadnfcommander-24c97f5b1fe1b666a3c53e8d36b0bea0ede307e0.tar.gz
nfcommander-24c97f5b1fe1b666a3c53e8d36b0bea0ede307e0.tar.bz2
nfcommander-24c97f5b1fe1b666a3c53e8d36b0bea0ede307e0.zip
Implement command output scanning
-rw-r--r--command.c75
-rw-r--r--nfcommander.c1
-rw-r--r--nfcommander.h1
3 files changed, 69 insertions, 8 deletions
diff --git a/command.c b/command.c
index 12e24c6..b222997 100644
--- a/command.c
+++ b/command.c
@@ -15,13 +15,16 @@
#define COMMAND_ALIVE 1
#define COMMAND_STOPPED 2
-#define INPUT_BUFFER_MAX 4096
+#define INPUT_BUFFER_MAX 2048
typedef struct {
uint8_t flags;
pid_t child;
int iopipe[2];
nfc_tag_info_t* tag;
+
+ size_t input_head;
+ uint8_t input[INPUT_BUFFER_MAX];
} command_t;
static size_t ncommands = 0;
@@ -29,16 +32,61 @@ static command_t* commands = NULL;
//TODO timeouting / SIGKILL
+static int command_scan_input(command_t* cmd, size_t bytes){
+ size_t n = 0;
+
+ //check for line ending
+ for(n = 0; n < bytes; n++){
+ if(cmd->input[cmd->input_head + n] == '\r' ||
+ cmd->input[cmd->input_head + n] == '\n'){
+ //terminate string
+ cmd->input[cmd->input_head + n] = 0;
+ //handle line
+ if(!strncmp((char*) cmd->input, "UPDATE ", strlen("UPDATE "))){
+ printf("Update: %s\n", cmd->input + 7);
+ }
+
+ //find beginning of next line
+ n++;
+ for(; n < bytes && !isprint(cmd->input[cmd->input_head + n]); n++){
+ }
+
+ if(n == bytes){
+ cmd->input_head = 0;
+ return 0;
+ }
+
+ //move back
+ memmove(cmd->input, cmd->input + cmd->input_head + n, bytes - n);
+ cmd->input_head = 0;
+
+ //try to find another sentence
+ return command_scan_input(cmd, bytes - n);
+ }
+ }
+
+ if(cmd->input_head + bytes > INPUT_BUFFER_MAX - 10){
+ //line too long - ignore it entirely until the next linebreak
+ cmd->input_head = 1;
+ cmd->input[0] = 0; //fail any test for UPDATE
+ return 0;
+ }
+
+ //no newline
+ cmd->input_head += bytes;
+ return 0;
+}
+
int command_handle(int fd){
size_t n = 0;
ssize_t bytes;
- uint8_t input_buffer[INPUT_BUFFER_MAX];
//find matching command
for(n = 0; n < ncommands; n++){
if(commands[n].flags & COMMAND_ALIVE
&& fd == commands[n].iopipe[0]){
- bytes = read(fd, input_buffer, sizeof(input_buffer) - 1);
+ bytes = read(fd, commands[n].input + commands[n].input_head,
+ sizeof(commands[n].input) - commands[n].input_head - 1);
if(bytes < 0){
perror("cmd/recv");
}
@@ -47,11 +95,11 @@ int command_handle(int fd){
core_manage_fd(commands[n].iopipe[0], 0, system_command);
close(commands[n].iopipe[0]);
commands[n].iopipe[0] = -1;
+ commands[n].input_head = 0;
}
else{
- //TODO handle
- input_buffer[bytes] = 0;
- printf("%d bytes from command %lu: %s\n", bytes, n, input_buffer);
+ //printf("%ld bytes from command %lu\n", bytes, n);
+ command_scan_input(commands + n, bytes);
}
return 0;
}
@@ -96,6 +144,8 @@ void command_reap(){
static int command_spawn(command_t* cmd, char* command_name, char* command_static, size_t arg_length){
char* workdir = config_get("command", "chdir");
char* handler = config_get("command", "handler");
+ size_t bytes;
+ char tag_uid[12] = "";
printf("Starting command %s, static %s\n", command_name, command_static);
if(pipe(cmd->iopipe)){
@@ -127,7 +177,17 @@ static int command_spawn(command_t* cmd, char* command_name, char* command_stati
}
close(cmd->iopipe[1]);
- //TODO set environment
+ //set environment
+ bytes = snprintf(tag_uid, sizeof(tag_uid), "%02X%02X%02X%02X",
+ cmd->tag->uid[0], cmd->tag->uid[1],
+ cmd->tag->uid[2], cmd->tag->uid[3]);
+ if(cmd->tag->uid_length > 4){
+ bytes += snprintf(tag_uid + bytes, sizeof(tag_uid) - bytes, "%02X%02X%02X",
+ cmd->tag->uid[4], cmd->tag->uid[5],
+ cmd->tag->uid[6]);
+ }
+ setenv("TAG_UID", tag_uid, 1);
+ //DYNAMIC_SIZE
//run actual command
if(handler){
@@ -209,6 +269,7 @@ int command_start(nfc_tag_info_t* info){
}
commands[p].tag = info;
+ commands[p].input_head = 0;
if(command_spawn(commands + p, (char*) command_name, (char*) command_static, arg_length)){
//TODO clean up and free command instance
}
diff --git a/nfcommander.c b/nfcommander.c
index 66838aa..125b237 100644
--- a/nfcommander.c
+++ b/nfcommander.c
@@ -86,7 +86,6 @@ int main(int argc, char** argv){
//start reader api
if(reader_init()){
- printf("Failed to start reader\n");
//TODO cleanup
return EXIT_FAILURE;
}
diff --git a/nfcommander.h b/nfcommander.h
index 0c24236..d380f78 100644
--- a/nfcommander.h
+++ b/nfcommander.h
@@ -34,6 +34,7 @@ typedef struct {
uint8_t* static_data;
size_t dynamic_length;
uint8_t* dynamic_data;
+ size_t dynamic_max;
} nfc_tag_info_t;
typedef int (*reader_plugin_init)(void);