1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Add unfinished gpgtar.

Collected changes and ports of bug fixes from stable.
This commit is contained in:
Werner Koch 2010-06-07 13:33:02 +00:00
parent 29cc88db7d
commit bbe388b5db
27 changed files with 2544 additions and 43 deletions

View file

@ -1,3 +1,22 @@
2010-06-07 Werner Koch <wk@g10code.com>
* estream.c (es_fname_get, es_fname_set): New.
(fname_set_internal): New.
(struct estream_internal): Add fields printable_fname and
printable_fname_inuse.
(_es_get_std_stream): Set stream name.
(es_fopen, es_freopen, es_deinitialize): Set fname.
* exechelp-posix.c (gnupg_spawn_process): Allow passing INFILE or
OUTFILE as NULL.
* exechelp-w32.c (gnupg_spawn_process): Ditto.
* exechelp-w32ce.c (gnupg_spawn_process): Return an error for
INFILE or OUTFILE passed as NULL.
2010-06-01 Werner Koch <wk@g10code.com>
* logging.c (log_get_stream): Make sture a log stream is available.
2010-05-30 Werner Koch <wk@g10code.com>
* init.c (writestring_via_estream): New.
@ -15,7 +34,7 @@
(es_func_fd_destroy): Implement a dummy stream.
* exechelp-w32ce.c (build_w32_commandline): Add args FD0_ISNULL
and FD1_ISNULL. Remove arg PGMNAME. Change callers.
and FD1_ISNULL. Remove arg PGMNAME. Change callers.
(gnupg_spawn_process_detached): Implement.
(gnupg_spawn_process_fd): Implement one special case for now.

View file

