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> 2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (MOSTLYCLEANFILES): New variable. * Makefile.am (MOSTLYCLEANFILES): New variable.

View File

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

View File

@ -57,6 +57,15 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
*okay = 2; /* data line */ *okay = 2; /* data line */
*off = 2; *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 else if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K' && line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' ')) && (line[2] == '\0' || line[2] == ' '))
@ -86,6 +95,13 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
while (line[*off] == ' ') while (line[*off] == ' ')
++*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 else
rc = ASSUAN_Invalid_Response; rc = ASSUAN_Invalid_Response;
return rc; 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 * @data_cb_arg: first argument passed to @data_cb
* @inquire_cb: Callback function for a inquire response * @inquire_cb: Callback function for a inquire response
* @inquire_cb_arg: first argument passed to @inquire_cb * @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 * FIXME: Write documentation
* *
@ -114,7 +132,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
AssuanError (*data_cb)(void *, const void *, size_t), AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg, void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *), 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; int rc, okay, off;
unsigned char *line; unsigned char *line;
@ -181,6 +201,25 @@ assuan_transact (ASSUAN_CONTEXT ctx,
goto again; 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; return rc;
} }

View File

@ -77,6 +77,9 @@ struct assuan_context_s {
In socket mode, the pid of the server */ In socket mode, the pid of the server */
int listen_fd; /* The fd we are listening on (used by socket servers) */ 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); void (*deinit_handler)(ASSUAN_CONTEXT);
int (*accept_handler)(ASSUAN_CONTEXT); int (*accept_handler)(ASSUAN_CONTEXT);
int (*finish_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 (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *); void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
int input_fd; /* set by INPUT command */ int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */ int output_fd; /* set by OUTPUT command */
@ -135,9 +137,3 @@ void _assuan_log_sanitized_string (const char *string);
#endif /*ASSUAN_DEFS_H*/ #endif /*ASSUAN_DEFS_H*/

View File

@ -464,6 +464,12 @@ process_request (ASSUAN_CONTEXT ctx)
if (!rc && ctx->outbound.data.error) if (!rc && ctx->outbound.data.error)
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 */ /* Error handling */
if (!rc) if (!rc)
{ {
@ -478,7 +484,7 @@ process_request (ASSUAN_CONTEXT ctx)
{ {
char errline[256]; char errline[256];
if (rc < 100) if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)", sprintf (errline, "ERR %d server fault (%.50s)",
ASSUAN_Server_Fault, assuan_strerror (rc)); ASSUAN_Server_Fault, assuan_strerror (rc));
else else

View File

@ -126,9 +126,10 @@ free_membuf (struct membuf *mb)
* @keyword: The keyword used for the inquire * @keyword: The keyword used for the inquire
* @r_buffer: Returns an allocated buffer * @r_buffer: Returns an allocated buffer
* @r_length: Returns the length of this 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 * 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]; char cmdbuf[100];
unsigned char *line, *p; unsigned char *line, *p;
int linelen; int linelen;
int nodataexpected;
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)) if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
|| !r_buffer || !r_length ) return ASSUAN_Invalid_Value;
nodataexpected = !r_buffer && !r_length && !maxlen;
if (!nodataexpected && (!r_buffer || !r_length))
return ASSUAN_Invalid_Value; return ASSUAN_Invalid_Value;
if (!ctx->is_server) if (!ctx->is_server)
return ASSUAN_Not_A_Server; return ASSUAN_Not_A_Server;
@ -151,7 +155,10 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
return ASSUAN_Nested_Commands; return ASSUAN_Nested_Commands;
ctx->in_inquire = 1; 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); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
rc = assuan_write_line (ctx, cmdbuf); 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' if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
&& (!line[3] || line[3] == ' ')) && (!line[3] || line[3] == ' '))
break; /* END command received*/ 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; rc = ASSUAN_Unexpected_Command;
goto leave; goto leave;
@ -205,13 +217,17 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
goto leave; goto leave;
} }
} }
*r_buffer = get_membuf (&mb, r_length); if (!nodataexpected)
if (!*r_buffer) {
rc = ASSUAN_Out_Of_Core; *r_buffer = get_membuf (&mb, r_length);
if (!*r_buffer)
rc = ASSUAN_Out_Of_Core;
}
leave: leave:
free_membuf (&mb); if (!nodataexpected)
free_membuf (&mb);
ctx->in_inquire = 0; ctx->in_inquire = 0;
return rc; return rc;
} }

