/* Copyright 2008 Rob Landley <rob@landley.net>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/cp.html
 * And http://opengroup.org/onlinepubs/9699919799/utilities/mv.html
 * And http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic.html#INSTALL
 *
 * Posix says "cp -Rf dir file" shouldn't delete file, but our -f does.
 *
 * Deviations from posix: -adlnrsvF, --preserve... about half the
 * functionality in this cp isn't in posix. Posix is stuck in the 1970's.
 *
 * TODO: --preserve=links
 * TODO: what's this _CP_mode system.posix_acl_ business? We chmod()?

// options shared between mv/cp must be in same order (right to left)
// for FLAG macros to work out right in shared infrastructure.

USE_CP(NEWTOY(cp, "<2"USE_CP_PRESERVE("(preserve):;")"RHLPprdaslvnF(remove-destination)fi[-HLPd][-ni]", TOYFLAG_BIN))
USE_MV(NEWTOY(mv, "<2vnF(remove-destination)fi[-ni]", TOYFLAG_BIN))
USE_INSTALL(NEWTOY(install, "<1cdDpsvm:o:g:", TOYFLAG_USR|TOYFLAG_BIN))

config CP
  bool "cp"
  default y
  help
    usage: cp [-adlnrsvfipRHLP] SOURCE... DEST

    Copy files from SOURCE to DEST.  If more than one SOURCE, DEST must
    be a directory.

    -f	delete destination files we can't write to
    -F	delete any existing destination file first (--remove-destination)
    -i	interactive, prompt before overwriting existing DEST
    -p	preserve timestamps, ownership, and mode
    -R	recurse into subdirectories (DEST must be a directory)
    -H	Follow symlinks listed on command line
    -L	Follow all symlinks
    -P	Do not follow symlinks [default]
    -a	same as -dpr
    -d	don't dereference symlinks
    -l	hard link instead of copy
    -n	no clobber (don't overwrite DEST)
    -r	synonym for -R
    -s	symlink instead of copy
    -v	verbose

config CP_PRESERVE
  bool "cp --preserve support"
  default y
  depends on CP
  help
    usage: cp [--preserve=motcxa]

    --preserve takes either a comma separated list of attributes, or the first
    letter(s) of:

            mode - permissions (ignore umask for rwx, copy suid and sticky bit)
       ownership - user and group
      timestamps - file creation, modification, and access times.
         context - security context
           xattr - extended attributes
             all - all of the above

config MV
  bool "mv"
  default y
  help
    usage: mv [-fivn] SOURCE... DEST"

    -f	force copy by deleting destination file
    -i	interactive, prompt before overwriting existing DEST
    -v	verbose
    -n	no clobber (don't overwrite DEST)

config INSTALL
  bool "install"
  default y
  help
    usage: install [-dDpsv] [-o USER] [-g GROUP] [-m MODE] [SOURCE...] DEST

    Copy files and set attributes.

    -d	Act like mkdir -p
    -D	Create leading directories for DEST
    -g	Make copy belong to GROUP
    -m	Set permissions to MODE
    -o	Make copy belong to USER
    -p	Preserve timestamps
    -s	Call "strip -p"
    -v	Verbose
*/

#define FORCE_FLAGS
#define FOR_cp
#include "toys.h"

GLOBALS(
  union {
    struct {
      // install's options
      char *group;
      char *user;
      char *mode;
    } i;
    struct {
      char *preserve;
    } c;
  };

  char *destname;
  struct stat top;
  int (*callback)(struct dirtree *try);
  uid_t uid;
  gid_t gid;
  int pflags;
)

struct cp_preserve {
  char *name;
} static const cp_preserve[] = TAGGED_ARRAY(CP,
  {"mode"}, {"ownership"}, {"timestamps"}, {"context"}, {"xattr"},
);

// Callback from dirtree_read() for each file/directory under a source dir.