@ -211,6 +211,7 @@ struct estream_internal
void *cookie; /* Cookie. */
void *opaque; /* Opaque data. */
unsigned int modeflags; /* Flags for the backend. */
char *printable_fname; /* Malloced filename for es_fname_get. */
off_t offset;
es_cookie_read_function_t func_read;
es_cookie_write_function_t func_write;
@ -227,6 +228,7 @@ struct estream_internal
unsigned int is_stdstream:1; /* This is a standard stream. */
unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */
unsigned int print_err: 1; /* Error in print_fun_writer. */
unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */
int print_errno; /* Errno from print_fun_writer. */
size_t print_ntotal; /* Bytes written from in print_fun_writer. */
FILE *print_fp; /* Stdio stream used by print_fun_writer. */
@ -266,8 +268,12 @@ static unsigned char custom_std_fds_valid[3];
#endif
/* Local prototypes. */
static void fname_set_internal (estream_t stream, const char *fname, int quote);
/* Macros. */
/* Calculate array dimension. */
@ -1275,6 +1281,8 @@ es_initialize (estream_t stream,
stream->intern->is_stdstream = 0;
stream->intern->stdstream_fd = 0;
stream->intern->deallocate_buffer = 0;
stream->intern->printable_fname = NULL;
stream->intern->printable_fname_inuse = 0;
stream->data_len = 0;
stream->data_offset = 0;
@ -1314,7 +1322,10 @@ es_deinitialize (estream_t stream)
if (func_close)
SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie));
mem_free (stream->intern->printable_fname);
stream->intern->printable_fname = NULL;
stream->intern->printable_fname_inuse = 0;
return err;
}
@ -2190,6 +2201,9 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode)
if (err)
goto out;
if (stream && path)
fname_set_internal (stream, path, 1);
out:
if (err && create_called)
@ -2467,6 +2481,9 @@ _es_get_std_stream (int fd)
stream->intern->stdstream_fd = fd;
if (fd == 2)
es_set_buffering (stream, NULL, _IOLBF, 0);
fname_set_internal (stream,
fd == 0? "[stdin]" :
fd == 1? "[stdout]" : "[stderr]", 0);
}
ESTREAM_LIST_UNLOCK;
return stream;
@ -2515,7 +2532,11 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode,
stream = NULL;
}
else
ESTREAM_UNLOCK (stream);
{
if (stream && path)
fname_set_internal (stream, path, 1);
ESTREAM_UNLOCK (stream);
}
}
else
{
@ -3407,6 +3428,68 @@ es_opaque_get (estream_t stream)
return opaque;
}
static void
fname_set_internal (estream_t stream, const char *fname, int quote)
{
if (stream->intern->printable_fname
&& !stream->intern->printable_fname_inuse)
{
mem_free (stream->intern->printable_fname);
stream->intern->printable_fname = NULL;
}
if (stream->intern->printable_fname)
return; /* Can't change because it is in use. */
if (*fname != '[')
quote = 0;
else
quote = !!quote;
stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1);
if (fname)
{
if (quote)
stream->intern->printable_fname[0] = '\\';
strcpy (stream->intern->printable_fname+quote, fname);
}
}
/* Set the filename attribute of STREAM. There is no error return.
as long as STREAM is valid. This function is called internally by
functions which open a filename. */
void
es_fname_set (estream_t stream, const char *fname)
{
if (fname)
{
ESTREAM_LOCK (stream);
fname_set_internal (stream, fname, 1);
ESTREAM_UNLOCK (stream);
}
}
/* Return the filename attribute of STREAM. In case no filename has
been set, "[?]" will be returned. The returned file name is valid
as long as STREAM is valid. */
const char *
es_fname_get (estream_t stream)
{
const char *fname;
ESTREAM_LOCK (stream);
fname = stream->intern->printable_fname;
if (fname)
stream->intern->printable_fname_inuse = 1;
ESTREAM_UNLOCK (stream);
if (!fname)
fname = "[?]";
return fname;
}
/* Print a BUFFER to STREAM while replacing all control characters and
the characters in DELIMITERS by standard C escape sequences.
Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL

View file

@ -128,6 +128,8 @@
#define es_tmpfile _ESTREAM_PREFIX(es_tmpfile)
#define es_opaque_set _ESTREAM_PREFIX(es_opaque_set)
#define es_opaque_get _ESTREAM_PREFIX(es_opaque_get)
#define es_fname_set _ESTREAM_PREFIX(es_fname_set)
#define es_fname_get _ESTREAM_PREFIX(es_fname_get)
#define es_write_sanitized_utf8_buffer \
_ESTREAM_PREFIX(es_write_sanitized_utf8_buffer)
#endif /*_ESTREAM_EXT_SYM_PREFIX*/
@ -358,6 +360,9 @@ estream_t es_tmpfile (void);
void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
void *es_opaque_get (estream_t stream);
void es_fname_set (estream_t stream, const char *fname);
const char *es_fname_get (estream_t stream);
#ifdef GNUPG_MAJOR_VERSION
int es_write_sanitized_utf8_buffer (estream_t stream,

View file

@ -313,11 +313,22 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
*statusfile = NULL;
*pid = (pid_t)(-1);
es_fflush (infile);
es_rewind (infile);
fd = es_fileno (infile);
fdout = es_fileno (outfile);
if (fd == -1 || fdout == -1)
if (infile)
{
es_fflush (infile);
es_rewind (infile);
fd = es_fileno (infile);
}
else
fd = -1;
if (outfile)
fdout = es_fileno (outfile);
else
fdout = -1;
if ((infile && fd == -1) || (outfile && fdout == -1))
log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
if (pipe (rp) == -1)

View file

@ -382,17 +382,30 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
int cr_flags;
char *cmdline;
int fd, fdout, rp[2];
HANDLE nullhd[];
int i;
(void)preexec;
/* Setup return values. */
*statusfile = NULL;
*pid = (pid_t)(-1);
es_fflush (infile);
es_rewind (infile);
fd = _get_osfhandle (es_fileno (infile));
fdout = _get_osfhandle (es_fileno (outfile));
if (fd == -1 || fdout == -1)
if (infile)
{
es_fflush (infile);
es_rewind (infile);
fd = _get_osfhandle (es_fileno (infile));
}
else
fd = -1;
if (outfile)
fdout = _get_osfhandle (es_fileno (outfile));
else
fdout = -1;
if ( (infile && fd == -1) || (outfile && fdout == -1))
log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
/* Prepare security attributes. */
@ -414,14 +427,17 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
return err;
}
nullhd[0] = fd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE;
nullhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
/* Start the process. Note that we can't run the PREEXEC function
because this would change our own environment. */
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
si.hStdInput = fd_to_handle (fd);
si.hStdOutput = fd_to_handle (fdout);
si.hStdInput = fd == -1? nullhd[0] : fd_to_handle (fd);
si.hStdOutput = outfd == -1? nullhd[1] : fd_to_handle (fdout);
si.hStdError = fd_to_handle (rp[1]);
cr_flags = (CREATE_DEFAULT_ERROR_MODE
@ -450,6 +466,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
xfree (cmdline);
cmdline = NULL;
/* Close the inherited handles to /dev/null. */
for (i=0; i < DIM (nullhd); i++)
if (nullhd[i] != INVALID_HANDLE_VALUE)
CloseHandle (nullhd[i]);
/* Close the other end of the pipe. */
CloseHandle (fd_to_handle (rp[1]));

View file

@ -501,6 +501,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
*statusfile = NULL;
*pid = (pid_t)(-1);
/* A NULL INFILE or OUTFILE is only used by gpgtar thus we don't
need to implement this for CE. */
if (!infile || !outfile)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
es_fflush (infile);
es_rewind (infile);

View file

@ -53,13 +53,14 @@ gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
stdin, write the output to OUTFILE, return a new stream in
STATUSFILE for stderr and the pid of the process in PID. The
arguments for the process are expected in the NULL terminated array
ARGV. The program name itself should not be included there. If
PREEXEC is not NULL, that function will be called right before the
exec. Calling gnupg_wait_process is required. Returns 0 on
success or an error code.
stdin, write the output to OUTFILE. INFILE or PUTFILE may be NULL
to connect thenm to /dev/null. Returns a new stream in STATUSFILE
for stderr and the pid of the process in PID. The arguments for the
process are expected in the NULL terminated array ARGV. The
program name itself should not be included there. If PREEXEC is
not NULL, that function will be called right before the exec.
Calling gnupg_wait_process is required. Returns 0 on success or an
error code.
FLAGS is a bit vector:

View file

@ -402,7 +402,11 @@ log_get_fd ()
estream_t
log_get_stream ()
{
assert (logstream);
if (!logstream)
{
log_set_file (NULL); /* Make sure a log stream has been set. */
assert (logstream);
}
return logstream;
}