Update assuan and jnlib to 20020424 from newpg.

This commit is contained in:
Marcus Brinkmann 2002-04-24 01:55:58 +00:00
parent 43da549e6a
commit a559c32a55
15 changed files with 342 additions and 38 deletions

View File

@ -1,3 +1,39 @@
2002-04-04 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug
output.
2002-03-06 Werner Koch <wk@gnupg.org>
* assuan-client.c (_assuan_read_from_server): Detect END.
(assuan_transact): Pass it to the data callback.
2002-02-27 Werner Koch <wk@gnupg.org>
* assuan-client.c (assuan_transact): Add 2 more arguments to
support status lines. Passing NULL yields the old behaviour.
* assuan-handler.c (process_request): Flush data lines send
without using the data fp.
2002-02-14 Werner Koch <wk@gnupg.org>
* assuan-inquire.c (assuan_inquire): Check for a cancel command
and return ASSUAN_Canceled. Allow for non-data inquiry.
* assuan.h: Add a few token specific error codes.
2002-02-13 Werner Koch <wk@gnupg.org>
* assuan-defs.h (assuan_context_s): New var CLIENT_PID.
* assuan-pipe-server.c (_assuan_new_context): set default value.
* assuan-socket-server.c (accept_connection): get the actual pid.
2002-02-12 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write.
* assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto.
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (MOSTLYCLEANFILES): New variable.

View File

@ -25,16 +25,37 @@
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "assuan-defs.h"
#ifdef HAVE_JNLIB_LOGGING
#include "../jnlib/logging.h"
#endif
static const char *
my_log_prefix (void)
{
#ifdef HAVE_JNLIB_LOGGING
return log_get_prefix (NULL);
#else
return "";
#endif
}
static int
writen ( int fd, const char *buffer, size_t length )
{
while (length)
{
#ifdef USE_GNU_PTH
int nwritten = pth_write (fd, buffer, length);
#else
int nwritten = write (fd, buffer, length);
#endif
if (nwritten < 0)
{
@ -59,7 +80,11 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
*r_nread = 0;
while (nleft > 0)
{
#ifdef USE_GNU_PTH
int n = pth_read (fd, buf, nleft);
#else
int n = read (fd, buf, nleft);
#endif
if (n < 0)
{
if (errno == EINTR)
@ -122,15 +147,15 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
if (rc)
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%p <- [Error: %s]\n",
ctx, strerror (errno));
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
my_log_prefix (), ctx, strerror (errno));
return ASSUAN_Read_Error;
}
if (!nread)
{
assert (ctx->inbound.eof);
if (ctx->log_fp)
fprintf (ctx->log_fp, "%p <- [EOF]\n", ctx);
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx);
return -1;
}
@ -163,7 +188,7 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
ctx->inbound.linelen = n;
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%p <- ", ctx);
fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -177,7 +202,7 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
}
if (ctx->log_fp)
fprintf (ctx->log_fp, "%p <- [Invalid line]\n", ctx);
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
*line = 0;
ctx->inbound.linelen = 0;
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
@ -229,7 +254,7 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
/* fixme: we should do some kind of line buffering */
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%p -> ", ctx);
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -300,7 +325,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%p -> ", ctx);
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -345,7 +370,7 @@ _assuan_cookie_write_flush (void *cookie)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%p -> ", ctx);
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else

View File

@ -57,6 +57,15 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
*okay = 2; /* data line */
*off = 2;
}
else if (linelen >= 1
&& line[0] == 'S'
&& (line[1] == '\0' || line[1] == ' '))
{
*okay = 4;
*off = 1;
while (line[*off] == ' ')
++*off;
}
else if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' '))
@ -86,6 +95,13 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
while (line[*off] == ' ')
++*off;
}
else if (linelen >= 3
&& line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
&& (line[3] == '\0' || line[3] == ' '))
{
*okay = 5; /* end line */
*off = 3;
}
else
rc = ASSUAN_Invalid_Response;
return rc;
@ -101,6 +117,8 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
* @data_cb_arg: first argument passed to @data_cb
* @inquire_cb: Callback function for a inquire response
* @inquire_cb_arg: first argument passed to @inquire_cb
* @status_cb: Callback function for a status response
* @status_cb_arg: first argument passed to @status_cb
*
* FIXME: Write documentation
*
@ -114,7 +132,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
void *inquire_cb_arg)
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
void *status_cb_arg)
{
int rc, okay, off;
unsigned char *line;
@ -181,6 +201,25 @@ assuan_transact (ASSUAN_CONTEXT ctx,
goto again;
}
}
else if (okay == 4)
{
if (status_cb)
rc = status_cb (status_cb_arg, line);
if (!rc)
goto again;
}
else if (okay == 5)
{
if (!data_cb)
rc = ASSUAN_No_Data_Callback;
else
{
rc = data_cb (data_cb_arg, NULL, 0);
if (!rc)
goto again;
}
}
return rc;
}

