aboutsummaryrefslogtreecommitdiffstats
path: root/tools/gpg-card.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-07-02 13:47:57 +0000
committerWerner Koch <[email protected]>2020-07-02 13:48:55 +0000
commitd70b8769c888f42896ae3ef4972bf82e9b5a0c32 (patch)
tree8a7334e5c82d69ec24a6b7c29e48971297a33f02 /tools/gpg-card.c
parentscd:nks: Fix certificate read problem with TCOS signature card v2. (diff)
downloadgnupg-d70b8769c888f42896ae3ef4972bf82e9b5a0c32.tar.gz
gnupg-d70b8769c888f42896ae3ef4972bf82e9b5a0c32.zip
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 <[email protected]>
Diffstat (limited to 'tools/gpg-card.c')
-rw-r--r--tools/gpg-card.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/tools/gpg-card.c b/tools/gpg-card.c
index 96b2bcf44..2fcc120fb 100644
--- a/tools/gpg-card.c
+++ b/tools/gpg-card.c
@@ -48,6 +48,8 @@
#define CONTROL_D ('D' - 'A' + 1)
+#define HISTORYNAME ".gpg-card_history"
+
/* Constants to identify the commands and options. */
enum opt_values
{
@@ -73,6 +75,7 @@ enum opt_values
oLCmessages,
oNoKeyLookup,
+ oNoHistory,
oDummy
};
@@ -99,6 +102,8 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_s (oLCmessages, "lc-messages","@"),
ARGPARSE_s_n (oNoKeyLookup,"no-key-lookup",
"use --no-key-lookup for \"list\""),
+ ARGPARSE_s_n (oNoHistory,"no-history",
+ "do not use the command history file"),
ARGPARSE_end ()
};
@@ -228,6 +233,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts)
case oLCmessages: opt.lc_messages = pargs->r.ret_str; break;
case oNoKeyLookup: opt.no_key_lookup = 1; break;
+ case oNoHistory: opt.no_history = 1; break;
default: pargs->err = 2; break;
}
@@ -315,6 +321,9 @@ main (int argc, char **argv)
}
opt.interactive = !cmdidx;
+ if (!opt.interactive)
+ opt.no_history = 1;
+
if (opt.interactive)
{
interactive_loop ();
@@ -3498,6 +3507,32 @@ cmd_apdu (card_info_t info, char *argstr)
}
+static gpg_error_t
+cmd_history (card_info_t info, char *argstr)
+{
+ int opt_list, opt_clear;
+
+ opt_list = has_option (argstr, "--list");
+ opt_clear = has_option (argstr, "--clear");
+
+ if (!info || !(opt_list || opt_clear))
+ return print_help
+ ("HISTORY --list\n"
+ " List the command history\n"
+ "HISTORY --clear\n"
+ " Clear the command history",
+ 0);
+
+ if (opt_list)
+ tty_printf ("Sorry, history listing not yet possible\n");
+
+ if (opt_clear)
+ tty_read_history (NULL, 0);
+
+ return 0;
+}
+
+
/* Data used by the command parser. This needs to be outside of the
@@ -3509,7 +3544,7 @@ enum cmdids
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSALUT, cmdCAFPR,
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP,
- cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU,
+ cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU, cmdHISTORY,
cmdINVCMD
};
@@ -3551,6 +3586,7 @@ static struct
{ "writekey", cmdWRITEKEY, N_("store a private key to a data object")},
{ "yubikey", cmdYUBIKEY, N_("Yubikey management commands")},
{ "apdu", cmdAPDU, NULL},
+ { "history", cmdHISTORY, N_("manage the command history")},
{ NULL, cmdINVCMD, NULL }
};
@@ -3679,6 +3715,7 @@ dispatch_command (card_info_t info, const char *orig_command)
case cmdUIF: err = cmd_uif (info, argstr); break;
case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break;
case cmdAPDU: err = cmd_apdu (info, argstr); break;
+ case cmdHISTORY: err = 0; break; /* Only used in interactive mode. */
case cmdINVCMD:
default:
@@ -3735,10 +3772,19 @@ interactive_loop (void)
card_info_t info = &info_buffer;
char *p;
int i;
+ const char *historyname = NULL;
/* In the interactive mode we do not want to print the program prefix. */
log_set_prefix (NULL, 0);
+ if (!opt.no_history)
+ {
+ historyname = make_filename (gnupg_homedir (), HISTORYNAME, NULL);
+ if (tty_read_history (historyname, 500))
+ log_info ("error reading '%s': %s\n",
+ historyname, gpg_strerror (gpg_error_from_syserror ()));
+ }
+
for (;;)
{
if (help_arg)
@@ -3818,7 +3864,7 @@ interactive_loop (void)
argstr = answer + strlen (answer);
if (!(cmd == cmdNOP || cmd == cmdQUIT || cmd == cmdHELP
- || cmd == cmdINVCMD))
+ || cmd == cmdHISTORY || cmd == cmdINVCMD))
{
/* If redisplay is set we know that there was an error reading
* the card. In this case we force a LIST command to retry. */
@@ -3926,6 +3972,7 @@ interactive_loop (void)
case cmdUIF: err = cmd_uif (info, argstr); break;
case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break;
case cmdAPDU: err = cmd_apdu (info, argstr); break;
+ case cmdHISTORY: err = cmd_history (info, argstr); break;
case cmdINVCMD:
default:
@@ -3962,7 +4009,12 @@ interactive_loop (void)
} /* End of main menu loop. */
leave:
+ if (historyname && tty_write_history (historyname))
+ log_info ("error writing '%s': %s\n",
+ historyname, gpg_strerror (gpg_error_from_syserror ()));
+
release_card_info (info);
+ xfree (historyname);
xfree (answer);
}