/* Rename a file relative to open directories.
   Copyright (C) 2009-2020 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* written by Eric Blake and Paul Eggert */

#include <config.h>

#include "renameatu.h"

#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#ifdef __linux__
# include <sys/syscall.h>
#endif

static int
errno_fail (int e)
{
  errno = e;
  return -1;
}

#if HAVE_RENAMEAT

# include <stdbool.h>
# include <stdlib.h>
# include <string.h>

# include "dirname.h"
# include "openat.h"

#else
# include "openat-priv.h"

static int
rename_noreplace (char const *src, char const *dst)
{
  /* This has a race between the call to lstat and the call to rename.  */
  struct stat st;
  return (lstat (dst, &st) == 0 || errno == EOVERFLOW ? errno_fail (EEXIST)
          : errno == ENOENT ? rename (src, dst)
          : -1);
}
#endif

#undef renameat

/* Rename FILE1, in the directory open on descriptor FD1, to FILE2, in
   the directory open on descriptor FD2.  If possible, do it without
   changing the working directory.  Otherwise, resort to using
   save_cwd/fchdir, then rename/restore_cwd.  If either the save_cwd or
   the restore_cwd fails, then give a diagnostic and exit nonzero.

   Obey FLAGS when doing the renaming.  If FLAGS is zero, this
   function is equivalent to renameat (FD1, SRC, FD2, DST).
   Otherwise, attempt to implement FLAGS even if the implementation is
   not atomic; this differs from the GNU/Linux native renameat2,
   which fails if it cannot guarantee atomicity.  */

int
renameatu (int fd1, char const *src, int fd2, char const *dst,
           unsigned int flags)
{
  int ret_val = -1;
  int err = EINVAL;

#ifdef HAVE_RENAMEAT2
  ret_val = renameat2 (fd1, src, fd2, dst, flags);
  err = errno;
#elif defined SYS_renameat2
  ret_val = syscall (SYS_renameat2, fd1, src, fd2, dst, flags);
  err = errno;
#elif defined RENAME_EXCL
  if (! (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE)))
    {
      ret_val = renameatx_np (fd1, src, fd2, dst,
                             ((flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)
                              | (flags & RENAME_NOREPLACE ? RENAME_EXCL : 0)));
      err = errno;
    }
#endif

  if (! (ret_val < 0 && (err == EINVAL || err == ENOSYS || err == ENOTSUP)))
    return ret_val;

#if HAVE_RENAMEAT
  {
  size_t src_len;
  size_t dst_len;
  char *src_temp = (char *) src;
  char *dst_temp = (char *) dst;
  bool src_slash;
  bool dst_slash;
  int rename_errno = ENOTDIR;
  struct stat src_st;
  struct stat dst_st;
  bool dst_found_nonexistent = false;

  if (flags != 0)
    {
      /* RENAME_NOREPLACE is the only flag currently supported.  */
      if (flags & ~RENAME_NOREPLACE)
        return errno_fail (ENOTSUP);
      else
        {
          /* This has a race between the call to lstatat and the calls to
             renameat below.  */
          if (lstatat (fd2, dst, &dst_st) == 0 || errno == EOVERFLOW)
            return errno_fail (EEXIST);
          if (errno != ENOENT)
            return -1;
          dst_found_nonexistent = true;
        }
    }

  /* Let strace see any ENOENT failure.  */
  src_len = strlen (src);
  dst_len = strlen (dst);
  if (!src_len || !dst_len)
    return renameat (fd1, src, fd2, dst);

  src_slash = src[src_len - 1] == '/';
  dst_slash = dst[dst_len - 1] == '/';
  if (!src_slash && !dst_slash)
    return renameat (fd1, src, fd2, dst);

  /* Presence of a trailing slash requires directory semantics.  If
     the source does not exist, or if the destination cannot be turned
     into a directory, give up now.  Otherwise, strip trailing slashes
     before calling rename.  */
  if (lstatat (fd1, src, &src_st))
    return -1;
  if (dst_found_nonexistent)
    {
      if (!S_ISDIR (src_st.st_mode))
        return errno_fail (ENOENT);
    }
  else if (lstatat (fd2, dst, &dst_st))
    {
      if (errno != ENOENT || !S_ISDIR (src_st.st_mode))
        return -1;
    }
  else if (!S_ISDIR (dst_st.st_mode))
    return errno_fail (ENOTDIR);
  else if (!S_ISDIR (src_st.st_mode))
    return errno_fail (EISDIR);

# if RENAME_TRAILING_SLASH_SOURCE_BUG
  /* See the lengthy comment in rename.c why Solaris 9 is forced to
     GNU behavior, while Solaris 10 is left with POSIX behavior,
     regarding symlinks with trailing slash.  */
  ret_val = -1;
  if (src_slash)
    {
      src_temp = strdup (src);
      if (!src_temp)
        {
          /* Rather than rely on strdup-posix, we set errno ourselves.  */
          rename_errno = ENOMEM;
          goto out;
        }
      strip_trailing_slashes (src_temp);
      if (lstatat (fd1, src_temp, &src_st))
        {
          rename_errno = errno;
          goto out;
        }
      if (S_ISLNK (src_st.st_mode))
        goto out;
    }
  if (dst_slash)
    {
      dst_temp = strdup (dst);
      if (!dst_temp)
        {
          rename_errno = ENOMEM;
          goto out;
        }
      strip_trailing_slashes (dst_temp);
      if (lstatat (fd2, dst_temp, &dst_st))
        {
          if (errno != ENOENT)
            {
              rename_errno = errno;
              goto out;
            }
        }
      else if (S_ISLNK (dst_st.st_mode))
        goto out;
    }
# endif /* RENAME_TRAILING_SLASH_SOURCE_BUG */

  /* renameat does not honor trailing / on Solaris 10.  Solve it in a
     similar manner to rename.  No need to worry about bugs not present
     on Solaris, since all other systems either lack renameat or honor
     trailing slash correctly.  */

  ret_val = renameat (fd1, src_temp, fd2, dst_temp);
  rename_errno = errno;
  goto out;
 out:
  if (src_temp != src)
    free (src_temp);
  if (dst_temp != dst)
    free (dst_temp);
  errno = rename_errno;
  return ret_val;
  }
#else /* !HAVE_RENAMEAT */

  /* RENAME_NOREPLACE is the only flag currently supported.  */
  if (flags & ~RENAME_NOREPLACE)
    return errno_fail (ENOTSUP);
  return at_func2 (fd1, src, fd2, dst, flags ? rename_noreplace : rename);

#endif /* !HAVE_RENAMEAT */
}