View File

@ -77,6 +77,9 @@ struct assuan_context_s {
In socket mode, the pid of the server */
int listen_fd; /* The fd we are listening on (used by socket servers) */
pid_t client_pid; /* for a socket server the PID of the client or -1
if not available */
void (*deinit_handler)(ASSUAN_CONTEXT);
int (*accept_handler)(ASSUAN_CONTEXT);
int (*finish_handler)(ASSUAN_CONTEXT);
@ -92,7 +95,6 @@ struct assuan_context_s {
void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */
@ -135,9 +137,3 @@ void _assuan_log_sanitized_string (const char *string);
#endif /*ASSUAN_DEFS_H*/

View File

@ -464,6 +464,12 @@ process_request (ASSUAN_CONTEXT ctx)
if (!rc && ctx->outbound.data.error)
rc = ctx->outbound.data.error;
}
else /* flush any data send w/o using the data fp */
{
assuan_send_data (ctx, NULL, 0);
if (!rc && ctx->outbound.data.error)
rc = ctx->outbound.data.error;
}
/* Error handling */
if (!rc)
{
@ -478,7 +484,7 @@ process_request (ASSUAN_CONTEXT ctx)
{
char errline[256];
if (rc < 100)
if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)",
ASSUAN_Server_Fault, assuan_strerror (rc));
else

View File

@ -126,9 +126,10 @@ free_membuf (struct membuf *mb)
* @keyword: The keyword used for the inquire
* @r_buffer: Returns an allocated buffer
* @r_length: Returns the length of this buffer
* @maxlen: If no 0, the size limit of the inquired data.
* @maxlen: If not 0, the size limit of the inquired data.
*
* A Server may use this to Send an inquire
* A Server may use this to Send an inquire. r_buffer, r_length and
* maxlen may all be NULL/0 to indicate that no real data is expected.
*
* Return value: 0 on success or an ASSUAN error code
**/
@ -141,9 +142,12 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char cmdbuf[100];
unsigned char *line, *p;
int linelen;
int nodataexpected;
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))
|| !r_buffer || !r_length )
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
return ASSUAN_Invalid_Value;
nodataexpected = !r_buffer && !r_length && !maxlen;
if (!nodataexpected && (!r_buffer || !r_length))
return ASSUAN_Invalid_Value;
if (!ctx->is_server)
return ASSUAN_Not_A_Server;
@ -151,7 +155,10 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
return ASSUAN_Nested_Commands;
ctx->in_inquire = 1;
init_membuf (&mb, maxlen? maxlen:1024, maxlen);
if (nodataexpected)
memset (&mb, 0, sizeof mb); /* avoid compiler warnings */
else
init_membuf (&mb, maxlen? maxlen:1024, maxlen);
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
rc = assuan_write_line (ctx, cmdbuf);
@ -172,7 +179,12 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
&& (!line[3] || line[3] == ' '))
break; /* END command received*/
if (line[0] != 'D' || line[1] != ' ')
if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
{
rc = ASSUAN_Canceled;
goto leave;
}
if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
{
rc = ASSUAN_Unexpected_Command;
goto leave;
@ -205,13 +217,17 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
goto leave;
}
}
*r_buffer = get_membuf (&mb, r_length);
if (!*r_buffer)
rc = ASSUAN_Out_Of_Core;
if (!nodataexpected)
{
*r_buffer = get_membuf (&mb, r_length);
if (!*r_buffer)
rc = ASSUAN_Out_Of_Core;
}
leave:
free_membuf (&mb);
if (!nodataexpected)
free_membuf (&mb);
ctx->in_inquire = 0;
return rc;
}

View File

@ -64,6 +64,7 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx)
ctx->outbound.fd = -1;
ctx->listen_fd = -1;
ctx->client_pid = (pid_t)-1;
/* use the pipe server handler as a default */
ctx->deinit_handler = deinit_pipe_server;
ctx->accept_handler = accept_connection;

