summaryrefslogtreecommitdiffstats
path: root/g13
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-12-14 10:16:46 +0100
committerWerner Koch <wk@gnupg.org>2016-02-13 17:06:39 +0100
commitc5d7045dafcfb569c11c90c04ea7a75328c80084 (patch)
tree6bc883c16dc1a34d7a0aca00f4f31b835961d3b9 /g13
parentcommon: Make gnupg_exec_tool conform to spec. (diff)
downloadgnupg2-c5d7045dafcfb569c11c90c04ea7a75328c80084.tar.xz
gnupg2-c5d7045dafcfb569c11c90c04ea7a75328c80084.zip
g13: Switch over to common/exectool.c.
* g13/sh-exectool.c: Remove. It has been replaced by common/exectool.c. * g13/Makefile.am (g13_syshelp_SOURCES): Remove sh-exectool.c * g13/sh-blockdev.c: Include exectool.h. Change sh_exec_tool to gnupg_exec-tool. * g13/sh-dmcrypt.c: Ditto. -- With commit 2ae07f826aa551db8adf714158fce962790a6b54 the exectool code was moved from a g13 feature branch to common/ so that it could be used by gpgtar. With this patch we finally remove the original code and use the one in common/. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g13')
-rw-r--r--g13/Makefile.am1
-rw-r--r--g13/g13-syshelp.h5
-rw-r--r--g13/sh-blockdev.c7
-rw-r--r--g13/sh-dmcrypt.c3
-rw-r--r--g13/sh-exectool.c303
5 files changed, 6 insertions, 313 deletions
diff --git a/g13/Makefile.am b/g13/Makefile.am
index a3cd1333d..62437e567 100644
--- a/g13/Makefile.am
+++ b/g13/Makefile.am
@@ -55,7 +55,6 @@ g13_syshelp_SOURCES = \
keyblob.h \
utils.c utils.h \
sh-cmd.c \
- sh-exectool.c \
sh-blockdev.c \
sh-dmcrypt.c
diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h
index 205488257..5a2055eb1 100644
--- a/g13/g13-syshelp.h
+++ b/g13/g13-syshelp.h
@@ -76,11 +76,6 @@ gpg_error_t sh_encrypt_keyblob (ctrl_t ctrl,
const void *keyblob, size_t keybloblen,
char **r_enckeyblob, size_t *r_enckeybloblen);
-/*-- sh-exectool.c --*/
-gpg_error_t sh_exec_tool (const char *pgmname, const char *argv[],
- const char *input_string,
- char **result, size_t *resultlen);
-
/*-- sh-blockdev.c --*/
gpg_error_t sh_blockdev_getsz (const char *name, unsigned long long *r_nblocks);
gpg_error_t sh_is_empty_partition (const char *name);
diff --git a/g13/sh-blockdev.c b/g13/sh-blockdev.c
index 2d431ea24..4b4dde464 100644
--- a/g13/sh-blockdev.c
+++ b/g13/sh-blockdev.c
@@ -29,6 +29,7 @@
#include "g13-syshelp.h"
#include <assuan.h>
#include "i18n.h"
+#include "exectool.h"
#include "keyblob.h"
#ifndef HAVE_STRTOULL
@@ -52,7 +53,7 @@ sh_blockdev_getsz (const char *name, unsigned long long *r_nblocks)
argv[0] = "--getsz";
argv[1] = name;
argv[2] = NULL;
- err = sh_exec_tool ("/sbin/blockdev", argv, NULL, &result, NULL);
+ err = gnupg_exec_tool ("/sbin/blockdev", argv, NULL, &result, NULL);
if (!err)
{
gpg_err_set_errno (0);
@@ -85,7 +86,7 @@ sh_is_empty_partition (const char *name)
argv[3] = "UUID";
argv[4] = name;
argv[5] = NULL;
- err = sh_exec_tool ("/sbin/blkid", argv, NULL, &buffer, NULL);
+ err = gnupg_exec_tool ("/sbin/blkid", argv, NULL, &buffer, NULL);
if (err)
return gpg_error (GPG_ERR_FALSE);
if (*buffer)
@@ -102,7 +103,7 @@ sh_is_empty_partition (const char *name)
argv[3] = "PARTUUID";
argv[4] = name;
argv[5] = NULL;
- err = sh_exec_tool ("/sbin/blkid", argv, NULL, &buffer, NULL);
+ err = gnupg_exec_tool ("/sbin/blkid", argv, NULL, &buffer, NULL);
if (err)
return gpg_error (GPG_ERR_FALSE);
if (!*buffer)
diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c
index 49950fd2b..a9aed0cc6 100644
--- a/g13/sh-dmcrypt.c
+++ b/g13/sh-dmcrypt.c
@@ -34,6 +34,7 @@
#include <assuan.h>
#include "i18n.h"
#include "utils.h"
+#include "exectool.h"
#include "keyblob.h"
/* The standard disk block size (logical). */
@@ -104,7 +105,7 @@ check_blockdev (const char *devname)
argv[0] = "deps";
argv[1] = NULL;
- err = sh_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
+ err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
}
if (err)
{
diff --git a/g13/sh-exectool.c b/g13/sh-exectool.c
deleted file mode 100644
index ab1809552..000000000
--- a/g13/sh-exectool.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* sh-exectool.c - Utility functions to execute a helper tool
- * Copyright (C) 2015 Werner Koch
- *
- * 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "g13-syshelp.h"
-#include <assuan.h>
-#include "i18n.h"
-#include "membuf.h"
-#include "exechelp.h"
-#include "sysutils.h"
-
-typedef struct
-{
- const char *pgmname;
- int cont;
- int used;
- char buffer[256];
-} read_and_log_buffer_t;
-
-
-static void
-read_and_log_stderr (read_and_log_buffer_t *state, es_poll_t *fderr)
-{
- gpg_error_t err;
- int c;
-
- if (!fderr)
- {
- /* Flush internal buffer. */
- if (state->used)
- {
- const char *pname;
- int len;
-
- state->buffer[state->used] = 0;
- state->used = 0;
-
- pname = strrchr (state->pgmname, '/');
- if (pname && pname != state->pgmname && pname[1])
- pname++;
- else
- pname = state->pgmname;
- /* If our pgmname plus colon is identical to the start of
- the output, print only the output. */
- len = strlen (pname);
- if (!state->cont
- && !strncmp (state->buffer, pname, len)
- && strlen (state->buffer) > strlen (pname)
- && state->buffer[len] == ':' )
- log_info ("%s\n", state->buffer);
- else
- log_info ("%s%c %s\n",
- pname, state->cont? '+':':', state->buffer);
- }
- state->cont = 0;
- return;
- }
- for (;;)
- {
- c = es_fgetc (fderr->stream);
- if (c == EOF)
- {
- if (es_feof (fderr->stream))
- {
- fderr->ignore = 1; /* Not anymore needed. */
- }
- else if (es_ferror (fderr->stream))
- {
- err = gpg_error_from_syserror ();
- log_error ("error reading stderr of '%s': %s\n",
- state->pgmname, gpg_strerror (err));
- fderr->ignore = 1; /* Disable. */
- }
-
- break;
- }
- else if (c == '\n')
- {
- read_and_log_stderr (state, NULL);
- }
- else
- {
- if (state->used >= sizeof state->buffer - 1)
- {
- read_and_log_stderr (state, NULL);
- state->cont = 1;
- }
- state->buffer[state->used++] = c;
- }
- }
-}
-
-
-static gpg_error_t
-read_stdout (membuf_t *mb, es_poll_t *fdout, const char *pgmname)
-{
- gpg_error_t err = 0;
- int c;
-
- for (;;)
- {
- c = es_fgetc (fdout->stream);
- if (c == EOF)
- {
- if (es_feof (fdout->stream))
- {
- fdout->ignore = 1; /* Ready. */
- }
- else if (es_ferror (fdout->stream))
- {
- err = gpg_error_from_syserror ();
- log_error ("error reading stdout of '%s': %s\n",
- pgmname, gpg_strerror (err));
- fdout->ignore = 1; /* Disable. */
- }
-
- break;
- }
- else
- {
- char buf[1];
- *buf = c;
- put_membuf (mb, buf, 1);
- }
- }
-
- return err;
-}
-
-
-/* Run the program PGMNAME with the command line arguments given in
- the NULL terminates array ARGV. If INPUT_STRING is not NULL it
- will be fed to stdin of the process. stderr is logged using
- log_info and the process' stdout is returned in a newly malloced
- buffer RESULT with the length stored at RESULTLEN if not given as
- NULL. A hidden Nul is appended to the output. On error NULL is
- stored at RESULT, a diagnostic is printed, and an error code
- returned. */
-gpg_error_t
-sh_exec_tool (const char *pgmname, const char *argv[],
- const char *input_string,
- char **result, size_t *resultlen)
-{
- gpg_error_t err;
- pid_t pid;
- estream_t infp = NULL;
- estream_t outfp, errfp;
- es_poll_t fds[3];
- int count;
- read_and_log_buffer_t fderrstate;
- membuf_t fdout_mb;
- size_t len, nwritten;
-
- *result = NULL;
- if (resultlen)
- *resultlen = 0;
- memset (fds, 0, sizeof fds);
- memset (&fderrstate, 0, sizeof fderrstate);
- init_membuf (&fdout_mb, 4096);
-
- err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT,
- NULL, GNUPG_SPAWN_NONBLOCK,
- input_string? &infp : NULL,
- &outfp, &errfp, &pid);
- if (err)
- {
- log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err));
- return err;
- }
-
- fderrstate.pgmname = pgmname;
-
- fds[0].stream = infp;
- fds[0].want_write = 1;
- if (!input_string)
- fds[0].ignore = 1;
- fds[1].stream = outfp;
- fds[1].want_read = 1;
- fds[2].stream = errfp;
- fds[2].want_read = 1;
- /* Now read as long as we have something to poll. We continue
- reading even after EOF or error on stdout so that we get the
- other error messages or remaining outout. */
- while (!fds[1].ignore && !fds[2].ignore)
- {
- count = es_poll (fds, DIM(fds), -1);
- if (count == -1)
- {
- err = gpg_error_from_syserror ();
- log_error ("error polling '%s': %s\n", pgmname, gpg_strerror (err));
- goto leave;
- }
- if (!count)
- {
- log_debug ("unexpected timeout while polling '%s'\n", pgmname);
- break;
- }
-
- if (fds[0].got_write)
- {
- len = strlen (input_string);
- log_debug ("writing '%s'\n", input_string);
- if (es_write (fds[0].stream, input_string, len, &nwritten))
- {
- if (errno != EAGAIN)
- {
- err = gpg_error_from_syserror ();
- log_error ("error writing '%s': %s\n",
- pgmname, gpg_strerror (err));
- goto leave;
- }
- else
- log_debug (" .. EAGAIN\n");
- }
- else
- {
- assert (nwritten <= len);
- input_string += nwritten;
- }
-
- if (es_fflush (fds[0].stream) && errno != EAGAIN)
- {
- err = gpg_error_from_syserror ();
- log_error ("error writing '%s' (flush): %s\n",
- pgmname, gpg_strerror (err));
- if (gpg_err_code (err) == GPG_ERR_EPIPE && !*input_string)
- {
- /* fixme: How can we tell whether estream has
- pending bytes after a HUP - which is an
- error? */
- }
- else
- goto leave;
- }
- if (!*input_string)
- {
- fds[0].ignore = 1; /* ready. */
- es_fclose (infp); infp = NULL;
- }
- }
-
- if (fds[1].got_read)
- read_stdout (&fdout_mb, fds + 1, pgmname); /* FIXME: Add error
- handling. */
- if (fds[2].got_read)
- read_and_log_stderr (&fderrstate, fds + 2);
-
- }
-
- read_and_log_stderr (&fderrstate, NULL); /* Flush. */
- es_fclose (infp); infp = NULL;
- es_fclose (outfp); outfp = NULL;
- es_fclose (errfp); errfp = NULL;
-
- err = gnupg_wait_process (pgmname, pid, 1, NULL);
- pid = (pid_t)(-1);
-
- leave:
- if (err)
- {
- gnupg_kill_process (pid);
- xfree (get_membuf (&fdout_mb, NULL));
- }
- else
- {
- put_membuf (&fdout_mb, "", 1); /* Make sure it is a string. */
- *result = get_membuf (&fdout_mb, resultlen);
- if (!*result)
- err = gpg_error_from_syserror ();
- }
-
- es_fclose (infp);
- es_fclose (outfp);
- es_fclose (errfp);
- if (pid != (pid_t)(-1))
- gnupg_wait_process (pgmname, pid, 1, NULL);
- gnupg_release_process (pid);
-
- return err;
-}