gpgtar: Make --files-from and --null work as described.

* tools/gpgtar-create.c (gpgtar_create): Add args files_from and
null_names.  Improve reading from a file.
* tools/gpgtar.c: Make global vars static.
(main): Remove tests for --files-from and --null option combinations.
Pass option variables to gpgtar_create.
--

GnuPG-bug-id: 5027
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-08-20 15:50:50 +02:00
parent 32aac55875
commit e276f63e4a
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 100 additions and 27 deletions

View File

@ -213,6 +213,36 @@ trim_spaces( char *str )
return str ; return str ;
} }
/* Same as trim_spaces but only condider, space, tab, cr and lf as space. */
char *
ascii_trim_spaces (char *str)
{
char *string, *p, *mark;
string = str;
/* Find first non-ascii space character. */
for (p=string; *p && ascii_isspace (*p); p++)
;
/* Move characters. */
for (mark=NULL; (*string = *p); string++, p++ )
{
if (ascii_isspace (*p))
{
if (!mark)
mark = string;
}
else
mark = NULL ;
}
if (mark)
*mark = '\0' ; /* Remove trailing spaces. */
return str ;
}
/**************** /****************
* remove trailing white spaces * remove trailing white spaces
*/ */

View File

@ -42,6 +42,7 @@ char *has_leading_keyword (const char *string, const char *keyword);
const char *memistr (const void *buf, size_t buflen, const char *sub); const char *memistr (const void *buf, size_t buflen, const char *sub);
char *mem2str( char *, const void *, size_t); char *mem2str( char *, const void *, size_t);
char *trim_spaces( char *string ); char *trim_spaces( char *string );
char *ascii_trim_spaces (char *string);
char *trim_trailing_spaces( char *string ); char *trim_trailing_spaces( char *string );
unsigned int trim_trailing_chars( unsigned char *line, unsigned len, unsigned int trim_trailing_chars( unsigned char *line, unsigned len,
const char *trimchars); const char *trimchars);

View File

@ -803,7 +803,7 @@ wchar_to_native (const wchar_t *string)
} }
/* Return a malloced wide char string from an UTF-8 encoded input /* Return a malloced wide char string from native encoded input
* string STRING. Caller must free this value. Returns NULL and sets * string STRING. Caller must free this value. Returns NULL and sets
* ERRNO on failure. Calling this function with STRING set to NULL is * ERRNO on failure. Calling this function with STRING set to NULL is
* not defined. */ * not defined. */

View File

