]> git.saurik.com Git - apple/copyfile.git/blobdiff - copyfile.3
copyfile-127.tar.gz
[apple/copyfile.git] / copyfile.3
index 2e78bf3ea5ec1b15e7ba29aa1202cff150a922ac..e7e94e3c22e16622d870a769e461439db05738c7 100644 (file)
@@ -25,6 +25,8 @@
 .Fn copyfile_state_get "copyfile_state_t state" "uint32_t flag" "void * dst"
 .Ft int
 .Fn copyfile_state_set "copyfile_state_t state" "uint32_t flag" "const void * src"
+.Ft typedef int
+.Fn (*copyfile_callback_t) "int what" "int stage" "copyfile_state_t state" "const char * src" "const char * dst" "void * ctx"
 .Sh DESCRIPTION
 These functions are used to copy a file's data and/or metadata.  (Metadata
 consists of permissions, extended attributes, access control lists, and so
@@ -101,6 +103,13 @@ and
 .Fn fcopyfile
 functions can also have their behavior modified by the following flags:
 .Bl -tag -width COPYFILE_NOFOLLOW_SRC
+.It Dv COPYFILE_RECURSIVE
+Causes
+.Fn copyfile
+to recursively copy a hierarchy.
+This flag is not used by
+.Fn fcopyfile ;
+see below for more information.
 .It Dv COPYFILE_CHECK
 Return a bitmask (corresponding to the
 .Va flags
@@ -151,11 +160,18 @@ file, if it is a symbolic link.  (This is only applicable for the
 .Fn copyfile
 function.)
 .It Dv COPYFILE_MOVE
-Unlink (remove) the
+Unlink (using 
+.Xr remove 3 )
+the
 .Fa from
 file.  (This is only applicable for the
 .Fn copyfile
-function.)
+function.)  No error is returned if
+.Xr remove 3
+fails.  Note that
+.Xr remove 3
+removes a symbolic link itself, not the
+target of the link.
 .It Dv COPYFILE_UNLINK
 Unlink the
 .Va to
@@ -220,21 +236,255 @@ parameter is a pointer to a pointer to a C string
 the returned value is a pointer to the
 .Va state 's
 copy, and must not be modified or released.
+.It Dv COPYFILE_STATE_STATUS_CB
+Get or set the callback status function (currently
+only used for recursive copies; see below for details).
+The
+.Va src
+parameter is a pointer to a function of type
+.Vt copyfile_callback_t
+(see above).
+.It Dv COPYFILE_STATE_STATUS_CTX
+Get or set the context parameter for the status
+call-back function (see below for details).
+The
+.Va src
+parameter is a
+.Vt void\ * .
 .It Dv COPYFILE_STATE_QUARANTINE
 Get or set the quarantine information with the source file.
 The
 .Va src
-parameter is a pointer to a
-.Vt qtn_file_t
-object (see
-.Pa <quarantine.h> ).
-In the case of
-.Dv COPYFILE_STATE_SET ,
-the object is cloned; in the case of
-.Dv COPYFILE_STATE_GET ,
-the object is simply returned, and it is up to the
-caller to clone it if desired.
+parameter is a pointer to an opaque
+object (type
+.Vt void\ *
+).
+.It Dv COPYFILE_STATE_COPIED
+Get the number of data bytes copied so far.
+(Only valid for
+.Fn copyfile_state_get ;
+see below for more details about callbacks.)
+The
+.Va dst
+parameter is a pointer to
+.Vt off_t
+(type
+.Vt off_t\ * ).
+.It Dv COPYFILE_STATE_XATTRNAME
+Get the name of the extended attribute during a callback
+for
+.Dv COPYFILE_COPY_XATTR
+(see below for details).  This field cannot be set,
+and may be
+.Dv NULL .
+.El
+.Sh Recursive Copies
+When given the
+.Dv COPYFILE_RECURSIVE
+flag,
+.Fn copyfile
+(but not
+.Fn fcopyfile )
+will use the 
+.Xr fts 3
+functions to recursively descend into the source file-system object.
+It then calls
+.Fn copyfile
+on each of the entries it finds that way.
+If a call-back function is given (using
+.Fn copyfile_state_set
+and
+.Dv COPYFILE_STATE_STATUS_CB ),
+the call-back function will be called four times for each directory
+object, and twice for all other objects.  (Each directory will
+be examined twice, once on entry -- before copying each of the
+objects contained in the directory -- and once on exit -- after
+copying each object contained in the directory, in order to perform
+some final cleanup.)
+.Pp
+The call-back function will have one of the following values
+as the first argument, indicating what is being copied:
+.Bl -tag -width COPYFILE_RECURSE_DIR_CLEANUP
+.It Dv COPYFILE_RECURSE_FILE
+The object being copied is a file (or, rather,
+something other than a directory).
+.It Dv COPYFILE_RECURSE_DIR
+The object being copied is a directory, and is being
+entered.  (That is, none of the filesystem objects contained
+within the directory have been copied yet.)
+.It Dv COPYFILE_RECURSE_DIR_CLEANUP
+The object being copied is a directory, and all of the
+objects contained have been copied.  At this stage, the destination directory
+being copied will have any extra permissions that were added to
+allow the copying will be removed.
+.It Dv COPYFILE_RECURSE_ERROR
+There was an error in processing an element of the source hierarchy;
+this happens when
+.Xr fts 3
+returns an error or unknown file type.
+(Currently, the second argument to the call-back function will always
+be
+.Dv COPYFILE_ERR
+in this case.)
 .El
