1.\" Copyright (c) 2010 Joerg Sonnenberger
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.Dd February 2, 2012
26.Dt ARCHIVE_ENTRY_LINKIFY 3
27.Os
28.Sh NAME
29.Nm archive_entry_linkresolver ,
30.Nm archive_entry_linkresolver_new ,
31.Nm archive_entry_linkresolver_set_strategy ,
32.Nm archive_entry_linkresolver_free ,
33.Nm archive_entry_linkify
34.Nd hardlink resolver functions
35.Sh LIBRARY
36Streaming Archive Library (libarchive, -larchive)
37.Sh SYNOPSIS
38.In archive_entry.h
39.Ft struct archive_entry_linkresolver *
40.Fn archive_entry_linkresolver_new void
41.Ft void
42.Fo archive_entry_linkresolver_set_strategy
43.Fa "struct archive_entry_linkresolver *resolver"
44.Fa "int format"
45.Fc
46.Ft void
47.Fo archive_entry_linkresolver_free
48.Fa "struct archive_entry_linkresolver *resolver"
49.Fc
50.Ft void
51.Fo archive_entry_linkify
52.Fa "struct archive_entry_linkresolver *resolver"
53.Fa "struct archive_entry **entry"
54.Fa "struct archive_entry **sparse"
55.Fc
56.Sh DESCRIPTION
57Programs that want to create archives have to deal with hardlinks.
58Hardlinks are handled in different ways by the archive formats.
59The basic strategies are:
60.Bl -enum
61.It
62Ignore hardlinks and store the body for each reference (old cpio, zip).
63.It
64Store the body the first time an inode is seen (ustar, pax).
65.It
66Store the body the last time an inode is seen (new cpio).
67.El
68.Pp
69The
70.Nm
71functions help by providing a unified interface and handling the complexity
72behind the scene.
73.Pp
74The
75.Nm
76functions assume that
77.Vt archive_entry
78instances have valid nlinks, inode and device values.
79The inode and device value is used to match entries.
80The nlinks value is used to determined if all references have been found and
81if the internal references can be recycled.
82.Pp
83The
84.Fn archive_entry_linkresolver_new
85function allocates a new link resolver.
86The instance can be freed using
87.Fn archive_entry_linkresolver_free .
88All deferred entries are flushed and the internal storage is freed.
89.Pp
90The
91.Fn archive_entry_linkresolver_set_strategy
92function selects the optimal hardlink strategy for the given format.
93The format code can be obtained from
94.Xr archive_format 3 .
95The function can be called more than once, but it is recommended to
96flush all deferred entries first.
97.Pp
98The
99.Fn archive_entry_linkify
100function is the core of
101.Nm .
102The
103.Fn entry
104argument points to the
105.Vt archive_entry
106that should be written.
107Depending on the strategy one of the following actions is taken:
108.Bl -enum
109.It
110For the simple archive formats
111.Va *entry
112is left unmodified and
113.Va *sparse
114is set to
115.Dv NULL .
116.It
117For tar like archive formats,
118.Va *sparse
119is set to
120.Dv NULL .
121If
122.Va *entry
123is
124.Dv NULL ,
125no action is taken.
126If the hardlink count of
127.Va *entry
128is larger than 1 and the file type is a regular file or symbolic link,
129the internal list is searched for a matching inode.
130If such an inode is found, the link count is decremented and the file size
131of
132.Va *entry
133is set to 0 to notify that no body should be written.
134If no such inode is found, a copy of the entry is added to the internal cache
135with a link count reduced by one.
136.It
137For new cpio like archive formats a value for
138.Va *entry
139of
140.Dv NULL
141is used to flush deferred entries.
142In that case
143.Va *entry
144is set to an arbitrary deferred entry and the entry itself is removed from the
145internal list.
146If the internal list is empty,
147.Va *entry
148is set to
149.Dv NULL .
150In either case,
151.Va *sparse
152is set to
153.Dv NULL
154and the function returns.
155If the hardlink count of
156.Va *entry
157is one or the file type is a directory or device,
158.Va *sparse
159is set to
160.Dv NULL
161and no further action is taken.
162Otherwise, the internal list is searched for a matching inode.
163If such an inode is not found, the entry is added to the internal list,
164both
165.Va *entry
166and
167.Va *sparse
168are set to
169.Dv NULL
170and the function returns.
171If such an inode is found, the link count is decremented.
172If it remains larger than one, the existing entry on the internal list
173is swapped with
174.Va *entry
175after retaining the link count.
176The existing entry is returned in
177.Va *entry .
178If the link count reached one, the new entry is also removed from the
179internal list and returned in
180.Va *sparse .
181Otherwise
182.Va *sparse
183is set to
184.Dv NULL .
185.El
186.Pp
187The general usage is therefore:
188.Bl -enum
189.It
190For each new archive entry, call
191.Fn archive_entry_linkify .
192.It
193Keep in mind that the entries returned may have a size of 0 now.
194.It
195If
196.Va *entry
197is not
198.Dv NULL ,
199archive it.
200.It
201If
202.Va *sparse
203is not
204.Dv NULL ,
205archive it.
206.It
207After all entries have been written to disk, call
208.Fn archive_entry_linkify
209with
210.Va *entry
211set to
212.Dv NULL
213and archive the returned entry as long as it is not
214.Dv NULL .
215.El
216.Sh RETURN VALUES
217.Fn archive_entry_linkresolver_new
218returns
219.Dv NULL
220on
221.Xr malloc 3
222failures.
223.Sh SEE ALSO
224.Xr archive_entry 3
225