aboutsummaryrefslogtreecommitdiff
path: root/lib/libarchive/archive_entry.h
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2008-05-26 17:00:24 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2008-05-26 17:00:24 +0000
commitfa07de5eeb36516701b3393f13acc1e1f702c634 (patch)
treed200bbdabe22d32b68a61172999be232d0c31d75 /lib/libarchive/archive_entry.h
parent037dab5792a349d02f4bb134d55e9402f3254c7c (diff)
MFp4: libarchive 2.5.4b. (Still 'b' until I get a bit more
feedback, but the 2.5 branch is shaping up nicely.) In addition to many small bug fixes and code improvements: * Another iteration of versioning; I think I've got it right now. * Portability: A lot of progress on Windows support (though I'm not committing all of the Windows support files to FreeBSD CVS) * Explicit tracking of MBS, WCS, and UTF-8 versions of strings in archive_entry; the archive_entry routines now correctly return NULL only when something is unset, setting NULL properly clears string values. Most charset conversions have been pushed down to archive_string. * Better handling of charset conversion failure when writing or reading UTF-8 headers in pax archives * archive_entry_linkify() provides multiple strategies for hardlink matching to suit different format expectations * More accurate bzip2 format detection * Joerg Sonnenberger's extensive improvements to mtree support * Rough support for self-extracting ZIP archives. Not an ideal approach, but it works for the archives I've tried. * New "sparsify" option in archive_write_disk converts blocks of nulls into seeks. * Better default behavior for the test harness; it now reports all failures by default instead of coredumping at the first one.
Notes
Notes: svn path=/head/; revision=179321
Diffstat (limited to 'lib/libarchive/archive_entry.h')
-rw-r--r--lib/libarchive/archive_entry.h329
1 files changed, 223 insertions, 106 deletions
diff --git a/lib/libarchive/archive_entry.h b/lib/libarchive/archive_entry.h
index 8c61b9553b63..c453483a65ac 100644
--- a/lib/libarchive/archive_entry.h
+++ b/lib/libarchive/archive_entry.h
@@ -28,20 +28,74 @@
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
+/*
+ * Note: archive_entry.h is for use outside of libarchive; the
+ * configuration headers (config.h, archive_platform.h, etc.) are
+ * purely internal. Do NOT use HAVE_XXX configuration macros to
+ * control the behavior of this header! If you must conditionalize,
+ * use predefined compiler and/or platform macros.
+ */
+
#include <sys/types.h>
#include <stddef.h> /* for wchar_t */
#include <time.h>
+
+/* Get appropriate definitions of standard POSIX-style types. */
+/* These should match the types used in 'struct stat' */
+#ifdef _WIN32
+#define __LA_UID_T unsigned int
+#define __LA_GID_T unsigned int
+#define __LA_DEV_T unsigned int
+#define __LA_MODE_T unsigned short
+#else
#include <unistd.h>
+#define __LA_UID_T uid_t
+#define __LA_GID_T gid_t
+#define __LA_DEV_T dev_t
+#define __LA_MODE_T mode_t
+#endif
+
+/*
+ * XXX Is this defined for all Windows compilers? If so, in what
+ * header? It would be nice to remove the __LA_INO_T indirection and
+ * just use plain ino_t everywhere. Likewise for the other types just
+ * above.
+ */
+#define __LA_INO_T ino_t
+
+
+/*
+ * On Windows, define LIBARCHIVE_STATIC if you're building or using a
+ * .lib. The default here assumes you're building a DLL. Only
+ * libarchive source should ever define __LIBARCHIVE_BUILD.
+ */
+#if ((defined __WIN32__) || (defined _WIN32)) && (!defined LIBARCHIVE_STATIC)
+# ifdef __LIBARCHIVE_BUILD
+# ifdef __GNUC__
+# define __LA_DECL __attribute__((dllexport)) extern
+# else
+# define __LA_DECL __declspec(dllexport)
+# endif
+# else
+# ifdef __GNUC__
+# define __LA_DECL __attribute__((dllimport)) extern
+# else
+# define __LA_DECL __declspec(dllimport)
+# endif
+# endif
+#else
+/* Static libraries on all platforms and shared libraries on non-Windows. */
+# define __LA_DECL
+#endif
#ifdef __cplusplus
extern "C" {
#endif
-
/*
* Description of an archive entry.
*
- * Basically, a "struct stat" with a few text fields added in.
+ * You can think of this as "struct stat" with some text fields added in.
*
* TODO: Add "comment", "charset", and possibly other entries that are
* supported by "pax interchange" format. However, GNU, ustar, cpio,
@@ -90,50 +144,51 @@ struct archive_entry;
* Basic object manipulation
*/
-struct archive_entry *archive_entry_clear(struct archive_entry *);
+__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
/* The 'clone' function does a deep copy; all of the strings are copied too. */
-struct archive_entry *archive_entry_clone(struct archive_entry *);
-void archive_entry_free(struct archive_entry *);
-struct archive_entry *archive_entry_new(void);
+__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
+__LA_DECL void archive_entry_free(struct archive_entry *);
+__LA_DECL struct archive_entry *archive_entry_new(void);
/*
* Retrieve fields from an archive_entry.
*/
-time_t archive_entry_atime(struct archive_entry *);
-long archive_entry_atime_nsec(struct archive_entry *);
-time_t archive_entry_ctime(struct archive_entry *);
-long archive_entry_ctime_nsec(struct archive_entry *);
-dev_t archive_entry_dev(struct archive_entry *);
-dev_t archive_entry_devmajor(struct archive_entry *);
-dev_t archive_entry_devminor(struct archive_entry *);
-mode_t archive_entry_filetype(struct archive_entry *);
-void archive_entry_fflags(struct archive_entry *,
+__LA_DECL time_t archive_entry_atime(struct archive_entry *);
+__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
+__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
+__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
+__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
+__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
+__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
+__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
+__LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
-const char *archive_entry_fflags_text(struct archive_entry *);
-gid_t archive_entry_gid(struct archive_entry *);
-const char *archive_entry_gname(struct archive_entry *);
-const wchar_t *archive_entry_gname_w(struct archive_entry *);
-const char *archive_entry_hardlink(struct archive_entry *);
-const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
-ino_t archive_entry_ino(struct archive_entry *);
-mode_t archive_entry_mode(struct archive_entry *);
-time_t archive_entry_mtime(struct archive_entry *);
-long archive_entry_mtime_nsec(struct archive_entry *);
-unsigned int archive_entry_nlink(struct archive_entry *);
-const char *archive_entry_pathname(struct archive_entry *);
-const wchar_t *archive_entry_pathname_w(struct archive_entry *);
-dev_t archive_entry_rdev(struct archive_entry *);
-dev_t archive_entry_rdevmajor(struct archive_entry *);
-dev_t archive_entry_rdevminor(struct archive_entry *);
-int64_t archive_entry_size(struct archive_entry *);
-const char *archive_entry_strmode(struct archive_entry *);
-const char *archive_entry_symlink(struct archive_entry *);
-const wchar_t *archive_entry_symlink_w(struct archive_entry *);
-uid_t archive_entry_uid(struct archive_entry *);
-const char *archive_entry_uname(struct archive_entry *);
-const wchar_t *archive_entry_uname_w(struct archive_entry *);
+__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
+__LA_DECL __LA_GID_T archive_entry_gid(struct archive_entry *);
+__LA_DECL const char *archive_entry_gname(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
+__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
+__LA_DECL __LA_INO_T archive_entry_ino(struct archive_entry *);
+__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
+__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
+__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
+__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
+__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
+__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
+__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
+__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
+__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
+__LA_DECL int64_t archive_entry_size(struct archive_entry *);
+__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
+__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
+__LA_DECL __LA_UID_T archive_entry_uid(struct archive_entry *);
+__LA_DECL const char *archive_entry_uname(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
/*
* Set fields in an archive_entry.
@@ -142,48 +197,54 @@ const wchar_t *archive_entry_uname_w(struct archive_entry *);
* In contrast, 'copy' functions do copy the object pointed to.
*/
-void archive_entry_set_atime(struct archive_entry *, time_t, long);
-void archive_entry_set_ctime(struct archive_entry *, time_t, long);
-void archive_entry_set_dev(struct archive_entry *, dev_t);
-void archive_entry_set_devmajor(struct archive_entry *, dev_t);
-void archive_entry_set_devminor(struct archive_entry *, dev_t);
-void archive_entry_set_filetype(struct archive_entry *, unsigned int);
-void archive_entry_set_fflags(struct archive_entry *,
+__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
+__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
+__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
+__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
unsigned long /* set */, unsigned long /* clear */);
/* Returns pointer to start of first invalid token, or NULL if none. */
/* Note that all recognized tokens are processed, regardless. */
-const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
+__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
+ const char *);
+__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
-void archive_entry_set_gid(struct archive_entry *, gid_t);
-void archive_entry_set_gname(struct archive_entry *, const char *);
-void archive_entry_copy_gname(struct archive_entry *, const char *);
-void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
-void archive_entry_set_hardlink(struct archive_entry *, const char *);
-void archive_entry_copy_hardlink(struct archive_entry *, const char *);
-void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
-void archive_entry_set_ino(struct archive_entry *, unsigned long);
-void archive_entry_set_link(struct archive_entry *, const char *);
-void archive_entry_copy_link(struct archive_entry *, const char *);
-void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
-void archive_entry_set_mode(struct archive_entry *, mode_t);
-void archive_entry_set_mtime(struct archive_entry *, time_t, long);
-void archive_entry_set_nlink(struct archive_entry *, unsigned int);
-void archive_entry_set_pathname(struct archive_entry *, const char *);
-void archive_entry_copy_pathname(struct archive_entry *, const char *);
-void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
-void archive_entry_set_perm(struct archive_entry *, mode_t);
-void archive_entry_set_rdev(struct archive_entry *, dev_t);
-void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
-void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
-void archive_entry_set_size(struct archive_entry *, int64_t);
-void archive_entry_set_symlink(struct archive_entry *, const char *);
-void archive_entry_copy_symlink(struct archive_entry *, const char *);
-void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
-void archive_entry_set_uid(struct archive_entry *, uid_t);
-void archive_entry_set_uname(struct archive_entry *, const char *);
-void archive_entry_copy_uname(struct archive_entry *, const char *);
-void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
-
+__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_GID_T);
+__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
+__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
+__LA_DECL void archive_entry_set_ino(struct archive_entry *, unsigned long);
+__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
+__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
+__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
+__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
+__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
+__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
+__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_size(struct archive_entry *, int64_t);
+__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
+__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_UID_T);
+__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
+__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
/*
* Routines to bulk copy fields to/from a platform-native "struct
* stat." Libarchive used to just store a struct stat inside of each
@@ -193,8 +254,8 @@ void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
*
* TODO: On Linux, provide both stat32 and stat64 versions of these functions.
*/
-const struct stat *archive_entry_stat(struct archive_entry *);
-void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
+__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
+__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
/*
* ACL routines. This used to simply store and return text-format ACL
@@ -242,11 +303,11 @@ void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
* POSIX.1e) is useful for handling archive formats that combine
* default and access information in a single ACL list.
*/
-void archive_entry_acl_clear(struct archive_entry *);
-void archive_entry_acl_add_entry(struct archive_entry *,
+__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
+__LA_DECL void archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
-void archive_entry_acl_add_entry_w(struct archive_entry *,
+__LA_DECL void archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
@@ -255,11 +316,11 @@ void archive_entry_acl_add_entry_w(struct archive_entry *,
* "next" entry. The want_type parameter allows you to request only
* access entries or only default entries.
*/
-int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
-int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
+__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
+__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
-int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
+__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const wchar_t ** /* name */);
@@ -276,11 +337,11 @@ int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
-const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
+__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */);
/* Return a count of entries matching 'want_type' */
-int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
+__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
/*
* Private ACL parser. This is private because it handles some
@@ -295,15 +356,15 @@ int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
* TODO: Move this declaration out of the public header and into
* a private header. Warnings above are silly.
*/
-int __archive_entry_acl_parse_w(struct archive_entry *,
+__LA_DECL int __archive_entry_acl_parse_w(struct archive_entry *,
const wchar_t *, int /* type */);
/*
* extended attributes
*/
-void archive_entry_xattr_clear(struct archive_entry *);
-void archive_entry_xattr_add_entry(struct archive_entry *,
+__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
+__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
const char * /* name */, const void * /* value */,
size_t /* size */);
@@ -312,37 +373,93 @@ void archive_entry_xattr_add_entry(struct archive_entry *,
* "next" entry.
*/
-int archive_entry_xattr_count(struct archive_entry *);
-int archive_entry_xattr_reset(struct archive_entry *);
-int archive_entry_xattr_next(struct archive_entry *,
+__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
+__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
+__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
- * Utility to detect hardlinks.
+ * Utility to match up hardlinks.
+ *
+ * The 'struct archive_entry_linkresolver' is a cache of archive entries
+ * for files with multiple links. Here's how to use it:
+ * 1. Create a lookup object with archive_entry_linkresolver_new()
+ * 2. Tell it the archive format you're using.
+ * 3. Hand each archive_entry to archive_entry_linkify().
+ * That function will return 0, 1, or 2 entries that should
+ * be written.
+ * 4. Call archive_entry_linkify(resolver, NULL) until
+ * no more entries are returned.
+ * 5. Call archive_entry_link_resolver_free(resolver) to free resources.
*
- * The 'struct archive_hardlink_lookup' is a cache of entry
- * names and dev/ino numbers. Here's how to use it:
- * 1. Create a lookup object with archive_hardlink_lookup_new()
- * 2. Hand each archive_entry to archive_hardlink_lookup().
- * That function will return NULL (this is not a hardlink to
- * a previous entry) or the pathname of the first entry
- * that matched this.
- * 3. Use archive_hardlink_lookup_free() to release the cache.
+ * The entries returned have their hardlink and size fields updated
+ * appropriately. If an entry is passed in that does not refer to
+ * a file with multiple links, it is returned unchanged. The intention
+ * is that you should be able to simply filter all entries through
+ * this machine.
*
* To make things more efficient, be sure that each entry has a valid
* nlinks value. The hardlink cache uses this to track when all links
* have been found. If the nlinks value is zero, it will keep every
* name in the cache indefinitely, which can use a lot of memory.
+ *
+ * Note that archive_entry_size() is reset to zero if the file
+ * body should not be written to the archive. Pay attention!
*/
-struct archive_entry_linkresolver;
+__LA_DECL struct archive_entry_linkresolver;
-struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
-void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
-const char *archive_entry_linkresolve(struct archive_entry_linkresolver *,
- struct archive_entry *);
+/*
+ * There are three different strategies for marking hardlinks.
+ * The descriptions below name them after the best-known
+ * formats that rely on each strategy:
+ *
+ * "Old cpio" is the simplest, it always returns any entry unmodified.
+ * As far as I know, only cpio formats use this. Old cpio archives
+ * store every link with the full body; the onus is on the dearchiver
+ * to detect and properly link the files as they are restored.
+ * "tar" is also pretty simple; it caches a copy the first time it sees
+ * any link. Subsequent appearances are modified to be hardlink
+ * references to the first one without any body. Used by all tar
+ * formats, although the newest tar formats permit the "old cpio" strategy
+ * as well. This strategy is very simple for the dearchiver,
+ * and reasonably straightforward for the archiver.
+ * "new cpio" is trickier. It stores the body only with the last
+ * occurrence. The complication is that we might not
+ * see every link to a particular file in a single session, so
+ * there's no easy way to know when we've seen the last occurrence.
+ * The solution here is to queue one link until we see the next.
+ * At the end of the session, you can enumerate any remaining
+ * entries by calling archive_entry_linkify(NULL) and store those
+ * bodies. If you have a file with three links l1, l2, and l3,
+ * you'll get the following behavior if you see all three links:
+ * linkify(l1) => NULL (the resolver stores l1 internally)
+ * linkify(l2) => l1 (resolver stores l2, you write l1)
+ * linkify(l3) => l2, l3 (all links seen, you can write both).
+ * If you only see l1 and l2, you'll get this behavior:
+ * linkify(l1) => NULL
+ * linkify(l2) => l1
+ * linkify(NULL) => l2 (at end, you retrieve remaining links)
+ * As the name suggests, this strategy is used by newer cpio variants.
+ * It's noticably more complex for the archiver, slightly more complex
+ * for the dearchiver than the tar strategy, but makes it straightforward
+ * to restore a file using any link by simply continuing to scan until
+ * you see a link that is stored with a body. In contrast, the tar
+ * strategy requires you to rescan the archive from the beginning to
+ * correctly extract an arbitrary link.
+ */
+
+__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
+__LA_DECL void archive_entry_linkresolver_set_strategy(
+ struct archive_entry_linkresolver *, int /* format_code */);
+__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
+__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
+ struct archive_entry **, struct archive_entry **);
#ifdef __cplusplus
}
#endif
+/* This is meaningless outside of this header. */
+#undef __LA_DECL
+
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */