/* cp.c  -- file copying (main routines)                                        This is the cp utility
   Copyright (C) 1989-2018 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/>.       
                                                                                
   Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */          The GNUv3 license
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <getopt.h>                                                             ...!includes auto-comment...
#include <selinux/selinux.h>                                                    ...!includes auto-comment......!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "argmatch.h"                                                           ...!includes auto-comment...
#include "backupfile.h"                                                         ...!includes auto-comment...
#include "copy.h"                                                               ...!includes auto-comment...
#include "cp-hash.h"                                                            ...!includes auto-comment......!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "filenamecat.h"                                                        ...!includes auto-comment...
#include "ignore-value.h"                                                       ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "stat-time.h"                                                          ...!includes auto-comment...
#include "utimens.h"                                                            ...!includes auto-comment...
#include "acl.h"                                                                ...!includes auto-comment...
                                                                                
#if ! HAVE_LCHOWN                                                               Line 39
# define lchown(name, uid, gid) chown (name, uid, gid)                          Line 40
#endif                                                                          Line 41
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "cp"                                                       Line 44
                                                                                
#define AUTHORS \                                                               Line 46
  proper_name ("Torbjorn Granlund"), \                                          Line 47
  proper_name ("David MacKenzie"), \                                            Line 48
  proper_name ("Jim Meyering")                                                  Line 49
                                                                                
/* Used by do_copy, make_dir_parents_private, and re_protect                    
   to keep a list of leading directories whose protections                      
   need to be fixed after copying. */                                           
struct dir_attr                                                                 Line 54
{                                                                               
  struct stat st;                                                               Line 56
  bool restore_mode;                                                            Line 57
  size_t slash_offset;                                                          Line 58
  struct dir_attr *next;                                                        Line 59
};                                                                              Block 1
                                                                                
/* For long options that have no equivalent short option, use a                 
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */      
enum                                                                            Line 64
{                                                                               
  ATTRIBUTES_ONLY_OPTION = CHAR_MAX + 1,                                        Line 66
  COPY_CONTENTS_OPTION,                                                         Line 67
  NO_PRESERVE_ATTRIBUTES_OPTION,                                                Line 68
  PARENTS_OPTION,                                                               Line 69
  PRESERVE_ATTRIBUTES_OPTION,                                                   Line 70
  REFLINK_OPTION,                                                               Line 71
  SPARSE_OPTION,                                                                Line 72
  STRIP_TRAILING_SLASHES_OPTION,                                                Line 73
  UNLINK_DEST_BEFORE_OPENING                                                    Line 74
};                                                                              Block 2
                                                                                
/* True if the kernel is SELinux enabled.  */                                   
static bool selinux_enabled;                                                    Line 78
                                                                                
/* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"               
   as its destination instead of the usual "e_dir/e_file." */                   
static bool parents_option = false;                                             Line 82
                                                                                
/* Remove any trailing slashes from each SOURCE argument.  */                   
static bool remove_trailing_slashes;                                            Line 85
                                                                                
static char const *const sparse_type_string[] =                                 Line 87
{                                                                               
  "never", "auto", "always", NULL                                               Line 89
};                                                                              Block 3
static enum Sparse_type const sparse_type[] =                                   Line 91
{                                                                               
  SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS                                      Line 93
};                                                                              Block 4
ARGMATCH_VERIFY (sparse_type_string, sparse_type);                              Line 95
                                                                                
static char const *const reflink_type_string[] =                                Line 97
{                                                                               
  "auto", "always", "never", NULL                                               Line 99
};                                                                              Block 5
static enum Reflink_type const reflink_type[] =                                 Line 101
{                                                                               
  REFLINK_AUTO, REFLINK_ALWAYS, REFLINK_NEVER                                   Line 103
};                                                                              Block 6
ARGMATCH_VERIFY (reflink_type_string, reflink_type);                            Line 105
                                                                                