int cp_node(struct dirtree *try)
{
  int fdout = -1, cfd = try->parent ? try->parent->extra : AT_FDCWD,
      tfd = dirtree_parentfd(try);
  unsigned flags = toys.optflags;
  char *catch = try->parent ? try->name : TT.destname, *err = "%s";
  struct stat cst;

  if (!dirtree_notdotdot(try)) return 0;

  // If returning from COMEAGAIN, jump straight to -p logic at end.
  if (S_ISDIR(try->st.st_mode) && try->again) {
    fdout = try->extra;
    err = 0;
  } else {

    // -d is only the same as -r for symlinks, not for directories
    if (S_ISLNK(try->st.st_mode) && (flags & FLAG_d)) flags |= FLAG_r;

    // Detect recursive copies via repeated top node (cp -R .. .) or
    // identical source/target (fun with hardlinks).
    if ((TT.top.st_dev == try->st.st_dev && TT.top.st_ino == try->st.st_ino
         && (catch = TT.destname))
        || (!fstatat(cfd, catch, &cst, 0) && cst.st_dev == try->st.st_dev
         && cst.st_ino == try->st.st_ino))
    {
      error_msg("'%s' is '%s'", catch, err = dirtree_path(try, 0));
      free(err);

      return 0;
    }

    // Handle -invF

    if (!faccessat(cfd, catch, F_OK, 0) && !S_ISDIR(cst.st_mode)) {
      char *s;

      if (S_ISDIR(try->st.st_mode)) {
        error_msg("dir at '%s'", s = dirtree_path(try, 0));
        free(s);
        return 0;
      } else if ((flags & FLAG_F) && unlinkat(cfd, catch, 0)) {
        error_msg("unlink '%s'", catch);
        return 0;
      } else if (flags & FLAG_n) return 0;
      else if (flags & FLAG_i) {
        fprintf(stderr, "%s: overwrite '%s'", toys.which->name,
          s = dirtree_path(try, 0));
        free(s);
        if (!yesno(1)) return 0;
      }
    }

    if (flags & FLAG_v) {
      char *s = dirtree_path(try, 0);
      printf("%s '%s'\n", toys.which->name, s);
      free(s);
    }

    // Loop for -f retry after unlink
    do {

      // directory, hardlink, symlink, mknod (char, block, fifo, socket), file

      // Copy directory

      if (S_ISDIR(try->st.st_mode)) {
        struct stat st2;

        if (!(flags & (FLAG_a|FLAG_r|FLAG_R))) {
          err = "Skipped dir '%s'";
          catch = try->name;
          break;
        }

        // Always make directory writeable to us, so we can create files in it.
        //
        // Yes, there's a race window between mkdir() and open() so it's
        // possible that -p can be made to chown a directory other than the one
        // we created. The closest we can do to closing this is make sure
        // that what we open _is_ a directory rather than something else.

        if (!mkdirat(cfd, catch, try->st.st_mode | 0200) || errno == EEXIST)
          if (-1 != (try->extra = openat(cfd, catch, O_NOFOLLOW)))
            if (!fstat(try->extra, &st2) && S_ISDIR(st2.st_mode))
              return DIRTREE_COMEAGAIN
                     | (DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L));

      // Hardlink

      } else if (flags & FLAG_l) {
        if (!linkat(tfd, try->name, cfd, catch, 0)) err = 0;

      // Copy tree as symlinks. For non-absolute paths this involves
      // appending the right number of .. entries as you go down the tree.

      } else if (flags & FLAG_s) {
        char *s;
        struct dirtree *or;
        int dotdots = 0;

        s = dirtree_path(try, 0);
        for (or = try; or->parent; or = or->parent) dotdots++;

        if (*or->name == '/') dotdots = 0;
        if (dotdots) {
          char *s2 = xmprintf("%*c%s", 3*dotdots, ' ', s);
          free(s);
          s = s2;
          while(dotdots--) {
            memcpy(s2, "../", 3);
            s2 += 3;
          }
        }
        if (!symlinkat(s, cfd, catch)) {
          err = 0;
          fdout = AT_FDCWD;
        }
        free(s);

      // Do something _other_ than copy contents of a file?
      } else if (!S_ISREG(try->st.st_mode)
                 && (try->parent || (flags & (FLAG_a|FLAG_r))))
      {
        int i;

        // make symlink, or make block/char/fifo/socket
        if (S_ISLNK(try->st.st_mode)
            ? (0 < (i = readlinkat(tfd, try->name, toybuf, sizeof(toybuf))) &&
               sizeof(toybuf) > i && !symlinkat(toybuf, cfd, catch))
            : !mknodat(cfd, catch, try->st.st_mode, try->st.st_rdev))
        {
          err = 0;
          fdout = AT_FDCWD;
        }

      // Copy contents of file.
      } else {
        int fdin;

        fdin = openat(tfd, try->name, O_RDONLY);
        if (fdin < 0) {
          catch = try->name;
          break;
        }
        fdout = openat(cfd, catch, O_RDWR|O_CREAT|O_TRUNC, try->st.st_mode);
        if (fdout >= 0) {
          xsendfile(fdin, fdout);
          err = 0;
        }

        // We only copy xattrs for files because there's no flistxattrat()
        if (TT.pflags&(_CP_xattr|_CP_context)) {
          ssize_t listlen = flistxattr(fdin, 0, 0), len;
          char *name, *value, *list;

          if (listlen>0) {
            list = xmalloc(listlen);
            flistxattr(fdin, list, listlen);
            list[listlen-1] = 0; // I do not trust this API.
            for (name = list; name-list < listlen; name += strlen(name)+1) {
              if (!(TT.pflags&_CP_xattr) && strncmp(name, "security.", 9))
                continue;
              if ((len = fgetxattr(fdin, name, 0, 0))>0) {
                value = xmalloc(len);
                if (len == fgetxattr(fdin, name, value, len))
                  if (fsetxattr(fdout, name, value, len, 0))
                    perror_msg("%s setxattr(%s=%s)", catch, name, value);
                free(value);
              }
            }
            free(list);
          }
        }

        close(fdin);
      }
    } while (err && (flags & (FLAG_f|FLAG_n)) && !unlinkat(cfd, catch, 0));
  }

  // Did we make a thing?
  if (fdout != -1) {
    int rc;

    // Inability to set --preserve isn't fatal, some require root access.

    // ownership
    if (TT.pflags & _CP_ownership) {

      // permission bits already correct for mknod and don't apply to symlink
      // If we can't get a filehandle to the actual object, use racy functions
      if (fdout == AT_FDCWD)
        rc = fchownat(cfd, catch, try->st.st_uid, try->st.st_gid,
                      AT_SYMLINK_NOFOLLOW);
      else rc = fchown(fdout, try->st.st_uid, try->st.st_gid);
      if (rc) {
        char *pp;

        perror_msg("chown '%s'", pp = dirtree_path(try, 0));
        free(pp);
      }
    }

    // timestamp
    if (TT.pflags & _CP_timestamps) {
      struct timespec times[] = {try->st.st_atim, try->st.st_mtim};

      if (fdout == AT_FDCWD) utimensat(cfd, catch, times, AT_SYMLINK_NOFOLLOW);
      else futimens(fdout, times);
    }

    // mode comes last because other syscalls can strip suid bit
    if (fdout != AT_FDCWD) {
      if (TT.pflags & _CP_mode) fchmod(fdout, try->st.st_mode);
      xclose(fdout);
    }

    if (CFG_MV && toys.which->name[0] == 'm')
      if (unlinkat(tfd, try->name, S_ISDIR(try->st.st_mode) ? AT_REMOVEDIR :0))
        err = "%s";
  }

  if (err) perror_msg(err, catch);
  return 0;
}

