diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/common-defs.h | 3 | ||||
-rw-r--r-- | common/gpgrlhelp.c | 71 | ||||
-rw-r--r-- | common/ttyio.c | 39 | ||||
-rw-r--r-- | common/ttyio.h | 2 |
4 files changed, 110 insertions, 5 deletions
diff --git a/common/common-defs.h b/common/common-defs.h index b1928e611..cad5405d0 100644 --- a/common/common-defs.h +++ b/common/common-defs.h @@ -47,7 +47,8 @@ void tty_private_set_rl_hooks (void (*init_stream) (FILE *), void (*inhibit_completion) (int), void (*cleanup_after_signal) (void), char *(*readline_fun) (const char*), - void (*add_history_fun) (const char*)); + void (*add_history_fun) (const char*), + int (*rw_history_fun)(const char *, int, int)); diff --git a/common/gpgrlhelp.c b/common/gpgrlhelp.c index 680d9998b..fd3a48f8a 100644 --- a/common/gpgrlhelp.c +++ b/common/gpgrlhelp.c @@ -77,11 +77,77 @@ init_stream (FILE *fp) rl_inhibit_completion = 1; } + +/* Read or write the history to or from the file FILENAME. The + * behaviour depends on the flag WRITE_MODE: + * + * In read mode (WRITE_MODE is false) these semantics are used: + * + * If NLINES is positive only this number of lines are read from the + * history and the history is always limited to that number of + * lines. A negative value for NLINES is undefined. + * + * If FILENAME is NULL the current history is cleared. If NLINES is + * positive the number of lines stored in the history is limited to + * that number. A negative value for NLINES is undefined. + * + * If WRITE_MODE is true these semantics are used: + * + * If NLINES is negative the history and the history file are + * cleared; if it is zero the entire history is written to the file; + * if it is positive the history is written to the file and the file + * is truncated to this number of lines. + * + * If FILENAME is NULL no file operations are done but if NLINES is + * negative the entire history is cleared. + * + * On success 0 is returned; on error -1 is returned and ERRNO is set. + */ +static int +read_write_history (const char *filename, int write_mode, int nlines) +{ + int rc; + + if (write_mode) + { + if (nlines < 0) + clear_history (); + rc = filename? write_history (filename) : 0; + if (!rc && filename && nlines > 0) + rc = history_truncate_file (filename, nlines); + if (rc) + { + gpg_err_set_errno (rc); + return -1; + } + } + else + { + clear_history (); + if (filename) + { + if (nlines) + rc = read_history_range (filename, 0, nlines); + else + rc = read_history (filename); + if (rc) + { + gpg_err_set_errno (rc); + return -1; + } + } + if (nlines > 0) + stifle_history (nlines); + } + + return 0; +} + #endif /*HAVE_LIBREADLINE*/ /* Initialize our readline code. This should be called as early as - possible as it is actually a constructur. */ + * possible as it is actually a constructor. */ void gnupg_rl_initialize (void) { @@ -91,7 +157,8 @@ gnupg_rl_initialize (void) inhibit_completion, cleanup_after_signal, readline, - add_history); + add_history, + read_write_history); rl_readline_name = GNUPG_NAME; #endif } diff --git a/common/ttyio.c b/common/ttyio.c index 4c095bc03..a27c095cf 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -101,7 +101,7 @@ static void (*my_rl_cleanup_after_signal) (void); static void (*my_rl_init_stream) (FILE *); static char *(*my_rl_readline) (const char*); static void (*my_rl_add_history) (const char*); - +static int (*my_rl_rw_history)(const char *, int, int); /* This is a wrapper around ttyname so that we can use it even when the standard streams are redirected. It figures the name out the @@ -703,7 +703,8 @@ tty_private_set_rl_hooks (void (*init_stream) (FILE *), void (*inhibit_completion) (int), void (*cleanup_after_signal) (void), char *(*readline_fun) (const char*), - void (*add_history_fun) (const char*)) + void (*add_history_fun) (const char*), + int (*rw_history_fun)(const char *, int, int)) { my_rl_init_stream = init_stream; my_rl_set_completer = set_completer; @@ -711,6 +712,40 @@ tty_private_set_rl_hooks (void (*init_stream) (FILE *), my_rl_cleanup_after_signal = cleanup_after_signal; my_rl_readline = readline_fun; my_rl_add_history = add_history_fun; + my_rl_rw_history = rw_history_fun; +} + + +/* Read the history from FILENAME or limit the size of the history. + * If FILENAME is NULL and NLINES is zero the current history is + * cleared. Returns 0 on success or -1 on error and sets ERRNO. No + * error is return if readline support is not available. */ +int +tty_read_history (const char *filename, int nlines) +{ + int rc; + + if (!my_rl_rw_history) + return 0; + + rc = my_rl_rw_history (filename, 0, nlines); + if (rc && gpg_err_code_from_syserror () == GPG_ERR_ENOENT) + rc = 0; + + return rc; +} + + +/* Write the current history to the file FILENAME. Returns 0 on + * success or -1 on error and sets ERRNO. No error is return if + * readline support is not available. */ +int +tty_write_history (const char *filename) +{ + if (!my_rl_rw_history) + return 0; + + return my_rl_rw_history (filename, 1, 0); } diff --git a/common/ttyio.h b/common/ttyio.h index 5bff82fbb..46bcc2ffc 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -66,6 +66,8 @@ void tty_disable_completion (void); #define tty_enable_completion(x) #define tty_disable_completion() #endif +int tty_read_history (const char *filename, int nlines); +int tty_write_history (const char *filename); void tty_cleanup_after_signal (void); void tty_cleanup_rl_after_signal (void); |