diff options
author | Werner Koch <wk@gnupg.org> | 2010-07-16 15:19:45 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2010-07-16 15:19:45 +0200 |
commit | 8b8925a2bdbb12dd537dde20a27cdb1416c2f1ae (patch) | |
tree | 366acb6bb52e61242bb39682ddddb76615c3ba34 /tools/gpgtar-extract.c | |
parent | Make it build on W32 again. (diff) | |
download | gnupg2-8b8925a2bdbb12dd537dde20a27cdb1416c2f1ae.tar.xz gnupg2-8b8925a2bdbb12dd537dde20a27cdb1416c2f1ae.zip |
Some work on porting dirmngr (unfinished)
Ported gpgtar to W32.
Diffstat (limited to 'tools/gpgtar-extract.c')
-rw-r--r-- | tools/gpgtar-extract.c | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 002215c5d..028ac0df4 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -32,7 +32,6 @@ #include "gpgtar.h" - static gpg_error_t extract_regular (estream_t stream, const char *dirname, tar_header_t hdr) @@ -79,6 +78,8 @@ extract_regular (estream_t stream, const char *dirname, /* Fixme: Set permissions etc. */ leave: + if (!err && opt.verbose) + log_info ("extracted `%s/'\n", fname); es_fclose (outfp); if (err && fname && outfp) { @@ -96,7 +97,9 @@ extract_directory (const char *dirname, tar_header_t hdr) { gpg_error_t err; char *fname; - + size_t prefixlen; + + prefixlen = strlen (dirname) + 1; fname = strconcat (dirname, "/", hdr->name, NULL); if (!fname) { @@ -107,14 +110,40 @@ extract_directory (const char *dirname, tar_header_t hdr) else err = 0; + if (fname[strlen (fname)-1] == '/') + fname[strlen (fname)-1] = 0; + + /* Note that we don't need to care about EEXIST because we always + extract into a new hierarchy. */ if (gnupg_mkdir (fname, "-rwx------")) { err = gpg_error_from_syserror (); - log_error ("error creating directory `%s': %s\n", - fname, gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_ENOENT) + { + /* Try to create the directory with parents but keep the + original error code in case of a failure. */ + char *p; + int rc = 0; + + for (p = fname+prefixlen; (p = strchr (p, '/')); p++) + { + *p = 0; + rc = gnupg_mkdir (fname, "-rwx------"); + *p = '/'; + if (rc) + break; + } + if (!rc && !gnupg_mkdir (fname, "-rwx------")) + err = 0; + } + if (err) + log_error ("error creating directory `%s': %s\n", + fname, gpg_strerror (err)); } leave: + if (!err && opt.verbose) + log_info ("created `%s/'\n", fname); xfree (fname); return err; } @@ -155,7 +184,8 @@ extract (estream_t stream, const char *dirname, tar_header_t hdr) { char record[RECORDSIZE]; - log_info ("unsupported file type for `%s' - skipped\n", hdr->name); + log_info ("unsupported file type %d for `%s' - skipped\n", + (int)hdr->typeflag, hdr->name); for (err = 0, n=0; !err && n < hdr->nrecords; n++) err = read_record (stream, record); } @@ -171,9 +201,31 @@ static char * create_directory (const char *dirprefix) { gpg_error_t err = 0; + char *prefix_buffer = NULL; char *dirname = NULL; + size_t n; int idx; + /* Remove common suffixes. */ + n = strlen (dirprefix); + if (n > 4 && (!compare_filenames (dirprefix + n - 4, EXTSEP_S "gpg") + || !compare_filenames (dirprefix + n - 4, EXTSEP_S "pgp") + || !compare_filenames (dirprefix + n - 4, EXTSEP_S "asc") + || !compare_filenames (dirprefix + n - 4, EXTSEP_S "pem") + || !compare_filenames (dirprefix + n - 4, EXTSEP_S "p7e"))) + { + prefix_buffer = xtrystrdup (dirprefix); + if (!prefix_buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + prefix_buffer[n-4] = 0; + dirprefix = prefix_buffer; + } + + + for (idx=1; idx < 5000; idx++) { xfree (dirname); @@ -184,14 +236,14 @@ create_directory (const char *dirprefix) goto leave; } if (!gnupg_mkdir (dirname, "-rwx------")) - goto leave; + goto leave; /* Ready. */ if (errno != EEXIST && errno != ENOTDIR) { err = gpg_error_from_syserror (); goto leave; } } - err = gpg_error_from_syserror (); + err = gpg_error (GPG_ERR_LIMIT_REACHED); leave: if (err) @@ -201,6 +253,7 @@ create_directory (const char *dirprefix) xfree (dirname); dirname = NULL; } + xfree (prefix_buffer); return dirname; } @@ -217,9 +270,6 @@ gpgtar_extract (const char *filename) if (filename) { - dirprefix = strrchr (filename, '/'); - if (dirprefix) - dirprefix++; stream = es_fopen (filename, "rb"); if (!stream) { @@ -231,6 +281,20 @@ gpgtar_extract (const char *filename) else stream = es_stdin; /* FIXME: How can we enforce binary mode? */ + + if (filename) + { + dirprefix = strrchr (filename, '/'); + if (dirprefix) + dirprefix++; + } + else if (opt.filename) + { + dirprefix = strrchr (opt.filename, '/'); + if (dirprefix) + dirprefix++; + } + if (!dirprefix || !*dirprefix) dirprefix = "GPGARCH"; |