From: Tim Kientzle Date: Sat, 3 May 2008 16:21:41 +0000 (-0400) Subject: archive_read_extract2() provides much of the convenience of X-Git-Tag: v2.6.0~272 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b22b37ae0fb1eec65f98d5cb8983c5de0f41af1d;p=thirdparty%2Flibarchive.git archive_read_extract2() provides much of the convenience of archive_read_extract() while allowing you to configure the archive_write_disk restore object. SVN-Revision: 20 --- diff --git a/libarchive/archive.h b/libarchive/archive.h index 293735bd7..ae7e9334b 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -386,9 +386,11 @@ __LA_DECL int archive_read_data_into_fd(struct archive *, int fd); /* Default: Overwrite files, even if one on disk is newer. */ #define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (2048) -__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, +__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, int flags); -__LA_DECL void archive_read_extract_set_progress_callback(struct archive *, +__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *, + struct archive * /* dest */); +__LA_DECL void archive_read_extract_set_progress_callback(struct archive *, void (*_progress_func)(void *), void *_user_data); /* Record the dev/ino of a file that will not be written. This is diff --git a/libarchive/archive_read.3 b/libarchive/archive_read.3 index e15c904a7..dbbe1f7f1 100644 --- a/libarchive/archive_read.3 +++ b/libarchive/archive_read.3 @@ -56,6 +56,7 @@ .\" #endif .Nm archive_read_data_into_fd , .Nm archive_read_extract , +.Nm archive_read_extract2 , .Nm archive_read_extract_set_progress_callback , .Nm archive_read_close , .Nm archive_read_finish @@ -145,6 +146,12 @@ .Fa "struct archive_entry *" .Fa "int flags" .Fc +.Ft int +.Fo archive_read_extract2 +.Fa "struct archive *src" +.Fa "struct archive_entry *" +.Fa "struct archive *dest" +.Fc .Ft void .Fo archive_read_extract_set_progress_callback .Fa "struct archive *" @@ -314,6 +321,22 @@ The .Va flags argument is passed unmodified to .Xr archive_write_disk_set_options 3 . +.It Fn archive_read_extract2 +This is another version of +.Fn archive_read_extract +that allows you to provide your own restore object. +In particular, this allows you to override the standard lookup functions +using +.Xr archive_write_disk_set_group_lookup 3 , +and +.Xr archive_write_disk_set_user_lookup 3 . +Note that +.Fn archive_read_extract2 +does not accept a +.Va flags +argument; you should use +.Fn archive_write_disk_set_options +to set the restore options yourself. .It Fn archive_read_extract_set_progress_callback Sets a pointer to a user-defined callback that can be used for updating progress displays during extraction. diff --git a/libarchive/archive_read_extract.c b/libarchive/archive_read_extract.c index bb5add7bb..ab01f7df3 100644 --- a/libarchive/archive_read_extract.c +++ b/libarchive/archive_read_extract.c @@ -82,34 +82,40 @@ get_extract(struct archive_read *a) int archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags) { - struct archive_read *a = (struct archive_read *)_a; struct extract *extract; - int r, r2; - extract = get_extract(a); + extract = get_extract((struct archive_read *)_a); if (extract == NULL) return (ARCHIVE_FATAL); + archive_write_disk_set_options(extract->ad, flags); + return (archive_read_extract2(_a, entry, extract->ad)); +} + +int +archive_read_extract2(struct archive *_a, struct archive_entry *entry, + struct archive *ad) +{ + struct archive_read *a = (struct archive_read *)_a; + int r, r2; /* Set up for this particular entry. */ - extract = a->extract; - archive_write_disk_set_options(a->extract->ad, flags); - archive_write_disk_set_skip_file(a->extract->ad, + archive_write_disk_set_skip_file(ad, a->skip_file_dev, a->skip_file_ino); - r = archive_write_header(a->extract->ad, entry); + r = archive_write_header(ad, entry); if (r < ARCHIVE_WARN) r = ARCHIVE_WARN; if (r != ARCHIVE_OK) /* If _write_header failed, copy the error. */ - archive_copy_error(&a->archive, extract->ad); + archive_copy_error(&a->archive, ad); else /* Otherwise, pour data into the entry. */ - r = copy_data(_a, a->extract->ad); - r2 = archive_write_finish_entry(a->extract->ad); + r = copy_data(_a, ad); + r2 = archive_write_finish_entry(ad); if (r2 < ARCHIVE_WARN) r2 = ARCHIVE_WARN; /* Use the first message. */ if (r2 != ARCHIVE_OK && r == ARCHIVE_OK) - archive_copy_error(&a->archive, extract->ad); + archive_copy_error(&a->archive, ad); /* Use the worst error return. */ if (r2 < r) r = r2;