From 24c97f5b1fe1b666a3c53e8d36b0bea0ede307e0 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 8 Jul 2023 16:33:24 +0200 Subject: Implement command output scanning --- command.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ nfcommander.c | 1 - nfcommander.h | 1 + 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); -- cgit v1.2.3