Esempio n. 1
0
int
smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
{
    bfd_boolean exists;
    struct stat s;
    int ret = 0;

    exists = lstat (to, &s) == 0;

#if 1
    /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
       fail instead.  Also, chown is not present.  */

    if (exists)
        remove (to);

    ret = rename (from, to);
    if (ret != 0)
    {
        /* We have to clean up here.  */
        non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
        unlink (from);
    }
#else
    /* Use rename only if TO is not a symbolic link and has
       only one hard link, and we have permission to write to it.  */
    if (! exists
            || (!S_ISLNK (s.st_mode)
                && S_ISREG (s.st_mode)
                && (s.st_mode & S_IWUSR)
                && s.st_nlink == 1)
       )
    {
        ret = rename (from, to);
        if (ret == 0)
        {
            if (exists)
            {
                /* Try to preserve the permission bits and ownership of
                TO.  First get the mode right except for the setuid
                 bit.  Then change the ownership.  Then fix the setuid
                 bit.  We do the chmod before the chown because if the
                 chown succeeds, and we are a normal user, we won't be
                 able to do the chmod afterward.  We don't bother to
                 fix the setuid bit first because that might introduce
                 a fleeting security problem, and because the chown
                 will clear the setuid bit anyhow.  We only fix the
                 setuid bit if the chown succeeds, because we don't
                 want to introduce an unexpected setuid file owned by
                 the user running objcopy.  */
//         chmod (to, s.st_mode & 0777);
//         if (chown (to, s.st_uid, s.st_gid) >= 0)
//       chmod (to, s.st_mode & 07777);
            }
        }
        else
        {
            /* We have to clean up here.  */
            non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
            unlink (from);
        }
    }
    else
    {
        ret = simple_copy (from, to);
        if (ret != 0)
            non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));

        if (preserve_dates)
            set_times (to, &s);
        unlink (from);
    }
#endif /* _WIN32 && !__CYGWIN32__ */

    return ret;
}
Esempio n. 2
0
int
smart_rename (const char *from, const char *to, int preserve_dates)
{
  bfd_boolean exists;
  struct stat s;
  int ret = 0;

  exists = lstat (to, &s) == 0;

#if defined (_WIN32) && !defined (__CYGWIN32__)
  /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
     fail instead.  Also, chown is not present.  */

  if (exists)
    remove (to);

  ret = rename (from, to);
  if (ret != 0)
    {
      /* We have to clean up here.  */
      non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno));
      unlink (from);
    }
#else
  /* Use rename only if TO is not a symbolic link and has
     only one hard link, and we have permission to write to it.  */
  if (! exists
      || (!S_ISLNK (s.st_mode)
	  && S_ISREG (s.st_mode)
	  && (s.st_mode & S_IWUSR)
	  && s.st_nlink == 1)
      )
    {
      ret = rename (from, to);
      if (ret == 0)
	{
	  if (exists)
	    {
	      /* Try to preserve the permission bits of TO. Don't
	       * restore special bits. */
	      chmod (to, s.st_mode & 0777);
	    }
	}
      else
	{
	  /* We have to clean up here.  */
	  non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno));
	  unlink (from);
	}
    }
  else
    {
      ret = simple_copy (from, to);
      if (ret != 0)
	non_fatal (_("unable to copy file '%s' reason: %s"), to, strerror (errno));

      if (preserve_dates)
	set_times (to, &s);
      unlink (from);
    }
#endif /* _WIN32 && !__CYGWIN32__ */

  return ret;
}