diff --git a/common/stringhelp.c b/common/stringhelp.c index dd1711684..3424048f9 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -213,6 +213,36 @@ trim_spaces( char *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 */ diff --git a/common/stringhelp.h b/common/stringhelp.h index 7df6c7656..42bb19aaf 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -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); char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); +char *ascii_trim_spaces (char *string); char *trim_trailing_spaces( char *string ); unsigned int trim_trailing_chars( unsigned char *line, unsigned len, const char *trimchars); diff --git a/common/utf8conv.c b/common/utf8conv.c index d2c282002..01604e176 100644 --- a/common/utf8conv.c +++ b/common/utf8conv.c @@ -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 * ERRNO on failure. Calling this function with STRING set to NULL is * not defined. */ diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index a08601634..9921074a3 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -744,20 +744,39 @@ write_eof_mark (estream_t stream) /* Create a new tarball using the names in the array INPATTERN. If 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 -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; struct scanctrl_s scanctrl_buffer; scanctrl_t scanctrl = &scanctrl_buffer; tar_header_t hdr, *start_tail; + estream_t files_from_stream = NULL; estream_t outstream = NULL; estream_t cipher_stream = NULL; int eof_seen = 0; 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); scanctrl->flist_tail = &scanctrl->flist; @@ -788,7 +807,7 @@ gpgtar_create (char **inpattern, int encrypt, int sign) pat = xtrystrdup (pattern); } - else /* Read null delimited pattern from stdin. */ + else /* Read Nul or LF delimited pattern from files_from_stream. */ { int c; char namebuf[4096]; @@ -796,17 +815,16 @@ gpgtar_create (char **inpattern, int encrypt, int sign) 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 (); log_error ("error reading '%s': %s\n", - "[stdin]", strerror (errno)); + files_from, gpg_strerror (err)); goto leave; } - /* Note: The Nul is a delimiter and not a terminator. */ - c = 0; + c = null_names ? 0 : '\n'; eof_seen = 1; } if (n >= sizeof namebuf - 1) @@ -815,15 +833,38 @@ gpgtar_create (char **inpattern, int encrypt, int sign) { skip_this = 1; log_error ("error reading '%s': %s\n", - "[stdin]", "filename too long"); + files_from, "filename too long"); } } else namebuf[n++] = c; - if (!c) + + if (null_names) { - namebuf[n] = 0; - break; + if (!c) + { + 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); } + if (files_from_stream && files_from_stream != es_stdin) + es_fclose (files_from_stream); + if (opt.outfile) { if (!strcmp (opt.outfile, "-")) diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 680ed3ddd..315f8a74b 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -140,10 +140,10 @@ static gpgrt_opt_t tar_opts[] = { /* Global flags. */ -enum cmd_and_opt_values cmd = 0; -int skip_crypto = 0; -const char *files_from = NULL; -int null_names = 0; +static enum cmd_and_opt_values cmd = 0; +static int skip_crypto = 0; +static const char *files_from = NULL; +static int null_names = 0; @@ -440,11 +440,6 @@ main (int argc, char **argv) parse_arguments (&pargs, opts); 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)) exit (2); @@ -482,12 +477,14 @@ main (int argc, char **argv) case aEncrypt: case aSign: case aSignEncrypt: - if ((!argc && !null_names) - || (argc && null_names)) + if ((!argc && !files_from) + || (argc && files_from)) gpgrt_usage (1); if (opt.filename) 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 && (cmd == aEncrypt || cmd == aSignEncrypt), cmd == aSign || cmd == aSignEncrypt); diff --git a/tools/gpgtar.h b/tools/gpgtar.h index 74bfb56e8..3e7aa5ed6 100644 --- a/tools/gpgtar.h +++ b/tools/gpgtar.h @@ -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); /*-- 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 --*/ gpg_error_t gpgtar_extract (const char *filename, int decrypt);