From 275acd2a60a2ffabff0f847e4cf76ed4edd09e26 Mon Sep 17 00:00:00 2001 From: Nate Bargmann Date: Fri, 22 Feb 2013 20:45:57 -0600 Subject: [PATCH] rotctl.c: Add options to save/read command history As commands from a previous session may not be desired, make reading the history file at rotctl start and writing to it at rotctl close optional by use of the -i/--read_history or -I/--save-history options. Compilation is conditional on having Readline and Readline History support detected at build system configuration time. History is stored in '$HOME/.rotctl_history' by default. An alternate path may be specified by setting the ROTCTL_HIST_DIR environment variable: $ ROTCTL_HIST_DIR=~/.rotctl rotctl -iI will temporarily set the history directory to /home/USER/.rotctl and create .rotctl_history if it does not exist. If the file cannot be read or written a warning message will be given on stderr. --- tests/rotctl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/tests/rotctl.c b/tests/rotctl.c index ba383d2f5..22bd27f20 100644 --- a/tests/rotctl.c +++ b/tests/rotctl.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #ifdef HAVE_LIBREADLINE @@ -48,6 +49,8 @@ extern char *readline (); #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY +# include +# define HST_SHRT_OPTS "iI" # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) @@ -57,7 +60,9 @@ extern void add_history (); extern int write_history (); extern int read_history (); # endif /* defined(HAVE_READLINE_HISTORY_H) */ - /* no history */ +#else +/* no history */ +#define HST_SHRT_OPTS "" #endif /* HAVE_READLINE_HISTORY */ @@ -88,6 +93,10 @@ static struct option long_options[] = {"set-conf", 1, 0, 'C'}, {"show-conf",0, 0, 'L'}, {"dump-caps",0, 0, 'u'}, +#ifdef HAVE_READLINE_HISTORY + {"read-history", 0, 0, 'i'}, + {"save-history", 0, 0, 'I'}, +#endif {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, @@ -120,6 +129,14 @@ int main (int argc, char *argv[]) int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; +#ifdef HAVE_READLINE_HISTORY + int rd_hist = 0; + int sv_hist = 0; + const char *hist_dir = NULL; + const char hist_file[] = "/.rotctl_history"; + char *hist_path = NULL; + struct stat hist_dir_stat; +#endif const char *rot_file=NULL; int serial_rate = 0; char conf_parms[MAXCONFLEN] = ""; @@ -128,7 +145,7 @@ int main (int argc, char *argv[]) int c; int option_index = 0; - c = getopt_long (argc, argv, SHORT_OPTIONS, + c = getopt_long (argc, argv, SHORT_OPTIONS HST_SHRT_OPTS, long_options, &option_index); if (c == -1) break; @@ -180,6 +197,14 @@ int main (int argc, char *argv[]) else send_cmd_term = optarg[0]; break; +#ifdef HAVE_READLINE_HISTORY + case 'i': + rd_hist++; + break; + case 'I': + sv_hist++; + break; +#endif case 'v': verbose++; break; @@ -268,9 +293,28 @@ int main (int argc, char *argv[]) #ifdef HAVE_LIBREADLINE if (interactive && prompt && have_rl) { - rl_readline_name = "rigctl"; + rl_readline_name = "rotctl"; #ifdef HAVE_READLINE_HISTORY using_history(); /* Initialize Readline History */ + + if (rd_hist || sv_hist) { + if (!(hist_dir = getenv("ROTCTL_HIST_DIR"))) + hist_dir = getenv("HOME"); + + if (((stat(hist_dir, &hist_dir_stat) == -1) && (errno == ENOENT)) + || !(S_ISDIR(hist_dir_stat.st_mode))) { + fprintf(stderr, "Warning: %s is not a directory!\n", hist_dir); + } + + hist_path = (char *)calloc((sizeof(char) * (strlen(hist_dir) + strlen(hist_file) + 1)), sizeof(char)); + + strncpy(hist_path, hist_dir, strlen(hist_dir)); + strncat(hist_path, hist_file, strlen(hist_file)); + } + + if (rd_hist && hist_path) + if (read_history(hist_path) == ENOENT) + fprintf(stderr, "Warning: Could not read history from %s\n", hist_path); #endif } #endif /* HAVE_LIBREADLINE */ @@ -282,6 +326,20 @@ int main (int argc, char *argv[]) } while (retcode == 0 || retcode == 2); +#ifdef HAVE_LIBREADLINE + if (interactive && prompt && have_rl) { +#ifdef HAVE_READLINE_HISTORY + if (sv_hist && hist_path) + if (write_history(hist_path) == ENOENT) + fprintf(stderr, "\nWarning: Could not write history to %s\n", hist_path); + + if ((rd_hist || sv_hist) && hist_path) { + free(hist_path); + hist_path = (char *)NULL; + } + } +#endif +#endif rot_close(my_rot); /* close port */ rot_cleanup(my_rot); /* if you care about memory */ @@ -303,6 +361,10 @@ void usage() " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" +#ifdef HAVE_READLINE_HISTORY + " -i, --read-history read prior interactive session history\n" + " -I, --save-history save current interactive session history\n" +#endif " -v, --verbose set verbose mode, cumulative\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n"