1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
<!-- Creator : groff version 1.23.0 -->
<!-- CreationDate: Mon Jan 5 10:42:43 2026 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="generator" content="groff -Thtml, see www.gnu.org">
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="Content-Style" content="text/css">
<style type="text/css">
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
h1 { text-align: center }
</style>
<title></title>
</head>
<body>
<hr>
<p><i>ARCHIVE_ENTRY_LINKIFY</i>(3) Library Functions Manual
<i>ARCHIVE_ENTRY_LINKIFY</i>(3)</p>
<p style="margin-top: 1em"><b>NAME</b></p>
<p style="margin-left:9%;">archive_entry_linkresolver,
archive_entry_linkresolver_new,
archive_entry_linkresolver_set_strategy,
archive_entry_linkresolver_free, archive_entry_linkify
— hardlink resolver functions</p>
<p style="margin-top: 1em"><b>LIBRARY</b></p>
<p style="margin-left:9%;">Streaming Archive Library
(libarchive, -larchive)</p>
<p style="margin-top: 1em"><b>SYNOPSIS</b></p>
<p style="margin-left:9%;"><b>#include
<archive_entry.h></b></p>
<p style="margin-left:9%; margin-top: 1em"><i>struct
archive_entry_linkresolver *</i></p>
<p style="margin-left:14%;"><b>archive_entry_linkresolver_new</b>(<i>void</i>);</p>
<p style="margin-left:9%; margin-top: 1em"><i>void</i></p>
<p><b>archive_entry_linkresolver_set_strategy</b>(<i>struct archive_entry_linkresolver *resolver</i>,
<i>int format</i>);</p>
<p style="margin-left:9%; margin-top: 1em"><i>void</i></p>
<p><b>archive_entry_linkresolver_free</b>(<i>struct archive_entry_linkresolver *resolver</i>);</p>
<p style="margin-left:9%; margin-top: 1em"><i>void</i></p>
<p><b>archive_entry_linkify</b>(<i>struct archive_entry_linkresolver *resolver</i>,
<i>struct archive_entry **entry</i>,
<i>struct archive_entry **sparse</i>);</p>
<p style="margin-top: 1em"><b>DESCRIPTION</b></p>
<p style="margin-left:9%;">Programs that want to create
archives have to deal with hardlinks. Hardlinks are handled
in different ways by the archive formats. The basic
strategies are:</p>
<p style="margin-top: 1em">1.</p>
<p style="margin-left:15%;">Ignore hardlinks and store the
body for each reference (old cpio, zip).</p>
<p style="margin-top: 1em">2.</p>
<p style="margin-left:15%;">Store the body the first time
an inode is seen (ustar, pax).</p>
<p style="margin-top: 1em">3.</p>
<p style="margin-left:15%;">Store the body the last time an
inode is seen (new cpio).</p>
<p style="margin-left:9%; margin-top: 1em">The
<b>archive_entry_linkresolver</b> functions help by
providing a unified interface and handling the complexity
behind the scene.</p>
<p style="margin-left:9%; margin-top: 1em">The
<b>archive_entry_linkresolver</b> functions assume that
<i>archive_entry</i> instances 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.</p>
<p style="margin-left:9%; margin-top: 1em">The
<b>archive_entry_linkresolver_new</b>() function allocates a
new link resolver. The instance can be freed using
<b>archive_entry_linkresolver_free</b>(). All deferred
entries are flushed and the internal storage is freed.</p>
<p style="margin-left:9%; margin-top: 1em">The
<b>archive_entry_linkresolver_set_strategy</b>() function
selects the optimal hardlink strategy for the given format.
The format code can be obtained from
<i>archive_format</i>(3). The function can be called more
than once, but it is recommended to flush all deferred
entries first.</p>
<p style="margin-left:9%; margin-top: 1em">The
<b>archive_entry_linkify</b>() function is the core of
<b>archive_entry_linkresolver</b>. The <b>entry</b>()
argument points to the <i>archive_entry</i> that should be
written. Depending on the strategy one of the following
actions is taken:</p>
<p style="margin-top: 1em">1.</p>
<p style="margin-left:15%;">For the simple archive formats
<i>*entry</i> is left unmodified and <i>*sparse</i> is set
to NULL.</p>
<p style="margin-top: 1em">2.</p>
<p style="margin-left:15%;">For tar like archive formats,
<i>*sparse</i> is set to NULL. If <i>*entry</i> is NULL, no
action is taken. If the hardlink count of <i>*entry</i> is
larger than 1 and the file type is a regular file or
symbolic link, the internal list is searched for a matching
inode. If such an inode is found, the link count is
decremented and the file size of <i>*entry</i> 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.</p>
<p style="margin-top: 1em">3.</p>
<p style="margin-left:15%;">For new cpio like archive
formats a value for <i>*entry</i> of NULL is used to flush
deferred entries. In that case <i>*entry</i> is set to an
arbitrary deferred entry and the entry itself is removed
from the internal list. If the internal list is empty,
<i>*entry</i> is set to NULL. In either case, <i>*sparse</i>
is set to NULL and the function returns. If the hardlink
count of <i>*entry</i> is one or the file type is a
directory or device, <i>*sparse</i> 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
<i>*entry</i> and <i>*sparse</i> are set to NULL and the
function returns. If such an inode is found, the link count
is decremented. If it remains larger than one, the existing
entry on the internal list is swapped with <i>*entry</i>
after retaining the link count. The existing entry is
returned in <i>*entry</i>. If the link count reached one,
the new entry is also removed from the internal list and
returned in <i>*sparse</i>. Otherwise <i>*sparse</i> is set
to NULL.</p>
<p style="margin-left:9%; margin-top: 1em">The general
usage is therefore:</p>
<p style="margin-top: 1em">1.</p>
<p style="margin-left:15%;">For each new archive entry,
call <b>archive_entry_linkify</b>().</p>
<p style="margin-top: 1em">2.</p>
<p style="margin-left:15%;">Keep in mind that the entries
returned may have a size of 0 now.</p>
<p style="margin-top: 1em">3.</p>
<p style="margin-left:15%;">If <i>*entry</i> is not NULL,
archive it.</p>
<p style="margin-top: 1em">4.</p>
<p style="margin-left:15%;">If <i>*sparse</i> is not NULL,
archive it.</p>
<p style="margin-top: 1em">5.</p>
<p style="margin-left:15%;">After all entries have been
written to disk, call <b>archive_entry_linkify</b>() with
<i>*entry</i> set to NULL and archive the returned entry as
long as it is not NULL.</p>
<p style="margin-top: 1em"><b>RETURN VALUES</b></p>
<p style="margin-left:9%;"><b>archive_entry_linkresolver_new</b>()
returns NULL on <i>malloc</i>(3) failures.</p>
<p style="margin-top: 1em"><b>SEE ALSO</b></p>
<p style="margin-left:9%;"><i>archive_entry</i>(3) Debian
February 2, 2012 <i>ARCHIVE_ENTRY_LINKIFY</i>(3)</p>
<hr>
</body>
</html>
|