View File

@ -25,6 +25,9 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "assuan-defs.h"
@ -35,13 +38,28 @@ accept_connection (ASSUAN_CONTEXT ctx)
struct sockaddr_un clnt_addr;
size_t len = sizeof clnt_addr;
ctx->client_pid = (pid_t)-1;
#ifdef USE_GNU_PTH
fd = pth_accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
#else
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
#endif
if (fd == -1)
{
ctx->os_errno = errno;
return ASSUAN_Accept_Failed;
}
#ifdef HAVE_SO_PEERCRED
{
struct ucred cr;
int cl = sizeof cr;
if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) )
ctx->client_pid = cr.pid;
}
#endif
ctx->inbound.fd = fd;
ctx->inbound.eof = 0;
ctx->inbound.linelen = 0;

View File

@ -73,6 +73,12 @@ typedef enum {
ASSUAN_Inquire_Unknown = 120,
ASSUAN_Inquire_Error = 121,
ASSUAN_Invalid_Option = 122,
ASSUAN_Invalid_Index = 123,
ASSUAN_Unexpected_Status = 124,
ASSUAN_Unexpected_Data = 125,
ASSUAN_Invalid_Status = 126,
ASSUAN_Not_Confirmed = 128,
ASSUAN_Bad_Certificate = 201,
ASSUAN_Bad_Certificate_Path = 202,
@ -89,6 +95,12 @@ typedef enum {
ASSUAN_CRL_Too_Old = 303,
ASSUAN_Not_Trusted = 304,
ASSUAN_Card_Error = 401,
ASSUAN_Invalid_Card = 402,
ASSUAN_No_PKCS15_App = 403,
ASSUAN_Card_Not_Present = 404,
ASSUAN_Invalid_Id = 405
} AssuanError;
/* This is a list of pre-registered ASSUAN commands */
@ -178,7 +190,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
void *inquire_cb_arg);
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
void *status_cb_arg);
/*-- assuan-inquire.c --*/

View File

@ -1,3 +1,33 @@
2002-04-04 Werner Koch <wk@gnupg.org>
* logging.c (log_get_prefix): New.
2002-03-15 Werner Koch <wk@gnupg.org>
* argparse.c (optfile_parse): Fixed missing argument handling.
2002-02-25 Werner Koch <wk@gnupg.org>
* stringhelp.c (ascii_memcasemem): New.
2002-02-14 Werner Koch <wk@gnupg.org>
* Makefile.am (INCLUDES): Add cflags for libgcrypt.
2002-02-07 Werner Koch <wk@gnupg.org>
* logging.c (log_set_fd): New.
* stringhelp.c (print_sanitized_buffer): New.
(print_sanitized_string): New.
2002-01-24 Werner Koch <wk@gnupg.org>
* argparse.c (strusage): Set default copyright notice year to 2002.
Fixed the copyright notice of this file, as it has always been
part of GnuPG and therefore belongs to the FSF.
2001-11-01 Marcus Brinkmann <marcus@g10code.de>
* logging.c (log_printf): Do not initialize ARG_PTR with 0, we
@ -72,8 +102,12 @@ Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
(do_logv): Add kludge to insert LFs.
Copyright 2000 Werner Koch (dd9jn)
Copyright 2001 g10 Code GmbH
***********************************************************
* Please note that Jnlib is maintained as part of GnuPG. *
* You may find it source-copied in other packages. *
***********************************************************
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without

View File

