summaryrefslogtreecommitdiff
path: root/src/assuan-connect.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-12-05 23:45:01 +0000
committerWerner Koch <wk@gnupg.org>2001-12-05 23:45:01 +0000
commite9a8c90d48d8d1118638293698f5bff0741a55f9 (patch)
tree0d88a5a2e59c2627b0f4e25c5a4117a844f2920c /src/assuan-connect.c
parent47e100a5fe010c4dad695d15f6941f5402565810 (diff)
downloadlibassuan-e9a8c90d48d8d1118638293698f5bff0741a55f9.tar.gz
assuan-connect.c (assuan_pipe_connect): Add more error reporting.
assuan-client.c: New. assuan-inquire.c: New. assuan-handler.c (process_request): Check for nested invocations.
Diffstat (limited to 'src/assuan-connect.c')
-rw-r--r--src/assuan-connect.c127
1 files changed, 112 insertions, 15 deletions
diff --git a/src/assuan-connect.c b/src/assuan-connect.c
index 37d4262..abc5d74 100644
--- a/src/assuan-connect.c
+++ b/src/assuan-connect.c
@@ -18,17 +18,56 @@
* 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
+#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. */
@@ -41,8 +80,8 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
int wp[2];
int fd[2];
- if (!name || !argv || !argv[0])
- return ASSUAN_General_Error;
+ if (!ctx || !name || !argv || !argv[0])
+ return ASSUAN_Invalid_Value;
if (!fixed_signals)
{
@@ -69,7 +108,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
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. */
@@ -82,6 +121,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
close (wp[1]);
return err;
}
+ (*ctx)->is_server = 0;
(*ctx)->pid = fork ();
if ((*ctx)->pid < 0)
@@ -96,25 +136,80 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
if ((*ctx)->pid == 0)
{
- close (rp[0]);
- close (wp[1]);
+ 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++)
+ {
+ if (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)
- {
- dup2 (rp[1], STDOUT_FILENO); /* Child's outbound is write end of read pipe. */
- close (rp[1]);
- }
+ {
+ 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)
- {
- dup2 (wp[0], STDIN_FILENO); /* Child's inbound is read end of write pipe. */
- close (wp[0]);
- }
- execv (name, argv);
- _exit (1);
+ {
+ 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]);
_assuan_read_line (*ctx); /* FIXME: Handshake. */
+
+#if 0 /* old stuff */
+ inbound.eof = 0;
+ inbound.linelen = 0;
+ inbound.attic.linelen = 0;
+
+ /* The server is available - read the greeting */
+ rc = read_from_agent (&okay);
+ if (rc)
+ {
+ log_error ("can't connect to the agent: %s\n", gnupg_strerror (rc));
+ }
+ else if (!okay)
+ {
+ log_error ("can't connect to the agent: %s\n", inbound.line);
+ rc = seterr (No_Agent);
+ }
+ else
+#endif
+
+
return 0;
}
@@ -133,3 +228,5 @@ assuan_get_pid (ASSUAN_CONTEXT ctx)
{
return ctx ? ctx->pid : -1;
}
+
+