Blame libarchive/archive_write.3

Packit 08bd4c
.\" Copyright (c) 2003-2011 Tim Kientzle
Packit 08bd4c
.\" All rights reserved.
Packit 08bd4c
.\"
Packit 08bd4c
.\" Redistribution and use in source and binary forms, with or without
Packit 08bd4c
.\" modification, are permitted provided that the following conditions
Packit 08bd4c
.\" are met:
Packit 08bd4c
.\" 1. Redistributions of source code must retain the above copyright
Packit 08bd4c
.\"    notice, this list of conditions and the following disclaimer.
Packit 08bd4c
.\" 2. Redistributions in binary form must reproduce the above copyright
Packit 08bd4c
.\"    notice, this list of conditions and the following disclaimer in the
Packit 08bd4c
.\"    documentation and/or other materials provided with the distribution.
Packit 08bd4c
.\"
Packit 08bd4c
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
Packit 08bd4c
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 08bd4c
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 08bd4c
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
Packit 08bd4c
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 08bd4c
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit 08bd4c
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit 08bd4c
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit 08bd4c
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit 08bd4c
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit 08bd4c
.\" SUCH DAMAGE.
Packit 08bd4c
.\"
Packit 08bd4c
.\" $FreeBSD$
Packit 08bd4c
.\"
Packit 08bd4c
.Dd February 2, 2012
Packit 08bd4c
.Dt ARCHIVE_WRITE 3
Packit 08bd4c
.Os
Packit 08bd4c
.Sh NAME
Packit 08bd4c
.Nm archive_write
Packit 08bd4c
.Nd functions for creating archives
Packit 08bd4c
.Sh LIBRARY
Packit 08bd4c
Streaming Archive Library (libarchive, -larchive)
Packit 08bd4c
.Sh SYNOPSIS
Packit 08bd4c
.In archive.h
Packit 08bd4c
.Sh DESCRIPTION
Packit 08bd4c
These functions provide a complete API for creating streaming
Packit 08bd4c
archive files.
Packit 08bd4c
The general process is to first create the
Packit 08bd4c
.Tn struct archive
Packit 08bd4c
object, set any desired options, initialize the archive, append entries, then
Packit 08bd4c
close the archive and release all resources.
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Create archive object
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_write_new 3 .
Packit 08bd4c
.Pp
Packit 08bd4c
To write an archive, you must first obtain an initialized
Packit 08bd4c
.Tn struct archive
Packit 08bd4c
object from
Packit 08bd4c
.Fn archive_write_new .
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Enable filters and formats, configure block size and padding
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_write_filter 3 ,
Packit 08bd4c
.Xr archive_write_format 3
Packit 08bd4c
and
Packit 08bd4c
.Xr archive_write_blocksize 3 .
Packit 08bd4c
.Pp
Packit 08bd4c
You can then modify this object for the desired operations with the
Packit 08bd4c
various
Packit 08bd4c
.Fn archive_write_set_XXX
Packit 08bd4c
functions.
Packit 08bd4c
In particular, you will need to invoke appropriate
Packit 08bd4c
.Fn archive_write_add_XXX
Packit 08bd4c
and
Packit 08bd4c
.Fn archive_write_set_XXX
Packit 08bd4c
functions to enable the corresponding compression and format
Packit 08bd4c
support.
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Set options
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_read_set_options 3 .
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Open archive
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_write_open 3 .
Packit 08bd4c
.Pp
Packit 08bd4c
Once you have prepared the
Packit 08bd4c
.Tn struct archive
Packit 08bd4c
object, you call
Packit 08bd4c
.Fn archive_write_open
Packit 08bd4c
to actually open the archive and prepare it for writing.
Packit 08bd4c
There are several variants of this function;
Packit 08bd4c
the most basic expects you to provide pointers to several
Packit 08bd4c
functions that can provide blocks of bytes from the archive.
Packit 08bd4c
There are convenience forms that allow you to
Packit 08bd4c
specify a filename, file descriptor,
Packit 08bd4c
.Ft "FILE *"
Packit 08bd4c
object, or a block of memory from which to write the archive data.
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Produce archive
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_write_header 3
Packit 08bd4c
and
Packit 08bd4c
.Xr archive_write_data 3 .
Packit 08bd4c
.Pp
Packit 08bd4c
Individual archive entries are written in a three-step
Packit 08bd4c
process:
Packit 08bd4c
You first initialize a
Packit 08bd4c
.Tn struct archive_entry
Packit 08bd4c
structure with information about the new entry.
Packit 08bd4c
At a minimum, you should set the pathname of the
Packit 08bd4c
entry and provide a
Packit 08bd4c
.Va struct stat
Packit 08bd4c
with a valid
Packit 08bd4c
.Va st_mode
Packit 08bd4c
field, which specifies the type of object and
Packit 08bd4c
.Va st_size
Packit 08bd4c
field, which specifies the size of the data portion of the object.
Packit 08bd4c
.\"
Packit 08bd4c
.Ss Release resources
Packit 08bd4c
See
Packit 08bd4c
.Xr archive_write_free 3 .
Packit 08bd4c
.Pp
Packit 08bd4c
After all entries have been written, use the
Packit 08bd4c
.Fn archive_write_free
Packit 08bd4c
function to release all resources.
Packit 08bd4c
.\"
Packit 08bd4c
.Sh EXAMPLE
Packit 08bd4c
The following sketch illustrates basic usage of the library.
Packit 08bd4c
In this example,
Packit 08bd4c
the callback functions are simply wrappers around the standard
Packit 08bd4c
.Xr open 2 ,
Packit 08bd4c
.Xr write 2 ,
Packit 08bd4c
and
Packit 08bd4c
.Xr close 2
Packit 08bd4c
system calls.
Packit 08bd4c
.Bd -literal -offset indent
Packit 08bd4c
#ifdef __linux__
Packit 08bd4c
#define	_FILE_OFFSET_BITS 64
Packit 08bd4c
#endif
Packit 08bd4c
#include <sys/stat.h>
Packit 08bd4c
#include <archive.h>
Packit 08bd4c
#include <archive_entry.h>
Packit 08bd4c
#include <fcntl.h>
Packit 08bd4c
#include <stdlib.h>
Packit 08bd4c
#include <unistd.h>
Packit 08bd4c
Packit 08bd4c
struct mydata {
Packit 08bd4c
  const char *name;
Packit 08bd4c
  int fd;
Packit 08bd4c
};
Packit 08bd4c
Packit 08bd4c
int
Packit 08bd4c
myopen(struct archive *a, void *client_data)
Packit 08bd4c
{
Packit 08bd4c
  struct mydata *mydata = client_data;
Packit 08bd4c
Packit 08bd4c
  mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644);
