| .\" 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. |
| .\" |
| .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 |
| .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_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. |
| .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. |