| .\" Copyright (c) 2003-2007 Tim Kientzle | 
 | .\" All rights reserved. | 
 | .\" | 
 | .\" Redistribution and use in source and binary forms, with or without | 
 | .\" modification, are permitted provided that the following conditions | 
 | .\" are met: | 
 | .\" 1. Redistributions of source code must retain the above copyright | 
 | .\"    notice, this list of conditions and the following disclaimer. | 
 | .\" 2. Redistributions in binary form must reproduce the above copyright | 
 | .\"    notice, this list of conditions and the following disclaimer in the | 
 | .\"    documentation and/or other materials provided with the distribution. | 
 | .\" | 
 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | 
 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
 | .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 
 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 | .\" SUCH DAMAGE. | 
 | .\" | 
 | .\" $FreeBSD$ | 
 | .\" | 
 | .Dd January 19, 2020 | 
 | .Dt ARCHIVE_WRITE_DISK 3 | 
 | .Os | 
 | .Sh NAME | 
 | .Nm archive_write_disk_new , | 
 | .Nm archive_write_disk_set_options , | 
 | .Nm archive_write_disk_set_skip_file , | 
 | .Nm archive_write_disk_set_group_lookup , | 
 | .Nm archive_write_disk_set_standard_lookup , | 
 | .Nm archive_write_disk_set_user_lookup | 
 | .Nd functions for creating objects on disk | 
 | .Sh LIBRARY | 
 | Streaming Archive Library (libarchive, -larchive) | 
 | .Sh SYNOPSIS | 
 | .In archive.h | 
 | .Ft struct archive * | 
 | .Fn archive_write_disk_new "void" | 
 | .Ft int | 
 | .Fn archive_write_disk_set_options "struct archive *" "int flags" | 
 | .Ft int | 
 | .Fn archive_write_disk_set_skip_file "struct archive *" "dev_t" "ino_t" | 
 | .Ft int | 
 | .Fo archive_write_disk_set_group_lookup | 
 | .Fa "struct archive *" | 
 | .Fa "void *" | 
 | .Fa "gid_t (*)(void *, const char *gname, gid_t gid)" | 
 | .Fa "void (*cleanup)(void *)" | 
 | .Fc | 
 | .Ft int | 
 | .Fn archive_write_disk_set_standard_lookup "struct archive *" | 
 | .Ft int | 
 | .Fo archive_write_disk_set_user_lookup | 
 | .Fa "struct archive *" | 
 | .Fa "void *" | 
 | .Fa "uid_t (*)(void *, const char *uname, uid_t uid)" | 
 | .Fa "void (*cleanup)(void *)" | 
 | .Fc | 
 | .Sh DESCRIPTION | 
 | These functions provide a complete API for creating objects on | 
 | disk from | 
 | .Tn struct archive_entry | 
 | descriptions. | 
 | They are most naturally used when extracting objects from an archive | 
 | using the | 
 | .Fn archive_read | 
 | interface. | 
 | The general process is to read | 
 | .Tn struct archive_entry | 
 | objects from an archive, then write those objects to a | 
 | .Tn struct archive | 
 | object created using the | 
 | .Fn archive_write_disk | 
 | family functions. | 
 | This interface is deliberately very similar to the | 
 | .Fn archive_write | 
 | interface used to write objects to a streaming archive. | 
 | .Bl -tag -width indent | 
 | .It Fn archive_write_disk_new | 
 | Allocates and initializes a | 
 | .Tn struct archive | 
 | object suitable for writing objects to disk. | 
 | .It Fn archive_write_disk_set_skip_file | 
 | Records the device and inode numbers of a file that should not be | 
 | overwritten. | 
 | This is typically used to ensure that an extraction process does not | 
 | overwrite the archive from which objects are being read. | 
 | This capability is technically unnecessary but can be a significant | 
 | performance optimization in practice. | 
 | .It Fn archive_write_disk_set_options | 
 | The options field consists of a bitwise OR of one or more of the | 
 | following values: | 
 | .Bl -tag -compact -width "indent" | 
 | .It Cm ARCHIVE_EXTRACT_ACL | 
 | Attempt to restore Access Control Lists. | 
 | By default, extended ACLs are ignored. | 
 | .It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS | 
 | Before removing a file system object prior to replacing it, clear | 
 | platform-specific file flags which might prevent its removal. | 
 | .It Cm ARCHIVE_EXTRACT_FFLAGS | 
 | Attempt to restore file attributes (file flags). | 
 | By default, file attributes are ignored. | 
 | See | 
 | .Xr chattr 1 | 
 | .Pq Linux | 
 | or | 
 | .Xr chflags 1 | 
 | .Pq FreeBSD, Mac OS X | 
 | for more information on file attributes. | 
 | .It Cm ARCHIVE_EXTRACT_MAC_METADATA | 
 | Mac OS X specific. | 
 | Restore metadata using | 
 | .Xr copyfile 3 . | 
 | By default, | 
 | .Xr copyfile 3 | 
 | metadata is ignored. | 
 | .It Cm ARCHIVE_EXTRACT_NO_OVERWRITE | 
 | Existing files on disk will not be overwritten. | 
 | By default, existing regular files are truncated and overwritten; | 
 | existing directories will have their permissions updated; | 
 | other pre-existing objects are unlinked and recreated from scratch. | 
 | .It Cm ARCHIVE_EXTRACT_OWNER | 
 | The user and group IDs should be set on the restored file. | 
 | By default, the user and group IDs are not restored. | 
 | .It Cm ARCHIVE_EXTRACT_PERM | 
 | Full permissions (including SGID, SUID, and sticky bits) should | 
 | be restored exactly as specified, without obeying the | 
 | current umask. | 
 | Note that SUID and SGID bits can only be restored if the | 
 | user and group ID of the object on disk are correct. | 
 | If | 
 | .Cm ARCHIVE_EXTRACT_OWNER | 
 | is not specified, then SUID and SGID bits will only be restored | 
 | if the default user and group IDs of newly-created objects on disk | 
 | happen to match those specified in the archive entry. | 
 | By default, only basic permissions are restored, and umask is obeyed. | 
 | .It Cm ARCHIVE_EXTRACT_SAFE_WRITES | 
 | Extract files atomically, by first creating a unique temporary file and then | 
 | renaming it to its required destination name. | 
 | This avoids a race where an application might see a partial file (or no | 
 | file) during extraction. | 
 | .It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS | 
 | Refuse to extract an absolute path. | 
 | The default is to not refuse such paths. | 
 | .It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT | 
 | Refuse to extract a path that contains a | 
 | .Pa .. | 
 | element anywhere within it. | 
 | The default is to not refuse such paths. | 
 | Note that paths ending in | 
 | .Pa .. | 
 | always cause an error, regardless of this flag. | 
 | .It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS | 
 | Refuse to extract any object whose final location would be altered | 
 | by a symlink on disk. | 
 | This is intended to help guard against a variety of mischief | 
 | caused by archives that (deliberately or otherwise) extract | 
 | files outside of the current directory. | 
 | The default is not to perform this check. | 
 | If | 
 | .It Cm ARCHIVE_EXTRACT_SPARSE | 
 | Scan data for blocks of NUL bytes and try to recreate them with holes. | 
 | This results in sparse files, independent of whether the archive format | 
 | supports or uses them. | 
 | .Cm ARCHIVE_EXTRACT_UNLINK | 
 | is specified together with this option, the library will | 
 | remove any intermediate symlinks it finds and return an | 
 | error only if such symlink could not be removed. | 
 | .It Cm ARCHIVE_EXTRACT_TIME | 
 | The timestamps (mtime, ctime, and atime) should be restored. | 
 | By default, they are ignored. | 
 | Note that restoring of atime is not currently supported. | 
 | .It Cm ARCHIVE_EXTRACT_UNLINK | 
 | Existing files on disk will be unlinked before any attempt to | 
 | create them. | 
 | In some cases, this can prove to be a significant performance improvement. | 
 | By default, existing files are truncated and rewritten, but | 
 | the file is not recreated. | 
 | In particular, the default behavior does not break existing hard links. | 
 | .It Cm ARCHIVE_EXTRACT_XATTR | 
 | Attempt to restore extended file attributes. | 
 | By default, they are ignored. | 
 | See | 
 | .Xr xattr 7 | 
 | .Pq Linux , | 
 | .Xr xattr 2 | 
 | .Pq Mac OS X , | 
 | or | 
 | .Xr getextattr 8 | 
 | .Pq FreeBSD | 
 | for more information on extended file attributes. | 
 | .El | 
 | .It Xo | 
 | .Fn archive_write_disk_set_group_lookup , | 
 | .Fn archive_write_disk_set_user_lookup | 
 | .Xc | 
 | The | 
 | .Tn struct archive_entry | 
 | objects contain both names and ids that can be used to identify users | 
 | and groups. | 
 | These names and ids describe the ownership of the file itself and | 
 | also appear in ACL lists. | 
 | By default, the library uses the ids and ignores the names, but | 
 | this can be overridden by registering user and group lookup functions. | 
 | To register, you must provide a lookup function which | 
 | accepts both a name and id and returns a suitable id. | 
 | You may also provide a | 
 | .Tn void * | 
 | pointer to a private data structure and a cleanup function for | 
 | that data. | 
 | The cleanup function will be invoked when the | 
 | .Tn struct archive | 
 | object is destroyed. | 
 | .It Fn archive_write_disk_set_standard_lookup | 
 | This convenience function installs a standard set of user | 
 | and group lookup functions. | 
 | These functions use | 
 | .Xr getpwnam 3 | 
 | and | 
 | .Xr getgrnam 3 | 
 | to convert names to ids, defaulting to the ids if the names cannot | 
 | be looked up. | 
 | These functions also implement a simple memory cache to reduce | 
 | the number of calls to | 
 | .Xr getpwnam 3 | 
 | and | 
 | .Xr getgrnam 3 . | 
 | .El | 
 | More information about the | 
 | .Va struct archive | 
 | object and the overall design of the library can be found in the | 
 | .Xr libarchive 3 | 
 | overview. | 
 | Many of these functions are also documented under | 
 | .Xr archive_write 3 . | 
 | .Sh RETURN VALUES | 
 | Most functions return | 
 | .Cm ARCHIVE_OK | 
 | (zero) on success, or one of several non-zero | 
 | error codes for errors. | 
 | Specific error codes include: | 
 | .Cm ARCHIVE_RETRY | 
 | for operations that might succeed if retried, | 
 | .Cm ARCHIVE_WARN | 
 | for unusual conditions that do not prevent further operations, and | 
 | .Cm ARCHIVE_FATAL | 
 | for serious errors that make remaining operations impossible. | 
 | .Pp | 
 | .Fn archive_write_disk_new | 
 | returns a pointer to a newly-allocated | 
 | .Tn struct archive | 
 | object. | 
 | .Pp | 
 | .Fn archive_write_data | 
 | returns a count of the number of bytes actually written, | 
 | or | 
 | .Li -1 | 
 | on error. | 
 | .\" | 
 | .Sh ERRORS | 
 | Detailed error codes and textual descriptions are available from the | 
 | .Fn archive_errno | 
 | and | 
 | .Fn archive_error_string | 
 | functions. | 
 | .\" | 
 | .Sh SEE ALSO | 
 | .Xr tar 1 , | 
 | .Xr archive_read 3 , | 
 | .Xr archive_write 3 , | 
 | .Xr libarchive 3 | 
 | .Sh HISTORY | 
 | The | 
 | .Nm libarchive | 
 | library first appeared in | 
 | .Fx 5.3 . | 
 | The | 
 | .Nm archive_write_disk | 
 | interface was added to | 
 | .Nm libarchive 2.0 | 
 | and first appeared in | 
 | .Fx 6.3 . | 
 | .Sh AUTHORS | 
 | .An -nosplit | 
 | The | 
 | .Nm libarchive | 
 | library was written by | 
 | .An Tim Kientzle Aq kientzle@acm.org . | 
 | .Sh BUGS | 
 | Directories are actually extracted in two distinct phases. | 
 | Directories are created during | 
 | .Fn archive_write_header , | 
 | but final permissions are not set until | 
 | .Fn archive_write_close . | 
 | This separation is necessary to correctly handle borderline | 
 | cases such as a non-writable directory containing | 
 | files, but can cause unexpected results. | 
 | In particular, directory permissions are not fully | 
 | restored until the archive is closed. | 
 | If you use | 
 | .Xr chdir 2 | 
 | to change the current directory between calls to | 
 | .Fn archive_read_extract | 
 | or before calling | 
 | .Fn archive_read_close , | 
 | you may confuse the permission-setting logic with | 
 | the result that directory permissions are restored | 
 | incorrectly. | 
 | .Pp | 
 | The library attempts to create objects with filenames longer than | 
 | .Cm PATH_MAX | 
 | by creating prefixes of the full path and changing the current directory. | 
 | Currently, this logic is limited in scope; the fixup pass does | 
 | not work correctly for such objects and the symlink security check | 
 | option disables the support for very long pathnames. | 
 | .Pp | 
 | Restoring the path | 
 | .Pa aa/../bb | 
 | does create each intermediate directory. | 
 | In particular, the directory | 
 | .Pa aa | 
 | is created as well as the final object | 
 | .Pa bb . | 
 | In theory, this can be exploited to create an entire directory hierarchy | 
 | with a single request. | 
 | Of course, this does not work if the | 
 | .Cm ARCHIVE_EXTRACT_NODOTDOT | 
 | option is specified. | 
 | .Pp | 
 | Implicit directories are always created obeying the current umask. | 
 | Explicit objects are created obeying the current umask unless | 
 | .Cm ARCHIVE_EXTRACT_PERM | 
 | is specified, in which case they current umask is ignored. | 
 | .Pp | 
 | SGID and SUID bits are restored only if the correct user and | 
 | group could be set. | 
 | If | 
 | .Cm ARCHIVE_EXTRACT_OWNER | 
 | is not specified, then no attempt is made to set the ownership. | 
 | In this case, SGID and SUID bits are restored only if the | 
 | user and group of the final object happen to match those specified | 
 | in the entry. | 
 | .Pp | 
 | The | 
 | .Dq standard | 
 | user-id and group-id lookup functions are not the defaults because | 
 | .Xr getgrnam 3 | 
 | and | 
 | .Xr getpwnam 3 | 
 | are sometimes too large for particular applications. | 
 | The current design allows the application author to use a more | 
 | compact implementation when appropriate. | 
 | .Pp | 
 | There should be a corresponding | 
 | .Nm archive_read_disk | 
 | interface that walks a directory hierarchy and returns archive | 
 | entry objects. |