mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-21 10:09:57 +01:00
gpgsm: Terminate key listing on output write error.
* sm/keylist.c (list_internal_keys): Detect write errors to the output stream. * sm/server.c (any_failure_printed): New var. (gpgsm_status2): Handle new var. Move statusfp init to ... (gpgsm_init_statusfp): new function. (gpgsm_exit_failure_status): New. * sm/gpgsm.c (main): Explicit statusfp init. (gpgsm_exit): Print failure status on error. -- Test by using gpgsm -k >/dev/full gpgsm -k --wit-colons >/dev/full and also by redirecting to a file on a small partition. GnuPG-bug-id: 6185
This commit is contained in:
parent
40707c8bff
commit
18081e2ecf
10
sm/gpgsm.c
10
sm/gpgsm.c
@ -1803,6 +1803,10 @@ main ( int argc, char **argv)
|
|||||||
gnupg_inhibit_set_foregound_window (1);
|
gnupg_inhibit_set_foregound_window (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Better make sure that we have a statusfp so that a failure status
|
||||||
|
* in gpgsm_exit can work even w/o any preeding status messages. */
|
||||||
|
gpgsm_init_statusfp (&ctrl);
|
||||||
|
|
||||||
/* Add default keybox. */
|
/* Add default keybox. */
|
||||||
if (!nrings && default_keyring && !opt.use_keyboxd)
|
if (!nrings && default_keyring && !opt.use_keyboxd)
|
||||||
{
|
{
|
||||||
@ -2356,6 +2360,12 @@ gpgsm_exit (int rc)
|
|||||||
else if (opt.assert_signer_list && !assert_signer_true)
|
else if (opt.assert_signer_list && !assert_signer_true)
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
||||||
|
/* If we had an error but not printed an error message, do it now.
|
||||||
|
* Note that the function will never print a second failure status
|
||||||
|
* line. */
|
||||||
|
if (rc)
|
||||||
|
gpgsm_exit_failure_status ();
|
||||||
|
|
||||||
gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
|
gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
|
||||||
if (opt.debug & DBG_MEMSTAT_VALUE)
|
if (opt.debug & DBG_MEMSTAT_VALUE)
|
||||||
{
|
{
|
||||||
|
@ -355,12 +355,14 @@ int gpgsm_parse_validation_model (const char *model);
|
|||||||
|
|
||||||
/*-- server.c --*/
|
/*-- server.c --*/
|
||||||
void gpgsm_server (certlist_t default_recplist);
|
void gpgsm_server (certlist_t default_recplist);
|
||||||
|
void gpgsm_init_statusfp (ctrl_t ctrl);
|
||||||
gpg_error_t gpgsm_status (ctrl_t ctrl, int no, const char *text);
|
gpg_error_t gpgsm_status (ctrl_t ctrl, int no, const char *text);
|
||||||
gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0);
|
gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0);
|
||||||
gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
|
gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
|
||||||
gpg_err_code_t ec);
|
gpg_err_code_t ec);
|
||||||
gpg_error_t gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text,
|
gpg_error_t gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text,
|
||||||
gpg_error_t err);
|
gpg_error_t err);
|
||||||
|
void gpgsm_exit_failure_status (void);
|
||||||
gpg_error_t gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total);
|
gpg_error_t gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total);
|
||||||
gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl,
|
gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl,
|
||||||
const unsigned char *line);
|
const unsigned char *line);
|
||||||
|
15
sm/keylist.c
15
sm/keylist.c
@ -1663,6 +1663,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
|
|||||||
|
|
||||||
resname = keydb_get_resource_name (hd);
|
resname = keydb_get_resource_name (hd);
|
||||||
|
|
||||||
|
es_clearerr (fp);
|
||||||
if (lastresname != resname )
|
if (lastresname != resname )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1716,6 +1717,20 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
|
|||||||
ksba_cert_release (lastcert);
|
ksba_cert_release (lastcert);
|
||||||
lastcert = cert;
|
lastcert = cert;
|
||||||
cert = NULL;
|
cert = NULL;
|
||||||
|
|
||||||
|
if (es_ferror (fp))
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
/* For faster key listings we flush the output after each cert
|
||||||
|
* only if we list secret keys. */
|
||||||
|
if ((mode & 2) && es_fflush (fp) && !rc)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error (_("error writing to output: %s\n"), gpg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
|
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
62
sm/server.c
62
sm/server.c
@ -37,6 +37,11 @@
|
|||||||
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
|
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
|
||||||
|
|
||||||
|
|
||||||
|
/* Used to track whether we printed any FAILURE status in non-server
|
||||||
|
* mode. */
|
||||||
|
static int any_failure_printed;
|
||||||
|
|
||||||
|
|
||||||
/* The filepointer for status message used in non-server mode */
|
/* The filepointer for status message used in non-server mode */
|
||||||
static FILE *statusfp;
|
static FILE *statusfp;
|
||||||
|
|
||||||
@ -1515,6 +1520,24 @@ gpgsm_server (certlist_t default_recplist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
gpgsm_init_statusfp (ctrl_t ctrl)
|
||||||
|
{
|
||||||
|
if (statusfp || ctrl->status_fd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctrl->status_fd == 1)
|
||||||
|
statusfp = stdout;
|
||||||
|
else if (ctrl->status_fd == 2)
|
||||||
|
statusfp = stderr;
|
||||||
|
else
|
||||||
|
statusfp = fdopen (ctrl->status_fd, "w");
|
||||||
|
|
||||||
|
if (!statusfp)
|
||||||
|
log_fatal ("can't open fd %d for status output: %s\n",
|
||||||
|
ctrl->status_fd, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
gpgsm_status2 (ctrl_t ctrl, int no, ...)
|
gpgsm_status2 (ctrl_t ctrl, int no, ...)
|
||||||
@ -1527,23 +1550,11 @@ gpgsm_status2 (ctrl_t ctrl, int no, ...)
|
|||||||
|
|
||||||
if (ctrl->no_server && ctrl->status_fd == -1)
|
if (ctrl->no_server && ctrl->status_fd == -1)
|
||||||
; /* No status wanted. */
|
; /* No status wanted. */
|
||||||
|
else if (ctrl->no_server && no == STATUS_FAILURE && any_failure_printed)
|
||||||
|
; /* Don't emit FAILURE a second time. */
|
||||||
else if (ctrl->no_server)
|
else if (ctrl->no_server)
|
||||||
{
|
{
|
||||||
if (!statusfp)
|
gpgsm_init_statusfp (ctrl);
|
||||||
{
|
|
||||||
if (ctrl->status_fd == 1)
|
|
||||||
statusfp = stdout;
|
|
||||||
else if (ctrl->status_fd == 2)
|
|
||||||
statusfp = stderr;
|
|
||||||
else
|
|
||||||
statusfp = fdopen (ctrl->status_fd, "w");
|
|
||||||
|
|
||||||
if (!statusfp)
|
|
||||||
{
|
|
||||||
log_fatal ("can't open fd %d for status output: %s\n",
|
|
||||||
ctrl->status_fd, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fputs ("[GNUPG:] ", statusfp);
|
fputs ("[GNUPG:] ", statusfp);
|
||||||
fputs (get_status_string (no), statusfp);
|
fputs (get_status_string (no), statusfp);
|
||||||
@ -1562,6 +1573,10 @@ gpgsm_status2 (ctrl_t ctrl, int no, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
putc ('\n', statusfp);
|
putc ('\n', statusfp);
|
||||||
|
|
||||||
|
if (no == STATUS_FAILURE)
|
||||||
|
any_failure_printed = 1;
|
||||||
|
|
||||||
if (ferror (statusfp))
|
if (ferror (statusfp))
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
else
|
else
|
||||||
@ -1614,6 +1629,23 @@ gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Function to print a FAILURE status line on exit. */
|
||||||
|
void
|
||||||
|
gpgsm_exit_failure_status (void)
|
||||||
|
{
|
||||||
|
/* stderr is used as a last but possible wrong resort if no status
|
||||||
|
* has yet been printed. */
|
||||||
|
FILE *fp = statusfp? statusfp : stderr;
|
||||||
|
|
||||||
|
if (any_failure_printed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fputs ("[GNUPG:] ", fp);
|
||||||
|
fputs (get_status_string (STATUS_FAILURE), fp);
|
||||||
|
fputs (" gpgsm-exit 50331649\n", fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This callback is used to emit progress status lines. */
|
/* This callback is used to emit progress status lines. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total)
|
gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user