Packit 08bd4c
  if (mydata->fd >= 0)
Packit 08bd4c
    return (ARCHIVE_OK);
Packit 08bd4c
  else
Packit 08bd4c
    return (ARCHIVE_FATAL);
Packit 08bd4c
}
Packit 08bd4c
Packit 08bd4c
la_ssize_t
Packit 08bd4c
mywrite(struct archive *a, void *client_data, const void *buff, size_t n)
Packit 08bd4c
{
Packit 08bd4c
  struct mydata *mydata = client_data;
Packit 08bd4c
Packit 08bd4c
  return (write(mydata->fd, buff, n));
Packit 08bd4c
}
Packit 08bd4c
Packit 08bd4c
int
Packit 08bd4c
myclose(struct archive *a, void *client_data)
Packit 08bd4c
{
Packit 08bd4c
  struct mydata *mydata = client_data;
Packit 08bd4c
Packit 08bd4c
  if (mydata->fd > 0)
Packit 08bd4c
    close(mydata->fd);
Packit 08bd4c
  return (0);
Packit 08bd4c
}
Packit 08bd4c
Packit 08bd4c
void
Packit 08bd4c
write_archive(const char *outname, const char **filename)
Packit 08bd4c
{
Packit 08bd4c
  struct mydata *mydata = malloc(sizeof(struct mydata));
Packit 08bd4c
  struct archive *a;
Packit 08bd4c
  struct archive_entry *entry;
Packit 08bd4c
  struct stat st;
Packit 08bd4c
  char buff[8192];
Packit 08bd4c
  int len;
Packit 08bd4c
  int fd;
Packit 08bd4c
Packit 08bd4c
  a = archive_write_new();
Packit 08bd4c
  mydata->name = outname;
Packit 08bd4c
  /* Set archive format and filter according to output file extension.
Packit 08bd4c
   * If it fails, set default format. Platform depended function.
Packit 08bd4c
   * See supported formats in archive_write_set_format_filter_by_ext.c */
Packit 08bd4c
  if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK)  {
Packit 08bd4c
    archive_write_add_filter_gzip(a);
Packit 08bd4c
    archive_write_set_format_ustar(a);
Packit 08bd4c
  }  