View File

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

View File

@ -25,6 +25,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "assuan-defs.h" #include "assuan-defs.h"
@ -35,13 +38,28 @@ accept_connection (ASSUAN_CONTEXT ctx)
struct sockaddr_un clnt_addr; struct sockaddr_un clnt_addr;
size_t len = sizeof 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 ); fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
#endif
if (fd == -1) if (fd == -1)
{ {
ctx->os_errno = errno; ctx->os_errno = errno;
return ASSUAN_Accept_Failed; 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.fd = fd;
ctx->inbound.eof = 0; ctx->inbound.eof = 0;
ctx->inbound.linelen = 0; ctx->inbound.linelen = 0;

View File

@ -73,6 +73,12 @@ typedef enum {
ASSUAN_Inquire_Unknown = 120, ASSUAN_Inquire_Unknown = 120,
ASSUAN_Inquire_Error = 121, ASSUAN_Inquire_Error = 121,
ASSUAN_Invalid_Option = 122, 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 = 201,
ASSUAN_Bad_Certificate_Path = 202, ASSUAN_Bad_Certificate_Path = 202,
@ -89,6 +95,12 @@ typedef enum {
ASSUAN_CRL_Too_Old = 303, ASSUAN_CRL_Too_Old = 303,
ASSUAN_Not_Trusted = 304, 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; } AssuanError;
/* This is a list of pre-registered ASSUAN commands */ /* 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), AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg, void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *), 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 --*/ /*-- 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> 2001-11-01 Marcus Brinkmann <marcus@g10code.de>
* logging.c (log_printf): Do not initialize ARG_PTR with 0, we * 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. (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 This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without 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; arg->r_opt = -arg->r_opt;
if( !opts[idx].short_opt ) /* unknown command/option */ if( !opts[idx].short_opt ) /* unknown command/option */
arg->r_opt = (opts[idx].flags & 256)? -7:-2; arg->r_opt = (opts[idx].flags & 256)? -7:-2;
else if( (opts[idx].flags & 8) ) /* no argument */ else if( !(opts[idx].flags & 7) ) /* does not take an arg */
arg->r_opt = -3; /* error */
else /* no or optional argument */
arg->r_type = 0; /* okay */ 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; break;
} }
else if( state == 3 ) { /* no argument found */ else if( state == 3 ) { /* no argument found */
@ -900,7 +902,7 @@ strusage( int level )
switch( level ) { switch( level ) {
case 11: p = "foo"; break; case 11: p = "foo"; break;
case 13: p = "0.0"; 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 = case 15: p =
"This program comes with ABSOLUTELY NO WARRANTY.\n" "This program comes with ABSOLUTELY NO WARRANTY.\n"
"This is free software, and you are welcome to redistribute it\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 ); setvbuf( fp, NULL, _IOLBF, 0 );
if( logstream && logstream != stderr ) if (logstream && logstream != stderr && logstream != stdout)
fclose( logstream ); fclose( logstream );
logstream = fp; logstream = fp;
missing_lf = 0; 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 void
log_set_prefix (const char *text, unsigned int flags) 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); 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 int
log_get_fd() log_get_fd()
{ {

View File

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

View File

@ -263,6 +263,52 @@ compare_filenames( const char *a, const char *b )
#endif #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 ******** ******** 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 ********* ********** missing string functions *********

View File

@ -37,6 +37,11 @@ char *make_dirname(const char *filepath);
char *make_filename( const char *first_part, ... ); char *make_filename( const char *first_part, ... );
int compare_filenames( const char *a, const char *b ); 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 ); const char *ascii_memistr( const char *buf, size_t buflen, const char *sub );
int ascii_isupper (int c); int ascii_isupper (int c);
int ascii_islower (int c); int ascii_islower (int c);
@ -44,6 +49,8 @@ int ascii_toupper (int c);
int ascii_tolower (int c); int ascii_tolower (int c);
int ascii_strcasecmp( const char *a, const char *b ); int ascii_strcasecmp( const char *a, const char *b );
int ascii_memcasecmp( const char *a, const char *b, size_t n ); 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 #ifndef HAVE_MEMICMP