@ -744,20 +744,39 @@ write_eof_mark (estream_t stream)
/* Create a new tarball using the names in the array INPATTERN. If /* Create a new tarball using the names in the array INPATTERN. If
INPATTERN is NULL take the pattern as null terminated strings from INPATTERN is NULL take the pattern as null terminated strings from
stdin. */ stdin or from the file specified by FILES_FROM. If NULL_NAMES is
set the filenames in such a file are delimited by a binary Nul and
not by a LF. */
gpg_error_t gpg_error_t
gpgtar_create (char **inpattern, int encrypt, int sign) gpgtar_create (char **inpattern, const char *files_from, int null_names,
int encrypt, int sign)
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
struct scanctrl_s scanctrl_buffer; struct scanctrl_s scanctrl_buffer;
scanctrl_t scanctrl = &scanctrl_buffer; scanctrl_t scanctrl = &scanctrl_buffer;
tar_header_t hdr, *start_tail; tar_header_t hdr, *start_tail;
estream_t files_from_stream = NULL;
estream_t outstream = NULL; estream_t outstream = NULL;
estream_t cipher_stream = NULL; estream_t cipher_stream = NULL;
int eof_seen = 0; int eof_seen = 0;
if (!inpattern) if (!inpattern)
es_set_binary (es_stdin); {
if (!files_from || !strcmp (files_from, "-"))
{
files_from = "-";
files_from_stream = es_stdin;
if (null_names)
es_set_binary (es_stdin);
}
else if (!(files_from_stream=es_fopen (files_from, null_names? "rb":"r")))
{
err = gpg_error_from_syserror ();
log_error ("error opening '%s': %s\n",
files_from, gpg_strerror (err));
return err;
}
}
memset (scanctrl, 0, sizeof *scanctrl); memset (scanctrl, 0, sizeof *scanctrl);
scanctrl->flist_tail = &scanctrl->flist; scanctrl->flist_tail = &scanctrl->flist;
@ -788,7 +807,7 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
pat = xtrystrdup (pattern); pat = xtrystrdup (pattern);
} }
else /* Read null delimited pattern from stdin. */ else /* Read Nul or LF delimited pattern from files_from_stream. */
{ {
int c; int c;
char namebuf[4096]; char namebuf[4096];
@ -796,17 +815,16 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
for (;;) for (;;)
{ {
if ((c = es_getc (es_stdin)) == EOF) if ((c = es_getc (files_from_stream)) == EOF)
{ {
if (es_ferror (es_stdin)) if (es_ferror (files_from_stream))
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
log_error ("error reading '%s': %s\n", log_error ("error reading '%s': %s\n",
"[stdin]", strerror (errno)); files_from, gpg_strerror (err));
goto leave; goto leave;
} }
/* Note: The Nul is a delimiter and not a terminator. */ c = null_names ? 0 : '\n';
c = 0;
eof_seen = 1; eof_seen = 1;
} }
if (n >= sizeof namebuf - 1) if (n >= sizeof namebuf - 1)
@ -815,15 +833,38 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
{ {
skip_this = 1; skip_this = 1;
log_error ("error reading '%s': %s\n", log_error ("error reading '%s': %s\n",
"[stdin]", "filename too long"); files_from, "filename too long");
} }
} }
else else
namebuf[n++] = c; namebuf[n++] = c;
if (!c)
if (null_names)
{ {
namebuf[n] = 0; if (!c)
break; {
namebuf[n] = 0;
break;
}
}
else /* Shall be LF delimited. */
{
if (!c)
{
if (!skip_this)
{
skip_this = 1;
log_error ("error reading '%s': %s\n",
files_from, "filename with embedded Nul");
}
}
else if ( c == '\n' )
{
namebuf[n] = 0;
ascii_trim_spaces (namebuf);
n = strlen (namebuf);
break;
}
} }
} }
@ -856,6 +897,9 @@ gpgtar_create (char **inpattern, int encrypt, int sign)
xfree (pat); xfree (pat);
} }
if (files_from_stream && files_from_stream != es_stdin)
es_fclose (files_from_stream);
if (opt.outfile) if (opt.outfile)
{ {
if (!strcmp (opt.outfile, "-")) if (!strcmp (opt.outfile, "-"))

View File

@ -140,10 +140,10 @@ static gpgrt_opt_t tar_opts[] = {
/* Global flags. */ /* Global flags. */
enum cmd_and_opt_values cmd = 0; static enum cmd_and_opt_values cmd = 0;
int skip_crypto = 0; static int skip_crypto = 0;
const char *files_from = NULL; static const char *files_from = NULL;
int null_names = 0; static int null_names = 0;
@ -440,11 +440,6 @@ main (int argc, char **argv)
parse_arguments (&pargs, opts); parse_arguments (&pargs, opts);
gpgrt_argparse (NULL, &pargs, NULL); gpgrt_argparse (NULL, &pargs, NULL);
if ((files_from && !null_names) || (!files_from && null_names))
log_error ("--files-from and --null may only be used in conjunction\n");
if (files_from && strcmp (files_from, "-"))
log_error ("--files-from only supports argument \"-\"\n");
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);
@ -482,12 +477,14 @@ main (int argc, char **argv)
case aEncrypt: case aEncrypt:
case aSign: case aSign:
case aSignEncrypt: case aSignEncrypt:
if ((!argc && !null_names) if ((!argc && !files_from)
|| (argc && null_names)) || (argc && files_from))
gpgrt_usage (1); gpgrt_usage (1);
if (opt.filename) if (opt.filename)
log_info ("note: ignoring option --set-filename\n"); log_info ("note: ignoring option --set-filename\n");
err = gpgtar_create (null_names? NULL :argv, err = gpgtar_create (files_from? NULL : argv,
files_from,
null_names,
!skip_crypto !skip_crypto
&& (cmd == aEncrypt || cmd == aSignEncrypt), && (cmd == aEncrypt || cmd == aSignEncrypt),
cmd == aSign || cmd == aSignEncrypt); cmd == aSign || cmd == aSignEncrypt);

View File

@ -130,7 +130,8 @@ gpg_error_t read_record (estream_t stream, void *record);
gpg_error_t write_record (estream_t stream, const void *record); gpg_error_t write_record (estream_t stream, const void *record);
/*-- gpgtar-create.c --*/ /*-- gpgtar-create.c --*/
gpg_error_t gpgtar_create (char **inpattern, int encrypt, int sign); gpg_error_t gpgtar_create (char **inpattern, const char *files_from,
int null_names, int encrypt, int sign);
/*-- gpgtar-extract.c --*/ /*-- gpgtar-extract.c --*/
gpg_error_t gpgtar_extract (const char *filename, int decrypt); gpg_error_t gpgtar_extract (const char *filename, int decrypt);