diff options
Diffstat (limited to 'src/copy.h')
-rw-r--r-- | src/copy.h | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/src/copy.h b/src/copy.h new file mode 100644 index 0000000..874d6f7 --- /dev/null +++ b/src/copy.h @@ -0,0 +1,307 @@ +/* core functions for copying files and directories + Copyright (C) 1989-2020 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" + +/* 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 disk. */ + SPARSE_ALWAYS +}; + +/* Control creation of COW files. */ +enum Reflink_type +{ + /* Default to a standard copy. */ + REFLINK_NEVER, + + /* Try a COW copy and fall back to a standard copy. */ + 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 true, attempt to set specified security context */ + bool 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 (const char *, const char *); +# undef rename +# define rename rpl_rename +# endif + +bool copy (char const *src_name, char const *dst_name, + bool nonexistent_dst, const struct cp_options *options, + bool *copy_into_self, bool *rename_succeeded); + +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); + +extern bool set_file_security_ctx (char const *dst_name, bool process_local, + bool recurse, const struct cp_options *x); + +void dest_info_init (struct cp_options *); +void src_info_init (struct cp_options *); + +void cp_options_default (struct cp_options *); +bool chown_failure_ok (struct cp_options const *) _GL_ATTRIBUTE_PURE; +mode_t cached_umask (void); + +#endif |