+.Pp
+The second argument to the call-back function will indicate
+the stage of the copy, and will be one of the following values:
+.Bl -tag -width COPYFILE_FINISH
+.It Dv COPYFILE_START
+Before copying has begun.  The third
+parameter will be a newly-created
+.Vt copyfile_state_t
+object with the call-back function and context pre-loaded.
+.It Dv COPYFILE_FINISH
+After copying has successfully finished.
+.It Dv COPYFILE_ERR
+Indicates an error has happened at some stage.  If the
+first argument to the call-back function is 
+.Dv COPYFILE_RECURSE_ERROR ,
+then an error occurred while processing the source hierarchy;
+otherwise, it will indicate what type of object was being copied,
+and
+.Dv errno
+will be set to indicate the error.
+.El
+.Pp
+The fourth and fifth
+parameters are the source and destination paths that
+are to be copied (or have been copied, or failed to copy, depending on
+the second argument).
+.Pp
+The last argument to the call-back function will be the value
+set by
+.Dv COPYFILE_STATE_STATUS_CTX ,
+if any.
+.Pp
+The call-back function is required to return one of the following
+values:
+.Bl -tag -width COPYFILE_CONTINUE
+.It Dv COPYFILE_CONTINUE
+The copy will continue as expected.
+.It Dv COPYFILE_SKIP
+This object will be skipped, and the next object will
+be processed.  (Note that, when entering a directory.
+returning
+.Dv COPYFILE_SKIP
+from the call-back function will prevent the contents
+of the directory from being copied.)
+.It Dv COPYFILE_QUIT
+The entire copy is aborted at this stage.  Any filesystem
+objects created up to this point will remain.
+.Fn copyfile
+will return -1, but
+.Dv errno
+will be unmodified.
+.El
+.Pp
+The call-back function must always return one of the values listed
+above; if not, the results are undefined.
+.Pp
+The call-back function will be called twice for each object
+(and an additional two times for directory cleanup); the first
+call will have a
+.Ar stage
+parameter of
+.Dv COPYFILE_START ;
+the second time, that value will be either
+.Dv COPYFILE_FINISH
+or
+.Dv COPYFILE_ERR
+to indicate a successful completion, or an error during
+processing.
+In the event of an error, the
+.Dv errno
+value will be set appropriately.
+.Pp
+The
+.Dv COPYFILE_PACK ,
+.Dv COPYFILE_UNPACK ,
+.Dv COPYFILE_MOVE ,
+and
+.Dv COPYFILE_UNLINK
+flags are not used during a recursive copy, and will result
+in an error being returned.
+.Sh Progress Callback
+In addition to the recursive callbacks described above,
+.Fn copyfile
+and
+.Fn fcopyfile
+will also use a callback to report data (e.g.,
+.Dv COPYFILE_DATA )
+progress.  If given, the callback will be invoked on each
+.Xr write 2
+call.  The first argument to the callback function will be
+.Dv COPYFILE_COPY_DATA .
+The second argument will either be
+.Dv COPYFILE_PROGRESS
+(indicating that the write was successful), or
+.Dv COPYFILE_ERR
+(indicating that there was an error of some sort).
+.Pp
+The amount of data bytes copied so far can be retrieved using
+.Fn copyfile_state_get ,
+with the
+.Dv COPYFILE_STATE_COPIED
+requestor (the argument type is a pointer to
+.Vt off_t ).
+.Pp
+When copying extended attributes, the first argument to the
+callback function will be
+.Dv COPYFILE_COPY_XATTR .
+The other arguments will be as described for
+.Dv COPYFILE_COPY_DATA ;
+the name of the extended attribute being copied may be
+retrieved using
+.Fn copyfile_state_get
+and the parameter
+.Dv COPYFILE_STATE_XATTRNAME .
+When using
+.Dv COPYFILE_PACK ,
+the callback may be called with
+.Dv COPYFILE_START
+for each of the extended attributes first, followed by
+.Dv COPYFILE_PROGRESS
+before getting and packing the data for each
+individual attribute, and then
+.Dv COPYFILE_FINISH
+when finished with each individual attribute.
+(That is,
+.Dv COPYFILE_START
+may be called for all of the extended attributes, before
+the first callback with
+.Dv COPYFILE_PROGRESS
+is invoked.)  Any attribute skipped by returning
+.Dv COPYFILE_SKIP
+from the
+.Dv COPYFILE_START
+callback will not be placed into the packed output file.
+.Pp
+The return value for the data callback must be one of
+.Bl -tag -width COPYFILE_CONTINUE
+.It Dv COPYFILE_CONTINUE
+The copy will continue as expected.
+(In the case of error, it will attempt to write the data again.)
+.It Dv COPYFILE_SKIP
+The data copy will be aborted, but without error.
+.It Dv COPYFILE_QUIT
+The data copy will be aborted; in the case of
+.Dv COPYFILE_PROGRESS ,
+.Dv errno
+will be set to
+.Dv ECANCELED .
+.El
+.Pp
+While the
+.Va src
+and
+.Va dst
+parameters will be passed in, they may be
+.Dv NULL
+in the case of
+.Fn fcopyfile .
 .Sh RETURN VALUES
 Except when given the
 .Dv COPYFILE_CHECK
