Update to current version in newpg module.
This commit is contained in:
parent
e70c184235
commit
b863cea7d7
@ -1,3 +1,69 @@
|
|||||||
|
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs.
|
||||||
|
|
||||||
|
2002-01-21 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-connect.c: Move all except assuan_get_pid to...
|
||||||
|
* assuan-pipe-connect.c: this.
|
||||||
|
(assuan_pipe_disconnect): Removed.
|
||||||
|
(do_finish, do_deinit): New
|
||||||
|
(assuan_pipe_connect): and set them into the context.
|
||||||
|
* assuan-socket-connect.c: New.
|
||||||
|
|
||||||
|
* assuan-util.c (_assuan_log_sanitized_string): New.
|
||||||
|
|
||||||
|
* assuan-pipe-server.c (assuan_init_pipe_server): Factored most
|
||||||
|
code out to ...
|
||||||
|
(_assuan_new_context): new func.
|
||||||
|
(_assuan_release_context): New
|
||||||
|
* assuan-connect.c (assuan_pipe_connect): Use the new functions.
|
||||||
|
|
||||||
|
2002-01-20 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan.h: Added Invalid Option error code.
|
||||||
|
|
||||||
|
* assuan-handler.c (std_handler_option): New.
|
||||||
|
(std_cmd_tbl): Add OPTION as standard command.
|
||||||
|
(assuan_register_option_handler): New.
|
||||||
|
(dispatch_command): Use case insensitive matching as a fallback.
|
||||||
|
(my_strcasecmp): New.
|
||||||
|
|
||||||
|
2002-01-19 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-buffer.c (_assuan_read_line): Add output logging.
|
||||||
|
(assuan_write_line): Ditto.
|
||||||
|
(_assuan_cookie_write_data): Ditto.
|
||||||
|
(_assuan_cookie_write_flush): Ditto.
|
||||||
|
* assuan-util.c (_assuan_log_print_buffer): New.
|
||||||
|
(assuan_set_log_stream): New.
|
||||||
|
(assuan_begin_confidential): New.
|
||||||
|
(assuan_end_confidential): New.
|
||||||
|
|
||||||
|
* assuan-defs.h: Add a few handler variables.
|
||||||
|
* assuan-pipe-server.c (assuan_deinit_pipe_server): Removed.
|
||||||
|
(deinit_pipe_server): New.
|
||||||
|
(assuan_deinit_server): New. Changed all callers to use this.
|
||||||
|
* assuan-listen.c (assuan_accept): Use the accept handler.
|
||||||
|
* assuan-handler.c (process_request): Use the close Handler.
|
||||||
|
* assuan-socket-server.c: New.
|
||||||
|
|
||||||
|
2002-01-14 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-client.c (_assuan_read_from_server): Skip spaces after
|
||||||
|
the keyword.
|
||||||
|
|
||||||
|
2002-01-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-handler.c (assuan_set_okay_line): New.
|
||||||
|
(process_request): And use it here.
|
||||||
|
|
||||||
|
2002-01-02 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a
|
||||||
|
hidden 0 behind the buffer so that the buffer can be used as a
|
||||||
|
string in certain contexts.
|
||||||
|
|
||||||
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
|
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* assuan-connect.c (assuan_pipe_connect): New argument
|
* assuan-connect.c (assuan_pipe_connect): New argument
|
||||||
@ -90,7 +156,7 @@
|
|||||||
* You may find it source-copied in other packages. *
|
* You may find it source-copied in other packages. *
|
||||||
***********************************************************
|
***********************************************************
|
||||||
|
|
||||||
Copyright 2001 Free Software Foundation, Inc.
|
Copyright 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
|
||||||
|
@ -38,7 +38,10 @@ libassuan_a_SOURCES = \
|
|||||||
assuan-listen.c \
|
assuan-listen.c \
|
||||||
assuan-connect.c \
|
assuan-connect.c \
|
||||||
assuan-client.c \
|
assuan-client.c \
|
||||||
assuan-pipe-server.c
|
assuan-pipe-server.c \
|
||||||
|
assuan-socket-server.c \
|
||||||
|
assuan-pipe-connect.c \
|
||||||
|
assuan-socket-connect.c
|
||||||
|
|
||||||
|
|
||||||
assuan-errors.c : assuan.h
|
assuan-errors.c : assuan.h
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -119,10 +120,17 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
|
|||||||
rc = readline (ctx->inbound.fd, line, LINELENGTH,
|
rc = readline (ctx->inbound.fd, line, LINELENGTH,
|
||||||
&nread, &ctx->inbound.eof);
|
&nread, &ctx->inbound.eof);
|
||||||
if (rc)
|
if (rc)
|
||||||
return ASSUAN_Read_Error;
|
{
|
||||||
|
if (ctx->log_fp)
|
||||||
|
fprintf (ctx->log_fp, "%p <- [Error: %s]\n",
|
||||||
|
ctx, strerror (errno));
|
||||||
|
return ASSUAN_Read_Error;
|
||||||
|
}
|
||||||
if (!nread)
|
if (!nread)
|
||||||
{
|
{
|
||||||
assert (ctx->inbound.eof);
|
assert (ctx->inbound.eof);
|
||||||
|
if (ctx->log_fp)
|
||||||
|
fprintf (ctx->log_fp, "%p <- [EOF]\n", ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,10 +161,23 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
|
|||||||
n--;
|
n--;
|
||||||
line[n] = 0;
|
line[n] = 0;
|
||||||
ctx->inbound.linelen = n;
|
ctx->inbound.linelen = n;
|
||||||
|
if (ctx->log_fp)
|
||||||
|
{
|
||||||
|
fprintf (ctx->log_fp, "%p <- ", ctx);
|
||||||
|
if (ctx->confidential)
|
||||||
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
|
else
|
||||||
|
_assuan_log_print_buffer (ctx->log_fp,
|
||||||
|
ctx->inbound.line,
|
||||||
|
ctx->inbound.linelen);
|
||||||
|
putc ('\n', ctx->log_fp);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->log_fp)
|
||||||
|
fprintf (ctx->log_fp, "%p <- [Invalid line]\n", 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;
|
||||||
@ -206,6 +227,17 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
|
|||||||
return ASSUAN_Invalid_Value;
|
return ASSUAN_Invalid_Value;
|
||||||
|
|
||||||
/* fixme: we should do some kind of line buffering */
|
/* fixme: we should do some kind of line buffering */
|
||||||
|
if (ctx->log_fp)
|
||||||
|
{
|
||||||
|
fprintf (ctx->log_fp, "%p -> ", ctx);
|
||||||
|
if (ctx->confidential)
|
||||||
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
|
else
|
||||||
|
_assuan_log_print_buffer (ctx->log_fp,
|
||||||
|
line, strlen (line));
|
||||||
|
putc ('\n', ctx->log_fp);
|
||||||
|
}
|
||||||
|
|
||||||
rc = writen (ctx->outbound.fd, line, strlen(line));
|
rc = writen (ctx->outbound.fd, line, strlen(line));
|
||||||
if (rc)
|
if (rc)
|
||||||
rc = ASSUAN_Write_Error;
|
rc = ASSUAN_Write_Error;
|
||||||
@ -266,6 +298,17 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
|
|||||||
|
|
||||||
if (linelen >= LINELENGTH-2-2)
|
if (linelen >= LINELENGTH-2-2)
|
||||||
{
|
{
|
||||||
|
if (ctx->log_fp)
|
||||||
|
{
|
||||||
|
fprintf (ctx->log_fp, "%p -> ", ctx);
|
||||||
|
if (ctx->confidential)
|
||||||
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
|
else
|
||||||
|
_assuan_log_print_buffer (ctx->log_fp,
|
||||||
|
ctx->outbound.data.line,
|
||||||
|
linelen);
|
||||||
|
putc ('\n', ctx->log_fp);
|
||||||
|
}
|
||||||
*line++ = '\n';
|
*line++ = '\n';
|
||||||
linelen++;
|
linelen++;
|
||||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
||||||
@ -300,6 +343,17 @@ _assuan_cookie_write_flush (void *cookie)
|
|||||||
line += linelen;
|
line += linelen;
|
||||||
if (linelen)
|
if (linelen)
|
||||||
{
|
{
|
||||||
|
if (ctx->log_fp)
|
||||||
|
{
|
||||||
|
fprintf (ctx->log_fp, "%p -> ", ctx);
|
||||||
|
if (ctx->confidential)
|
||||||
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
|
else
|
||||||
|
_assuan_log_print_buffer (ctx->log_fp,
|
||||||
|
ctx->outbound.data.line,
|
||||||
|
linelen);
|
||||||
|
putc ('\n', ctx->log_fp);
|
||||||
|
}
|
||||||
*line++ = '\n';
|
*line++ = '\n';
|
||||||
linelen++;
|
linelen++;
|
||||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
||||||
|
@ -63,6 +63,8 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
|
|||||||
{
|
{
|
||||||
*okay = 1;
|
*okay = 1;
|
||||||
*off = 2;
|
*off = 2;
|
||||||
|
while (line[*off] == ' ')
|
||||||
|
++*off;
|
||||||
}
|
}
|
||||||
else if (linelen >= 3
|
else if (linelen >= 3
|
||||||
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||||
@ -70,6 +72,8 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
|
|||||||
{
|
{
|
||||||
*okay = 0;
|
*okay = 0;
|
||||||
*off = 3;
|
*off = 3;
|
||||||
|
while (line[*off] == ' ')
|
||||||
|
++*off;
|
||||||
}
|
}
|
||||||
else if (linelen >= 7
|
else if (linelen >= 7
|
||||||
&& line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
|
&& line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
|
||||||
@ -79,6 +83,8 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
|
|||||||
{
|
{
|
||||||
*okay = 3;
|
*okay = 3;
|
||||||
*off = 7;
|
*off = 7;
|
||||||
|
while (line[*off] == ' ')
|
||||||
|
++*off;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = ASSUAN_Invalid_Response;
|
rc = ASSUAN_Invalid_Response;
|
||||||
|
@ -33,208 +33,18 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
#ifdef _POSIX_OPEN_MAX
|
/* Disconnect and release the context CTX. */
|
||||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
|
||||||
#else
|
|
||||||
#define MAX_OPEN_FDS 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
#include "../jnlib/logging.h"
|
|
||||||
#define LOGERROR1(a,b) log_error ((a), (b))
|
|
||||||
#else
|
|
||||||
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
writen ( int fd, const char *buffer, size_t length )
|
|
||||||
{
|
|
||||||
while (length)
|
|
||||||
{
|
|
||||||
int nwritten = write (fd, buffer, length);
|
|
||||||
|
|
||||||
if (nwritten < 0)
|
|
||||||
{
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
return -1; /* write error */
|
|
||||||
}
|
|
||||||
length -= nwritten;
|
|
||||||
buffer += nwritten;
|
|
||||||
}
|
|
||||||
return 0; /* okay */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect to a server over a pipe, creating the assuan context and
|
|
||||||
returning it in CTX. The server filename is NAME, the argument
|
|
||||||
vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file
|
|
||||||
descriptors not to close in the child. */
|
|
||||||
AssuanError
|
|
||||||
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
|
||||||
int *fd_child_list)
|
|
||||||
{
|
|
||||||
static int fixed_signals = 0;
|
|
||||||
AssuanError err;
|
|
||||||
int rp[2];
|
|
||||||
int wp[2];
|
|
||||||
int fd[2];
|
|
||||||
|
|
||||||
if (!ctx || !name || !argv || !argv[0])
|
|
||||||
return ASSUAN_Invalid_Value;
|
|
||||||
|
|
||||||
if (!fixed_signals)
|
|
||||||
{
|
|
||||||
struct sigaction act;
|
|
||||||
|
|
||||||
sigaction (SIGPIPE, NULL, &act);
|
|
||||||
if (act.sa_handler == SIG_DFL)
|
|
||||||
{
|
|
||||||
act.sa_handler = SIG_IGN;
|
|
||||||
sigemptyset (&act.sa_mask);
|
|
||||||
act.sa_flags = 0;
|
|
||||||
sigaction (SIGPIPE, &act, NULL);
|
|
||||||
}
|
|
||||||
fixed_signals = 1;
|
|
||||||
/* FIXME: This is not MT safe */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipe (rp) < 0)
|
|
||||||
return ASSUAN_General_Error;
|
|
||||||
|
|
||||||
if (pipe (wp) < 0)
|
|
||||||
{
|
|
||||||
close (rp[0]);
|
|
||||||
close (rp[1]);
|
|
||||||
return ASSUAN_General_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd[0] = rp[0]; /* Our inbound is read end of read pipe. */
|
|
||||||
fd[1] = wp[1]; /* Our outbound is write end of write pipe. */
|
|
||||||
|
|
||||||
err = assuan_init_pipe_server (ctx, fd); /* FIXME: Common code should be factored out. */
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
close (rp[0]);
|
|
||||||
close (rp[1]);
|
|
||||||
close (wp[0]);
|
|
||||||
close (wp[1]);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
(*ctx)->is_server = 0;
|
|
||||||
|
|
||||||
(*ctx)->pid = fork ();
|
|
||||||
if ((*ctx)->pid < 0)
|
|
||||||
{
|
|
||||||
close (rp[0]);
|
|
||||||
close (rp[1]);
|
|
||||||
close (wp[0]);
|
|
||||||
close (wp[1]);
|
|
||||||
assuan_deinit_pipe_server (*ctx); /* FIXME: Common code should be factored out. */
|
|
||||||
return ASSUAN_General_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*ctx)->pid == 0)
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
char errbuf[512];
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
int log_fd = log_get_fd ();
|
|
||||||
#endif
|
|
||||||
/* close all files which will not be duped but keep stderr
|
|
||||||
and log_stream for now */
|
|
||||||
n = sysconf (_SC_OPEN_MAX);
|
|
||||||
if (n < 0)
|
|
||||||
n = MAX_OPEN_FDS;
|
|
||||||
for (i=0; i < n; i++)
|
|
||||||
{
|
|
||||||
int *fdp = fd_child_list;
|
|
||||||
|
|
||||||
if (fdp)
|
|
||||||
{
|
|
||||||
while (*fdp != -1 && *fdp != i)
|
|
||||||
fdp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(fdp && *fdp != -1)
|
|
||||||
&& i != fileno (stderr)
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
&& i != log_fd
|
|
||||||
#endif
|
|
||||||
&& i != rp[1] && i != wp[0])
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
/* Dup handles and to stdin/stdout and exec */
|
|
||||||
if (rp[1] != STDOUT_FILENO)
|
|
||||||
{
|
|
||||||
if (dup2 (rp[1], STDOUT_FILENO) == -1)
|
|
||||||
{
|
|
||||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
|
||||||
_exit (4);
|
|
||||||
}
|
|
||||||
close (rp[1]);
|
|
||||||
}
|
|
||||||
if (wp[0] != STDIN_FILENO)
|
|
||||||
{
|
|
||||||
if (dup2 (wp[0], STDIN_FILENO) == -1)
|
|
||||||
{
|
|
||||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
|
||||||
_exit (4);
|
|
||||||
}
|
|
||||||
close (wp[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
execv (name, argv);
|
|
||||||
/* oops - use the pipe to tell the parent about it */
|
|
||||||
snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n",
|
|
||||||
ASSUAN_Problem_Starting_Server, name, strerror (errno));
|
|
||||||
errbuf[sizeof(errbuf)-1] = 0;
|
|
||||||
writen (1, errbuf, strlen (errbuf));
|
|
||||||
_exit (4);
|
|
||||||
}
|
|
||||||
|
|
||||||
close (rp[1]);
|
|
||||||
close (wp[0]);
|
|
||||||
|
|
||||||
/* initial handshake */
|
|
||||||
{
|
|
||||||
int okay, off;
|
|
||||||
|
|
||||||
err = _assuan_read_from_server (*ctx, &okay, &off);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
|
||||||
}
|
|
||||||
else if (okay != 1)
|
|
||||||
{
|
|
||||||
LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
|
|
||||||
err = ASSUAN_Connect_Failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
if ((*ctx)->pid != -1)
|
|
||||||
waitpid ((*ctx)->pid, NULL, 0); /* FIXME Check return value. */
|
|
||||||
assuan_deinit_pipe_server (*ctx); /* FIXME: Common code should be factored out. */
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
assuan_pipe_disconnect (ASSUAN_CONTEXT ctx)
|
assuan_disconnect (ASSUAN_CONTEXT ctx)
|
||||||
{
|
{
|
||||||
assuan_write_line (ctx, "BYE");
|
if (ctx)
|
||||||
close (ctx->inbound.fd);
|
{
|
||||||
close (ctx->outbound.fd);
|
assuan_write_line (ctx, "BYE");
|
||||||
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
|
ctx->finish_handler (ctx);
|
||||||
assuan_deinit_pipe_server (ctx);
|
ctx->deinit_handler (ctx);
|
||||||
|
ctx->deinit_handler = NULL;
|
||||||
|
_assuan_release_context (ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t
|
pid_t
|
||||||
@ -242,5 +52,3 @@ assuan_get_pid (ASSUAN_CONTEXT ctx)
|
|||||||
{
|
{
|
||||||
return ctx ? ctx->pid : -1;
|
return ctx ? ctx->pid : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,13 +35,18 @@ struct cmdtbl_s {
|
|||||||
struct assuan_context_s {
|
struct assuan_context_s {
|
||||||
AssuanError err_no;
|
AssuanError err_no;
|
||||||
const char *err_str;
|
const char *err_str;
|
||||||
|
int os_errno; /* last system error number used with certain error codes*/
|
||||||
|
|
||||||
|
int confidential;
|
||||||
int is_server; /* set if this is context belongs to a server */
|
int is_server; /* set if this is context belongs to a server */
|
||||||
int in_inquire;
|
int in_inquire;
|
||||||
char *hello_line;
|
char *hello_line;
|
||||||
|
char *okay_line; /* see assan_set_okay_line() */
|
||||||
|
|
||||||
void *user_pointer; /* for assuan_[gs]et_pointer () */
|
void *user_pointer; /* for assuan_[gs]et_pointer () */
|
||||||
|
|
||||||
|
FILE *log_fp;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int fd;
|
int fd;
|
||||||
int eof;
|
int eof;
|
||||||
@ -68,7 +73,13 @@ struct assuan_context_s {
|
|||||||
|
|
||||||
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
|
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
|
||||||
connection and must terminate then */
|
connection and must terminate then */
|
||||||
pid_t pid; /* In pipe mode, the pid of the child server process. */
|
pid_t pid; /* In pipe mode, the pid of the child server process.
|
||||||
|
In socket mode, the pid of the server */
|
||||||
|
int listen_fd; /* The fd we are listening on (used by socket servers) */
|
||||||
|
|
||||||
|
void (*deinit_handler)(ASSUAN_CONTEXT);
|
||||||
|
int (*accept_handler)(ASSUAN_CONTEXT);
|
||||||
|
int (*finish_handler)(ASSUAN_CONTEXT);
|
||||||
|
|
||||||
struct cmdtbl_s *cmdtbl;
|
struct cmdtbl_s *cmdtbl;
|
||||||
size_t cmdtbl_used; /* used entries */
|
size_t cmdtbl_used; /* used entries */
|
||||||
@ -77,6 +88,7 @@ struct assuan_context_s {
|
|||||||
void (*bye_notify_fnc)(ASSUAN_CONTEXT);
|
void (*bye_notify_fnc)(ASSUAN_CONTEXT);
|
||||||
void (*reset_notify_fnc)(ASSUAN_CONTEXT);
|
void (*reset_notify_fnc)(ASSUAN_CONTEXT);
|
||||||
void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
|
void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
|
||||||
|
int (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*);
|
||||||
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 *);
|
||||||
|
|
||||||
@ -84,11 +96,14 @@ struct assuan_context_s {
|
|||||||
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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*-- assuan-pipe-server.c --*/
|
||||||
|
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
|
||||||
|
void _assuan_release_context (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
|
|
||||||
/*-- assuan-handler.c --*/
|
/*-- assuan-handler.c --*/
|
||||||
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
|
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
@ -114,6 +129,9 @@ void _assuan_free (void *p);
|
|||||||
|
|
||||||
#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t))
|
#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t))
|
||||||
|
|
||||||
|
void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
|
||||||
|
void _assuan_log_sanitized_string (const char *string);
|
||||||
|
|
||||||
|
|
||||||
#endif /*ASSUAN_DEFS_H*/
|
#endif /*ASSUAN_DEFS_H*/
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
|
||||||
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +50,53 @@ std_handler_cancel (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
return set_error (ctx, Not_Implemented, NULL);
|
return set_error (ctx, Not_Implemented, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
std_handler_option (ASSUAN_CONTEXT ctx, char *line)
|
||||||
|
{
|
||||||
|
char *key, *value, *p;
|
||||||
|
|
||||||
|
for (key=line; spacep (key); key++)
|
||||||
|
;
|
||||||
|
if (!*key)
|
||||||
|
return set_error (ctx, Syntax_Error, "argument required");
|
||||||
|
if (*key == '=')
|
||||||
|
return set_error (ctx, Syntax_Error, "no option name given");
|
||||||
|
for (value=key; *value && !spacep (value) && *value != '='; value++)
|
||||||
|
;
|
||||||
|
if (*value)
|
||||||
|
{
|
||||||
|
if (spacep (value))
|
||||||
|
*value++ = 0; /* terminate key */
|
||||||
|
for (; spacep (value); value++)
|
||||||
|
;
|
||||||
|
if (*value == '=')
|
||||||
|
{
|
||||||
|
*value++ = 0; /* terminate key */
|
||||||
|
for (; spacep (value); value++)
|
||||||
|
;
|
||||||
|
if (!*value)
|
||||||
|
return set_error (ctx, Syntax_Error, "option argument expected");
|
||||||
|
}
|
||||||
|
if (*value)
|
||||||
|
{
|
||||||
|
for (p = value + strlen(value) - 1; p > value && spacep (p); p--)
|
||||||
|
;
|
||||||
|
if (p > value)
|
||||||
|
*++p = 0; /* strip trailing spaces */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*key == '-' && key[1] == '-' && key[2])
|
||||||
|
key += 2; /* the double dashes are optional */
|
||||||
|
if (*key == '-')
|
||||||
|
return set_error (ctx, Syntax_Error,
|
||||||
|
"option should not begin with one dash");
|
||||||
|
|
||||||
|
if (ctx->option_handler_fnc)
|
||||||
|
return ctx->option_handler_fnc (ctx, key, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
|
std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
|
||||||
{
|
{
|
||||||
@ -147,6 +195,7 @@ static struct {
|
|||||||
} std_cmd_table[] = {
|
} std_cmd_table[] = {
|
||||||
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
|
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
|
||||||
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
|
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
|
||||||
|
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
||||||
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
|
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
|
||||||
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
|
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
|
||||||
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
|
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
|
||||||
@ -154,6 +203,7 @@ static struct {
|
|||||||
|
|
||||||
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
|
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
|
||||||
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
|
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
|
||||||
|
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -262,6 +312,17 @@ assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
assuan_register_option_handler (ASSUAN_CONTEXT ctx,
|
||||||
|
int (*fnc)(ASSUAN_CONTEXT,
|
||||||
|
const char*, const char*))
|
||||||
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
ctx->option_handler_fnc = fnc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
assuan_register_input_notify (ASSUAN_CONTEXT ctx,
|
assuan_register_input_notify (ASSUAN_CONTEXT ctx,
|
||||||
void (*fnc)(ASSUAN_CONTEXT, const char *))
|
void (*fnc)(ASSUAN_CONTEXT, const char *))
|
||||||
@ -312,6 +373,20 @@ handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen)
|
|||||||
return set_error (ctx, Not_Implemented, NULL);
|
return set_error (ctx, Not_Implemented, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* like ascii_strcasecmp but assume that B is already uppercase */
|
||||||
|
static int
|
||||||
|
my_strcasecmp (const char *a, const char *b)
|
||||||
|
{
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (; *a && *b; a++, b++)
|
||||||
|
{
|
||||||
|
if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the line, break out the command, find it in the command
|
/* Parse the line, break out the command, find it in the command
|
||||||
table, remove leading and white spaces from the arguments, all the
|
table, remove leading and white spaces from the arguments, all the
|
||||||
@ -339,8 +414,18 @@ dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen)
|
|||||||
shift = p - line;
|
shift = p - line;
|
||||||
|
|
||||||
for (i=0; (s=ctx->cmdtbl[i].name); i++)
|
for (i=0; (s=ctx->cmdtbl[i].name); i++)
|
||||||
if (!strcmp (line, s))
|
{
|
||||||
break;
|
if (!strcmp (line, s))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!s)
|
||||||
|
{ /* and try case insensitive */
|
||||||
|
for (i=0; (s=ctx->cmdtbl[i].name); i++)
|
||||||
|
{
|
||||||
|
if (!my_strcasecmp (line, s))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!s)
|
if (!s)
|
||||||
return set_error (ctx, Unknown_Command, NULL);
|
return set_error (ctx, Unknown_Command, NULL);
|
||||||
line += shift;
|
line += shift;
|
||||||
@ -382,17 +467,18 @@ process_request (ASSUAN_CONTEXT ctx)
|
|||||||
/* Error handling */
|
/* Error handling */
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
rc = assuan_write_line (ctx, "OK");
|
rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK");
|
||||||
}
|
}
|
||||||
else if (rc == -1)
|
else if (rc == -1)
|
||||||
{ /* No error checking because the peer may have already disconnect */
|
{ /* No error checking because the peer may have already disconnect */
|
||||||
assuan_write_line (ctx, "OK closing connection");
|
assuan_write_line (ctx, "OK closing connection");
|
||||||
|
ctx->finish_handler (ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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
|
||||||
@ -405,6 +491,12 @@ process_request (ASSUAN_CONTEXT ctx)
|
|||||||
rc = assuan_write_line (ctx, errline);
|
rc = assuan_write_line (ctx, errline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->confidential = 0;
|
||||||
|
if (ctx->okay_line)
|
||||||
|
{
|
||||||
|
xfree (ctx->okay_line);
|
||||||
|
ctx->okay_line = NULL;
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,6 +614,35 @@ assuan_get_data_fp (ASSUAN_CONTEXT ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the text used for the next OK reponse. This string is
|
||||||
|
automatically reset to NULL after the next command. */
|
||||||
|
AssuanError
|
||||||
|
assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
|
||||||
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
if (!line)
|
||||||
|
{
|
||||||
|
xfree (ctx->okay_line);
|
||||||
|
ctx->okay_line = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: we need to use gcry_is_secure() to test whether
|
||||||
|
we should allocate the entire line in secure memory */
|
||||||
|
char *buf = xtrymalloc (3+strlen(line)+1);
|
||||||
|
if (!buf)
|
||||||
|
return ASSUAN_Out_Of_Core;
|
||||||
|
strcpy (buf, "OK ");
|
||||||
|
strcpy (buf+3, line);
|
||||||
|
xfree (ctx->okay_line);
|
||||||
|
ctx->okay_line = buf;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
|
assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-inquire.c - handle inquire stuff
|
/* assuan-inquire.c - handle inquire stuff
|
||||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -56,7 +56,8 @@ init_membuf (struct membuf *mb, int initiallen, size_t maxlen)
|
|||||||
mb->out_of_core = 0;
|
mb->out_of_core = 0;
|
||||||
mb->too_large = 0;
|
mb->too_large = 0;
|
||||||
mb->maxlen = maxlen;
|
mb->maxlen = maxlen;
|
||||||
mb->buf = xtrymalloc (initiallen);
|
/* we need to allocate one byte more for get_membuf */
|
||||||
|
mb->buf = xtrymalloc (initiallen+1);
|
||||||
if (!mb->buf)
|
if (!mb->buf)
|
||||||
mb->out_of_core = 1;
|
mb->out_of_core = 1;
|
||||||
}
|
}
|
||||||
@ -78,7 +79,8 @@ put_membuf (struct membuf *mb, const void *buf, size_t len)
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
mb->size += len + 1024;
|
mb->size += len + 1024;
|
||||||
p = xtryrealloc (mb->buf, mb->size);
|
/* we need to allocate one byte more for get_membuf */
|
||||||
|
p = xtryrealloc (mb->buf, mb->size+1);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
mb->out_of_core = 1;
|
mb->out_of_core = 1;
|
||||||
@ -102,6 +104,7 @@ get_membuf (struct membuf *mb, size_t *len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */
|
||||||
p = mb->buf;
|
p = mb->buf;
|
||||||
*len = mb->len;
|
*len = mb->len;
|
||||||
mb->buf = NULL;
|
mb->buf = NULL;
|
||||||
|
@ -69,15 +69,13 @@ assuan_accept (ASSUAN_CONTEXT ctx)
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return ASSUAN_Invalid_Value;
|
return ASSUAN_Invalid_Value;
|
||||||
|
|
||||||
/* fixme: cancel existing connection */
|
|
||||||
if (ctx->pipe_mode > 1)
|
if (ctx->pipe_mode > 1)
|
||||||
return -1; /* second invocation for pipemode -> terminate */
|
return -1; /* second invocation for pipemode -> terminate */
|
||||||
|
ctx->finish_handler (ctx);
|
||||||
|
|
||||||
if (!ctx->pipe_mode)
|
rc = ctx->accept_handler (ctx);
|
||||||
{
|
if (rc)
|
||||||
|
return rc;
|
||||||
/* fixme: wait for request */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send the hello */
|
/* send the hello */
|
||||||
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
|
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
|
||||||
|
269
assuan/assuan-pipe-connect.c
Normal file
269
assuan/assuan-pipe-connect.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/* assuan-pipe-connect.c - Establish a pipe connection (client)
|
||||||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
#ifdef _POSIX_OPEN_MAX
|
||||||
|
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
||||||
|
#else
|
||||||
|
#define MAX_OPEN_FDS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
#include "../jnlib/logging.h"
|
||||||
|
#define LOGERROR1(a,b) log_error ((a), (b))
|
||||||
|
#else
|
||||||
|
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
writen ( int fd, const char *buffer, size_t length )
|
||||||
|
{
|
||||||
|
while (length)
|
||||||
|
{
|
||||||
|
int nwritten = write (fd, buffer, length);
|
||||||
|
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
return -1; /* write error */
|
||||||
|
}
|
||||||
|
length -= nwritten;
|
||||||
|
buffer += nwritten;
|
||||||
|
}
|
||||||
|
return 0; /* okay */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_finish (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx->inbound.fd != -1)
|
||||||
|
{
|
||||||
|
close (ctx->inbound.fd);
|
||||||
|
ctx->inbound.fd = -1;
|
||||||
|
}
|
||||||
|
if (ctx->outbound.fd != -1)
|
||||||
|
{
|
||||||
|
close (ctx->outbound.fd);
|
||||||
|
ctx->outbound.fd = -1;
|
||||||
|
}
|
||||||
|
if (ctx->pid != -1)
|
||||||
|
{
|
||||||
|
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
|
||||||
|
ctx->pid = -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_deinit (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
do_finish (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Connect to a server over a pipe, creating the assuan context and
|
||||||
|
returning it in CTX. The server filename is NAME, the argument
|
||||||
|
vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file
|
||||||
|
descriptors not to close in the child. */
|
||||||
|
AssuanError
|
||||||
|
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
||||||
|
int *fd_child_list)
|
||||||
|
{
|
||||||
|
static int fixed_signals = 0;
|
||||||
|
AssuanError err;
|
||||||
|
int rp[2];
|
||||||
|
int wp[2];
|
||||||
|
|
||||||
|
if (!ctx || !name || !argv || !argv[0])
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
|
||||||
|
if (!fixed_signals)
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
|
||||||
|
sigaction (SIGPIPE, NULL, &act);
|
||||||
|
if (act.sa_handler == SIG_DFL)
|
||||||
|
{
|
||||||
|
act.sa_handler = SIG_IGN;
|
||||||
|
sigemptyset (&act.sa_mask);
|
||||||
|
act.sa_flags = 0;
|
||||||
|
sigaction (SIGPIPE, &act, NULL);
|
||||||
|
}
|
||||||
|
fixed_signals = 1;
|
||||||
|
/* FIXME: This is not MT safe */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipe (rp) < 0)
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
|
||||||
|
if (pipe (wp) < 0)
|
||||||
|
{
|
||||||
|
close (rp[0]);
|
||||||
|
close (rp[1]);
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = _assuan_new_context (ctx);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
close (rp[0]);
|
||||||
|
close (rp[1]);
|
||||||
|
close (wp[0]);
|
||||||
|
close (wp[1]);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
(*ctx)->pipe_mode = 1;
|
||||||
|
(*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */
|
||||||
|
(*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */
|
||||||
|
(*ctx)->deinit_handler = do_deinit;
|
||||||
|
(*ctx)->finish_handler = do_finish;
|
||||||
|
|
||||||
|
(*ctx)->pid = fork ();
|
||||||
|
if ((*ctx)->pid < 0)
|
||||||
|
{
|
||||||
|
close (rp[0]);
|
||||||
|
close (rp[1]);
|
||||||
|
close (wp[0]);
|
||||||
|
close (wp[1]);
|
||||||
|
_assuan_release_context (*ctx);
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*ctx)->pid == 0)
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
char errbuf[512];
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
int log_fd = log_get_fd ();
|
||||||
|
#endif
|
||||||
|
/* close all files which will not be duped but keep stderr
|
||||||
|
and log_stream for now */
|
||||||
|
n = sysconf (_SC_OPEN_MAX);
|
||||||
|
if (n < 0)
|
||||||
|
n = MAX_OPEN_FDS;
|
||||||
|
for (i=0; i < n; i++)
|
||||||
|
{
|
||||||
|
int *fdp = fd_child_list;
|
||||||
|
|
||||||
|
if (fdp)
|
||||||
|
{
|
||||||
|
while (*fdp != -1 && *fdp != i)
|
||||||
|
fdp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fdp && *fdp != -1)
|
||||||
|
&& i != fileno (stderr)
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
&& i != log_fd
|
||||||
|
#endif
|
||||||
|
&& i != rp[1] && i != wp[0])
|
||||||
|
close(i);
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* Dup handles and to stdin/stdout and exec */
|
||||||
|
if (rp[1] != STDOUT_FILENO)
|
||||||
|
{
|
||||||
|
if (dup2 (rp[1], STDOUT_FILENO) == -1)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
||||||
|
_exit (4);
|
||||||
|
}
|
||||||
|
close (rp[1]);
|
||||||
|
}
|
||||||
|
if (wp[0] != STDIN_FILENO)
|
||||||
|
{
|
||||||
|
if (dup2 (wp[0], STDIN_FILENO) == -1)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
||||||
|
_exit (4);
|
||||||
|
}
|
||||||
|
close (wp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
execv (name, argv);
|
||||||
|
/* oops - use the pipe to tell the parent about it */
|
||||||
|
snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n",
|
||||||
|
ASSUAN_Problem_Starting_Server, name, strerror (errno));
|
||||||
|
errbuf[sizeof(errbuf)-1] = 0;
|
||||||
|
writen (1, errbuf, strlen (errbuf));
|
||||||
|
_exit (4);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (rp[1]);
|
||||||
|
close (wp[0]);
|
||||||
|
|
||||||
|
/* initial handshake */
|
||||||
|
{
|
||||||
|
int okay, off;
|
||||||
|
|
||||||
|
err = _assuan_read_from_server (*ctx, &okay, &off);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
||||||
|
}
|
||||||
|
else if (okay != 1)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
|
||||||
|
err = ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
assuan_disconnect (*ctx);
|
||||||
|
*ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,9 +24,31 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
deinit_pipe_server (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
/* nothing to do for this simple server */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
accept_connection (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
/* This is a NOP for a pipe server */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
finish_connection (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
/* This is a NOP for a pipe server */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a new context. Note that the handlers are set up for a pipe
|
||||||
|
server/client - this wau we don't need extra dummy functions */
|
||||||
int
|
int
|
||||||
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
|
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
|
||||||
{
|
{
|
||||||
ASSUAN_CONTEXT ctx;
|
ASSUAN_CONTEXT ctx;
|
||||||
int rc;
|
int rc;
|
||||||
@ -35,14 +57,17 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
|
|||||||
ctx = xtrycalloc (1, sizeof *ctx);
|
ctx = xtrycalloc (1, sizeof *ctx);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return ASSUAN_Out_Of_Core;
|
return ASSUAN_Out_Of_Core;
|
||||||
ctx->is_server = 1;
|
|
||||||
ctx->input_fd = -1;
|
ctx->input_fd = -1;
|
||||||
ctx->output_fd = -1;
|
ctx->output_fd = -1;
|
||||||
|
|
||||||
ctx->inbound.fd = filedes[0];
|
ctx->inbound.fd = -1;
|
||||||
ctx->outbound.fd = filedes[1];
|
ctx->outbound.fd = -1;
|
||||||
|
|
||||||
ctx->pipe_mode = 1;
|
ctx->listen_fd = -1;
|
||||||
|
/* use the pipe server handler as a default */
|
||||||
|
ctx->deinit_handler = deinit_pipe_server;
|
||||||
|
ctx->accept_handler = accept_connection;
|
||||||
|
ctx->finish_handler = finish_connection;
|
||||||
|
|
||||||
rc = _assuan_register_std_commands (ctx);
|
rc = _assuan_register_std_commands (ctx);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -52,22 +77,47 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = _assuan_new_context (r_ctx);
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
ASSUAN_CONTEXT ctx = *r_ctx;
|
||||||
|
|
||||||
|
ctx->is_server = 1;
|
||||||
|
ctx->inbound.fd = filedes[0];
|
||||||
|
ctx->outbound.fd = filedes[1];
|
||||||
|
ctx->pipe_mode = 1;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
|
_assuan_release_context (ASSUAN_CONTEXT ctx)
|
||||||
{
|
{
|
||||||
if (ctx)
|
if (ctx)
|
||||||
{
|
{
|
||||||
xfree (ctx->hello_line);
|
xfree (ctx->hello_line);
|
||||||
|
xfree (ctx->okay_line);
|
||||||
xfree (ctx);
|
xfree (ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
assuan_deinit_server (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
/* We use this function pointer to avoid linking other server
|
||||||
|
when not needed but still allow for a generic deinit function */
|
||||||
|
ctx->deinit_handler (ctx);
|
||||||
|
ctx->deinit_handler = NULL;
|
||||||
|
_assuan_release_context (ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
150
assuan/assuan-socket-connect.c
Normal file
150
assuan/assuan-socket-connect.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* assuan-socket-connect.c - Assuan socket based client
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
#include "../jnlib/logging.h"
|
||||||
|
#define LOGERROR(a) log_error ((a))
|
||||||
|
#define LOGERROR1(a,b) log_error ((a), (b))
|
||||||
|
#define LOGERROR2(a,b,c) log_error ((a), (b), (c))
|
||||||
|
#define LOGERRORX(a) log_printf ((a))
|
||||||
|
#else
|
||||||
|
#define LOGERROR(a) fprintf (stderr, (a))
|
||||||
|
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
||||||
|
#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c))
|
||||||
|
#define LOGERRORX(a) fputs ((a), stderror)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_finish (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx->inbound.fd != -1)
|
||||||
|
{
|
||||||
|
close (ctx->inbound.fd);
|
||||||
|
}
|
||||||
|
ctx->inbound.fd = -1;
|
||||||
|
ctx->outbound.fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_deinit (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
do_finish (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Make a connection to the Unix domain socket NAME and return a new
|
||||||
|
Assuan context in CTX. SERVER_PID is currently not used but may
|
||||||
|
becode handy in future. */
|
||||||
|
AssuanError
|
||||||
|
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
||||||
|
const char *name, pid_t server_pid)
|
||||||
|
{
|
||||||
|
AssuanError err;
|
||||||
|
ASSUAN_CONTEXT ctx;
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un srvr_addr;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!r_ctx || !name)
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
*r_ctx = NULL;
|
||||||
|
|
||||||
|
/* we require that the name starts with a slash, so that we can
|
||||||
|
alter reuse this function for other socket types */
|
||||||
|
if (*name != '/')
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
if (strlen (name)+1 >= sizeof srvr_addr.sun_path)
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
|
||||||
|
err = _assuan_new_context (&ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
ctx->pid = server_pid; /* save it in case we need it later */
|
||||||
|
ctx->deinit_handler = do_deinit;
|
||||||
|
ctx->finish_handler = do_finish;
|
||||||
|
|
||||||
|
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("can't create socket: %s\n", strerror (errno));
|
||||||
|
_assuan_release_context (ctx);
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&srvr_addr, 0, sizeof srvr_addr );
|
||||||
|
srvr_addr.sun_family = AF_UNIX;
|
||||||
|
strcpy (srvr_addr.sun_path, name);
|
||||||
|
len = (offsetof (struct sockaddr_un, sun_path)
|
||||||
|
+ strlen (srvr_addr.sun_path) + 1);
|
||||||
|
|
||||||
|
if (connect (fd, (struct sockaddr*)&srvr_addr, len) == -1)
|
||||||
|
{
|
||||||
|
LOGERROR2 ("can't connect to `%s': %s\n", name, strerror (errno));
|
||||||
|
_assuan_release_context (ctx);
|
||||||
|
close (fd );
|
||||||
|
return ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->inbound.fd = fd;
|
||||||
|
ctx->outbound.fd = fd;
|
||||||
|
|
||||||
|
/* initial handshake */
|
||||||
|
{
|
||||||
|
int okay, off;
|
||||||
|
|
||||||
|
err = _assuan_read_from_server (ctx, &okay, &off);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
||||||
|
}
|
||||||
|
else if (okay != 1)
|
||||||
|
{
|
||||||
|
LOGERROR ("can't connect server: `");
|
||||||
|
_assuan_log_sanitized_string (ctx->inbound.line);
|
||||||
|
LOGERRORX ("'\n");
|
||||||
|
err = ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
assuan_disconnect (ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*r_ctx = ctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
121
assuan/assuan-socket-server.c
Normal file
121
assuan/assuan-socket-server.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* assuan-socket-server.c - Assuan socket based server
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
accept_connection (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un clnt_addr;
|
||||||
|
size_t len = sizeof clnt_addr;
|
||||||
|
|
||||||
|
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
ctx->os_errno = errno;
|
||||||
|
return ASSUAN_Accept_Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->inbound.fd = fd;
|
||||||
|
ctx->inbound.eof = 0;
|
||||||
|
ctx->inbound.linelen = 0;
|
||||||
|
ctx->inbound.attic.linelen = 0;
|
||||||
|
ctx->inbound.attic.pending = 0;
|
||||||
|
|
||||||
|
ctx->outbound.fd = fd;
|
||||||
|
ctx->outbound.data.linelen = 0;
|
||||||
|
ctx->outbound.data.error = 0;
|
||||||
|
|
||||||
|
ctx->confidential = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
finish_connection (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx->inbound.fd != -1)
|
||||||
|
{
|
||||||
|
close (ctx->inbound.fd);
|
||||||
|
}
|
||||||
|
ctx->inbound.fd = -1;
|
||||||
|
ctx->outbound.fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
deinit_socket_server (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
finish_connection (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize a server for the socket LISTEN_FD which has already be
|
||||||
|
put into listen mode */
|
||||||
|
int
|
||||||
|
assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
|
||||||
|
{
|
||||||
|
ASSUAN_CONTEXT ctx;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
*r_ctx = NULL;
|
||||||
|
ctx = xtrycalloc (1, sizeof *ctx);
|
||||||
|
if (!ctx)
|
||||||
|
return ASSUAN_Out_Of_Core;
|
||||||
|
ctx->is_server = 1;
|
||||||
|
ctx->input_fd = -1;
|
||||||
|
ctx->output_fd = -1;
|
||||||
|
|
||||||
|
ctx->inbound.fd = -1;
|
||||||
|
ctx->outbound.fd = -1;
|
||||||
|
|
||||||
|
ctx->listen_fd = listen_fd;
|
||||||
|
ctx->deinit_handler = deinit_socket_server;
|
||||||
|
ctx->accept_handler = accept_connection;
|
||||||
|
ctx->finish_handler = finish_connection;
|
||||||
|
|
||||||
|
rc = _assuan_register_std_commands (ctx);
|
||||||
|
if (rc)
|
||||||
|
xfree (ctx);
|
||||||
|
else
|
||||||
|
*r_ctx = ctx;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
#include "../jnlib/logging.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void *(*alloc_func)(size_t n) = malloc;
|
static void *(*alloc_func)(size_t n) = malloc;
|
||||||
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
||||||
@ -96,3 +100,97 @@ assuan_get_pointer (ASSUAN_CONTEXT ctx)
|
|||||||
return ctx? ctx->user_pointer : NULL;
|
return ctx? ctx->user_pointer : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
if (ctx->log_fp)
|
||||||
|
fflush (ctx->log_fp);
|
||||||
|
ctx->log_fp = fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
assuan_begin_confidential (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
ctx->confidential = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
assuan_end_confidential (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
ctx->confidential = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
const unsigned char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n=length,s=buffer; n; n--, s++)
|
||||||
|
{
|
||||||
|
if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = buffer;
|
||||||
|
if (!n && *s != '[')
|
||||||
|
fwrite (buffer, length, 1, fp);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putc ('[', fp);
|
||||||
|
for (n=0; n < length; n++, s++)
|
||||||
|
fprintf (fp, " %02x", *s);
|
||||||
|
putc (' ', fp);
|
||||||
|
putc (']', fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* print a user supplied string after filtering out potential bad
|
||||||
|
characters*/
|
||||||
|
void
|
||||||
|
_assuan_log_sanitized_string (const char *string)
|
||||||
|
{
|
||||||
|
const unsigned char *s = string;
|
||||||
|
#ifdef HAVE_JNLIB_LOGGING
|
||||||
|
FILE *fp = log_get_stream ();
|
||||||
|
#else
|
||||||
|
FILE *fp = stderr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (; *s; s++)
|
||||||
|
{
|
||||||
|
if (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
|
||||||
|
{
|
||||||
|
putc ('\\', fp);
|
||||||
|
if (*s == '\n')
|
||||||
|
putc ('n', fp);
|
||||||
|
else if (*s == '\r')
|
||||||
|
putc ('r', fp);
|
||||||
|
else if (*s == '\f')
|
||||||
|
putc ('f', fp);
|
||||||
|
else if (*s == '\v')
|
||||||
|
putc ('v', fp);
|
||||||
|
else if (*s == '\b')
|
||||||
|
putc ('b', fp);
|
||||||
|
else if (!*s)
|
||||||
|
putc ('0', fp);
|
||||||
|
else
|
||||||
|
fprintf (fp, "x%02x", *s );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
putc (*s, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan.c - Definitions for the Assuna protocol
|
/* assuan.c - Definitions for the Assuna protocol
|
||||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -47,6 +47,7 @@ typedef enum {
|
|||||||
ASSUAN_No_Data_Callback = 12,
|
ASSUAN_No_Data_Callback = 12,
|
||||||
ASSUAN_No_Inquire_Callback = 13,
|
ASSUAN_No_Inquire_Callback = 13,
|
||||||
ASSUAN_Connect_Failed = 14,
|
ASSUAN_Connect_Failed = 14,
|
||||||
|
ASSUAN_Accept_Failed = 15,
|
||||||
|
|
||||||
/* error codes above 99 are meant as status codes */
|
/* error codes above 99 are meant as status codes */
|
||||||
ASSUAN_Not_Implemented = 100,
|
ASSUAN_Not_Implemented = 100,
|
||||||
@ -69,6 +70,9 @@ typedef enum {
|
|||||||
ASSUAN_Invalid_Data = 117,
|
ASSUAN_Invalid_Data = 117,
|
||||||
ASSUAN_Unexpected_Command = 118,
|
ASSUAN_Unexpected_Command = 118,
|
||||||
ASSUAN_Too_Much_Data = 119,
|
ASSUAN_Too_Much_Data = 119,
|
||||||
|
ASSUAN_Inquire_Unknown = 120,
|
||||||
|
ASSUAN_Inquire_Error = 121,
|
||||||
|
ASSUAN_Invalid_Option = 122,
|
||||||
|
|
||||||
ASSUAN_Bad_Certificate = 201,
|
ASSUAN_Bad_Certificate = 201,
|
||||||
ASSUAN_Bad_Certificate_Path = 202,
|
ASSUAN_Bad_Certificate_Path = 202,
|
||||||
@ -83,6 +87,7 @@ typedef enum {
|
|||||||
ASSUAN_Cert_Revoked = 301,
|
ASSUAN_Cert_Revoked = 301,
|
||||||
ASSUAN_No_CRL_For_Cert = 302,
|
ASSUAN_No_CRL_For_Cert = 302,
|
||||||
ASSUAN_CRL_Too_Old = 303,
|
ASSUAN_CRL_Too_Old = 303,
|
||||||
|
ASSUAN_Not_Trusted = 304,
|
||||||
|
|
||||||
} AssuanError;
|
} AssuanError;
|
||||||
|
|
||||||
@ -93,6 +98,7 @@ typedef enum {
|
|||||||
ASSUAN_CMD_BYE,
|
ASSUAN_CMD_BYE,
|
||||||
ASSUAN_CMD_AUTH,
|
ASSUAN_CMD_AUTH,
|
||||||
ASSUAN_CMD_RESET,
|
ASSUAN_CMD_RESET,
|
||||||
|
ASSUAN_CMD_OPTION,
|
||||||
ASSUAN_CMD_DATA,
|
ASSUAN_CMD_DATA,
|
||||||
ASSUAN_CMD_END,
|
ASSUAN_CMD_END,
|
||||||
ASSUAN_CMD_INPUT,
|
ASSUAN_CMD_INPUT,
|
||||||
@ -120,6 +126,11 @@ int assuan_register_input_notify (ASSUAN_CONTEXT ctx,
|
|||||||
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
||||||
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
|
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
|
||||||
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
||||||
|
|
||||||
|
int assuan_register_option_handler (ASSUAN_CONTEXT ctx,
|
||||||
|
int (*fnc)(ASSUAN_CONTEXT,
|
||||||
|
const char*, const char*));
|
||||||
|
|
||||||
int assuan_process (ASSUAN_CONTEXT ctx);
|
int assuan_process (ASSUAN_CONTEXT ctx);
|
||||||
int assuan_process_next (ASSUAN_CONTEXT ctx);
|
int assuan_process_next (ASSUAN_CONTEXT ctx);
|
||||||
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
||||||
@ -127,6 +138,7 @@ int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
|||||||
|
|
||||||
|
|
||||||
FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx);
|
FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx);
|
||||||
|
AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line);
|
||||||
void assuan_write_status (ASSUAN_CONTEXT ctx,
|
void assuan_write_status (ASSUAN_CONTEXT ctx,
|
||||||
const char *keyword, const char *text);
|
const char *keyword, const char *text);
|
||||||
|
|
||||||
@ -142,13 +154,21 @@ AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx);
|
|||||||
|
|
||||||
/*-- assuan-pipe-server.c --*/
|
/*-- assuan-pipe-server.c --*/
|
||||||
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
|
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
|
||||||
void assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx);
|
void assuan_deinit_server (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
|
/*-- assuan-socket-server.c --*/
|
||||||
|
int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd);
|
||||||
|
|
||||||
|
|
||||||
/*-- assuan-connect.c --*/
|
/*-- assuan-pipe-connect.c --*/
|
||||||
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
||||||
char *const argv[], int *fd_child_list);
|
char *const argv[], int *fd_child_list);
|
||||||
void assuan_pipe_disconnect (ASSUAN_CONTEXT ctx);
|
/*-- assuan-socket-connect.c --*/
|
||||||
|
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
||||||
|
pid_t server_pid);
|
||||||
|
|
||||||
|
/*-- assuan-connect.c --*/
|
||||||
|
void assuan_disconnect (ASSUAN_CONTEXT ctx);
|
||||||
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
|
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
/*-- assuan-client.c --*/
|
/*-- assuan-client.c --*/
|
||||||
@ -178,10 +198,13 @@ AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
|
|||||||
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||||
void *(*new_realloc_func)(void *p, size_t n),
|
void *(*new_realloc_func)(void *p, size_t n),
|
||||||
void (*new_free_func)(void*) );
|
void (*new_free_func)(void*) );
|
||||||
|
void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp);
|
||||||
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
|
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
|
||||||
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
|
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
|
||||||
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
|
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
|
void assuan_begin_confidential (ASSUAN_CONTEXT ctx);
|
||||||
|
void assuan_end_confidential (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
/*-- assuan-errors.c (built) --*/
|
/*-- assuan-errors.c (built) --*/
|
||||||
const char *assuan_strerror (AssuanError err);
|
const char *assuan_strerror (AssuanError err);
|
||||||
|
@ -5,6 +5,22 @@
|
|||||||
unconditionally.
|
unconditionally.
|
||||||
Reported by Jose Carlos Garcia Sogo <jsogo@debian.org>.
|
Reported by Jose Carlos Garcia Sogo <jsogo@debian.org>.
|
||||||
|
|
||||||
|
2002-01-19 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* logging.c (log_get_stream): New.
|
||||||
|
|
||||||
|
2001-12-05 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* logging.c (log_set_prefix): New.
|
||||||
|
(do_logv): Include prefix and pid only if enabled. Print time only
|
||||||
|
when explicitly enabled.
|
||||||
|
(log_logv): New.
|
||||||
|
* logging.h: Include log_logv() only when requested.
|
||||||
|
|
||||||
|
2001-11-06 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* strlist.c, strlist.h: New. Taken from pgnupg/util/strgutil.c
|
||||||
|
|
||||||
2001-08-30 Werner Koch <wk@gnupg.org>
|
2001-08-30 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* logging.c (log_printf): Don't pass NULL instead of arg_ptr.
|
* logging.c (log_printf): Don't pass NULL instead of arg_ptr.
|
||||||
|
@ -26,11 +26,14 @@ noinst_LIBRARIES = libjnlib.a
|
|||||||
|
|
||||||
|
|
||||||
#libjnlib_a_LDFLAGS =
|
#libjnlib_a_LDFLAGS =
|
||||||
libjnlib_a_SOURCES = libjnlib-config.h \
|
libjnlib_a_SOURCES = \
|
||||||
xmalloc.c xmalloc.h \
|
libjnlib-config.h \
|
||||||
stringhelp.c stringhelp.h \
|
stringhelp.c stringhelp.h \
|
||||||
argparse.c argparse.h \
|
strlist.c strlist.h \
|
||||||
logging.c logging.h \
|
argparse.c argparse.h \
|
||||||
types.h mischelp.h
|
logging.c logging.h \
|
||||||
|
dotlock.c dotlock.h \
|
||||||
|
types.h mischelp.h
|
||||||
|
|
||||||
|
# xmalloc.c xmalloc.h
|
||||||
|
|
||||||
|
@ -900,7 +900,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) 2000 Free Software Foundation, Inc."; break;
|
case 14: p = "Copyright (C) 2001 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"
|
||||||
|
@ -26,11 +26,9 @@
|
|||||||
#ifndef LIBJNLIB_CONFIG_H
|
#ifndef LIBJNLIB_CONFIG_H
|
||||||
#define LIBJNLIB_CONFIG_H
|
#define LIBJNLIB_CONFIG_H
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include <gcrypt.h> /* gcry_malloc & Cie. */
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SIMPLE_GETTEXT
|
#ifdef USE_SIMPLE_GETTEXT
|
||||||
int set_gettext_file( const char *filename );
|
int set_gettext_file( const char *filename );
|
||||||
const char *gettext( const char *msgid );
|
const char *gettext( const char *msgid );
|
||||||
@ -58,11 +56,11 @@
|
|||||||
#endif /* !USE_SIMPLE_GETTEXT */
|
#endif /* !USE_SIMPLE_GETTEXT */
|
||||||
|
|
||||||
|
|
||||||
#define jnlib_xmalloc(a) xmalloc( (a) )
|
#define jnlib_xmalloc(a) gcry_xmalloc( (a) )
|
||||||
#define jnlib_xcalloc(a,b) xcalloc( (a), (b) )
|
#define jnlib_xcalloc(a,b) gcry_xcalloc( (a), (b) )
|
||||||
#define jnlib_xrealloc(a,n) xrealloc( (a), (n) )
|
#define jnlib_xrealloc(a,n) gcry_xrealloc( (a), (n) )
|
||||||
#define jnlib_xstrdup(a) xstrdup( (a) )
|
#define jnlib_xstrdup(a) gcry_xstrdup( (a) )
|
||||||
#define jnlib_free(a) free( (a) )
|
#define jnlib_free(a) gcry_free( (a) )
|
||||||
|
|
||||||
#define jnlib_log_debug log_debug
|
#define jnlib_log_debug log_debug
|
||||||
#define jnlib_log_info log_info
|
#define jnlib_log_info log_info
|
||||||
@ -73,3 +71,5 @@
|
|||||||
|
|
||||||
#endif /*LIBJNUTIL_CONFIG_H*/
|
#endif /*LIBJNUTIL_CONFIG_H*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
157
jnlib/logging.c
157
jnlib/logging.c
@ -31,26 +31,23 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define JNLIB_NEED_LOG_LOGV 1
|
||||||
#include "libjnlib-config.h"
|
#include "libjnlib-config.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
enum my_log_levels {
|
|
||||||
MY_LOG_BEGIN, /* only print the timestamp if configured */
|
|
||||||
MY_LOG_CONT,
|
|
||||||
MY_LOG_INFO,
|
|
||||||
MY_LOG_WARN,
|
|
||||||
MY_LOG_ERROR,
|
|
||||||
MY_LOG_FATAL,
|
|
||||||
MY_LOG_BUG,
|
|
||||||
MY_LOG_DEBUG
|
|
||||||
};
|
|
||||||
|
|
||||||
static FILE *logstream;
|
static FILE *logstream;
|
||||||
static int use_time;
|
static char prefix_buffer[80];
|
||||||
|
static int with_time;
|
||||||
|
static int with_prefix;
|
||||||
|
static int with_pid;
|
||||||
|
|
||||||
static int missing_lf;
|
static int missing_lf;
|
||||||
static int errorcount;
|
static int errorcount;
|
||||||
|
|
||||||
@ -95,61 +92,93 @@ log_set_file( const char *name )
|
|||||||
if( logstream && logstream != stderr )
|
if( logstream && logstream != stderr )
|
||||||
fclose( logstream );
|
fclose( logstream );
|
||||||
logstream = fp;
|
logstream = fp;
|
||||||
use_time = fp != stderr;
|
|
||||||
missing_lf = 0;
|
missing_lf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
log_set_prefix (const char *text, unsigned int flags)
|
||||||
|
{
|
||||||
|
if (text)
|
||||||
|
{
|
||||||
|
strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
|
||||||
|
prefix_buffer[sizeof (prefix_buffer)-1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
with_prefix = (flags & 1);
|
||||||
|
with_time = (flags & 2);
|
||||||
|
with_pid = (flags & 4);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
log_get_fd()
|
log_get_fd()
|
||||||
{
|
{
|
||||||
return fileno(logstream?logstream:stderr);
|
return fileno(logstream?logstream:stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
log_get_stream ()
|
||||||
|
{
|
||||||
|
return logstream?logstream:stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_logv( int level, const char *fmt, va_list arg_ptr )
|
do_logv( int level, const char *fmt, va_list arg_ptr )
|
||||||
{
|
{
|
||||||
if( !logstream )
|
if (!logstream)
|
||||||
logstream = stderr;
|
logstream = stderr;
|
||||||
|
|
||||||
if( missing_lf && level != MY_LOG_CONT )
|
if (missing_lf && level != JNLIB_LOG_CONT)
|
||||||
putc('\n', logstream );
|
putc('\n', logstream );
|
||||||
missing_lf = 0;
|
missing_lf = 0;
|
||||||
|
|
||||||
if( use_time && level != MY_LOG_CONT ) {
|
if (level != JNLIB_LOG_CONT)
|
||||||
/* Note this does not work for multiple line logging as we would
|
{ /* Note this does not work for multiple line logging as we would
|
||||||
* need to print to a buffer first */
|
* need to print to a buffer first */
|
||||||
struct tm *tp;
|
if (with_time)
|
||||||
time_t atime = time(NULL);
|
{
|
||||||
|
struct tm *tp;
|
||||||
|
time_t atime = time (NULL);
|
||||||
|
|
||||||
tp = localtime( &atime );
|
tp = localtime (&atime);
|
||||||
fprintf( logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
|
fprintf (logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
|
||||||
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
||||||
tp->tm_hour, tp->tm_min, tp->tm_sec );
|
tp->tm_hour, tp->tm_min, tp->tm_sec );
|
||||||
|
}
|
||||||
|
if (with_prefix)
|
||||||
|
fputs (prefix_buffer, logstream);
|
||||||
|
if (with_pid)
|
||||||
|
fprintf (logstream, "[%u]", (unsigned int)getpid ());
|
||||||
|
if (!with_time)
|
||||||
|
putc (':', logstream);
|
||||||
|
putc (' ', logstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( level ) {
|
switch (level)
|
||||||
case MY_LOG_BEGIN: break;
|
{
|
||||||
case MY_LOG_CONT: break;
|
case JNLIB_LOG_BEGIN: break;
|
||||||
case MY_LOG_INFO: break;
|
case JNLIB_LOG_CONT: break;
|
||||||
case MY_LOG_WARN: break;
|
case JNLIB_LOG_INFO: break;
|
||||||
case MY_LOG_ERROR: break;
|
case JNLIB_LOG_WARN: break;
|
||||||
case MY_LOG_FATAL: fputs("Fatal: ",logstream ); break;
|
case JNLIB_LOG_ERROR: break;
|
||||||
case MY_LOG_BUG: fputs("Ohhhh jeeee: ", logstream); break;
|
case JNLIB_LOG_FATAL: fputs("Fatal: ",logstream ); break;
|
||||||
case MY_LOG_DEBUG: fputs("DBG: ", logstream ); break;
|
case JNLIB_LOG_BUG: fputs("Ohhhh jeeee: ", logstream); break;
|
||||||
default: fprintf(logstream,"[Unknown log level %d]: ", level ); break;
|
case JNLIB_LOG_DEBUG: fputs("DBG: ", logstream ); break;
|
||||||
|
default: fprintf(logstream,"[Unknown log level %d]: ", level ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fmt ) {
|
if (fmt)
|
||||||
vfprintf(logstream,fmt,arg_ptr) ;
|
{
|
||||||
if( *fmt && fmt[strlen(fmt)-1] != '\n' )
|
vfprintf(logstream,fmt,arg_ptr) ;
|
||||||
missing_lf = 1;
|
if (*fmt && fmt[strlen(fmt)-1] != '\n')
|
||||||
|
missing_lf = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( level == MY_LOG_FATAL )
|
if (level == JNLIB_LOG_FATAL)
|
||||||
exit(2);
|
exit(2);
|
||||||
if( level == MY_LOG_BUG )
|
if (level == JNLIB_LOG_BUG)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -163,6 +192,11 @@ do_log( int level, const char *fmt, ... )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
log_logv (int level, const char *fmt, va_list arg_ptr)
|
||||||
|
{
|
||||||
|
do_logv (level, fmt, arg_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
log_info( const char *fmt, ... )
|
log_info( const char *fmt, ... )
|
||||||
@ -170,7 +204,7 @@ log_info( const char *fmt, ... )
|
|||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
do_logv( MY_LOG_INFO, fmt, arg_ptr );
|
do_logv( JNLIB_LOG_INFO, fmt, arg_ptr );
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +214,7 @@ log_error( const char *fmt, ... )
|
|||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
do_logv( MY_LOG_ERROR, fmt, arg_ptr );
|
do_logv( JNLIB_LOG_ERROR, fmt, arg_ptr );
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
/* protect against counter overflow */
|
/* protect against counter overflow */
|
||||||
if( errorcount < 30000 )
|
if( errorcount < 30000 )
|
||||||
@ -194,7 +228,7 @@ log_fatal( const char *fmt, ... )
|
|||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
do_logv( MY_LOG_FATAL, fmt, arg_ptr );
|
do_logv( JNLIB_LOG_FATAL, fmt, arg_ptr );
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
abort(); /* never called, bugs it makes the compiler happy */
|
abort(); /* never called, bugs it makes the compiler happy */
|
||||||
}
|
}
|
||||||
@ -205,7 +239,7 @@ log_bug( const char *fmt, ... )
|
|||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
do_logv( MY_LOG_BUG, fmt, arg_ptr );
|
do_logv( JNLIB_LOG_BUG, fmt, arg_ptr );
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
abort(); /* never called, but it makes the compiler happy */
|
abort(); /* never called, but it makes the compiler happy */
|
||||||
}
|
}
|
||||||
@ -216,7 +250,7 @@ log_debug( const char *fmt, ... )
|
|||||||
va_list arg_ptr ;
|
va_list arg_ptr ;
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
do_logv( MY_LOG_DEBUG, fmt, arg_ptr );
|
do_logv( JNLIB_LOG_DEBUG, fmt, arg_ptr );
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,16 +261,35 @@ log_printf (const char *fmt, ...)
|
|||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
|
|
||||||
va_start (arg_ptr, fmt);
|
va_start (arg_ptr, fmt);
|
||||||
do_logv (fmt ? MY_LOG_CONT : MY_LOG_BEGIN, fmt, arg_ptr);
|
do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, fmt, arg_ptr);
|
||||||
va_end (arg_ptr);
|
va_end (arg_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
|
||||||
|
dump, with TEXT just an empty string, print a trailing linefeed,
|
||||||
|
otherwise print an entire debug line. */
|
||||||
|
void
|
||||||
|
log_printhex (const char *text, const void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
if (text && *text)
|
||||||
|
log_debug ("%s ", text);
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
const unsigned char *p = buffer;
|
||||||
|
log_printf ("%02X", *p);
|
||||||
|
for (length--, p++; length--; p++)
|
||||||
|
log_printf (" %02X", *p);
|
||||||
|
}
|
||||||
|
if (text)
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
||||||
void
|
void
|
||||||
bug_at( const char *file, int line, const char *func )
|
bug_at( const char *file, int line, const char *func )
|
||||||
{
|
{
|
||||||
do_log( MY_LOG_BUG,
|
do_log( JNLIB_LOG_BUG,
|
||||||
("... this is a bug (%s:%d:%s)\n"), file, line, func );
|
("... this is a bug (%s:%d:%s)\n"), file, line, func );
|
||||||
abort(); /* never called, but it makes the compiler happy */
|
abort(); /* never called, but it makes the compiler happy */
|
||||||
}
|
}
|
||||||
@ -244,7 +297,7 @@ bug_at( const char *file, int line, const char *func )
|
|||||||
void
|
void
|
||||||
bug_at( const char *file, int line )
|
bug_at( const char *file, int line )
|
||||||
{
|
{
|
||||||
do_log( MY_LOG_BUG,
|
do_log( JNLIB_LOG_BUG,
|
||||||
_("you found a bug ... (%s:%d)\n"), file, line);
|
_("you found a bug ... (%s:%d)\n"), file, line);
|
||||||
abort(); /* never called, but it makes the compiler happy */
|
abort(); /* never called, but it makes the compiler happy */
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mischelp.h"
|
#include "mischelp.h"
|
||||||
|
|
||||||
|
|
||||||
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_prefix (const char *text, unsigned int flags);
|
||||||
int log_get_fd(void);
|
int log_get_fd(void);
|
||||||
|
FILE *log_get_stream (void);
|
||||||
|
|
||||||
#ifdef JNLIB_GCC_M_FUNCTION
|
#ifdef JNLIB_GCC_M_FUNCTION
|
||||||
void bug_at( const char *file, int line, const char *func ) JNLIB_GCC_A_NR;
|
void bug_at( const char *file, int line, const char *func ) JNLIB_GCC_A_NR;
|
||||||
@ -36,12 +39,36 @@ int log_get_fd(void);
|
|||||||
# define BUG() bug_at( __FILE__ , __LINE__ )
|
# define BUG() bug_at( __FILE__ , __LINE__ )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* To avoid mandatory inclusion of stdarg and other stuff, do it only
|
||||||
|
if explicitly requested to do so. */
|
||||||
|
#ifdef JNLIB_NEED_LOG_LOGV
|
||||||
|
#include <stdarg.h>
|
||||||
|
enum jnlib_log_levels {
|
||||||
|
JNLIB_LOG_BEGIN,
|
||||||
|
JNLIB_LOG_CONT,
|
||||||
|
JNLIB_LOG_INFO,
|
||||||
|
JNLIB_LOG_WARN,
|
||||||
|
JNLIB_LOG_ERROR,
|
||||||
|
JNLIB_LOG_FATAL,
|
||||||
|
JNLIB_LOG_BUG,
|
||||||
|
JNLIB_LOG_DEBUG
|
||||||
|
};
|
||||||
|
void log_logv (int level, const char *fmt, va_list arg_ptr);
|
||||||
|
#endif /*JNLIB_NEED_LOG_LOGV*/
|
||||||
|
|
||||||
|
|
||||||
void log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
|
void log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
|
||||||
void log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
|
void log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
|
||||||
void log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
void log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
||||||
void log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
void log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
||||||
void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
||||||
void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
|
||||||
|
void log_printhex (const char *text, const void *buffer, size_t length);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBJNLIB_LOGGING_H*/
|
#endif /*LIBJNLIB_LOGGING_H*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
133
jnlib/strlist.c
Normal file
133
jnlib/strlist.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/* strlist.c - string helpers
|
||||||
|
* Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "libjnlib-config.h"
|
||||||
|
#include "strlist.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
free_strlist( STRLIST sl )
|
||||||
|
{
|
||||||
|
STRLIST sl2;
|
||||||
|
|
||||||
|
for(; sl; sl = sl2 ) {
|
||||||
|
sl2 = sl->next;
|
||||||
|
jnlib_free(sl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRLIST
|
||||||
|
add_to_strlist( STRLIST *list, const char *string )
|
||||||
|
{
|
||||||
|
STRLIST sl;
|
||||||
|
|
||||||
|
sl = jnlib_xmalloc( sizeof *sl + strlen(string));
|
||||||
|
sl->flags = 0;
|
||||||
|
strcpy(sl->d, string);
|
||||||
|
sl->next = *list;
|
||||||
|
*list = sl;
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/****************
|
||||||
|
* same as add_to_strlist() but if is_utf8 is *not* set a conversion
|
||||||
|
* to UTF8 is done
|
||||||
|
*/
|
||||||
|
STRLIST
|
||||||
|
add_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
|
||||||
|
{
|
||||||
|
STRLIST sl;
|
||||||
|
|
||||||
|
if( is_utf8 )
|
||||||
|
sl = add_to_strlist( list, string );
|
||||||
|
else {
|
||||||
|
char *p = native_to_utf8( string );
|
||||||
|
sl = add_to_strlist( list, p );
|
||||||
|
m_free( p );
|
||||||
|
}
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STRLIST
|
||||||
|
append_to_strlist( STRLIST *list, const char *string )
|
||||||
|
{
|
||||||
|
STRLIST r, sl;
|
||||||
|
|
||||||
|
sl = jnlib_xmalloc( sizeof *sl + strlen(string));
|
||||||
|
sl->flags = 0;
|
||||||
|
strcpy(sl->d, string);
|
||||||
|
sl->next = NULL;
|
||||||
|
if( !*list )
|
||||||
|
*list = sl;
|
||||||
|
else {
|
||||||
|
for( r = *list; r->next; r = r->next )
|
||||||
|
;
|
||||||
|
r->next = sl;
|
||||||
|
}
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
STRLIST
|
||||||
|
append_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
|
||||||
|
{
|
||||||
|
STRLIST sl;
|
||||||
|
|
||||||
|
if( is_utf8 )
|
||||||
|
sl = append_to_strlist( list, string );
|
||||||
|
else {
|
||||||
|
char *p = native_to_utf8( string );
|
||||||
|
sl = append_to_strlist( list, p );
|
||||||
|
m_free( p );
|
||||||
|
}
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STRLIST
|
||||||
|
strlist_prev( STRLIST head, STRLIST node )
|
||||||
|
{
|
||||||
|
STRLIST n;
|
||||||
|
|
||||||
|
for(n=NULL; head && head != node; head = head->next )
|
||||||
|
n = head;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRLIST
|
||||||
|
strlist_last( STRLIST node )
|
||||||
|
{
|
||||||
|
if( node )
|
||||||
|
for( ; node->next ; node = node->next )
|
||||||
|
;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
43
jnlib/strlist.h
Normal file
43
jnlib/strlist.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* strlist.h
|
||||||
|
* Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBJNLIB_STRLIST_H
|
||||||
|
#define LIBJNLIB_STRLIST_H
|
||||||
|
|
||||||
|
struct string_list {
|
||||||
|
struct string_list *next;
|
||||||
|
unsigned int flags;
|
||||||
|
char d[1];
|
||||||
|
};
|
||||||
|
typedef struct string_list *STRLIST;
|
||||||
|
|
||||||
|
|
||||||
|
void free_strlist( STRLIST sl );
|
||||||
|
STRLIST add_to_strlist( STRLIST *list, const char *string );
|
||||||
|
STRLIST add_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
|
||||||
|
STRLIST append_to_strlist( STRLIST *list, const char *string );
|
||||||
|
STRLIST append_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
|
||||||
|
STRLIST strlist_prev( STRLIST head, STRLIST node );
|
||||||
|
STRLIST strlist_last( STRLIST node );
|
||||||
|
|
||||||
|
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*LIBJNLIB_STRLIST_H*/
|
Loading…
Reference in New Issue
Block a user