diff --git a/hkd.1 b/hkd.1 index 263f5a8..6b3ffd0 100644 --- a/hkd.1 +++ b/hkd.1 @@ -6,6 +6,7 @@ hkd \- simple HotKey Daemon .SH SYNOPSIS .SY hkd .OP \-v +.OP \-c file .YS .SH DESCRIPTION @@ -22,6 +23,10 @@ correctly. .IP \-v verbose, prints the internal pressed key buffer upon change acting as a crude keylogger :^) +.IP "\-c file" +override default configuration file location, instead using the specified +.I file +as the temporary config file .SH FILES The configuration files are searched in the following order: @@ -85,7 +90,9 @@ This is a valid config file example Known bugs are: .IP - Commands in the config file cannot be multiline -.IP - +.IP - +Invalid config files are not detected properly, or at least not explicitly +.IP - Child processes are waited at program exit possibly causing the process tree to hang as there is no real child process control diff --git a/hkd.c b/hkd.c index 17f279f..4af3f39 100644 --- a/hkd.c +++ b/hkd.c @@ -206,9 +206,12 @@ struct hotkey_list_e { }; struct hotkey_list_e *hotkey_list = NULL; -int dead = 0; // exit flag const char evdev_root_dir[] = "/dev/input/"; unsigned long hotkey_size_mask = 0; +char *ext_config_file = NULL; +/* Flags */ +int vflag = 0; +int dead = 0; // exit flag /* key buffer operations */ int key_buffer_add (struct key_buffer*, unsigned short); @@ -237,16 +240,18 @@ int main (int argc, char *argv[]) action.sa_handler = int_handler; sigaction(SIGINT, &action, NULL); - /* Verbose flag */ - int vflag = 0; - /* Parse command line arguments */ int opc; - while ((opc = getopt(argc, argv, "v")) != -1) { + while ((opc = getopt(argc, argv, "vc:")) != -1) { switch (opc) { case 'v': vflag = 1; - break; + case 'c': + ext_config_file = malloc(strlen(optarg) + 1); + if (!ext_config_file) + die("malloc in main()"); + strcpy(ext_config_file, optarg); + break; } } @@ -588,11 +593,10 @@ void hotkey_list_add (struct hotkey_list_e *head, struct key_buffer *kb, char *c void parse_config_file (void) { - wordexp_t result = {0}; FILE *fd; - for (int i = 0; i < array_size_const(config_paths); i++) { - switch (wordexp(config_paths[i], &result, 0)) { + if (ext_config_file) { + switch (wordexp(ext_config_file, &result, 0)) { case 0: break; case WRDE_NOSPACE: @@ -607,12 +611,34 @@ void parse_config_file (void) fd = fopen(result.we_wordv[0], "r"); wordfree(&result); - if (fd) - break; - perror(yellow("error opening config file")); + if (!fd) + die("error opening config file"); + free(ext_config_file); + ext_config_file = NULL; + } else { + for (int i = 0; i < array_size_const(config_paths); i++) { + switch (wordexp(config_paths[i], &result, 0)) { + case 0: + break; + case WRDE_NOSPACE: + /* If the error was WRDE_NOSPACE, + * then perhaps part of the result was allocated */ + wordfree (&result); + die("not enough space") + default: + /* Some other error */ + die("path not valid"); + } + + fd = fopen(result.we_wordv[0], "r"); + wordfree(&result); + if (fd) + break; + perror(yellow("error opening config file")); + } + if (!fd) + die("could not open any config files, check the log for more details"); } - if (!fd) - die("could not open any config files, check the log for more details"); struct key_buffer kb; for (int linenum = 1;; linenum++) {