2020-03-04 16:55:40 +01:00
|
|
|
|
ARCHIVE_ENTRY_LINKIFY(3) BSD Library Functions Manual ARCHIVE_ENTRY_LINKIFY(3)
|
|
|
|
|
|
|
|
|
|
NAME
|
|
|
|
|
archive_entry_linkresolver, archive_entry_linkresolver_new,
|
|
|
|
|
archive_entry_linkresolver_set_strategy, archive_entry_linkresolver_free,
|
2021-12-09 12:22:14 +01:00
|
|
|
|
archive_entry_linkify — hardlink resolver functions
|
2020-03-04 16:55:40 +01:00
|
|
|
|
|
|
|
|
|
LIBRARY
|
|
|
|
|
Streaming Archive Library (libarchive, -larchive)
|
|
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
|
#include <archive_entry.h>
|
|
|
|
|
|
|
|
|
|
struct archive_entry_linkresolver *
|
|
|
|
|
archive_entry_linkresolver_new(void);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *resolver,
|
|
|
|
|
int format);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
archive_entry_linkresolver_free(struct archive_entry_linkresolver *resolver);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
archive_entry_linkify(struct archive_entry_linkresolver *resolver,
|
|
|
|
|
struct archive_entry **entry, struct archive_entry **sparse);
|
|
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
|
Programs that want to create archives have to deal with hardlinks.
|
2021-12-09 12:22:14 +01:00
|
|
|
|
Hardlinks are handled in different ways by the archive formats. The ba‐
|
|
|
|
|
sic strategies are:
|
2020-03-04 16:55:40 +01:00
|
|
|
|
|
|
|
|
|
1. Ignore hardlinks and store the body for each reference (old cpio,
|
|
|
|
|
zip).
|
|
|
|
|
|
|
|
|
|
2. Store the body the first time an inode is seen (ustar, pax).
|
|
|
|
|
|
|
|
|
|
3. Store the body the last time an inode is seen (new cpio).
|
|
|
|
|
|
2021-12-09 12:22:14 +01:00
|
|
|
|
The archive_entry_linkresolver functions help by providing a unified in‐
|
|
|
|
|
terface and handling the complexity behind the scene.
|
2020-03-04 16:55:40 +01:00
|
|
|
|
|
2021-12-09 12:22:14 +01:00
|
|
|
|
The archive_entry_linkresolver functions assume that archive_entry in‐
|
|
|
|
|
stances have valid nlinks, inode and device values. The inode and device
|
|
|
|
|
value is used to match entries. The nlinks value is used to determined
|
|
|
|
|
if all references have been found and if the internal references can be
|
|
|
|
|
recycled.
|
2020-03-04 16:55:40 +01:00
|
|
|
|
|
2021-12-09 12:22:14 +01:00
|
|
|
|
The archive_entry_linkresolver_new() function allocates a new link re‐
|
|
|
|
|
solver. The instance can be freed using
|
2020-03-04 16:55:40 +01:00
|
|
|
|
archive_entry_linkresolver_free(). All deferred entries are flushed and
|
|
|
|
|
the internal storage is freed.
|
|
|
|
|
|
2021-12-09 12:22:14 +01:00
|
|
|
|
The archive_entry_linkresolver_set_strategy() function selects the opti‐
|
|
|
|
|
mal hardlink strategy for the given format. The format code can be ob‐
|
|
|
|
|
tained from archive_format(3). The function can be called more than
|
2020-03-04 16:55:40 +01:00
|
|
|
|
once, but it is recommended to flush all deferred entries first.
|
|
|
|
|
|
|
|
|
|
The archive_entry_linkify() function is the core of
|
|
|
|
|
archive_entry_linkresolver. The entry() argument points to the
|
|
|
|
|
archive_entry that should be written. Depending on the strategy one of
|
|
|
|
|
the following actions is taken:
|
|
|
|
|
|
|
|
|
|
1. For the simple archive formats *entry is left unmodified and *sparse
|
|
|
|
|
is set to NULL.
|
|
|
|
|
|
|
|
|
|
2. For tar like archive formats, *sparse is set to NULL. If *entry is
|
|
|
|
|
NULL, no action is taken. If the hardlink count of *entry is larger
|
2021-12-09 12:22:14 +01:00
|
|
|
|
than 1 and the file type is a regular file or symbolic link, the in‐
|
|
|
|
|
ternal list is searched for a matching inode. If such an inode is
|
2020-03-04 16:55:40 +01:00
|
|
|
|
found, the link count is decremented and the file size of *entry is
|
|
|
|
|
set to 0 to notify that no body should be written. If no such inode
|
|
|
|
|
is found, a copy of the entry is added to the internal cache with a
|
|
|
|
|
link count reduced by one.
|
|
|
|
|
|
|
|
|
|
3. For new cpio like archive formats a value for *entry of NULL is used
|
2021-12-09 12:22:14 +01:00
|
|
|
|
to flush deferred entries. In that case *entry is set to an arbi‐
|
|
|
|
|
trary deferred entry and the entry itself is removed from the inter‐
|
2020-03-04 16:55:40 +01:00
|
|
|
|
nal list. If the internal list is empty, *entry is set to NULL. In
|
|
|
|
|
either case, *sparse is set to NULL and the function returns. If
|
|
|
|
|
the hardlink count of *entry is one or the file type is a directory
|
|
|
|
|
or device, *sparse is set to NULL and no further action is taken.
|
|
|
|
|
Otherwise, the internal list is searched for a matching inode. If
|
|
|
|
|
such an inode is not found, the entry is added to the internal list,
|
|
|
|
|
both *entry and *sparse are set to NULL and the function returns.
|
2021-12-09 12:22:14 +01:00
|
|
|
|
If such an inode is found, the link count is decremented. If it re‐
|
|
|
|
|
mains larger than one, the existing entry on the internal list is
|
2020-03-04 16:55:40 +01:00
|
|
|
|
swapped with *entry after retaining the link count. The existing
|
|
|
|
|
entry is returned in *entry. If the link count reached one, the new
|
|
|
|
|
entry is also removed from the internal list and returned in
|
|
|
|
|
*sparse. Otherwise *sparse is set to NULL.
|
|
|
|
|
|
|
|
|
|
The general usage is therefore:
|
|
|
|
|
|
|
|
|
|
1. For each new archive entry, call archive_entry_linkify().
|
|
|
|
|
|
|
|
|
|
2. Keep in mind that the entries returned may have a size of 0 now.
|
|
|
|
|
|
|
|
|
|
3. If *entry is not NULL, archive it.
|
|
|
|
|
|
|
|
|
|
4. If *sparse is not NULL, archive it.
|
|
|
|
|
|
|
|
|
|
5. After all entries have been written to disk, call
|
2021-12-09 12:22:14 +01:00
|
|
|
|
archive_entry_linkify() with *entry set to NULL and archive the re‐
|
|
|
|
|
turned entry as long as it is not NULL.
|
2020-03-04 16:55:40 +01:00
|
|
|
|
|
|
|
|
|
RETURN VALUES
|
|
|
|
|
archive_entry_linkresolver_new() returns NULL on malloc(3) failures.
|
|
|
|
|
|
|
|
|
|
SEE ALSO
|
|
|
|
|
archive_entry(3)
|
|
|
|
|
|
|
|
|
|
BSD February 2, 2012 BSD
|