From 5e004f989eb6c56d4ed3d562c9a112c78f533632 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 1 May 2022 16:20:47 +0100 Subject: [PATCH] Cleanup for PR#8 --- fxlink/fxlink.h | 9 +++++ fxlink/interactive.c | 93 +++++++++----------------------------------- fxlink/main.c | 74 ++++++++++++++++------------------- fxlink/ud2.c | 4 +- fxlink/util.c | 29 ++++++++++++++ fxlink/util.h | 16 ++++++++ 6 files changed, 106 insertions(+), 119 deletions(-) diff --git a/fxlink/fxlink.h b/fxlink/fxlink.h index 1d00369..d702c42 100644 --- a/fxlink/fxlink.h +++ b/fxlink/fxlink.h @@ -9,6 +9,15 @@ #include "filter.h" #include "util.h" +struct fxlink_options +{ + bool quiet; + bool force_unmount; + FILE *log_file; +}; + +extern struct fxlink_options options; + /* Main function for -l */ int main_list(filter_t *filter, delay_t *delay, libusb_context *context); diff --git a/fxlink/interactive.c b/fxlink/interactive.c index 109279e..752d971 100644 --- a/fxlink/interactive.c +++ b/fxlink/interactive.c @@ -12,45 +12,11 @@ #include #include #include -#include -#include -#include /* Video capture trackers, to avoid spamming terminal with messages */ static int last_message_was_video = 0; static int video_frame_count = 0; -/* external global variables coming from user arguments*/ -extern bool silentmode; -extern bool loginfile; -extern char *userlogfilename; - -static char *output_file(char const *path,char const *type,char const *suffix) -{ - char *filename = NULL; - int counter = 1; - - time_t time_raw; - struct tm time_bd; - time(&time_raw); - localtime_r(&time_raw, &time_bd); - - while(1) { - asprintf(&filename, "%s/fxlink-%.16s-%04d.%02d.%02d-%02dh%02d-%d.%s", - path, type, time_bd.tm_year + 1900, time_bd.tm_mon, - time_bd.tm_mday, time_bd.tm_hour, time_bd.tm_min, counter, suffix); - if(!filename) continue; - - /* Try to find a name for a file that doesn't exist */ - if(access(filename, F_OK) == -1) break; - - free(filename); - counter++; - } - - return filename; -} - static bool message_new(message_t *msg, usb_fxlink_header_t const *h) { int version_major = (h->version >> 8) & 0xff; @@ -67,13 +33,15 @@ static bool message_new(message_t *msg, usb_fxlink_header_t const *h) last_message_was_video = 0; } - if (!silentmode) fprintf(stderr, "New message (v%d.%d): application '%.16s', type '%.16s', " - "size %d bytes", version_major, version_minor, h->application, - h->type, h->size); + if(!options.quiet) { + fprintf(stderr, "New message (v%d.%d): application '%.16s', type " + "'%.16s', size %d bytes", version_major, version_minor, + h->application, h->type, h->size); + } if(last_message_was_video) fprintf(stderr, " [video frame #%d]", ++video_frame_count); - else + else if(!options.quiet) fprintf(stderr, "\n"); msg->output = malloc(h->size); @@ -95,7 +63,7 @@ static void message_finish(message_t *msg) if(!strncmp(msg->header.application, "fxlink", 16)) { if(!strncmp(msg->header.type, "image", 16)) { usb_fxlink_image_t *img = (void *)msg->output; - char *filename = output_file(path, msg->header.type, "png"); + char *filename = gen_file_name(path, msg->header.type, "png"); uint8_t **row_pointers = fxlink_protocol_decode_image(msg); fxlink_png_save(row_pointers, img->width, img->height, filename); @@ -108,41 +76,16 @@ static void message_finish(message_t *msg) } if(!strncmp(msg->header.type, "text", 16)) { - /* I choose the option of maintening a console ouptut even if log in file is set */ - /* this can be removed by uncommenting the following line */ - //if (!loginfile) - { - if (!silentmode) { - printf("------------------\n"); - fwrite(msg->output, 1, msg->header.size, stdout); - if(msg->output[msg->header.size - 1] != '\n') printf("\n"); - printf("------------------\n"); - } - else { - fwrite(msg->output, 1, msg->header.size, stdout); - if(msg->output[msg->header.size - 1] != '\n') printf("\n"); - } - } - if (loginfile) { - FILE *fp = fopen( userlogfilename, "a" ); - if(!fp) { - err("could not save to '%s': %m", userlogfilename); - return; - } - - if (!silentmode) { - fprintf(fp, "------------------\n"); - fwrite(msg->output, 1, msg->header.size, fp); - if(msg->output[msg->header.size - 1] != '\n') fprintf(fp, "\n"); - fprintf(fp, "------------------\n"); - } - else { - fwrite(msg->output, 1, msg->header.size, fp); - if(msg->output[msg->header.size - 1] != '\n') fprintf(fp, "\n"); - } - - fclose( fp ); + if(!options.quiet) + printf("------------------\n"); + fwrite(msg->output, 1, msg->header.size, stdout); + if(!options.quiet) { + if(msg->output[msg->header.size - 1] != '\n') printf("\n"); + printf("------------------\n"); } + + if(options.log_file) + fwrite(msg->output, 1, msg->header.size, options.log_file); return; } @@ -160,7 +103,7 @@ static void message_finish(message_t *msg) } /* Default to saving to a blob */ - char *filename = output_file(path, "blob", "bin"); + char *filename = gen_file_name(path, "blob", "bin"); FILE *fp = fopen(filename, "wb"); if(!fp) { err("could not save to '%s': %m", filename); @@ -188,7 +131,7 @@ static void message_output(message_t *msg, void *buffer, int size) if(msg->size_read >= msg->header.size) { bool is_video = !strncmp(msg->header.application, "fxlink", 16) && !strncmp(msg->header.type, "video", 16); - if(!is_video && !silentmode) + if(!is_video && !options.quiet) fprintf(stderr, "Successfully read %d bytes\n", msg->size_read); message_finish(msg); msg->valid = false; diff --git a/fxlink/main.c b/fxlink/main.c index 0c13fad..153c90a 100644 --- a/fxlink/main.c +++ b/fxlink/main.c @@ -11,8 +11,6 @@ #include #include #include -#include - int main_test(libusb_device *device, libusb_context *context); @@ -38,12 +36,11 @@ static const char *help_string = " connect. If DELAY is unspecified, wait indefinitely.\n" " -f FILTER Filter which calculators can be detected and used\n" " --libusb-log=LEVEL libusb log level: NONE, ERROR, WARNING, INFO, DEBUG\n" -" --fxlink-log=file Log text data into a logfile called file. If file is\n" -" missing, a generic filename will be created.\n" -" -q, --quiet Activate quiet mode, i.e. minimum verbosity and very\n" -" limited decorations (no extra messages).\n" -" -u, --unmount Force unmount disk at the end of operations, even if\n" -" not mounted here\n" +" --fxlink-log[=FILE] Log fxlink text messages into FILE (append mode). If\n" +" FILE is missing, a timestamp-name will be generated.\n" +" -q, --quiet Quite mode (minimum verbosity)\n" +" -u, --unmount In -s mode, always unmount the disk, even if it was\n" +" mounted by someone else\n" "\n" "Device filters:\n" " A device filter is a comma-separated list of properties that a device has\n" @@ -63,10 +60,8 @@ static const char *help_string = " serial_number=ID Matches this specific serial number. Requires write\n" " access to the device in libusb. [libusb, udisks2]\n"; -bool silentmode = false; -bool loginfile = false; -char *userlogfilename = NULL; -bool forceunmount = false; +/* Global options */ +struct fxlink_options options; int main(int argc, char **argv) { @@ -74,22 +69,25 @@ int main(int argc, char **argv) delay_t delay = delay_seconds(0); filter_t *filter = NULL; + options.quiet = false; + options.force_unmount = false; + options.log_file = NULL; + //--- // Command-line argument parsing //--- - enum { LIBUSB_LOG=1 }; - enum { LOG_IN_FILE=2 }; + enum { LIBUSB_LOG=1, LOG_TO_FILE=2 }; const struct option longs[] = { - { "help", no_argument, NULL, 'h' }, - { "list", no_argument, NULL, 'l' }, - { "blocks", no_argument, NULL, 'b' }, - { "send", no_argument, NULL, 's' }, - { "interactive", no_argument, NULL, 'i' }, + { "help", no_argument, NULL, 'h' }, + { "list", no_argument, NULL, 'l' }, + { "blocks", no_argument, NULL, 'b' }, + { "send", no_argument, NULL, 's' }, + { "interactive", no_argument, NULL, 'i' }, { "libusb-log", required_argument, NULL, LIBUSB_LOG }, - { "quiet", no_argument, NULL, 'q' }, - { "fxlink-log", optional_argument, NULL, LOG_IN_FILE }, - { "unmount", no_argument, NULL, 'u' }, + { "quiet", no_argument, NULL, 'q' }, + { "fxlink-log", optional_argument, NULL, LOG_TO_FILE }, + { "unmount", no_argument, NULL, 'u' }, }; while(option >= 0 && option != '?') @@ -119,29 +117,20 @@ int main(int argc, char **argv) "NONE, ERROR, WARNING, INFO or DEBUG\n", optarg); break; case 'q': - printf("Enabling quiet mode (i.e. minimum verbosity)\n"); - silentmode = true; + options.quiet = true; break; case 'u': - printf("Force unmount the disk at the end.\n"); - forceunmount = true; + options.force_unmount = true; break; - case LOG_IN_FILE: - printf("Enabling Log in File Mode\n"); - loginfile = true; - if (optarg) { - asprintf( &userlogfilename, "%s", optarg ); - } + case LOG_TO_FILE: + if(optarg) + options.log_file = fopen(optarg, "a"); else { - time_t time_raw; - struct tm time_bd; - time(&time_raw); - localtime_r(&time_raw, &time_bd); - asprintf( &userlogfilename, "./fxlink-logfile-%04d.%02d.%02d-%02dh%02d.log", - time_bd.tm_year + 1900, time_bd.tm_mon + 1, time_bd.tm_mday, - time_bd.tm_hour, time_bd.tm_min ); + char *name = gen_file_name(".", "logfile", "log"); + printf("--fxlink-log will output in '%s'\n", name); + options.log_file = fopen(name, "a"); + free(name); } - printf("Log File will be : %s \n", userlogfilename ); break; case 'w': if(!optarg) { @@ -212,7 +201,10 @@ int main(int argc, char **argv) rc = main_interactive(filter, &delay, context); } - if(context) libusb_exit(context); + if(context) + libusb_exit(context); + if(options.log_file) + fclose(options.log_file); return rc; } diff --git a/fxlink/ud2.c b/fxlink/ud2.c index 765d4e4..ddd4a2e 100644 --- a/fxlink/ud2.c +++ b/fxlink/ud2.c @@ -16,8 +16,6 @@ // UDisks2 utility functions //--- -extern bool forceunmount; - int ud2_start(UDisksClient **udc_ptr, UDisksManager **udm_ptr) { GError *error = NULL; @@ -360,7 +358,7 @@ int main_send(filter_t *filter, delay_t *delay, char **files) } /* Unmount the filesystem and eject the device if we mounted it */ - if(mounted_here || forceunmount) { + if(mounted_here || options.force_unmount) { GVariant *args = g_variant_new("a{sv}", NULL); udisks_filesystem_call_unmount_sync(fs, args, NULL, &error); if(error) err("while unmounting %s: %s", dev, error->message); diff --git a/fxlink/util.c b/fxlink/util.c index db8550f..b7850d8 100644 --- a/fxlink/util.c +++ b/fxlink/util.c @@ -1,6 +1,35 @@ #include "util.h" +#include +#include #include #include +#include + +char *gen_file_name(char const *path, char const *name, char const *suffix) +{ + char *filename = NULL; + int counter = 1; + + time_t time_raw; + struct tm time_bd; + time(&time_raw); + localtime_r(&time_raw, &time_bd); + + while(1) { + asprintf(&filename, "%s/fxlink-%.16s-%04d.%02d.%02d-%02dh%02d-%d.%s", + path, name, time_bd.tm_year + 1900, time_bd.tm_mon + 1, + time_bd.tm_mday, time_bd.tm_hour, time_bd.tm_min, counter, suffix); + if(!filename) continue; + + /* Try to find a name for a file that doesn't exist */ + if(access(filename, F_OK) == -1) break; + + free(filename); + counter++; + } + + return filename; +} delay_t delay_none(void) { diff --git a/fxlink/util.h b/fxlink/util.h index 97dbabc..d9c4a83 100644 --- a/fxlink/util.h +++ b/fxlink/util.h @@ -29,6 +29,22 @@ fprintf(stderr, "error: " fmt ": %s\n", ##__VA_ARGS__, \ libusb_strerror(rc)) +//--- +// File name generation +//--- + +/* gen_file_name(): Generate a unique timestamp-based file name + + This function generates a unique name for a file to be stored in [path], + with the specified [name] component, and the provided [suffix]. The + generated path looks like + + /fxlink--2021.05.09-19h23-1. + + with the [-1] suffix being chosen as to avoid overriding extisting files. + Returns a newly-allocated string to be freed after use. */ +char *gen_file_name(char const *path, char const *name, char const *suffix); + //--- // Delay //---