@@ -245,6 +495,23 @@ and
 return less than 0 on error, and 0 on success.
 All of the other functions return 0 on success, and less than 0
 on error.
+.Sh WARNING
+Both
+.Fn copyfile
+and
+.Fn fcopyfile
+can copy symbolic links; there is a gap between when the source
+link is examined and the actual copy is started, and this can
+be a potential security risk, especially if the process has
+elevated privileges.
+.Pp
+When performing a recursive copy, if the source hierarchy
+changes while the copy is occurring, the results are undefined.
+.Pp
+.Fn fcopyfile
+does not reset the seek position for either source or destination.
+This can result in the destination file being a different size
+than the source file.
 .Sh ERRORS
 .Fn copyfile
 and
@@ -252,20 +519,32 @@ and
 will fail if:
 .Bl -tag -width Er
 .It Bq Er EINVAL
-Either the
+An invalid flag was passed in with
+.Dv COPYFILE_RECURSIVE .
+.It Bq Er EINVAL
+The
 .Va from
 or
 .Va to
-parameter was a
+parameter to
+.Fn copyfile
+was a
 .Dv NULL
-pointer (
-.Fn copyfile ),
-or a negative number (
-.Fn fcopyfile ).
+pointer.
+.It Bq Er EINVAL
+The
+.Va from
+or
+.Va to
+parameter to
+.Fn copyfile
+was a negative number.
 .It Bq Er ENOMEM
 A memory allocation failed.
 .It Bq Er ENOTSUP
 The source file was not a directory, symbolic link, or regular file.
+.It Bq Er ECANCELED
+The copy was cancelled by callback.
 .El
 In addition, both functions may set
 .Dv errno
@@ -289,11 +568,20 @@ copyfile(NULL, "/tmp/bar", s, COPYFILE_ALL);
 /* Now copy the same source file to another destination file */
 copyfile(NULL, "/tmp/car", s, COPYFILE_ALL);
 copyfile_state_free(s);
+/* Remove extended attributes from a file */
+copyfile("/dev/null", "/tmp/bar", NULL, COPYFILE_XATTR);
 .Ed
+.Sh SEE ALSO
+.Xr listxattr 2 ,
+.Xr getxattr 2 ,
+.Xr setxattr 2 ,
+.Xr acl 3
 .Sh BUGS
 Both
 .Fn copyfile
 functions lack a way to set the input or output block size.
+.Pp
+Recursive copies do not honor hard links.
 .Sh HISTORY
 The
 .Fn copyfile