summaryrefslogtreecommitdiffstats
path: root/src/copy.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/copy.h')
-rw-r--r--src/copy.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/copy.h b/src/copy.h
new file mode 100644
index 0000000..1f1de86
--- /dev/null
+++ b/src/copy.h
@@ -0,0 +1,316 @@
+/* core functions for copying files and directories
+ Copyright (C) 1989-2022 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Extracted from cp.c and librarified by Jim Meyering. */
+
+#ifndef COPY_H
+# define COPY_H
+
+# include <stdbool.h>
+# include "hash.h"
+
+struct selabel_handle;
+
+/* Control creation of sparse files (files with holes). */
+enum Sparse_type
+{
+ SPARSE_UNUSED,
+
+ /* Never create holes in DEST. */
+ SPARSE_NEVER,
+
+ /* This is the default. Use a crude (and sometimes inaccurate)
+ heuristic to determine if SOURCE has holes. If so, try to create
+ holes in DEST. */
+ SPARSE_AUTO,
+
+ /* For every sufficiently long sequence of bytes in SOURCE, try to
+ create a corresponding hole in DEST. There is a performance penalty
+ here because CP has to search for holes in SRC. But if the holes are
+ big enough, that penalty can be offset by the decrease in the amount
+ of data written to the file system. */
+ SPARSE_ALWAYS
+};
+
+/* Control creation of COW files. */
+enum Reflink_type
+{
+ /* Do a standard copy. */
+ REFLINK_NEVER,
+
+ /* Try a COW copy and fall back to a standard copy; this is the default. */
+ REFLINK_AUTO,
+
+ /* Require a COW copy and fail if not available. */
+ REFLINK_ALWAYS
+};
+
+/* This type is used to help mv (via copy.c) distinguish these cases. */
+enum Interactive
+{
+ I_ALWAYS_YES = 1,
+ I_ALWAYS_NO,
+ I_ASK_USER,
+ I_UNSPECIFIED
+};
+
+/* How to handle symbolic links. */
+enum Dereference_symlink
+{
+ DEREF_UNDEFINED = 1,
+
+ /* Copy the symbolic link itself. -P */
+ DEREF_NEVER,
+
+ /* If the symbolic is a command line argument, then copy
+ its referent. Otherwise, copy the symbolic link itself. -H */
+ DEREF_COMMAND_LINE_ARGUMENTS,
+
+ /* Copy the referent of the symbolic link. -L */
+ DEREF_ALWAYS
+};
+
+# define VALID_SPARSE_MODE(Mode) \
+ ((Mode) == SPARSE_NEVER \
+ || (Mode) == SPARSE_AUTO \
+ || (Mode) == SPARSE_ALWAYS)
+
+# define VALID_REFLINK_MODE(Mode) \
+ ((Mode) == REFLINK_NEVER \
+ || (Mode) == REFLINK_AUTO \
+ || (Mode) == REFLINK_ALWAYS)
+
+/* These options control how files are copied by at least the
+ following programs: mv (when rename doesn't work), cp, install.
+ So, if you add a new member, be sure to initialize it in
+ mv.c, cp.c, and install.c. */
+struct cp_options
+{
+ enum backup_type backup_type;
+
+ /* How to handle symlinks in the source. */
+ enum Dereference_symlink dereference;
+
+ /* This value is used to determine whether to prompt before removing
+ each existing destination file. It works differently depending on
+ whether move_mode is set. See code/comments in copy.c. */
+ enum Interactive interactive;
+
+ /* Control creation of sparse files. */
+ enum Sparse_type sparse_mode;
+
+ /* Set the mode of the destination file to exactly this value
+ if SET_MODE is nonzero. */
+ mode_t mode;
+
+ /* If true, copy all files except (directories and, if not dereferencing
+ them, symbolic links,) as if they were regular files. */
+ bool copy_as_regular;
+
+ /* If true, remove each existing destination nondirectory before
+ trying to open it. */
+ bool unlink_dest_before_opening;
+
+ /* If true, first try to open each existing destination nondirectory,
+ then, if the open fails, unlink and try again.
+ This option must be set for 'cp -f', in case the destination file
+ exists when the open is attempted. It is irrelevant to 'mv' since
+ any destination is sure to be removed before the open. */
+ bool unlink_dest_after_failed_open;
+
+ /* If true, create hard links instead of copying files.
+ Create destination directories as usual. */
+ bool hard_link;
+
+ /* If true, rather than copying, first attempt to use rename.
+ If that fails, then resort to copying. */
+ bool move_mode;
+
+ /* If true, install(1) is the caller. */
+ bool install_mode;
+
+ /* Whether this process has appropriate privileges to chown a file
+ whose owner is not the effective user ID. */
+ bool chown_privileges;
+
+ /* Whether this process has appropriate privileges to do the
+ following operations on a file even when it is owned by some
+ other user: set the file's atime, mtime, mode, or ACL; remove or
+ rename an entry in the file even though it is a sticky directory,
+ or to mount on the file. */
+ bool owner_privileges;
+
+ /* If true, when copying recursively, skip any subdirectories that are
+ on different file systems from the one we started on. */
+ bool one_file_system;
+
+ /* If true, attempt to give the copies the original files' permissions,
+ owner, group, and timestamps. */
+ bool preserve_ownership;
+ bool preserve_mode;
+ bool preserve_timestamps;
+ bool explicit_no_preserve_mode;
+
+ /* If non-null, attempt to set specified security context */
+ struct selabel_handle *set_security_context;
+
+ /* Enabled for mv, and for cp by the --preserve=links option.
+ If true, attempt to preserve in the destination files any
+ logical hard links between the source files. If used with cp's
+ --no-dereference option, and copying two hard-linked files,
+ the two corresponding destination files will also be hard linked.
+
+ If used with cp's --dereference (-L) option, then, as that option implies,
+ hard links are *not* preserved. However, when copying a file F and
+ a symlink S to F, the resulting S and F in the destination directory
+ will be hard links to the same file (a copy of F). */
+ bool preserve_links;
+
+ /* Optionally don't copy the data, either with CoW reflink files or
+ explicitly with the --attributes-only option. */
+ bool data_copy_required;
+
+ /* If true and any of the above (for preserve) file attributes cannot
+ be applied to a destination file, treat it as a failure and return
+ nonzero immediately. E.g. for cp -p this must be true, for mv it
+ must be false. */
+ bool require_preserve;
+
+ /* If true, attempt to preserve the SELinux security context, too.
+ Set this only if the kernel is SELinux enabled. */
+ bool preserve_security_context;
+
+ /* Useful only when preserve_context is true.
+ If true, a failed attempt to preserve file's security context
+ propagates failure "out" to the caller, along with full diagnostics.
+ If false, a failure to preserve file's security context does not
+ change the invoking application's exit status, but may output diagnostics.
+ For example, with 'cp --preserve=context' this flag is "true",
+ while with 'cp --preserve=all' or 'cp -a', it is "false". */
+ bool require_preserve_context;
+
+ /* If true, attempt to preserve extended attributes using libattr.
+ Ignored if coreutils are compiled without xattr support. */
+ bool preserve_xattr;
+
+ /* Useful only when preserve_xattr is true.
+ If true, a failed attempt to preserve file's extended attributes
+ propagates failure "out" to the caller, along with full diagnostics.
+ If false, a failure to preserve file's extended attributes does not
+ change the invoking application's exit status, but may output diagnostics.
+ For example, with 'cp --preserve=xattr' this flag is "true",
+ while with 'cp --preserve=all' or 'cp -a', it is "false". */
+ bool require_preserve_xattr;
+
+ /* This allows us to output warnings in cases 2 and 4 below,
+ while being quiet for case 1 (when reduce_diagnostics is true).
+ 1. cp -a try to copy xattrs with no errors
+ 2. cp --preserve=all copy xattrs with all but ENOTSUP warnings
+ 3. cp --preserve=xattr,context copy xattrs with all errors
+ 4. mv copy xattrs with all but ENOTSUP warnings
+ */
+ bool reduce_diagnostics;
+
+ /* If true, copy directories recursively and copy special files
+ as themselves rather than copying their contents. */
+ bool recursive;
+
+ /* If true, set file mode to value of MODE. Otherwise,
+ set it based on current umask modified by UMASK_KILL. */
+ bool set_mode;
+
+ /* If true, create symbolic links instead of copying files.
+ Create destination directories as usual. */
+ bool symbolic_link;
+
+ /* If true, do not copy a nondirectory that has an existing destination
+ with the same or newer modification time. */
+ bool update;
+
+ /* If true, display the names of the files before copying them. */
+ bool verbose;
+
+ /* If true, stdin is a tty. */
+ bool stdin_tty;
+
+ /* If true, open a dangling destination symlink when not in move_mode.
+ Otherwise, copy_reg gives a diagnostic (it refuses to write through
+ such a symlink) and returns false. */
+ bool open_dangling_dest_symlink;
+
+ /* If true, this is the last filed to be copied. mv uses this to
+ avoid some unnecessary work. */
+ bool last_file;
+
+ /* Zero if the source has already been renamed to the destination; a
+ positive errno number if this failed with the given errno; -1 if
+ no attempt has been made to rename. Always -1, except for mv. */
+ int rename_errno;
+
+ /* Control creation of COW files. */
+ enum Reflink_type reflink_mode;
+
+ /* This is a set of destination name/inode/dev triples. Each such triple
+ represents a file we have created corresponding to a source file name
+ that was specified on the command line. Use it to avoid clobbering
+ source files in commands like this:
+ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
+ For now, it protects only regular files when copying (i.e., not renaming).
+ When renaming, it protects all non-directories.
+ Use dest_info_init to initialize it, or set it to NULL to disable
+ this feature. */
+ Hash_table *dest_info;
+
+ /* FIXME */
+ Hash_table *src_info;
+};
+
+/* Arrange to make rename calls go through the wrapper function
+ on systems with a rename function that fails for a source file name
+ specified with a trailing slash. */
+# if RENAME_TRAILING_SLASH_BUG
+int rpl_rename (char const *, char const *);
+# undef rename
+# define rename rpl_rename
+# endif
+
+bool copy (char const *src_name, char const *dst_name,
+ int dst_dirfd, char const *dst_relname,
+ int nonexistent_dst, const struct cp_options *options,
+ bool *copy_into_self, bool *rename_succeeded)
+ _GL_ATTRIBUTE_NONNULL ((1, 2, 4, 6, 7));
+
+extern bool set_process_security_ctx (char const *src_name,
+ char const *dst_name,
+ mode_t mode, bool new_dst,
+ const struct cp_options *x)
+ _GL_ATTRIBUTE_NONNULL ();
+
+extern bool set_file_security_ctx (char const *dst_name,
+ bool recurse, const struct cp_options *x)
+ _GL_ATTRIBUTE_NONNULL ();
+
+void dest_info_init (struct cp_options *) _GL_ATTRIBUTE_NONNULL ();
+void dest_info_free (struct cp_options *) _GL_ATTRIBUTE_NONNULL ();
+void src_info_init (struct cp_options *) _GL_ATTRIBUTE_NONNULL ();
+void src_info_free (struct cp_options *) _GL_ATTRIBUTE_NONNULL ();
+
+void cp_options_default (struct cp_options *) _GL_ATTRIBUTE_NONNULL ();
+bool chown_failure_ok (struct cp_options const *)
+ _GL_ATTRIBUTE_NONNULL () _GL_ATTRIBUTE_PURE;
+mode_t cached_umask (void);
+
+#endif