void cp_main(void)
{
  char *destname = toys.optargs[--toys.optc];
  int i, destdir = !stat(destname, &TT.top) && S_ISDIR(TT.top.st_mode);

  if (toys.optc>1 && !destdir) error_exit("'%s' not directory", destname);

  if (toys.optflags & (FLAG_a|FLAG_p)) {
    TT.pflags = CP_mode|CP_ownership|CP_timestamps;
    umask(0);
  }
  // Not using comma_args() (yet?) because interpeting as letters.
  if (CFG_CP_PRESERVE && (toys.optflags & FLAG_preserve)) {
    char *pre = xstrdup(TT.c.preserve), *s;

    if (comma_scan(pre, "all", 1)) TT.pflags = ~0;
    for (i=0; i<ARRAY_LEN(cp_preserve); i++)
      if (comma_scan(pre, cp_preserve[i].name, 1)) TT.pflags |= 1<<i;
    if (*pre) {

      // Try to interpret as letters, commas won't set anything this doesn't.
      for (s = TT.c.preserve; *s; s++) {
        for (i=0; i<ARRAY_LEN(cp_preserve); i++)
          if (*s == *cp_preserve[i].name) break;
        if (i == ARRAY_LEN(cp_preserve)) {
          if (*s == 'a') TT.pflags = ~0;
          else break;
        } else TT.pflags |= 1<<i;
      }

      if (*s) error_exit("bad --preserve=%s", pre);
    }
    free(pre);
  }
  if (!TT.callback) TT.callback = cp_node;

  // Loop through sources
  for (i=0; i<toys.optc; i++) {
    char *src = toys.optargs[i];
    int rc = 1;

    if (destdir) TT.destname = xmprintf("%s/%s", destname, basename(src));
    else TT.destname = destname;

    errno = EXDEV;
    if (CFG_MV && toys.which->name[0] == 'm') {
      if (!(toys.optflags & FLAG_f)) {
        struct stat st;

        // Technically "is writeable" is more complicated (022 is not writeable
        // by the owner, just everybody _else_) but I don't care.
        if (!stat(TT.destname, &st)
          && ((toys.optflags & FLAG_i) || !(st.st_mode & 0222)))
        {
          fprintf(stderr, "%s: overwrite '%s'", toys.which->name, TT.destname);
          if (!yesno(1)) rc = 0;
          else unlink(TT.destname);
        }
      }

      if (rc) rc = rename(src, TT.destname);
    }

    // Copy if we didn't mv, skipping nonexistent sources
    if (rc) {
      if (errno!=EXDEV || dirtree_flagread(src, DIRTREE_SHUTUP+
        DIRTREE_SYMFOLLOW*!!(toys.optflags&(FLAG_H|FLAG_L)), TT.callback))
          perror_msg("bad '%s'", src);
    }
    if (destdir) free(TT.destname);
  }
}

