use estream for status output.

This commit is contained in:
Werner Koch 2010-06-07 17:04:50 +00:00
parent c8eb7bd839
commit db0fd50da1
2 changed files with 148 additions and 121 deletions

View File

@ -1,3 +1,7 @@
2010-06-07 Werner Koch <wk@g10code.com>
* cpr.c: Use estream for status output.
2010-05-12 Werner Koch <wk@g10code.com> 2010-05-12 Werner Koch <wk@g10code.com>
* armor.c (radix64_read): Extended 2006-04-28 fix to fix bug#1179. * armor.c (radix64_read): Extended 2006-04-28 fix to fix bug#1179.

265
g10/cpr.c
View File

@ -40,8 +40,9 @@
#define CONTROL_D ('D' - 'A' + 1) #define CONTROL_D ('D' - 'A' + 1)
/* The stream to output the status information. Output is disabled if
static FILE *statusfp; this is NULL. */
static estream_t statusfp;
static void static void
@ -94,68 +95,74 @@ status_currently_allowed (int no)
void void
set_status_fd ( int fd ) set_status_fd (int fd)
{ {
static int last_fd = -1; static int last_fd = -1;
if (fd != -1 && last_fd == fd)
return;
if ( fd != -1 && last_fd == fd ) if (statusfp && statusfp != es_stdout && statusfp != es_stderr )
return; es_fclose (statusfp);
statusfp = NULL;
if ( statusfp && statusfp != stdout && statusfp != stderr ) if (fd == -1)
fclose (statusfp); return;
statusfp = NULL;
if ( fd == -1 ) if (fd == 1)
return; statusfp = es_stdout;
else if (fd == 2)
if( fd == 1 ) statusfp = es_stderr;
statusfp = stdout; else
else if( fd == 2 ) statusfp = es_fdopen (fd, "w");
statusfp = stderr; if (!statusfp)
else {
statusfp = fdopen( fd, "w" ); log_fatal ("can't open fd %d for status output: %s\n",
if( !statusfp ) { fd, strerror (errno));
log_fatal("can't open fd %d for status output: %s\n",
fd, strerror(errno));
} }
last_fd = fd; last_fd = fd;
gcry_set_progress_handler ( progress_cb, NULL ); gcry_set_progress_handler (progress_cb, NULL);
} }
int int
is_status_enabled() is_status_enabled ()
{ {
return !!statusfp; return !!statusfp;
} }
void void
write_status ( int no ) write_status ( int no )
{ {
write_status_text( no, NULL ); write_status_text( no, NULL );
} }
void
write_status_text ( int no, const char *text)
{
if( !statusfp || !status_currently_allowed (no) )
return; /* Not enabled or allowed. */
fputs ( "[GNUPG:] ", statusfp ); void
fputs ( get_status_string (no), statusfp ); write_status_text (int no, const char *text)
if( text ) { {
putc ( ' ', statusfp ); if (!statusfp || !status_currently_allowed (no) )
for (; *text; text++) { return; /* Not enabled or allowed. */
if (*text == '\n')
fputs ( "\\n", statusfp ); es_fputs ("[GNUPG:] ", statusfp);
else if (*text == '\r') es_fputs (get_status_string (no), statusfp);
fputs ( "\\r", statusfp ); if ( text )
else {
putc ( *(const byte *)text, statusfp ); es_putc ( ' ', statusfp);
for (; *text; text++)
{
if (*text == '\n')
es_fputs ("\\n", statusfp);
else if (*text == '\r')
es_fputs ("\\r", statusfp);
else
es_fputc ( *(const byte *)text, statusfp);
} }
} }
putc ('\n',statusfp); es_putc ('\n', statusfp);
if ( fflush (statusfp) && opt.exit_on_status_write_error ) if (es_fflush (statusfp) && opt.exit_on_status_write_error)
g10_exit (0); g10_exit (0);
} }
@ -166,23 +173,23 @@ write_status_error (const char *where, gpg_error_t err)
if (!statusfp || !status_currently_allowed (STATUS_ERROR)) if (!statusfp || !status_currently_allowed (STATUS_ERROR))
return; /* Not enabled or allowed. */ return; /* Not enabled or allowed. */
fprintf (statusfp, "[GNUPG:] %s %s %u\n", es_fprintf (statusfp, "[GNUPG:] %s %s %u\n",
get_status_string (STATUS_ERROR), where, err); get_status_string (STATUS_ERROR), where, err);
if (fflush (statusfp) && opt.exit_on_status_write_error) if (es_fflush (statusfp) && opt.exit_on_status_write_error)
g10_exit (0); g10_exit (0);
} }
/* Same as above but only putputs the error code. */ /* Same as above but outputs the error code only. */
void void
write_status_errcode (const char *where, int errcode) write_status_errcode (const char *where, int errcode)
{ {
if (!statusfp || !status_currently_allowed (STATUS_ERROR)) if (!statusfp || !status_currently_allowed (STATUS_ERROR))
return; /* Not enabled or allowed. */ return; /* Not enabled or allowed. */
fprintf (statusfp, "[GNUPG:] %s %s %u\n", es_fprintf (statusfp, "[GNUPG:] %s %s %u\n",
get_status_string (STATUS_ERROR), where, gpg_err_code (errcode)); get_status_string (STATUS_ERROR), where, gpg_err_code (errcode));
if (fflush (statusfp) && opt.exit_on_status_write_error) if (es_fflush (statusfp) && opt.exit_on_status_write_error)
g10_exit (0); g10_exit (0);
} }
@ -194,73 +201,83 @@ write_status_errcode (const char *where, int errcode)
* A wrap of -1 forces spaces not to be encoded as %20. * A wrap of -1 forces spaces not to be encoded as %20.
*/ */
void void
write_status_text_and_buffer ( int no, const char *string, write_status_text_and_buffer (int no, const char *string,
const char *buffer, size_t len, int wrap ) const char *buffer, size_t len, int wrap)
{ {
const char *s, *text; const char *s, *text;
int esc, first; int esc, first;
int lower_limit = ' '; int lower_limit = ' ';
size_t n, count, dowrap; size_t n, count, dowrap;
if( !statusfp || !status_currently_allowed (no) ) if (!statusfp || !status_currently_allowed (no))
return; /* Not enabled or allowed. */ return; /* Not enabled or allowed. */
if (wrap == -1) { if (wrap == -1)
lower_limit--; {
wrap = 0; lower_limit--;
wrap = 0;
} }
text = get_status_string (no); text = get_status_string (no);
count = dowrap = first = 1; count = dowrap = first = 1;
do { do
if (dowrap) { {
fprintf (statusfp, "[GNUPG:] %s ", text ); if (dowrap)
count = dowrap = 0; {
if (first && string) { es_fprintf (statusfp, "[GNUPG:] %s ", text);
fputs (string, statusfp); count = dowrap = 0;
count += strlen (string); if (first && string)
/* Make sure that there is space after the string. */ {
if (*string && string[strlen (string)-1] != ' ') es_fputs (string, statusfp);
{ count += strlen (string);
putc (' ', statusfp); /* Make sure that there is a space after the string. */
count++; if (*string && string[strlen (string)-1] != ' ')
} {
es_putc (' ', statusfp);
count++;
}
} }
first = 0; first = 0;
} }
for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { for (esc=0, s=buffer, n=len; n && !esc; s++, n--)
if ( *s == '%' || *(const byte*)s <= lower_limit {
|| *(const byte*)s == 127 ) if (*s == '%' || *(const byte*)s <= lower_limit
esc = 1; || *(const byte*)s == 127 )
if ( wrap && ++count > wrap ) { esc = 1;
dowrap=1; if (wrap && ++count > wrap)
break; {
dowrap=1;
break;
} }
} }
if (esc) { if (esc)
s--; n++; {
s--; n++;
} }
if (s != buffer) if (s != buffer)
fwrite (buffer, s-buffer, 1, statusfp ); es_fwrite (buffer, s-buffer, 1, statusfp);
if ( esc ) { if ( esc )
fprintf (statusfp, "%%%02X", *(const byte*)s ); {
s++; n--; es_fprintf (statusfp, "%%%02X", *(const byte*)s );
s++; n--;
} }
buffer = s; buffer = s;
len = n; len = n;
if ( dowrap && len ) if (dowrap && len)
putc ( '\n', statusfp ); es_putc ('\n', statusfp);
} while ( len ); }
while (len);
putc ('\n',statusfp); es_putc ('\n',statusfp);
if ( fflush (statusfp) && opt.exit_on_status_write_error ) if (es_fflush (statusfp) && opt.exit_on_status_write_error)
g10_exit (0); g10_exit (0);
} }
void void
write_status_buffer ( int no, const char *buffer, size_t len, int wrap ) write_status_buffer (int no, const char *buffer, size_t len, int wrap)
{ {
write_status_text_and_buffer (no, NULL, buffer, len, wrap); write_status_text_and_buffer (no, NULL, buffer, len, wrap);
} }
@ -285,13 +302,13 @@ write_status_begin_signing (gcry_md_hd_t md)
buflen = 0; buflen = 0;
for (i=1; i <= 11; i++) for (i=1; i <= 11; i++)
if (i < 4 || i > 7) if (i < 4 || i > 7)
if ( gcry_md_is_enabled (md, i) && buflen < DIM(buf) ) if (gcry_md_is_enabled (md, i) && buflen < DIM(buf))
{ {
snprintf (buf+buflen, DIM(buf) - buflen - 1, snprintf (buf+buflen, DIM(buf) - buflen - 1,
"%sH%d", buflen? " ":"",i); "%sH%d", buflen? " ":"",i);
buflen += strlen (buf+buflen); buflen += strlen (buf+buflen);
} }
write_status_text ( STATUS_BEGIN_SIGNING, buf ); write_status_text (STATUS_BEGIN_SIGNING, buf);
} }
else else
write_status ( STATUS_BEGIN_SIGNING ); write_status ( STATUS_BEGIN_SIGNING );
@ -301,28 +318,34 @@ write_status_begin_signing (gcry_md_hd_t md)
static int static int
myread(int fd, void *buf, size_t count) myread(int fd, void *buf, size_t count)
{ {
int rc; int rc;
do { do
rc = read( fd, buf, count ); {
} while ( rc == -1 && errno == EINTR ); rc = read( fd, buf, count );
if ( !rc && count ) { }
static int eof_emmited=0; while (rc == -1 && errno == EINTR);
if ( eof_emmited < 3 ) {
*(char*)buf = CONTROL_D; if (!rc && count)
rc = 1; {
eof_emmited++; static int eof_emmited=0;
if ( eof_emmited < 3 )
{
*(char*)buf = CONTROL_D;
rc = 1;
eof_emmited++;
} }
else { /* Ctrl-D not caught - do something reasonable */ else /* Ctrl-D not caught - do something reasonable */
{
#ifdef HAVE_DOSISH_SYSTEM #ifdef HAVE_DOSISH_SYSTEM
#ifndef HAVE_W32CE_SYSTEM #ifndef HAVE_W32CE_SYSTEM
raise (SIGINT); /* nothing to hangup under DOS */ raise (SIGINT); /* Nothing to hangup under DOS. */
#endif #endif
#else #else
raise (SIGHUP); /* no more input data */ raise (SIGHUP); /* No more input data. */
#endif #endif
} }
} }
return rc; return rc;
} }
@ -336,8 +359,8 @@ do_get_from_fd ( const char *keyword, int hidden, int getbool )
int i, len; int i, len;
char *string; char *string;
if (statusfp != stdout) if (statusfp != es_stdout)
fflush (stdout); es_fflush (es_stdout);
write_status_text (getbool? STATUS_GET_BOOL : write_status_text (getbool? STATUS_GET_BOOL :
hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword); hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword);