aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/common-defs.h3
-rw-r--r--common/gpgrlhelp.c71
-rw-r--r--common/ttyio.c39
-rw-r--r--common/ttyio.h2
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);