static struct option const long_opts[] =                                        Line 107
{                                                                               
  {"archive", no_argument, NULL, 'a'},                                          Line 109
  {"attributes-only", no_argument, NULL, ATTRIBUTES_ONLY_OPTION},               Line 110
  {"backup", optional_argument, NULL, 'b'},                                     Line 111
  {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},                   Line 112
  {"dereference", no_argument, NULL, 'L'},                                      Line 113
  {"force", no_argument, NULL, 'f'},                                            Line 114
  {"interactive", no_argument, NULL, 'i'},                                      Line 115
  {"link", no_argument, NULL, 'l'},                                             Line 116
  {"no-clobber", no_argument, NULL, 'n'},                                       Line 117
  {"no-dereference", no_argument, NULL, 'P'},                                   Line 118
  {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION},      Line 119
  {"no-target-directory", no_argument, NULL, 'T'},                              Line 120
  {"one-file-system", no_argument, NULL, 'x'},                                  Line 121
  {"parents", no_argument, NULL, PARENTS_OPTION},                               Line 122
  {"path", no_argument, NULL, PARENTS_OPTION},   /* Deprecated.  */             Line 123
  {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},            Line 124
  {"recursive", no_argument, NULL, 'R'},                                        Line 125
  {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},        Line 126
  {"sparse", required_argument, NULL, SPARSE_OPTION},                           Line 127
  {"reflink", optional_argument, NULL, REFLINK_OPTION},                         Line 128
  {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, Line 129
  {"suffix", required_argument, NULL, 'S'},                                     Line 130
  {"symbolic-link", no_argument, NULL, 's'},                                    Line 131
  {"target-directory", required_argument, NULL, 't'},                           Line 132
  {"update", no_argument, NULL, 'u'},                                           Line 133
  {"verbose", no_argument, NULL, 'v'},                                          Line 134
  {GETOPT_SELINUX_CONTEXT_OPTION_DECL},                                         Line 135
  {GETOPT_HELP_OPTION_DECL},                                                    Line 136
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 137
  {NULL, 0, NULL, 0}                                                            Line 138
};                                                                              Block 7
                                                                                
void                                                                            Line 141
usage (int status)                                                              Line 142
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 144
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 146
    {                                                                           
      printf (_("\                                                              Line 148
Usage: %s [OPTION]... [-T] SOURCE DEST\n\                                       Line 149
  or:  %s [OPTION]... SOURCE... DIRECTORY\n\                                    Line 150
  or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\                                 Line 151
"),                                                                             Line 152
              program_name, program_name, program_name);                        Line 153
      fputs (_("\                                                               Line 154
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\                     Line 155
"), stdout);                                                                    Line 156
                                                                                
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 160
  -a, --archive                same as -dR --preserve=all\n\                    Line 161
      --attributes-only        don't copy the file data, just the attributes\n\ Line 162
      --backup[=CONTROL]       make a backup of each existing destination file\ Line 163
\n\                                                                             
  -b                           like --backup but does not accept an argument\n\ Line 165
      --copy-contents          copy contents of special files when recursive\n\ Line 166
  -d                           same as --no-dereference --preserve=links\n\     Line 167
"), stdout);                                                                    Line 168
      fputs (_("\                                                               Line 169
  -f, --force                  if an existing destination file cannot be\n\     Line 170
                                 opened, remove it and try again (this option\n\Line 171
                                 is ignored when the -n option is also used)\n\ Line 172
  -i, --interactive            prompt before overwrite (overrides a previous -n\Line 173...!syscalls auto-comment...
\n\                                                                             
                                  option)\n\                                    Line 175
  -H                           follow command-line symbolic links in SOURCE\n\  Line 176
"), stdout);                                                                    Line 177
      fputs (_("\                                                               Line 178
  -l, --link                   hard link files instead of copying\n\            Line 179
  -L, --dereference            always follow symbolic links in SOURCE\n\        Line 180
"), stdout);                                                                    Line 181
      fputs (_("\                                                               Line 182
  -n, --no-clobber             do not overwrite an existing file (overrides\n\  Line 183
                                 a previous -i option)\n\                       Line 184
  -P, --no-dereference         never follow symbolic links in SOURCE\n\         Line 185
"), stdout);                                                                    Line 186
      fputs (_("\                                                               Line 187
  -p                           same as --preserve=mode,ownership,timestamps\n\  Line 188
      --preserve[=ATTR_LIST]   preserve the specified attributes (default:\n\   Line 189
                                 mode,ownership,timestamps), if possible\n\     Line 190
                                 additional attributes: context, links, xattr,\ Line 191
\n\                                                                             
                                 all\n\                                         Line 193
"), stdout);                                                                    Line 194
      fputs (_("\                                                               Line 195
      --no-preserve=ATTR_LIST  don't preserve the specified attributes\n\       Line 196
      --parents                use full source file name under DIRECTORY\n\     Line 197
"), stdout);                                                                    Line 198
      fputs (_("\                                                               Line 199
  -R, -r, --recursive          copy directories recursively\n\                  Line 200
      --reflink[=WHEN]         control clone/CoW copies. See below\n\           Line 201
      --remove-destination     remove each existing destination file before\n\  Line 202
                                 attempting to open it (contrast with --force)\ Line 203
\n"), stdout);                                                                  Line 204
      fputs (_("\                                                               Line 205
      --sparse=WHEN            control creation of sparse files. See below\n\   Line 206
      --strip-trailing-slashes  remove any trailing slashes from each SOURCE\n\ Line 207
                                 argument\n\                                    Line 208
"), stdout);                                                                    Line 209
      fputs (_("\                                                               Line 210
  -s, --symbolic-link          make symbolic links instead of copying\n\        Line 211
  -S, --suffix=SUFFIX          override the usual backup suffix\n\              Line 212
  -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\ Line 213
  -T, --no-target-directory    treat DEST as a normal file\n\                   Line 214
"), stdout);                                                                    Line 215
      fputs (_("\                                                               Line 216
  -u, --update                 copy only when the SOURCE file is newer\n\       Line 217
                                 than the destination file or when the\n\       Line 218
                                 destination file is missing\n\                 Line 219
  -v, --verbose                explain what is being done\n\                    Line 220
  -x, --one-file-system        stay on this file system\n\                      Line 221
"), stdout);                                                                    Line 222
      fputs (_("\                                                               Line 223
  -Z                           set SELinux security context of destination\n\   Line 224
                                 file to default type\n\                        Line 225
      --context[=CTX]          like -Z, or if CTX is specified then set the\n\  Line 226
                                 SELinux or SMACK security context to CTX\n\    Line 227
"), stdout);                                                                    Line 228
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 229
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 230
      fputs (_("\                                                               Line 231
\n\                                                                             
By default, sparse SOURCE files are detected by a crude heuristic and the\n\    Line 233
corresponding DEST file is made sparse as well.  That is the behavior\n\        Line 234
selected by --sparse=auto.  Specify --sparse=always to create a sparse DEST\n\  Line 235
file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\ Line 236
Use --sparse=never to inhibit creation of sparse files.\n\                      Line 237
"), stdout);                                                                    Line 238
      fputs (_("\                                                               Line 239
\n\                                                                             
When --reflink[=always] is specified, perform a lightweight copy, where the\n\  Line 241
data blocks are copied only when modified.  If this is not possible the copy\n\ Line 242
fails, or if --reflink=auto is specified, fall back to a standard copy.\n\      Line 243
Use --reflink=never to ensure a standard copy is performed.\n\                  Line 244
"), stdout);                                                                    Line 245
      emit_backup_suffix_note ();                                               Line 246
      fputs (_("\                                                               Line 247
\n\                                                                             
As a special case, cp makes a backup of SOURCE when the force and backup\n\     Line 249
options are given and SOURCE and DEST are the same name for an existing,\n\     Line 250
regular file.\n\                                                                Line 251
"), stdout);                                                                    Line 252
      emit_ancillary_info (PROGRAM_NAME);                                       Line 253
    }                                                                           
  exit (status);                                                                Line 255
}                                                                               Block 8
                                                                                
/* Ensure that the parent directories of CONST_DST_NAME have the                
   correct protections, for the --parents option.  This is done                 
   after all copying has been completed, to allow permissions                   
   that don't include user write/execute.                                       
                                                                                
   SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the            
   source directory name.                                                       
                                                                                
   ATTR_LIST is a null-terminated linked list of structures that                
   indicates the end of the filename of each intermediate directory             
   in CONST_DST_NAME that may need to have its attributes changed.              
   The command 'cp --parents --preserve a/b/c d/e_dir' changes the              
   attributes of the directories d/e_dir/a and d/e_dir/a/b to match             
   the corresponding source directories regardless of whether they              
   existed before the 'cp' command was given.                                   
                                                                                
   Return true if the parent of CONST_DST_NAME and any intermediate             
   directories specified by ATTR_LIST have the proper permissions               
   when done.  */                                                               
                                                                                
static bool                                                                     Line 278
re_protect (char const *const_dst_name, size_t src_offset,                      Line 279
            struct dir_attr *attr_list, const struct cp_options *x)             Line 280
{                                                                               
  struct dir_attr *p;                                                           Line 282
  char *dst_name;  /* A copy of CONST_DST_NAME we can change. */                Line 283
  char *src_name;  /* The source name in 'dst_name'. */                         Line 284
                                                                                
  ASSIGN_STRDUPA (dst_name, const_dst_name);                                    Line 286
  src_name = dst_name + src_offset;                                             Line 287
                                                                                
  for (p = attr_list; p; p = p->next)                                           Line 289
    {                                                                           
      dst_name[p->slash_offset] = '\0';                                         Line 291
                                                                                
      /* Adjust the times (and if possible, ownership) for the copy.            
         chown turns off set[ug]id bits for non-root,                           
         so do the chmod last.  */                                              
                                                                                
      if (x->preserve_timestamps)                                               Line 297
        {                                                                       
          struct timespec timespec[2];                                          Line 299
                                                                                
          timespec[0] = get_stat_atime (&p->st);                                Line 301
          timespec[1] = get_stat_mtime (&p->st);                                Line 302
                                                                                
          if (utimens (dst_name, timespec))                                     Line 304
            {                                                                   
              error (0, errno, _("failed to preserve times for %s"),            Line 306
                     quoteaf (dst_name));                                       Line 307
              return false;                                                     Line 308
            }                                                                   
        }                                                                       
                                                                                
      if (x->preserve_ownership)                                                Line 312
        {                                                                       
          if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0)               Line 314
            {                                                                   
              if (! chown_failure_ok (x))                                       Line 316
                {                                                               
                  error (0, errno, _("failed to preserve ownership for %s"),    Line 318
                         quoteaf (dst_name));                                   Line 319
                  return false;                                                 Line 320
                }                                                               
              /* Failing to preserve ownership is OK. Still, try to preserve    
                 the group, but ignore the possible error. */                   
              ignore_value (lchown (dst_name, -1, p->st.st_gid));               Line 324
            }                                                                   
        }                                                                       
                                                                                
      if (x->preserve_mode)                                                     Line 328
        {                                                                       
          if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)        Line 330
            return false;                                                       Line 331
        }                                                                       
      else if (p->restore_mode)                                                 Line 333
        {                                                                       
          if (lchmod (dst_name, p->st.st_mode) != 0)                            Line 335
            {                                                                   
              error (0, errno, _("failed to preserve permissions for %s"),      Line 337
                     quoteaf (dst_name));                                       Line 338
              return false;                                                     Line 339
            }                                                                   
        }                                                                       
                                                                                
      dst_name[p->slash_offset] = '/';                                          Line 343
    }                                                                           
  return true;                                                                  Line 345
}                                                                               Block 9
                                                                                
/* Ensure that the parent directory of CONST_DIR exists, for                    
   the --parents option.                                                        
                                                                                
   SRC_OFFSET is the index in CONST_DIR (which is a destination                 
   directory) of the beginning of the source directory name.                    
   Create any leading directories that don't already exist.                     
   If VERBOSE_FMT_STRING is nonzero, use it as a printf format                  
   string for printing a message after successfully making a directory.         
   The format should take two string arguments: the names of the                
   source and destination directories.                                          
   Creates a linked list of attributes of intermediate directories,             
   *ATTR_LIST, for re_protect to use after calling copy.                        
   Sets *NEW_DST if this function creates parent of CONST_DIR.                  
                                                                                
   Return true if parent of CONST_DIR exists as a directory with the proper     
   permissions when done.  */                                                   
                                                                                
/* FIXME: Synch this function with the one in ../lib/mkdir-p.c.  */             
                                                                                
static bool                                                                     Line 367
make_dir_parents_private (char const *const_dir, size_t src_offset,             Line 368
                          char const *verbose_fmt_string,                       Line 369
                          struct dir_attr **attr_list, bool *new_dst,           Line 370
                          const struct cp_options *x)                           Line 371
{                                                                               
  struct stat stats;                                                            Line 373
  char *dir;  /* A copy of CONST_DIR we can change.  */                         Line 374
  char *src;  /* Source name in DIR.  */                                        Line 375
  char *dst_dir; /* Leading directory of DIR.  */                               Line 376
  size_t dirlen; /* Length of DIR.  */                                          Line 377
                                                                                
  ASSIGN_STRDUPA (dir, const_dir);                                              Line 379
                                                                                
  src = dir + src_offset;                                                       Line 381
                                                                                
  dirlen = dir_len (dir);                                                       Line 383
  dst_dir = alloca (dirlen + 1);                                                Line 384
  memcpy (dst_dir, dir, dirlen);                                                Line 385
  dst_dir[dirlen] = '\0';                                                       Line 386
                                                                                
  *attr_list = NULL;                                                            Line 388
                                                                                
  /* XXX: If all dirs are present at the destination,                           
     no permissions or security contexts will be updated.  */                   
  if (stat (dst_dir, &stats) != 0)                                              Line 392...!syscalls auto-comment...
    {                                                                           
      /* A parent of CONST_DIR does not exist.                                  
         Make all missing intermediate directories. */                          
      char *slash;                                                              Line 396
                                                                                
      slash = src;                                                              Line 398
      while (*slash == '/')                                                     Line 399
        slash++;                                                                Line 400
      while ((slash = strchr (slash, '/')))                                     Line 401
        {                                                                       
          struct dir_attr *new IF_LINT ( = NULL);                               Line 403
          bool missing_dir;                                                     Line 404
                                                                                
          *slash = '\0';                                                        Line 406
          missing_dir = (stat (dir, &stats) != 0);                              Line 407...!syscalls auto-comment...
                                                                                
          if (missing_dir || x->preserve_ownership || x->preserve_mode          Line 409
              || x->preserve_timestamps)                                        Line 410
            {                                                                   
              /* Add this directory to the list of directories whose            
                 modes might need fixing later. */                              
              struct stat src_st;                                               Line 414
              int src_errno = (stat (src, &src_st) != 0                         Line 415...!syscalls auto-comment...
                               ? errno                                          Line 416
                               : S_ISDIR (src_st.st_mode)                       Line 417
                               ? 0                                              
                               : ENOTDIR);                                      Line 419
              if (src_errno)                                                    Line 420
                {                                                               
                  error (0, src_errno, _("failed to get attributes of %s"),     Line 422
                         quoteaf (src));                                        Line 423
                  return false;                                                 Line 424
                }                                                               
                                                                                
              new = xmalloc (sizeof *new);                                      Line 427
              new->st = src_st;                                                 Line 428
              new->slash_offset = slash - dir;                                  Line 429
              new->restore_mode = false;                                        Line 430
              new->next = *attr_list;                                           Line 431
              *attr_list = new;                                                 Line 432
            }                                                                   
                                                                                
          /* If required set the default context for created dirs.  */          
          if (! set_process_security_ctx (src, dir,                             Line 436
                                          missing_dir ? new->st.st_mode : 0,    Line 437
                                          missing_dir, x))                      Line 438
            return false;                                                       Line 439
                                                                                
          if (missing_dir)                                                      Line 441
            {                                                                   
              mode_t src_mode;                                                  Line 443
              mode_t omitted_permissions;                                       Line 444
              mode_t mkdir_mode;                                                Line 445
                                                                                
              /* This component does not exist.  We must set                    
                 *new_dst and new->st.st_mode inside this loop because,         
                 for example, in the command 'cp --parents ../a/../b/c e_dir',  
                 make_dir_parents_private creates only e_dir/../a if            
                 ./b already exists. */                                         
              *new_dst = true;                                                  Line 452
              src_mode = new->st.st_mode;                                       Line 453
                                                                                
              /* If the ownership or special mode bits might change,            
                 omit some permissions at first, so unauthorized users          
                 cannot nip in before the file is ready.  */                    
              omitted_permissions = (src_mode                                   Line 458
                                     & (x->preserve_ownership                   Line 459
                                        ? S_IRWXG | S_IRWXO                     Line 460
                                        : x->preserve_mode                      Line 461
                                        ? S_IWGRP | S_IWOTH                     Line 462
                                        : 0));                                  Line 463
                                                                                
              /* POSIX says mkdir's behavior is implementation-defined when     
                 (src_mode & ~S_IRWXUGO) != 0.  However, common practice is     
                 to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir    
                 decide what to do with S_ISUID | S_ISGID | S_ISVTX.  */        
              mkdir_mode = x->explicit_no_preserve_mode ? S_IRWXUGO : src_mode; Line 469
              mkdir_mode &= CHMOD_MODE_BITS & ~omitted_permissions;             Line 470
              if (mkdir (dir, mkdir_mode) != 0)                                 Line 471...!syscalls auto-comment...
                {                                                               
                  error (0, errno, _("cannot make directory %s"),               Line 473
                         quoteaf (dir));                                        Line 474
                  return false;                                                 Line 475
                }                                                               
              else                                                              Line 477
                {                                                               
                  if (verbose_fmt_string != NULL)                               Line 479
                    printf (verbose_fmt_string, src, dir);                      Line 480
                }                                                               
                                                                                
              /* We need search and write permissions to the new directory      
                 for writing the directory's contents. Check if these           
                 permissions are there.  */                                     
                                                                                
              if (lstat (dir, &stats))                                          Line 487...!syscalls auto-comment...
                {                                                               
                  error (0, errno, _("failed to get attributes of %s"),         Line 489
                         quoteaf (dir));                                        Line 490
                  return false;                                                 Line 491
                }                                                               
                                                                                
                                                                                
              if (! x->preserve_mode)                                           Line 495
                {                                                               
                  if (omitted_permissions & ~stats.st_mode)                     Line 497
                    omitted_permissions &= ~ cached_umask ();                   Line 498
                  if (omitted_permissions & ~stats.st_mode                      Line 499
                      || (stats.st_mode & S_IRWXU) != S_IRWXU)                  Line 500
                    {                                                           
                      new->st.st_mode = stats.st_mode | omitted_permissions;    Line 502
                      new->restore_mode = true;                                 Line 503
                    }                                                           
                }                                                               
                                                                                
              if ((stats.st_mode & S_IRWXU) != S_IRWXU)                         Line 507
                {                                                               
                  /* Make the new directory searchable and writable.            
                     The original permissions will be restored later.  */       
                                                                                
                  if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)               Line 512
                    {                                                           
                      error (0, errno, _("setting permissions for %s"),         Line 514
                             quoteaf (dir));                                    Line 515
                      return false;                                             Line 516
                    }                                                           
                }                                                               
            }                                                                   
          else if (!S_ISDIR (stats.st_mode))                                    Line 520
            {                                                                   
              error (0, 0, _("%s exists but is not a directory"),               Line 522
                     quoteaf (dir));                                            Line 523
              return false;                                                     Line 524
            }                                                                   
          else                                                                  Line 526
            *new_dst = false;                                                   Line 527
                                                                                
          /* For existing dirs, set the security context as per that already    
             set for the process global context.  */                            
          if (! *new_dst                                                        Line 531
              && (x->set_security_context || x->preserve_security_context))     Line 532
            {                                                                   
              if (! set_file_security_ctx (dir, x->preserve_security_context,   Line 534
                                           false, x)                            Line 535
                  && x->require_preserve_context)                               Line 536
                  return false;                                                 Line 537
            }                                                                   
                                                                                
          *slash++ = '/';                                                       Line 540
                                                                                
          /* Avoid unnecessary calls to 'stat' when given                       
             file names containing multiple adjacent slashes.  */               
          while (*slash == '/')                                                 Line 544
            slash++;                                                            Line 545
        }                                                                       
    }                                                                           
                                                                                
  /* We get here if the parent of DIR already exists.  */                       
                                                                                
  else if (!S_ISDIR (stats.st_mode))                                            Line 551
    {                                                                           
      error (0, 0, _("%s exists but is not a directory"), quoteaf (dst_dir));   Line 553
      return false;                                                             Line 554
    }                                                                           
  else                                                                          Line 556
    {                                                                           
      *new_dst = false;                                                         Line 558
    }                                                                           
  return true;                                                                  Line 560
}                                                                               Block 10
                                                                                
/* FILE is the last operand of this command.                                    
   Return true if FILE is a directory.                                          
                                                                                
   Without -f, report an error and exit if FILE exists                          
   but can't be accessed.                                                       
                                                                                
   If the file exists and is accessible store the file's status into *ST.       
   Otherwise, set *NEW_DST.  */                                                 
                                                                                
static bool                                                                     Line 572
target_directory_operand (char const *file, struct stat *st,                    Line 573
                          bool *new_dst, bool forcing)                          Line 574
{                                                                               
  int err = (stat (file, st) == 0 ? 0 : errno);                                 Line 576...!syscalls auto-comment...
  bool is_a_dir = !err && S_ISDIR (st->st_mode);                                Line 577
  if (err)                                                                      Line 578
    {                                                                           
      if (err == ENOENT)                                                        Line 580
        *new_dst = true;                                                        Line 581
      else if (forcing)                                                         Line 582
        st->st_mode = 0;  /* clear so we don't enter --backup case below.  */   Line 583
      else                                                                      Line 584
        die (EXIT_FAILURE, err, _("failed to access %s"), quoteaf (file));      Line 585
    }                                                                           
  return is_a_dir;                                                              Line 587
}                                                                               Block 11
                                                                                
/* Scan the arguments, and copy each by calling copy.                           
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 593
do_copy (int n_files, char **file, const char *target_directory,                Line 594
         bool no_target_directory, struct cp_options *x)                        Line 595
{                                                                               
  struct stat sb;                                                               Line 597
  bool new_dst = false;                                                         Line 598
  bool ok = true;                                                               Line 599
  bool forcing = x->unlink_dest_before_opening                                  Line 600
                 || x->unlink_dest_after_failed_open;                           Line 601
                                                                                
  if (n_files <= !target_directory)                                             Line 603
    {                                                                           
      if (n_files <= 0)                                                         Line 605
        error (0, 0, _("missing file operand"));                                Line 606
      else                                                                      Line 607
        error (0, 0, _("missing destination file operand after %s"),            Line 608
               quoteaf (file[0]));                                              Line 609
      usage (EXIT_FAILURE);                                                     Line 610
    }                                                                           
                                                                                
  if (no_target_directory)                                                      Line 613
    {                                                                           
      if (target_directory)                                                     Line 615
        die (EXIT_FAILURE, 0,                                                   Line 616
             _("cannot combine --target-directory (-t) "                        Line 617
               "and --no-target-directory (-T)"));                              Line 618
      if (2 < n_files)                                                          Line 619
        {                                                                       
          error (0, 0, _("extra operand %s"), quoteaf (file[2]));               Line 621
          usage (EXIT_FAILURE);                                                 Line 622
        }                                                                       
      /* Update NEW_DST and SB, which may be checked below.  */                 
      ignore_value (target_directory_operand (file[n_files -1], &sb, &new_dst,  Line 625
                                              forcing));                        Line 626
    }                                                                           
  else if (!target_directory)                                                   Line 628
    {                                                                           
      if (2 <= n_files                                                          Line 630
          && target_directory_operand (file[n_files - 1], &sb, &new_dst,        Line 631
                                       forcing))                                Line 632
        target_directory = file[--n_files];                                     Line 633
      else if (2 < n_files)                                                     Line 634
        die (EXIT_FAILURE, 0, _("target %s is not a directory"),                Line 635
             quoteaf (file[n_files - 1]));                                      Line 636
    }                                                                           
                                                                                
  if (target_directory)                                                         Line 639
    {                                                                           
      /* cp file1...filen edir                                                  
         Copy the files 'file1' through 'filen'                                 
         to the existing directory 'edir'. */                                   
                                                                                
      /* Initialize these hash tables only if we'll need them.                  
         The problems they're used to detect can arise only if                  
         there are two or more files to copy.  */                               
      if (2 <= n_files)                                                         Line 648
        {                                                                       
          dest_info_init (x);                                                   Line 650
          src_info_init (x);                                                    Line 651
        }                                                                       
                                                                                
      for (int i = 0; i < n_files; i++)                                         Line 654
        {                                                                       
          char *dst_name;                                                       Line 656
          bool parent_exists = true;  /* True if dir_name (dst_name) exists. */ Line 657
          struct dir_attr *attr_list;                                           Line 658
          char *arg_in_concat = NULL;                                           Line 659
          char *arg = file[i];                                                  Line 660
                                                                                
          /* Trailing slashes are meaningful (i.e., maybe worth preserving)     
             only in the source file names.  */                                 
          if (remove_trailing_slashes)                                          Line 664
            strip_trailing_slashes (arg);                                       Line 665
                                                                                
          if (parents_option)                                                   Line 667
            {                                                                   
              char *arg_no_trailing_slash;                                      Line 669
                                                                                
              /* Use 'arg' without trailing slashes in constructing destination 
                 file names.  Otherwise, we can end up trying to create a       
                 directory via 'mkdir ("dst/foo/"...', which is not portable.   
                 It fails, due to the trailing slash, on at least               
                 NetBSD 1.[34] systems.  */                                     
              ASSIGN_STRDUPA (arg_no_trailing_slash, arg);                      Line 676
              strip_trailing_slashes (arg_no_trailing_slash);                   Line 677
                                                                                
              /* Append all of 'arg' (minus any trailing slash) to 'dest'.  */  
              dst_name = file_name_concat (target_directory,                    Line 680
                                           arg_no_trailing_slash,               Line 681
                                           &arg_in_concat);                     Line 682
                                                                                
              /* For --parents, we have to make sure that the directory         
                 dir_name (dst_name) exists.  We may have to create a few       
                 leading directories. */                                        
              parent_exists =                                                   Line 687
                (make_dir_parents_private                                       Line 688
                 (dst_name, arg_in_concat - dst_name,                           Line 689
                  (x->verbose ? "%s -> %s\n" : NULL),                           Line 690
                  &attr_list, &new_dst, x));                                    Line 691
            }                                                                   
          else                                                                  Line 693
            {                                                                   
              char *arg_base;                                                   Line 695
              /* Append the last component of 'arg' to 'target_directory'.  */  
              ASSIGN_STRDUPA (arg_base, last_component (arg));                  Line 697
              strip_trailing_slashes (arg_base);                                Line 698
              /* For 'cp -R source/.. dest', don't copy into 'dest/..'. */      
              dst_name = (STREQ (arg_base, "..")                                Line 700
                          ? xstrdup (target_directory)                          Line 701
                          : file_name_concat (target_directory, arg_base,       Line 702
                                              NULL));                           Line 703
            }                                                                   
                                                                                
          if (!parent_exists)                                                   Line 706
            {                                                                   
              /* make_dir_parents_private failed, so don't even                 
                 attempt the copy.  */                                          
              ok = false;                                                       Line 710
            }                                                                   
          else                                                                  Line 712
            {                                                                   
              bool copy_into_self;                                              Line 714
              ok &= copy (arg, dst_name, new_dst, x, ©_into_self, NULL);    Line 715
                                                                                
              if (parents_option)                                               Line 717
                ok &= re_protect (dst_name, arg_in_concat - dst_name,           Line 718
                                  attr_list, x);                                Line 719
            }                                                                   
                                                                                
          if (parents_option)                                                   Line 722
            {                                                                   
              while (attr_list)                                                 Line 724
                {                                                               
                  struct dir_attr *p = attr_list;                               Line 726
                  attr_list = attr_list->next;                                  Line 727
                  free (p);                                                     Line 728
                }                                                               
            }                                                                   
                                                                                
          free (dst_name);                                                      Line 732
        }                                                                       
    }                                                                           
  else /* !target_directory */                                                  Line 735
    {                                                                           
      char const *new_dest;                                                     Line 737
      char const *source = file[0];                                             Line 738
      char const *dest = file[1];                                               Line 739
      bool unused;                                                              Line 740
                                                                                
      if (parents_option)                                                       Line 742
        {                                                                       
          error (0, 0,                                                          Line 744
                 _("with --parents, the destination must be a directory"));     Line 745
          usage (EXIT_FAILURE);                                                 Line 746
        }                                                                       
                                                                                
      /* When the force and backup options have been specified and              
         the source and destination are the same name for an existing           
         regular file, convert the user's command, e.g.,                        
         'cp --force --backup foo foo' to 'cp --force foo fooSUFFIX'            
         where SUFFIX is determined by any version control options used.  */    
                                                                                
      if (x->unlink_dest_after_failed_open                                      Line 755
          && x->backup_type != no_backups                                       Line 756
          && STREQ (source, dest)                                               Line 757
          && !new_dst && S_ISREG (sb.st_mode))                                  Line 758
        {                                                                       
          static struct cp_options x_tmp;                                       Line 760
                                                                                
          new_dest = find_backup_file_name (dest, x->backup_type);              Line 762
          /* Set x->backup_type to 'no_backups' so that the normal backup       
             mechanism is not used when performing the actual copy.             
             backup_type must be set to 'no_backups' only *after* the above     
             call to find_backup_file_name -- that function uses                
             backup_type to determine the suffix it applies.  */                
          x_tmp = *x;                                                           Line 768
          x_tmp.backup_type = no_backups;                                       Line 769
          x = &x_tmp;                                                           Line 770
        }                                                                       
      else                                                                      Line 772
        {                                                                       
          new_dest = dest;                                                      Line 774
        }                                                                       
                                                                                
      ok = copy (source, new_dest, 0, x, &unused, NULL);                        Line 777
    }                                                                           
                                                                                
  return ok;                                                                    Line 780
}                                                                               Block 12
                                                                                
static void                                                                     Line 783
cp_option_init (struct cp_options *x)                                           Line 784
{                                                                               
  cp_options_default (x);                                                       Line 786
  x->copy_as_regular = true;                                                    Line 787
  x->dereference = DEREF_UNDEFINED;                                             Line 788
  x->unlink_dest_before_opening = false;                                        Line 789
  x->unlink_dest_after_failed_open = false;                                     Line 790
  x->hard_link = false;                                                         Line 791
  x->interactive = I_UNSPECIFIED;                                               Line 792
  x->move_mode = false;                                                         Line 793
  x->install_mode = false;                                                      Line 794
  x->one_file_system = false;                                                   Line 795
  x->reflink_mode = REFLINK_NEVER;                                              Line 796
                                                                                
  x->preserve_ownership = false;                                                Line 798
  x->preserve_links = false;                                                    Line 799
  x->preserve_mode = false;                                                     Line 800
  x->preserve_timestamps = false;                                               Line 801
  x->explicit_no_preserve_mode = false;                                         Line 802
  x->preserve_security_context = false; /* -a or --preserve=context.  */        Line 803
  x->require_preserve_context = false;  /* --preserve=context.  */              Line 804
  x->set_security_context = false;      /* -Z, set sys default context. */      Line 805
  x->preserve_xattr = false;                                                    Line 806
  x->reduce_diagnostics = false;                                                Line 807
  x->require_preserve_xattr = false;                                            Line 808
                                                                                
  x->data_copy_required = true;                                                 Line 810
  x->require_preserve = false;                                                  Line 811
  x->recursive = false;                                                         Line 812
  x->sparse_mode = SPARSE_AUTO;                                                 Line 813
  x->symbolic_link = false;                                                     Line 814
  x->set_mode = false;                                                          Line 815
  x->mode = 0;                                                                  Line 816
                                                                                
  /* Not used.  */                                                              
  x->stdin_tty = false;                                                         Line 819
                                                                                
  x->update = false;                                                            Line 821
  x->verbose = false;                                                           Line 822
                                                                                
  /* By default, refuse to open a dangling destination symlink, because         
     in general one cannot do that safely, give the current semantics of        
     open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).       
     But POSIX requires it.  */                                                 
  x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;           Line 828
                                                                                
  x->dest_info = NULL;                                                          Line 830
  x->src_info = NULL;                                                           Line 831
}                                                                               Block 13
                                                                                
/* Given a string, ARG, containing a comma-separated list of arguments          
   to the --preserve option, set the appropriate fields of X to ON_OFF.  */     
static void                                                                     Line 836
decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)        Line 837
{                                                                               
  enum File_attribute                                                           Line 839
    {                                                                           
      PRESERVE_MODE,                                                            Line 841
      PRESERVE_TIMESTAMPS,                                                      Line 842
      PRESERVE_OWNERSHIP,                                                       Line 843
      PRESERVE_LINK,                                                            Line 844
      PRESERVE_CONTEXT,                                                         Line 845
      PRESERVE_XATTR,                                                           Line 846
      PRESERVE_ALL                                                              Line 847
    };                                                                          
  static enum File_attribute const preserve_vals[] =                            Line 849
    {                                                                           
      PRESERVE_MODE, PRESERVE_TIMESTAMPS,                                       Line 851
      PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR,      Line 852
      PRESERVE_ALL                                                              Line 853
    };                                                                          
  /* Valid arguments to the '--preserve' option. */                             
  static char const* const preserve_args[] =                                    Line 856
    {                                                                           
      "mode", "timestamps",                                                     Line 858
      "ownership", "links", "context", "xattr", "all", NULL                     Line 859
    };                                                                          
  ARGMATCH_VERIFY (preserve_args, preserve_vals);                               Line 861
                                                                                
  char *arg_writable = xstrdup (arg);                                           Line 863
  char *s = arg_writable;                                                       Line 864
  do                                                                            
    {                                                                           
      /* find next comma */                                                     
      char *comma = strchr (s, ',');                                            Line 868
      enum File_attribute val;                                                  Line 869
                                                                                
      /* If we found a comma, put a NUL in its place and advance.  */           
      if (comma)                                                                Line 872
        *comma++ = 0;                                                           Line 873
                                                                                
      /* process S.  */                                                         
      val = XARGMATCH (on_off ? "--preserve" : "--no-preserve",                 Line 876
                       s, preserve_args, preserve_vals);                        Line 877
      switch (val)                                                              Line 878
        {                                                                       
        case PRESERVE_MODE:                                                     Line 880
          x->preserve_mode = on_off;                                            Line 881
          x->explicit_no_preserve_mode = !on_off;                               Line 882
          break;                                                                Line 883
                                                                                
        case PRESERVE_TIMESTAMPS:                                               Line 885
          x->preserve_timestamps = on_off;                                      Line 886
          break;                                                                Line 887
                                                                                
        case PRESERVE_OWNERSHIP:                                                Line 889
          x->preserve_ownership = on_off;                                       Line 890
          break;                                                                Line 891
                                                                                
        case PRESERVE_LINK:                                                     Line 893
          x->preserve_links = on_off;                                           Line 894
          break;                                                                Line 895
                                                                                
        case PRESERVE_CONTEXT:                                                  Line 897
          x->require_preserve_context = on_off;                                 Line 898
          x->preserve_security_context = on_off;                                Line 899
          break;                                                                Line 900
                                                                                
        case PRESERVE_XATTR:                                                    Line 902
          x->preserve_xattr = on_off;                                           Line 903
          x->require_preserve_xattr = on_off;                                   Line 904
          break;                                                                Line 905
                                                                                
        case PRESERVE_ALL:                                                      Line 907
          x->preserve_mode = on_off;                                            Line 908
          x->preserve_timestamps = on_off;                                      Line 909
          x->preserve_ownership = on_off;                                       Line 910
          x->preserve_links = on_off;                                           Line 911
          x->explicit_no_preserve_mode = !on_off;                               Line 912
          if (selinux_enabled)                                                  Line 913
            x->preserve_security_context = on_off;                              Line 914
          x->preserve_xattr = on_off;                                           Line 915
          break;                                                                Line 916
                                                                                
        default:                                                                Line 918
          abort ();                                                             ...!common auto-comment...
        }                                                                       
      s = comma;                                                                Line 921
    }                                                                           
  while (s);                                                                    Line 923
                                                                                
  free (arg_writable);                                                          Line 925
}                                                                               Block 14
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 929
{                                                                               
  int c;                                                                        Line 931
  bool ok;                                                                      Line 932
  bool make_backups = false;                                                    Line 933
  char const *backup_suffix = NULL;                                             Line 934
  char *version_control_string = NULL;                                          Line 935
  struct cp_options x;                                                          Line 936
  bool copy_contents = false;                                                   Line 937
  char *target_directory = NULL;                                                Line 938
  bool no_target_directory = false;                                             Line 939
  char const *scontext = NULL;                                                  Line 940
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdin);                                                         Close stdout on exit (see gnulib)
                                                                                
  selinux_enabled = (0 < is_selinux_enabled ());                                ...!common auto-comment...
  cp_option_init (&x);                                                          Line 951
                                                                                
  while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",               Line 953
                           long_opts, NULL))                                    Line 954
         != -1)                                                                 Line 955
    {                                                                           
      switch (c)                                                                Line 957
        {                                                                       
        case SPARSE_OPTION:                                                     Line 959
          x.sparse_mode = XARGMATCH ("--sparse", optarg,                        Line 960
                                     sparse_type_string, sparse_type);          Line 961
          break;                                                                Line 962
                                                                                
        case REFLINK_OPTION:                                                    Line 964
          if (optarg == NULL)                                                   Line 965
            x.reflink_mode = REFLINK_ALWAYS;                                    Line 966
          else                                                                  Line 967
            x.reflink_mode = XARGMATCH ("--reflink", optarg,                    Line 968
                                       reflink_type_string, reflink_type);      Line 969
          break;                                                                Line 970
                                                                                
        case 'a':                                                               Line 972
          /* Like -dR --preserve=all with reduced failure diagnostics.  */      
          x.dereference = DEREF_NEVER;                                          Line 974
          x.preserve_links = true;                                              Line 975
          x.preserve_ownership = true;                                          Line 976
          x.preserve_mode = true;                                               Line 977
          x.preserve_timestamps = true;                                         Line 978
          x.require_preserve = true;                                            Line 979
          if (selinux_enabled)                                                  Line 980
             x.preserve_security_context = true;                                Line 981
          x.preserve_xattr = true;                                              Line 982
          x.reduce_diagnostics = true;                                          Line 983
          x.recursive = true;                                                   Line 984
          break;                                                                Line 985
                                                                                
        case 'b':                                                               Line 987
          make_backups = true;                                                  Line 988
          if (optarg)                                                           Line 989
            version_control_string = optarg;                                    Line 990
          break;                                                                Line 991
                                                                                
        case ATTRIBUTES_ONLY_OPTION:                                            Line 993
          x.data_copy_required = false;                                         Line 994
          break;                                                                Line 995
                                                                                
        case COPY_CONTENTS_OPTION:                                              Line 997
          copy_contents = true;                                                 Line 998
          break;                                                                Line 999
                                                                                
        case 'd':                                                               Line 1001
          x.preserve_links = true;                                              Line 1002
          x.dereference = DEREF_NEVER;                                          Line 1003
          break;                                                                Line 1004
                                                                                
        case 'f':                                                               Line 1006
          x.unlink_dest_after_failed_open = true;                               Line 1007
          break;                                                                Line 1008
                                                                                
        case 'H':                                                               Line 1010
          x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;                         Line 1011
          break;                                                                Line 1012
                                                                                
        case 'i':                                                               Line 1014
          x.interactive = I_ASK_USER;                                           Line 1015
          break;                                                                Line 1016
                                                                                
        case 'l':                                                               Line 1018
          x.hard_link = true;                                                   Line 1019
          break;                                                                Line 1020
                                                                                
        case 'L':                                                               Line 1022
          x.dereference = DEREF_ALWAYS;                                         Line 1023
          break;                                                                Line 1024
                                                                                
        case 'n':                                                               Line 1026
          x.interactive = I_ALWAYS_NO;                                          Line 1027
          break;                                                                Line 1028
                                                                                
        case 'P':                                                               Line 1030
          x.dereference = DEREF_NEVER;                                          Line 1031
          break;                                                                Line 1032
                                                                                
        case NO_PRESERVE_ATTRIBUTES_OPTION:                                     Line 1034
          decode_preserve_arg (optarg, &x, false);                              Line 1035
          break;                                                                Line 1036
                                                                                
        case PRESERVE_ATTRIBUTES_OPTION:                                        Line 1038
          if (optarg == NULL)                                                   Line 1039
            {                                                                   
              /* Fall through to the case for 'p' below.  */                    
            }                                                                   
          else                                                                  Line 1043
            {                                                                   
              decode_preserve_arg (optarg, &x, true);                           Line 1045
              x.require_preserve = true;                                        Line 1046
              break;                                                            Line 1047
            }                                                                   
          FALLTHROUGH;                                                          Line 1049
                                                                                
        case 'p':                                                               Line 1051
          x.preserve_ownership = true;                                          Line 1052
          x.preserve_mode = true;                                               Line 1053
          x.preserve_timestamps = true;                                         Line 1054
          x.require_preserve = true;                                            Line 1055
          break;                                                                Line 1056
                                                                                
        case PARENTS_OPTION:                                                    Line 1058
          parents_option = true;                                                Line 1059
          break;                                                                Line 1060
                                                                                
        case 'r':                                                               Line 1062
        case 'R':                                                               Line 1063
          x.recursive = true;                                                   Line 1064
          break;                                                                Line 1065
                                                                                
        case UNLINK_DEST_BEFORE_OPENING:                                        Line 1067
          x.unlink_dest_before_opening = true;                                  Line 1068
          break;                                                                Line 1069
                                                                                
        case STRIP_TRAILING_SLASHES_OPTION:                                     Line 1071
          remove_trailing_slashes = true;                                       Line 1072
          break;                                                                Line 1073
                                                                                
        case 's':                                                               Line 1075
          x.symbolic_link = true;                                               Line 1076
          break;                                                                Line 1077
                                                                                
        case 't':                                                               Line 1079
          if (target_directory)                                                 Line 1080
            die (EXIT_FAILURE, 0,                                               Line 1081
                 _("multiple target directories specified"));                   Line 1082
          else                                                                  Line 1083
            {                                                                   
              struct stat st;                                                   Line 1085
              if (stat (optarg, &st) != 0)                                      Line 1086...!syscalls auto-comment...
                die (EXIT_FAILURE, errno, _("failed to access %s"),             Line 1087
                     quoteaf (optarg));                                         Line 1088
              if (! S_ISDIR (st.st_mode))                                       Line 1089
                die (EXIT_FAILURE, 0, _("target %s is not a directory"),        Line 1090
                     quoteaf (optarg));                                         Line 1091
            }                                                                   
          target_directory = optarg;                                            Line 1093
          break;                                                                Line 1094
                                                                                
        case 'T':                                                               Line 1096
          no_target_directory = true;                                           Line 1097
          break;                                                                Line 1098
                                                                                
        case 'u':                                                               Line 1100
          x.update = true;                                                      Line 1101
          break;                                                                Line 1102
                                                                                
        case 'v':                                                               Line 1104
          x.verbose = true;                                                     Line 1105
          break;                                                                Line 1106
                                                                                
        case 'x':                                                               Line 1108
          x.one_file_system = true;                                             Line 1109
          break;                                                                Line 1110
                                                                                
        case 'Z':                                                               Line 1112
          /* politely decline if we're not on a selinux-enabled kernel.  */     
          if (selinux_enabled)                                                  Line 1114
            {                                                                   
              if (optarg)                                                       Line 1116
                scontext = optarg;                                              Line 1117
              else                                                              Line 1118
                x.set_security_context = true;                                  Line 1119
            }                                                                   
          else if (optarg)                                                      Line 1121
            {                                                                   
              error (0, 0,                                                      Line 1123
                     _("warning: ignoring --context; "                          Line 1124
                       "it requires an SELinux-enabled kernel"));               Line 1125
            }                                                                   
          break;                                                                Line 1127
                                                                                
        case 'S':                                                               Line 1129
          make_backups = true;                                                  Line 1130
          backup_suffix = optarg;                                               Line 1131
          break;                                                                Line 1132
                                                                                
        case_GETOPT_HELP_CHAR;                                                  Line 1134
                                                                                
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 1136
                                                                                
        default:                                                                Line 1138
          usage (EXIT_FAILURE);                                                 Line 1139
        }                                                                       
    }                                                                           
                                                                                
  if (x.hard_link && x.symbolic_link)                                           Line 1143
    {                                                                           
      error (0, 0, _("cannot make both hard and symbolic links"));              Line 1145
      usage (EXIT_FAILURE);                                                     Line 1146
    }                                                                           
                                                                                
  if (x.interactive == I_ALWAYS_NO)                                             Line 1149
    x.update = false;                                                           Line 1150
                                                                                
  if (make_backups && x.interactive == I_ALWAYS_NO)                             Line 1152
    {                                                                           
      error (0, 0,                                                              Line 1154
             _("options --backup and --no-clobber are mutually exclusive"));    Line 1155
      usage (EXIT_FAILURE);                                                     Line 1156
    }                                                                           
                                                                                
  if (x.reflink_mode == REFLINK_ALWAYS && x.sparse_mode != SPARSE_AUTO)         Line 1159
    {                                                                           
      error (0, 0, _("--reflink can be used only with --sparse=auto"));         Line 1161
      usage (EXIT_FAILURE);                                                     Line 1162
    }                                                                           
                                                                                
  x.backup_type = (make_backups                                                 Line 1165
                   ? xget_version (_("backup type"),                            Line 1166
                                   version_control_string)                      Line 1167
                   : no_backups);                                               Line 1168
  set_simple_backup_suffix (backup_suffix);                                     Line 1169
                                                                                
  if (x.dereference == DEREF_UNDEFINED)                                         Line 1171
    {                                                                           
      if (x.recursive && ! x.hard_link)                                         Line 1173
        /* This is compatible with FreeBSD.  */                                 
        x.dereference = DEREF_NEVER;                                            Line 1175
      else                                                                      Line 1176
        x.dereference = DEREF_ALWAYS;                                           Line 1177
    }                                                                           
                                                                                
  if (x.recursive)                                                              Line 1180
    x.copy_as_regular = copy_contents;                                          Line 1181
                                                                                
  /* Ensure -Z overrides -a.  */                                                
  if ((x.set_security_context || scontext)                                      Line 1184
      && ! x.require_preserve_context)                                          Line 1185
    x.preserve_security_context = false;                                        Line 1186
                                                                                
  if (x.preserve_security_context && (x.set_security_context || scontext))      Line 1188
    die (EXIT_FAILURE, 0,                                                       Line 1189
         _("cannot set target context and preserve it"));                       Line 1190
                                                                                
  if (x.require_preserve_context && ! selinux_enabled)                          Line 1192
    die (EXIT_FAILURE, 0,                                                       Line 1193
         _("cannot preserve security context "                                  Line 1194
           "without an SELinux-enabled kernel"));                               Line 1195
                                                                                
  /* FIXME: This handles new files.  But what about existing files?             
     I.e., if updating a tree, new files would have the specified context,      
     but shouldn't existing files be updated for consistency like this?         
       if (scontext)                                                            
         restorecon (dst_path, 0, true);                                        
   */                                                                           
  if (scontext && setfscreatecon (se_const (scontext)) < 0)                     Line 1203
    die (EXIT_FAILURE, errno,                                                   Line 1204
         _("failed to set default file creation context to %s"),                Line 1205
         quote (scontext));                                                     Line 1206
                                                                                
#if !USE_XATTR                                                                  Line 1208
  if (x.require_preserve_xattr)                                                 Line 1209
    die (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "       Line 1210
                            "built without xattr support"));                    Line 1211
#endif                                                                          Line 1212
                                                                                
  /* Allocate space for remembering copied and created files.  */               
                                                                                
  hash_init ();                                                                 Line 1216
                                                                                
  ok = do_copy (argc - optind, argv + optind,                                   Line 1218
                target_directory, no_target_directory, &x);                     Line 1219
                                                                                
#ifdef lint                                                                     Line 1221
  forget_all ();                                                                Line 1222
#endif                                                                          Line 1223
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 1225
}                                                                               Block 15