@ -276,10 +276,12 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
arg->r_opt = -arg->r_opt;
if( !opts[idx].short_opt ) /* unknown command/option */
arg->r_opt = (opts[idx].flags & 256)? -7:-2;
else if( (opts[idx].flags & 8) ) /* no argument */
arg->r_opt = -3; /* error */
else /* no or optional argument */
else if( !(opts[idx].flags & 7) ) /* does not take an arg */
arg->r_type = 0; /* okay */
else if( (opts[idx].flags & 8) ) /* argument is optional */
arg->r_type = 0; /* okay */
else /* required argument */
arg->r_opt = -3; /* error */
break;
}
else if( state == 3 ) { /* no argument found */
@ -900,7 +902,7 @@ strusage( int level )
switch( level ) {
case 11: p = "foo"; break;
case 13: p = "0.0"; break;
case 14: p = "Copyright (C) 2001 Free Software Foundation, Inc."; break;
case 14: p = "Copyright (C) 2002 Free Software Foundation, Inc."; break;
case 15: p =
"This program comes with ABSOLUTELY NO WARRANTY.\n"
"This is free software, and you are welcome to redistribute it\n"

View File

@ -89,12 +89,37 @@ log_set_file( const char *name )
}
setvbuf( fp, NULL, _IOLBF, 0 );
if( logstream && logstream != stderr )
fclose( logstream );
if (logstream && logstream != stderr && logstream != stdout)
fclose( logstream );
logstream = fp;
missing_lf = 0;
}
void
log_set_fd (int fd)
{
FILE *fp;
if (fd == 1)
fp = stdout;
else if (fd == 2)
fp = stderr;
else
fp = fdopen (fd, "a");
if (!fp)
{
fprintf (stderr, "failed to fdopen log fd %d: %s\n",
fd, strerror(errno));
return;
}
setvbuf (fp, NULL, _IOLBF, 0);
if (logstream && logstream != stderr && logstream != stdout)
fclose( logstream);
logstream = fp;
missing_lf = 0;
}
void
log_set_prefix (const char *text, unsigned int flags)
@ -110,6 +135,23 @@ log_set_prefix (const char *text, unsigned int flags)
with_pid = (flags & 4);
}
const char *
log_get_prefix (unsigned int *flags)
{
if (flags)
{
*flags = 0;
if (with_prefix)
*flags |= 1;
if (with_time)
*flags |= 2;
if (with_pid)
*flags |=4;
}
return prefix_buffer;
}
int
log_get_fd()
{

View File

@ -27,7 +27,9 @@
int log_get_errorcount (int clear);
void log_set_file( const char *name );
void log_set_fd (int fd);
void log_set_prefix (const char *text, unsigned int flags);
const char *log_get_prefix (unsigned int *flags);
int log_get_fd(void);
FILE *log_get_stream (void);

View File

@ -263,6 +263,52 @@ compare_filenames( const char *a, const char *b )
#endif
}
/* Print a BUFFER to stream FP while replacing all control characters
and the character DELIM with standard C eescape sequences. Returns
the number of characters printed. */
size_t
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, int delim)
{
const unsigned char *p = buffer;
size_t count = 0;
for (; length; length--, p++, count++)
{
if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim)
{
putc ('\\', fp);
count++;
if (*p == '\n')
putc ('n', fp);
else if (*p == '\r')
putc ('r', fp);
else if (*p == '\f')
putc ('f', fp);
else if (*p == '\v')
putc ('v', fp);
else if (*p == '\b')
putc ('b', fp);
else if (!*p)
putc('0', fp);
else
{
fprintf (fp, "x%02x", *p);
count += 2;
}
}
else
putc (*p, fp);
}
return count;
}
size_t
print_sanitized_string (FILE *fp, const char *string, int delim)
{
return string? print_sanitized_buffer (fp, string, strlen (string), delim):0;
}
/****************************************************
******** locale insensitive ctype functions ********
@ -336,6 +382,26 @@ ascii_strcmp( const char *a, const char *b )
}
void *
ascii_memcasemem (const void *haystack, size_t nhaystack,
const void *needle, size_t nneedle)
{
if (!nneedle)
return (void*)haystack; /* finding an empty needle is really easy */
if (nneedle <= nhaystack)
{
const unsigned char *a = haystack;
const unsigned char *b = a + nhaystack - nneedle;
for (; a <= b; a++)
{
if ( !ascii_memcasecmp (a, needle, nneedle) )
return (void *)a;
}
}
return NULL;
}
/*********************************************
********** missing string functions *********

View File

@ -37,6 +37,11 @@ char *make_dirname(const char *filepath);
char *make_filename( const char *first_part, ... );
int compare_filenames( const char *a, const char *b );
size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
int delim);
size_t print_sanitized_string (FILE *fp, const char *string, int delim);
const char *ascii_memistr( const char *buf, size_t buflen, const char *sub );
int ascii_isupper (int c);
int ascii_islower (int c);
@ -44,6 +49,8 @@ int ascii_toupper (int c);
int ascii_tolower (int c);
int ascii_strcasecmp( const char *a, const char *b );
int ascii_memcasecmp( const char *a, const char *b, size_t n );
void *ascii_memcasemem (const void *haystack, size_t nhaystack,
const void *needle, size_t nneedle);
#ifndef HAVE_MEMICMP