void mv_main(void)
{
  toys.optflags |= FLAG_d|FLAG_p|FLAG_R;

  cp_main();
}

// Export cp flags into install's flag context.

static inline int cp_flag_F(void) { return FLAG_F; };
static inline int cp_flag_p(void) { return FLAG_p; };
static inline int cp_flag_v(void) { return FLAG_v; };

// Switch to install's flag context
#define CLEANUP_cp
#define FOR_install
#include <generated/flags.h>

static int install_node(struct dirtree *try)
{
  try->st.st_mode = (TT.i.mode)
    ? string_to_mode(TT.i.mode, try->st.st_mode) : 0755;
  if (TT.i.group) try->st.st_gid = TT.gid;
  if (TT.i.user) try->st.st_uid = TT.uid;

  // Always returns 0 because no -r
  cp_node(try);

  // No -r so always one level deep, so destname as set by cp_node() is correct
  if (toys.optflags & FLAG_s)
    if (xrun((char *[]){"strip", "-p", TT.destname, 0})) toys.exitval = 1;

  return 0;
}

void install_main(void)
{
  char **ss;
  int flags = toys.optflags;

  if (flags & FLAG_d) {
    for (ss = toys.optargs; *ss; ss++) {
      if (mkpathat(AT_FDCWD, *ss, 0777, 3)) perror_msg_raw(*ss);
      if (flags & FLAG_v) printf("%s\n", *ss);
    }

    return;
  }

  if (toys.optflags & FLAG_D) {
    TT.destname = toys.optargs[toys.optc-1];
    if (mkpathat(AT_FDCWD, TT.destname, 0, 2))
      perror_exit("-D '%s'", TT.destname);
    if (toys.optc == 1) return;
  }
  if (toys.optc < 2) error_exit("needs 2 args");

  // Translate flags from install to cp
  toys.optflags = cp_flag_F();
  if (flags & FLAG_v) toys.optflags |= cp_flag_v();
  if (flags & (FLAG_p|FLAG_o|FLAG_g)) toys.optflags |= cp_flag_p();

  if (TT.i.user) TT.uid = xgetpwnamid(TT.i.user)->pw_uid;
  if (TT.i.group) TT.gid = xgetgrnamid(TT.i.group)->gr_gid;

  TT.callback = install_node;
  cp_main();
}
