1.\" Copyright (c) 2003-2011 Tim Kientzle
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.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
26.\"
27.Dd March 23, 2011
28.Dt ARCHIVE_WRITE 3
29.Os
30.Sh NAME
31.Nm archive_write
32.Nd functions for creating archives
33.Sh SYNOPSIS
34.In archive.h
35.Sh DESCRIPTION
36These functions provide a complete API for creating streaming
37archive files.
38The general process is to first create the
39.Tn struct archive
40object, set any desired options, initialize the archive, append entries, then
41close the archive and release all resources.
42.\"
43.Ss Create archive object
44See
45.Xr archive_write_new 3 .
46.Pp
47To write an archive, you must first obtain an initialized
48.Tn struct archive
49object from
50.Fn archive_write_new .
51.\"
52.Ss Enable filters and formats, configure block size and padding
53See
54.Xr archive_write_filter 3 ,
55.Xr archive_write_format 3
56and
57.Xr archive_write_blocksize 3 .
58.Pp
59You can then modify this object for the desired operations with the
60various
61.Fn archive_write_set_XXX
62functions.
63In particular, you will need to invoke appropriate
64.Fn archive_write_add_XXX
65and
66.Fn archive_write_set_XXX
67functions to enable the corresponding compression and format
68support.
69.\"
70.Ss Set options
71See
72.Xr archive_read_set_options 3 .
73.\"
74.Ss Open archive
75See
76.Xr archive_write_open 3 .
77.Pp
78Once you have prepared the
79.Tn struct archive
80object, you call
81.Fn archive_write_open
82to actually open the archive and prepare it for writing.
83There are several variants of this function;
84the most basic expects you to provide pointers to several
85functions that can provide blocks of bytes from the archive.
86There are convenience forms that allow you to
87specify a filename, file descriptor,
88.Ft "FILE *"
89object, or a block of memory from which to write the archive data.
90.\"
91.Ss Produce archive
92See
93.Xr archive_write_header 3
94and
95.Xr archive_write_data 3 .
96.Pp
97Individual archive entries are written in a three-step
98process:
99You first initialize a
100.Tn struct archive_entry
101structure with information about the new entry.
102At a minimum, you should set the pathname of the
103entry and provide a
104.Va struct stat
105with a valid
106.Va st_mode
107field, which specifies the type of object and
108.Va st_size
109field, which specifies the size of the data portion of the object.
110.\"
111.Ss Release resources
112See
113.Xr archive_write_free 3 .
114.Pp
115After all entries have been written, use the
116.Fn archive_write_free
117function to release all resources.
118.\"
119.Sh EXAMPLE
120The following sketch illustrates basic usage of the library.
121In this example,
122the callback functions are simply wrappers around the standard
123.Xr open 2 ,
124.Xr write 2 ,
125and
126.Xr close 2
127system calls.
128.Bd -literal -offset indent
129#ifdef __linux__
130#define	_FILE_OFFSET_BITS 64
131#endif
132#include <sys/stat.h>
133#include <archive.h>
134#include <archive_entry.h>
135#include <fcntl.h>
136#include <stdlib.h>
137#include <unistd.h>
138
139struct mydata {
140  const char *name;
141  int fd;
142};
143
144int
145myopen(struct archive *a, void *client_data)
146{
147  struct mydata *mydata = client_data;
148
149  mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644);
150  if (mydata->fd >= 0)
151    return (ARCHIVE_OK);
152  else
153    return (ARCHIVE_FATAL);
154}
155
156ssize_t
157mywrite(struct archive *a, void *client_data, const void *buff, size_t n)
158{
159  struct mydata *mydata = client_data;
160
161  return (write(mydata->fd, buff, n));
162}
163
164int
165myclose(struct archive *a, void *client_data)
166{
167  struct mydata *mydata = client_data;
168
169  if (mydata->fd > 0)
170    close(mydata->fd);
171  return (0);
172}
173
174void
175write_archive(const char *outname, const char **filename)
176{
177  struct mydata *mydata = malloc(sizeof(struct mydata));
178  struct archive *a;
179  struct archive_entry *entry;
180  struct stat st;
181  char buff[8192];
182  int len;
183  int fd;
184
185  a = archive_write_new();
186  mydata->name = outname;
187  archive_write_add_filter_gzip(a);
188  archive_write_set_format_ustar(a);
189  archive_write_open(a, mydata, myopen, mywrite, myclose);
190  while (*filename) {
191    stat(*filename, &st);
192    entry = archive_entry_new();
193    archive_entry_copy_stat(entry, &st);
194    archive_entry_set_pathname(entry, *filename);
195    archive_write_header(a, entry);
196    if ((fd = open(*filename, O_RDONLY)) != -1) {
197      len = read(fd, buff, sizeof(buff));
198      while ( len > 0 ) {
199        archive_write_data(a, buff, len);
200        len = read(fd, buff, sizeof(buff));
201      }
202      close(fd);
203    }
204    archive_entry_free(entry);
205    filename++;
206  }
207  archive_write_free(a);
208}
209
210int main(int argc, const char **argv)
211{
212  const char *outname;
213  argv++;
214  outname = argv++;
215  write_archive(outname, argv);
216  return 0;
217}
218.Ed
219.Sh SEE ALSO
220.Xr tar 1 ,
221.Xr libarchive 3 ,
222.Xr archive_write_set_options 3 ,
223.Xr cpio 5 ,
224.Xr mtree 5 ,
225.Xr tar 5
226.Sh HISTORY
227The
228.Nm libarchive
229library first appeared in
230.Fx 5.3 .
231.Sh AUTHORS
232.An -nosplit
233The
234.Nm libarchive
235library was written by
236.An Tim Kientzle Aq kientzle@acm.org .
237.Sh BUGS
238There are many peculiar bugs in historic tar implementations that may cause
239certain programs to reject archives written by this library.
240For example, several historic implementations calculated header checksums
241incorrectly and will thus reject valid archives; GNU tar does not fully support
242pax interchange format; some old tar implementations required specific
243field terminations.
244.Pp
245The default pax interchange format eliminates most of the historic
246tar limitations and provides a generic key/value attribute facility
247for vendor-defined extensions.
248One oversight in POSIX is the failure to provide a standard attribute
249for large device numbers.
250This library uses
251.Dq SCHILY.devminor
252and
253.Dq SCHILY.devmajor
254for device numbers that exceed the range supported by the backwards-compatible
255ustar header.
256These keys are compatible with Joerg Schilling's
257.Nm star
258archiver.
259Other implementations may not recognize these keys and will thus be unable
260to correctly restore device nodes with large device numbers from archives
261created by this library.
262