Packit 08bd4c
  archive_write_open(a, mydata, myopen, mywrite, myclose);
Packit 08bd4c
  while (*filename) {
Packit 08bd4c
    stat(*filename, &st);
Packit 08bd4c
    entry = archive_entry_new();
Packit 08bd4c
    archive_entry_copy_stat(entry, &st);
Packit 08bd4c
    archive_entry_set_pathname(entry, *filename);
Packit 08bd4c
    archive_write_header(a, entry);
Packit 08bd4c
    if ((fd = open(*filename, O_RDONLY)) != -1) {
Packit 08bd4c
      len = read(fd, buff, sizeof(buff));
Packit 08bd4c
      while (len > 0) {
Packit 08bd4c
        archive_write_data(a, buff, len);
Packit 08bd4c
        len = read(fd, buff, sizeof(buff));
Packit 08bd4c
      }
Packit 08bd4c
      close(fd);
Packit 08bd4c
    }
Packit 08bd4c
    archive_entry_free(entry);
Packit 08bd4c
    filename++;
Packit 08bd4c
  }
Packit 08bd4c
  archive_write_free(a);
Packit 08bd4c
}
Packit 08bd4c
Packit 08bd4c
int main(int argc, const char **argv)
Packit 08bd4c
{
Packit 08bd4c
  const char *outname;
Packit 08bd4c
  argv++;
Packit 08bd4c
  outname = *argv++;
Packit 08bd4c
  write_archive(outname, argv);
Packit 08bd4c
  return 0;
Packit 08bd4c
}
Packit 08bd4c
.Ed
Packit 08bd4c
.Sh SEE ALSO
Packit 08bd4c
.Xr tar 1 ,
Packit 08bd4c
.Xr libarchive 3 ,
Packit 08bd4c
.Xr archive_write_set_options 3 ,
Packit 08bd4c
.Xr cpio 5 ,
Packit 08bd4c
.Xr mtree 5 ,
Packit 08bd4c
.Xr tar 5
Packit 08bd4c
.Sh HISTORY
Packit 08bd4c
The
Packit 08bd4c
.Nm libarchive
Packit 08bd4c
library first appeared in
Packit 08bd4c
.Fx 5.3 .
Packit 08bd4c
.Sh AUTHORS
Packit 08bd4c
.An -nosplit
Packit 08bd4c
The
Packit 08bd4c
.Nm libarchive
Packit 08bd4c
library was written by
Packit 08bd4c
.An Tim Kientzle Aq kientzle@acm.org .
Packit 08bd4c
.Sh BUGS
Packit 08bd4c
There are many peculiar bugs in historic tar implementations that may cause
Packit 08bd4c
certain programs to reject archives written by this library.
Packit 08bd4c
For example, several historic implementations calculated header checksums
Packit 08bd4c
incorrectly and will thus reject valid archives; GNU tar does not fully support
Packit 08bd4c
pax interchange format; some old tar implementations required specific
Packit 08bd4c
field terminations.
Packit 08bd4c
.Pp
Packit 08bd4c
The default pax interchange format eliminates most of the historic
Packit 08bd4c
tar limitations and provides a generic key/value attribute facility
Packit 08bd4c
for vendor-defined extensions.
Packit 08bd4c
One oversight in POSIX is the failure to provide a standard attribute
Packit 08bd4c
for large device numbers.
Packit 08bd4c
This library uses
Packit 08bd4c
.Dq SCHILY.devminor
Packit 08bd4c
and
Packit 08bd4c
.Dq SCHILY.devmajor
Packit 08bd4c
for device numbers that exceed the range supported by the backwards-compatible
Packit 08bd4c
ustar header.
Packit 08bd4c
These keys are compatible with Joerg Schilling's
Packit 08bd4c
.Nm star
Packit 08bd4c
archiver.
Packit 08bd4c
Other implementations may not recognize these keys and will thus be unable
Packit 08bd4c
to correctly restore device nodes with large device numbers from archives
Packit 08bd4c
created by this library.