mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
Support a history file in gpg-card and gpg-connect-agent.
* common/gpgrlhelp.c (read_write_history): New. (gnupg_rl_initialize): Register new function. * common/ttyio.c (my_rl_rw_history): New var. (tty_private_set_rl_hooks): Add arg read_write_history. (tty_read_history): New. (tty_write_history): New. * tools/gpg-card.c (HISTORYNAME): New. (oNoHistory): New enum value. (opts): New option --no-history. (cmd_history): New. (cmds): New command "history". (interactive_loop): Read and save the history. * tools/gpg-connect-agent.c (HISTORYNAME): New. (opts): New option --no-history. (main): Read and save the history. New command /history. -- Yeah, finally we have stored history; I should have added this much earlier. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
07aef873eb
commit
d70b8769c8
9 changed files with 216 additions and 7 deletions
|
@ -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));
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue