1<!-- Creator     : groff version 1.22.4 -->
2<!-- CreationDate: Sun Aug 22 23:03:26 2021 -->
3<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4"http://www.w3.org/TR/html4/loose.dtd">
5<html>
6<head>
7<meta name="generator" content="groff -Thtml, see www.gnu.org">
8<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
9<meta name="Content-Style" content="text/css">
10<style type="text/css">
11       p       { margin-top: 0; margin-bottom: 0; vertical-align: top }
12       pre     { margin-top: 0; margin-bottom: 0; vertical-align: top }
13       table   { margin-top: 0; margin-bottom: 0; vertical-align: top }
14       h1      { text-align: center }
15</style>
16<title></title>
17</head>
18<body>
19
20<hr>
21
22
23<p>ARCHIVE_WRITE(3) BSD Library Functions Manual
24ARCHIVE_WRITE(3)</p>
25
26<p style="margin-top: 1em"><b>NAME</b></p>
27
28<p style="margin-left:6%;"><b>archive_write</b> &mdash;
29functions for creating archives</p>
30
31<p style="margin-top: 1em"><b>LIBRARY</b></p>
32
33<p style="margin-left:6%;">Streaming Archive Library
34(libarchive, -larchive)</p>
35
36<p style="margin-top: 1em"><b>SYNOPSIS</b></p>
37
38<p style="margin-left:6%;"><b>#include
39&lt;archive.h&gt;</b></p>
40
41<p style="margin-top: 1em"><b>DESCRIPTION</b></p>
42
43<p style="margin-left:6%;">These functions provide a
44complete API for creating streaming archive files. The
45general process is to first create the struct archive
46object, set any desired options, initialize the archive,
47append entries, then close the archive and release all
48resources.</p>
49
50<p style="margin-left:6%; margin-top: 1em"><b>Create
51archive object</b> <br>
52See archive_write_new(3).</p>
53
54<p style="margin-left:6%; margin-top: 1em">To write an
55archive, you must first obtain an initialized struct archive
56object from <b>archive_write_new</b>().</p>
57
58<p style="margin-left:6%; margin-top: 1em"><b>Enable
59filters and formats, configure block size and padding</b>
60<br>
61See archive_write_filter(3), archive_write_format(3) and
62archive_write_blocksize(3).</p>
63
64<p style="margin-left:6%; margin-top: 1em">You can then
65modify this object for the desired operations with the
66various <b>archive_write_set_XXX</b>() functions. In
67particular, you will need to invoke appropriate
68<b>archive_write_add_XXX</b>() and
69<b>archive_write_set_XXX</b>() functions to enable the
70corresponding compression and format support.</p>
71
72<p style="margin-left:6%; margin-top: 1em"><b>Set
73options</b> <br>
74See archive_write_set_options(3).</p>
75
76<p style="margin-left:6%; margin-top: 1em"><b>Open
77archive</b> <br>
78See archive_write_open(3).</p>
79
80<p style="margin-left:6%; margin-top: 1em">Once you have
81prepared the struct archive object, you call
82<b>archive_write_open</b>() to actually open the archive and
83prepare it for writing. There are several variants of this
84function; the most basic expects you to provide pointers to
85several functions that can provide blocks of bytes from the
86archive. There are convenience forms that allow you to
87specify a filename, file descriptor, <i>FILE *</i> object,
88or a block of memory from which to write the archive
89data.</p>
90
91<p style="margin-left:6%; margin-top: 1em"><b>Produce
92archive</b> <br>
93See archive_write_header(3) and archive_write_data(3).</p>
94
95<p style="margin-left:6%; margin-top: 1em">Individual
96archive entries are written in a three-step process: You
97first initialize a struct archive_entry structure with
98information about the new entry. At a minimum, you should
99set the pathname of the entry and provide a <i>struct
100stat</i> with a valid <i>st_mode</i> field, which specifies
101the type of object and <i>st_size</i> field, which specifies
102the size of the data portion of the object.</p>
103
104<p style="margin-left:6%; margin-top: 1em"><b>Release
105resources</b> <br>
106See archive_write_free(3).</p>
107
108<p style="margin-left:6%; margin-top: 1em">After all
109entries have been written, use the
110<b>archive_write_free</b>() function to release all
111resources.</p>
112
113<p style="margin-top: 1em"><b>EXAMPLES</b></p>
114
115<p style="margin-left:6%;">The following sketch illustrates
116basic usage of the library. In this example, the callback
117functions are simply wrappers around the standard open(2),
118write(2), and close(2) system calls.</p>
119
120<p style="margin-left:14%; margin-top: 1em">#ifdef
121__linux__</p>
122
123<table width="100%" border="0" rules="none" frame="void"
124       cellspacing="0" cellpadding="0">
125<tr valign="top" align="left">
126<td width="14%"></td>
127<td width="10%">
128
129
130<p>#define</p></td>
131<td width="11%">
132
133
134<p>_FILE_OFFSET_BITS 64</p></td>
135<td width="65%">
136</td></tr>
137</table>
138
139<p style="margin-left:14%;">#endif <br>
140#include &lt;sys/stat.h&gt; <br>
141#include &lt;archive.h&gt; <br>
142#include &lt;archive_entry.h&gt; <br>
143#include &lt;fcntl.h&gt; <br>
144#include &lt;stdlib.h&gt; <br>
145#include &lt;unistd.h&gt;</p>
146
147<p style="margin-left:14%; margin-top: 1em">struct mydata {
148<br>
149const char *name; <br>
150int fd; <br>
151};</p>
152
153<p style="margin-left:14%; margin-top: 1em">int <br>
154myopen(struct archive *a, void *client_data) <br>
155{ <br>
156struct mydata *mydata = client_data;</p>
157
158<p style="margin-left:14%; margin-top: 1em">mydata-&gt;fd =
159open(mydata-&gt;name, O_WRONLY | O_CREAT, 0644); <br>
160if (mydata-&gt;fd &gt;= 0) <br>
161return (ARCHIVE_OK); <br>
162else <br>
163return (ARCHIVE_FATAL); <br>
164}</p>
165
166<p style="margin-left:14%; margin-top: 1em">la_ssize_t <br>
167mywrite(struct archive *a, void *client_data, const void
168*buff, size_t n) <br>
169{ <br>
170struct mydata *mydata = client_data;</p>
171
172<p style="margin-left:14%; margin-top: 1em">return
173(write(mydata-&gt;fd, buff, n)); <br>
174}</p>
175
176<p style="margin-left:14%; margin-top: 1em">int <br>
177myclose(struct archive *a, void *client_data) <br>
178{ <br>
179struct mydata *mydata = client_data;</p>
180
181<p style="margin-left:14%; margin-top: 1em">if
182(mydata-&gt;fd &gt; 0) <br>
183close(mydata-&gt;fd); <br>
184return (0); <br>
185}</p>
186
187<p style="margin-left:14%; margin-top: 1em">void <br>
188write_archive(const char *outname, const char **filename)
189<br>
190{ <br>
191struct mydata *mydata = malloc(sizeof(struct mydata)); <br>
192struct archive *a; <br>
193struct archive_entry *entry; <br>
194struct stat st; <br>
195char buff[8192]; <br>
196int len; <br>
197int fd;</p>
198
199<p style="margin-left:14%; margin-top: 1em">a =
200archive_write_new(); <br>
201mydata-&gt;name = outname; <br>
202/* Set archive format and filter according to output file
203extension. <br>
204* If it fails, set default format. Platform depended
205function. <br>
206* See supported formats in
207archive_write_set_format_filter_by_ext.c */ <br>
208if (archive_write_set_format_filter_by_ext(a, outname) !=
209ARCHIVE_OK) { <br>
210archive_write_add_filter_gzip(a); <br>
211archive_write_set_format_ustar(a); <br>
212} <br>
213archive_write_open(a, mydata, myopen, mywrite, myclose);
214<br>
215while (*filename) { <br>
216stat(*filename, &amp;st); <br>
217entry = archive_entry_new(); <br>
218archive_entry_copy_stat(entry, &amp;st); <br>
219archive_entry_set_pathname(entry, *filename); <br>
220archive_write_header(a, entry); <br>
221if ((fd = open(*filename, O_RDONLY)) != -1) { <br>
222len = read(fd, buff, sizeof(buff)); <br>
223while (len &gt; 0) { <br>
224archive_write_data(a, buff, len); <br>
225len = read(fd, buff, sizeof(buff)); <br>
226} <br>
227close(fd); <br>
228} <br>
229archive_entry_free(entry); <br>
230filename++; <br>
231} <br>
232archive_write_free(a); <br>
233}</p>
234
235<p style="margin-left:14%; margin-top: 1em">int main(int
236argc, const char **argv) <br>
237{ <br>
238const char *outname; <br>
239argv++; <br>
240outname = *argv++; <br>
241write_archive(outname, argv); <br>
242return 0; <br>
243}</p>
244
245<p style="margin-top: 1em"><b>SEE ALSO</b></p>
246
247<p style="margin-left:6%;">tar(1),
248archive_write_set_options(3), libarchive(3), cpio(5),
249mtree(5), tar(5)</p>
250
251<p style="margin-top: 1em"><b>HISTORY</b></p>
252
253<p style="margin-left:6%;">The <b>libarchive</b> library
254first appeared in FreeBSD&nbsp;5.3.</p>
255
256<p style="margin-top: 1em"><b>AUTHORS</b></p>
257
258<p style="margin-left:6%;">The <b>libarchive</b> library
259was written by Tim Kientzle &lt;kientzle@acm.org&gt;.</p>
260
261<p style="margin-top: 1em"><b>BUGS</b></p>
262
263<p style="margin-left:6%;">There are many peculiar bugs in
264historic tar implementations that may cause certain programs
265to reject archives written by this library. For example,
266several historic implementations calculated header checksums
267incorrectly and will thus reject valid archives; GNU tar
268does not fully support pax interchange format; some old tar
269implementations required specific field terminations.</p>
270
271<p style="margin-left:6%; margin-top: 1em">The default pax
272interchange format eliminates most of the historic tar
273limitations and provides a generic key/value attribute
274facility for vendor-defined extensions. One oversight in
275POSIX is the failure to provide a standard attribute for
276large device numbers. This library uses
277&ldquo;SCHILY.devminor&rdquo; and
278&ldquo;SCHILY.devmajor&rdquo; for device numbers that exceed
279the range supported by the backwards-compatible ustar
280header. These keys are compatible with Joerg
281Schilling&rsquo;s <b>star</b> archiver. Other
282implementations may not recognize these keys and will thus
283be unable to correctly restore device nodes with large
284device numbers from archives created by this library.</p>
285
286<p style="margin-left:6%; margin-top: 1em">BSD
287February&nbsp;2, 2012 BSD</p>
288<hr>
289</body>
290</html>
291