From: bg@nada.kth.se
Subject: (none)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Fri, 10 Apr 1992 19:09:49 GMT

A few enhancements and bugfixes to fileutils-3.2,
se the ChangeLog for more information.

*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:21 1992
--- ChangeLog	Fri Apr 10 16:28:44 1992
***************
*** 1,3 ****
--- 1,19 ----
+ Fri Apr 10 16:13:44 1992  Bjorn Gronvall  (bg at bg.nada.kth.se)
+ 
+ 	* install.c (get_ids): Use deafult creator/group of file when
+ 	not -g or -o option used. This is not the same as using	the
+ 	effective uid and gid!
+ 
+ 	* cp.c (copy_reg) install.c mv.c New file lib/copyreg.c:
+ 	The copy_reg function was moved from cp.c into libfu for
+ 	the benefit of mv and install.
+ 
+ 	* mv.c (copy): Added option --chown-verbose (-c). Useful for
+ 	sysops who have to know when chown fails.
+ 
+ 	* cp.c (copy, re_protect): Added option --chown-verbose (-c)
+ 	and -archive-preserve (-A) which is a synonym for -dcpR.
+ 
  Wed Apr  1 16:00:08 1992  David J. MacKenzie  (djm@wookumz.gnu.ai.mit.edu)
  
  	* Version 3.2.
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:22 1992
--- lib/Makefile.in	Tue Apr  7 21:23:17 1992
***************
*** 21,27 ****
  srcdir = @srcdir@/lib
  @VPATH@
  
! SOURCES = argmatch.c backupfile.c basename.c dirname.c eaccess.c \
  error.c filemode.c fsusage.c getopt.c getopt1.c \
  getversion.c idcache.c isdir.c makepath.c \
  modechange.c mountlist.c savedir.c \
--- 21,27 ----
  srcdir = @srcdir@/lib
  @VPATH@
  
! SOURCES = argmatch.c backupfile.c basename.c copyreg.c dirname.c eaccess.c \
  error.c filemode.c fsusage.c getopt.c getopt1.c \
  getversion.c idcache.c isdir.c makepath.c \
  modechange.c mountlist.c savedir.c \
***************
*** 30,36 ****
  fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
  strdup.c strstr.c
  
! OBJECTS = argmatch.o backupfile.o basename.o dirname.o eaccess.o \
  error.o filemode.o getopt.o getopt1.o \
  getversion.o idcache.o isdir.o makepath.o \
  modechange.o savedir.o \
--- 30,36 ----
  fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
  strdup.c strstr.c
  
! OBJECTS = argmatch.o backupfile.o basename.o copyreg.o dirname.o eaccess.o \
  error.o filemode.o getopt.o getopt1.o \
  getversion.o idcache.o isdir.o makepath.o \
  modechange.o savedir.o \
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:23 1992
--- lib/copyreg.c	Fri Apr 10 16:55:42 1992
***************
*** 0 ****
--- 1,202 ----
+ /* cp.c  -- file copying (main routines)
+    Copyright (C) 1989, 1990, 1991 Free Software Foundation.
+ 
+    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 2, 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+    Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
+ 
+ /* Copy a regular file from SRC_PATH to DST_PATH.
+    If the source file contains holes, copies holes and blocks of zeros
+    in the source file as holes in the target file.
+    (Holes are read as zeroes by the `read' system call.)
+    Return 0 if successful, 1 if an error occurred. */
+ 
+ #ifdef _AIX
+  #pragma alloca
+ #endif
+ 
+ #include "system.h"
+ 
+ int
+ copy_reg (src_path, dst_path)
+      char *src_path;
+      char *dst_path;
+ {
+   char *buf;
+   int buf_size;
+   int target_desc;
+   int source_desc;
+   int n_read;
+   int n_written;
+   struct stat sb;
+   char *cp;
+   int *ip;
+   int return_val = 0;
+   long n_read_total = 0;
+   int last_write_made_hole = 0;
+   int make_holes = 0;
+ 
+   source_desc = open (src_path, O_RDONLY);
+   if (source_desc < 0)
+     {
+       error (0, errno, "%s", src_path);
+       return 1;
+     }
+ 
+   /* Create the new regular file with small permissions initially,
+      to not create a security hole.  */
+ 
+   target_desc = open (dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+   if (target_desc < 0)
+     {
+       error (0, errno, "cannot create regular file `%s'", dst_path);
+       return_val = 1;
+       goto ret2;
+     }
+ 
+   /* Find out the optimal buffer size.  */
+ 
+   if (fstat (target_desc, &sb))
+     {
+       error (0, errno, "%s", dst_path);
+       return_val = 1;
+       goto ret;
+     }
+ 
+   buf_size = ST_BLKSIZE (sb);
+ 
+ #ifndef ST_BLOCKS_MISSING
+   if (S_ISREG (sb.st_mode))
+     {
+       /* Find out whether the file contains any sparse blocks. */
+ 
+       if (fstat (source_desc, &sb))
+ 	{
+ 	  error (0, errno, "%s", src_path);
+ 	  return_val = 1;
+ 	  goto ret;
+ 	}
+ 
+       /* If the file has fewer blocks than would normally
+ 	 be needed for a file of its size, then
+ 	 at least one of the blocks in the file is a hole. */
+       if (S_ISREG (sb.st_mode) &&
+ 	  sb.st_size - (sb.st_blocks * DEV_BSIZE) >= DEV_BSIZE)
+ 	make_holes = 1;
+     }
+ #endif
+ 
+   /* Make a buffer with space for a sentinel at the end.  */
+ 
+   buf = (char *) alloca (buf_size + sizeof (int));
+ 
+   for (;;)
+     {
+       n_read = read (source_desc, buf, buf_size);
+       if (n_read < 0)
+ 	{
+ 	  error (0, errno, "%s", src_path);
+ 	  return_val = 1;
+ 	  goto ret;
+ 	}
+       if (n_read == 0)
+ 	break;
+ 
+       n_read_total += n_read;
+ 
+       ip = 0;
+       if (make_holes)
+ 	{
+ 	  buf[n_read] = 1;	/* Sentinel to stop loop.  */
+ 
+ 	  /* Find first non-zero *word*, or the word with the sentinel.  */
+ 
+ 	  ip = (int *) buf;
+ 	  while (*ip++ == 0)
+ 	    ;
+ 
+ 	  /* Find the first non-zero *byte*, or the sentinel.  */
+ 
+ 	  cp = (char *) (ip - 1);
+ 	  while (*cp++ == 0)
+ 	    ;
+ 
+ 	  /* If we found the sentinel, the whole input block was zero,
+ 	     and we can make a hole.  */
+ 
+ 	  if (cp > buf + n_read)
+ 	    {
+ 	      /* Make a hole.  */
+ 	      if (lseek (target_desc, (off_t) n_read, SEEK_CUR) < 0L)
+ 		{
+ 		  error (0, errno, "%s", dst_path);
+ 		  return_val = 1;
+ 		  goto ret;
+ 		}
+ 	      last_write_made_hole = 1;
+ 	    }
+ 	  else
+ 	    /* Clear to indicate that a normal write is needed. */
+ 	    ip = 0;
+ 	}
+       if (ip == 0)
+ 	{
+ 	  n_written = write (target_desc, buf, n_read);
+ 	  if (n_written < n_read)
+ 	    {
+ 	      error (0, errno, "%s", dst_path);
+ 	      return_val = 1;
+ 	      goto ret;
+ 	    }
+ 	  last_write_made_hole = 0;
+ 	}
+     }
+ 
+   /* If the file ends with a `hole', something needs to be written at
+      the end.  Otherwise the kernel would truncate the file at the end
+      of the last write operation.  */
+ 
+   if (last_write_made_hole)
+     {
+ #ifndef FTRUNCATE_MISSING
+       /* Write a null character and truncate it again.  */
+       if (write (target_desc, "", 1) != 1
+ 	  || ftruncate (target_desc, n_read_total) < 0)
+ #else
+       /* Seek backwards one character and write a null.  */
+       if (lseek (target_desc, (off_t) -1, SEEK_CUR) < 0L
+ 	  || write (target_desc, "", 1) != 1)
+ #endif
+ 	{
+ 	  error (0, errno, "%s", dst_path);
+ 	  return_val = 1;
+ 	}
+     }
+ 
+ ret:
+   if (close (target_desc) < 0)
+     {
+       error (0, errno, "%s", dst_path);
+       return_val = 1;
+     }
+ ret2:
+   if (close (source_desc) < 0)
+     {
+       error (0, errno, "%s", src_path);
+       return_val = 1;
+     }
+ 
+   return return_val;
+ }
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:24 1992
--- man/cp.1	Fri Apr 10 15:58:19 1992
***************
*** 10,21 ****
  .br
  Options:
  .br
! [\-abdfilprsuvxPR] [\-S backup-suffix] [\-V {numbered,existing,simple}]
  [\-\-backup] [\-\-no-dereference] [\-\-force] [\-\-interactive]
  [\-\-one-file-system] [\-\-preserve] [\-\-recursive] [\-\-update]
  [\-\-verbose] [\-\-suffix=backup-suffix]
! [\-\-version-control={numbered,existing,simple}] [\-\-archive] [\-\-path]
! [\-\-link] [\-\-symbolic-link]
  .SH DESCRIPTION
  This manual page
  documents the GNU version of
--- 10,22 ----
  .br
  Options:
  .br
! [\-abcdfilprsuvxAPR] [\-S backup-suffix] [\-V {numbered,existing,simple}]
  [\-\-backup] [\-\-no-dereference] [\-\-force] [\-\-interactive]
  [\-\-one-file-system] [\-\-preserve] [\-\-recursive] [\-\-update]
  [\-\-verbose] [\-\-suffix=backup-suffix]
! [\-\-version-control={numbered,existing,simple}] 
! [\-\-archive] [\-\-archive-preserve] [\-\-path]
! [\-\-link] [\-\-symbolic-link] [\-\-chown-verbose]
  .SH DESCRIPTION
  This manual page
  documents the GNU version of
***************
*** 31,41 ****
  .TP
  .I "\-a, \-\-archive"
  Preserve as much as possible of the structure and attributes of the
  original files in the copy.  The same as
! .IR \-dpR .
  .TP
  .I "\-b, \-\-backup"
  Make backups of files that are about to be overwritten or removed.
  .TP
  .I "\-d, \-\-no-dereference"
  Copy symbolic links as symbolic links rather than copying the files
--- 32,52 ----
  .TP
  .I "\-a, \-\-archive"
  Preserve as much as possible of the structure and attributes of the
+ original files in the copy.  Similar to
+ .IR \-A 
+ but don't report when preservation of owner and/or group fails.
+ .TP
+ .I "\-A, \-\-archive-preserve"
+ Preserve the structure and attributes of the
  original files in the copy.  The same as
! .IR \-dpRc .
  .TP
  .I "\-b, \-\-backup"
  Make backups of files that are about to be overwritten or removed.
+ .TP
+ .I "\-c, \-\-chown-verbose"
+ Report when chown fails to change owner and/or group.
+ Useful for system administrators.
  .TP
  .I "\-d, \-\-no-dereference"
  Copy symbolic links as symbolic links rather than copying the files
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:27 1992
--- man/mv.1	Fri Apr 10 15:59:33 1992
***************
*** 10,18 ****
  .br
  Options:
  .br
! [\-bfiuv] [\-S backup-suffix] [\-V {numbered,existing,simple}]
  [\-\-backup] [\-\-force] [\-\-interactive] [\-\-update] [\-\-verbose]
  [\-\-suffix=backup-suffix] [\-\-version-control={numbered,existing,simple}]
  .SH DESCRIPTION
  This manual page
  documents the GNU version of
--- 10,19 ----
  .br
  Options:
  .br
! [\-bcfiuv] [\-S backup-suffix] [\-V {numbered,existing,simple}]
  [\-\-backup] [\-\-force] [\-\-interactive] [\-\-update] [\-\-verbose]
  [\-\-suffix=backup-suffix] [\-\-version-control={numbered,existing,simple}]
+ [\-\-chown-verbose]
  .SH DESCRIPTION
  This manual page
  documents the GNU version of
***************
*** 36,43 ****
  .I "\-b, \-\-backup"
  Make backups of files that are about to be removed.
  .TP
! .I "\-f, \-\-force"
! Remove existing destination files and never prompt the user.
  .TP
  .I "\-i, \-\-interactive"
  Prompt whether to overwrite each destination file that already
--- 37,45 ----
  .I "\-b, \-\-backup"
  Make backups of files that are about to be removed.
  .TP
! .I "\-c, \-\-chown-verbose"
! Report when chown fails to change owner and/or group.
! Useful for system administrators.
  .TP
  .I "\-i, \-\-interactive"
  Prompt whether to overwrite each destination file that already
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:28 1992
--- src/cp-aux.c	Fri Apr 10 16:11:58 1992
***************
*** 34,44 ****
  Usage: %s [options] source dest\n\
         %s [options] source... directory\n\
  Options:\n\
!        [-abdfilprsuvxPR] [-S backup-suffix] [-V {numbered,existing,simple}]\n\
         [--backup] [--no-dereference] [--force] [--interactive]\n\
         [--one-file-system] [--preserve] [--recursive] [--update] [--verbose]\n\
         [--suffix=backup-suffix] [--version-control={numbered,existing,simple}]\n\
!        [--archive] [--path] [--link] [--symbolic-link]\n",
  	   program_name, program_name);
  
    exit (2);
--- 34,45 ----
  Usage: %s [options] source dest\n\
         %s [options] source... directory\n\
  Options:\n\
!        [-abcdfilprsuvxAPR] [-S backup-suffix] [-V {numbered,existing,simple}]\n\
         [--backup] [--no-dereference] [--force] [--interactive]\n\
         [--one-file-system] [--preserve] [--recursive] [--update] [--verbose]\n\
         [--suffix=backup-suffix] [--version-control={numbered,existing,simple}]\n\
!        [--archive] [--archive-preserve] [--path] [--link] [--symbolic-link] 
!        [--chown-verbose]\n",
  	   program_name, program_name);
  
    exit (2);
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:29 1992
--- src/cp.c	Wed Apr  8 16:40:46 1992
***************
*** 80,85 ****
--- 80,89 ----
     ownership, and timestamps. */
  int flag_preserve = 0;
  
+ /* If nonzero, report when chown fails
+    to change ownership and/or group. */
+ int chown_verbose = 0;
+ 
  /* If nonzero, copy directories recursively and copy special files
     as themselves rather than copying their contents. */
  int flag_recursive = 0;
***************
*** 108,114 ****
--- 112,120 ----
  struct option long_opts[] =
  {
    {"archive", 0, NULL, 'a'},
+   {"archive-preserve", 0, NULL, 'A'},
    {"backup", 0, NULL, 'b'},
+   {"chown-verbose", 0, NULL, 'c'},
    {"force", 0, NULL, 'f'},
    {"interactive", 0, NULL, 'i'},
    {"link", 0, NULL, 'l'},
***************
*** 148,154 ****
  
    umask_kill = 0777777 ^ umask (0);
  
!   while ((c = getopt_long (argc, argv, "abdfilprsuvxPRS:V:", long_opts,
  			   (int *) 0)) != EOF)
      {
        switch (c)
--- 154,160 ----
  
    umask_kill = 0777777 ^ umask (0);
  
!   while ((c = getopt_long (argc, argv, "abcdfilprsuvxAPRS:V:", long_opts,
  			   (int *) 0)) != EOF)
      {
        switch (c)
***************
*** 163,172 ****
--- 169,190 ----
  	  flag_copy_as_regular = 0;
  	  break;
  
+ 	case 'A':		/* Like -dcpR. */
+ 	  flag_dereference = 0;
+ 	  flag_preserve = 1;
+ 	  flag_recursive = 1;
+ 	  flag_copy_as_regular = 0;
+ 	  chown_verbose = 1;
+ 	  break;
+ 
  	case 'b':
  	  make_backups = 1;
  	  break;
  
+ 	case 'c':
+ 	  chown_verbose = 1;
+ 	  break;
+ 
  	case 'd':
  	  flag_dereference = 0;
  	  break;
***************
*** 749,757 ****
  	  return 1;
  	}
  
!       if (chown (dst_path, src_sb.st_uid, src_sb.st_gid) && errno != EPERM)
  	{
! 	  error (0, errno, "%s", dst_path);
  	  return 1;
  	}
      }
--- 767,775 ----
  	  return 1;
  	}
  
!       if (chown (dst_path, src_sb.st_uid, src_sb.st_gid) && chown_verbose)
  	{
! 	  error (0, errno, "chown %s", dst_path);
  	  return 1;
  	}
      }
***************
*** 960,968 ****
  	      return 1;
  	    }
  
! 	  if (chown (dst_path, src_sb.st_uid, src_sb.st_gid) && errno != EPERM)
  	    {
! 	      error (0, errno, "%s", dst_path);
  	      return 1;
  	    }
  	}
--- 978,986 ----
  	      return 1;
  	    }
  
! 	  if (chown (dst_path, src_sb.st_uid, src_sb.st_gid) && chown_verbose)
  	    {
! 	      error (0, errno, "chown %s", dst_path);
  	      return 1;
  	    }
  	}
***************
*** 1028,1209 ****
      }
    free (name_space);
    return -ret;
- }
- 
- /* Copy a regular file from SRC_PATH to DST_PATH.
-    If the source file contains holes, copies holes and blocks of zeros
-    in the source file as holes in the target file.
-    (Holes are read as zeroes by the `read' system call.)
-    Return 0 if successful, -1 if an error occurred. */
- 
- int
- copy_reg (src_path, dst_path)
-      char *src_path;
-      char *dst_path;
- {
-   char *buf;
-   int buf_size;
-   int target_desc;
-   int source_desc;
-   int n_read;
-   int n_written;
-   struct stat sb;
-   char *cp;
-   int *ip;
-   int return_val = 0;
-   long n_read_total = 0;
-   int last_write_made_hole = 0;
-   int make_holes = 0;
- 
-   source_desc = open (src_path, O_RDONLY);
-   if (source_desc < 0)
-     {
-       error (0, errno, "%s", src_path);
-       return -1;
-     }
- 
-   /* Create the new regular file with small permissions initially,
-      to not create a security hole.  */
- 
-   target_desc = open (dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-   if (target_desc < 0)
-     {
-       error (0, errno, "cannot create regular file `%s'", dst_path);
-       return_val = -1;
-       goto ret2;
-     }
- 
-   /* Find out the optimal buffer size.  */
- 
-   if (fstat (target_desc, &sb))
-     {
-       error (0, errno, "%s", dst_path);
-       return_val = -1;
-       goto ret;
-     }
- 
-   buf_size = ST_BLKSIZE (sb);
- 
- #ifndef ST_BLOCKS_MISSING
-   if (S_ISREG (sb.st_mode))
-     {
-       /* Find out whether the file contains any sparse blocks. */
- 
-       if (fstat (source_desc, &sb))
- 	{
- 	  error (0, errno, "%s", src_path);
- 	  return_val = -1;
- 	  goto ret;
- 	}
- 
-       /* If the file has fewer blocks than would normally
- 	 be needed for a file of its size, then
- 	 at least one of the blocks in the file is a hole. */
-       if (S_ISREG (sb.st_mode) &&
- 	  sb.st_size - (sb.st_blocks * DEV_BSIZE) >= DEV_BSIZE)
- 	make_holes = 1;
-     }
- #endif
- 
-   /* Make a buffer with space for a sentinel at the end.  */
- 
-   buf = (char *) alloca (buf_size + sizeof (int));
- 
-   for (;;)
-     {
-       n_read = read (source_desc, buf, buf_size);
-       if (n_read < 0)
- 	{
- 	  error (0, errno, "%s", src_path);
- 	  return_val = -1;
- 	  goto ret;
- 	}
-       if (n_read == 0)
- 	break;
- 
-       n_read_total += n_read;
- 
-       ip = 0;
-       if (make_holes)
- 	{
- 	  buf[n_read] = 1;	/* Sentinel to stop loop.  */
- 
- 	  /* Find first non-zero *word*, or the word with the sentinel.  */
- 
- 	  ip = (int *) buf;
- 	  while (*ip++ == 0)
- 	    ;
- 
- 	  /* Find the first non-zero *byte*, or the sentinel.  */
- 
- 	  cp = (char *) (ip - 1);
- 	  while (*cp++ == 0)
- 	    ;
- 
- 	  /* If we found the sentinel, the whole input block was zero,
- 	     and we can make a hole.  */
- 
- 	  if (cp > buf + n_read)
- 	    {
- 	      /* Make a hole.  */
- 	      if (lseek (target_desc, (off_t) n_read, SEEK_CUR) < 0L)
- 		{
- 		  error (0, errno, "%s", dst_path);
- 		  return_val = -1;
- 		  goto ret;
- 		}
- 	      last_write_made_hole = 1;
- 	    }
- 	  else
- 	    /* Clear to indicate that a normal write is needed. */
- 	    ip = 0;
- 	}
-       if (ip == 0)
- 	{
- 	  n_written = write (target_desc, buf, n_read);
- 	  if (n_written < n_read)
- 	    {
- 	      error (0, errno, "%s", dst_path);
- 	      return_val = -1;
- 	      goto ret;
- 	    }
- 	  last_write_made_hole = 0;
- 	}
-     }
- 
-   /* If the file ends with a `hole', something needs to be written at
-      the end.  Otherwise the kernel would truncate the file at the end
-      of the last write operation.  */
- 
-   if (last_write_made_hole)
-     {
- #ifndef FTRUNCATE_MISSING
-       /* Write a null character and truncate it again.  */
-       if (write (target_desc, "", 1) != 1
- 	  || ftruncate (target_desc, n_read_total) < 0)
- #else
-       /* Seek backwards one character and write a null.  */
-       if (lseek (target_desc, (off_t) -1, SEEK_CUR) < 0L
- 	  || write (target_desc, "", 1) != 1)
- #endif
- 	{
- 	  error (0, errno, "%s", dst_path);
- 	  return_val = -1;
- 	}
-     }
- 
- ret:
-   if (close (target_desc) < 0)
-     {
-       error (0, errno, "%s", dst_path);
-       return_val = -1;
-     }
- ret2:
-   if (close (source_desc) < 0)
-     {
-       error (0, errno, "%s", src_path);
-       return_val = -1;
-     }
- 
-   return return_val;
  }
--- 1046,1049 ----
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:32 1992
--- src/install.c	Thu Apr  9 10:32:57 1992
***************
*** 267,275 ****
    return ret;
  }
  
- /* A chunk of a file being copied. */
- static char buffer[READ_SIZE];
- 
  /* Copy file FROM onto file TO, creating TO if necessary.
     Return 0 if the copy is successful, 1 if not. */
  
--- 267,272 ----
***************
*** 310,360 ****
        unlink (to);
      }
  
!   fromfd = open (from, O_RDONLY, 0);
!   if (fromfd == -1)
!     {
!       error (0, errno, "%s", from);
!       return 1;
!     }
! 
!   /* Make sure to open the file in a mode that allows writing. */
!   tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC, 0600);
!   if (tofd == -1)
!     {
!       error (0, errno, "%s", to);
!       close (fromfd);
!       return 1;
!     }
! 
!   while ((bytes = read (fromfd, buffer, READ_SIZE)) > 0)
!     if (write (tofd, buffer, bytes) != bytes)
!       {
! 	error (0, errno, "%s", to);
! 	goto copy_error;
!       }
! 
!   if (bytes == -1)
!     {
!       error (0, errno, "%s", from);
!       goto copy_error;
!     }
! 
!   if (close (fromfd) < 0)
!     {
!       error (0, errno, "%s", from);
!       ret = 1;
!     }
!   if (close (tofd) < 0)
!     {
!       error (0, errno, "%s", to);
!       ret = 1;
!     }
!   return ret;
! 
!  copy_error:
!   close (fromfd);
!   close (tofd);
!   return 1;
  }
  
  /* Set the attributes of file or directory PATH.
--- 307,313 ----
        unlink (to);
      }
  
!   return copy_reg (from, to);
  }
  
  /* Set the attributes of file or directory PATH.
***************
*** 365,370 ****
--- 318,324 ----
       char *path;
  {
    int err = 0;
+   int ret_val = 0;
  
    /* chown must precede chmod because on some systems,
       chown clears the set[ug]id bits for non-superusers,
***************
*** 373,387 ****
       be able to chmod them.  So don't give files away.  */
  
    if (chown (path, owner_id, group_id))
!     err = errno;
    if (chmod (path, mode))
!     err = errno;
    if (err)
      {
!       error (0, err, "%s", path);
!       return 1;
      }
!   return 0;
  }
  
  /* Strip the symbol table from the file PATH.
--- 327,347 ----
       be able to chmod them.  So don't give files away.  */
  
    if (chown (path, owner_id, group_id))
!     {
!       err = errno;
!       ret_val = 1;
!     }
    if (chmod (path, mode))
!     {
!       error (0, err, "chmod %s", path);
!       ret_val = 1;
!     }
    if (err)
      {
!       error (0, err, "chown %s", path);
!       ret_val = 1;
      }
!   return ret_val;
  }
  
  /* Strip the symbol table from the file PATH.
***************
*** 436,442 ****
        endpwent ();
      }
    else
!     owner_id = getuid ();
  
    if (group_name)
      {
--- 396,402 ----
        endpwent ();
      }
    else
!     owner_id = -1;		/* Use default */
  
    if (group_name)
      {
***************
*** 452,458 ****
        endgrent ();
      }
    else
!     group_id = getgid ();
  }
  
  /* Return nonzero if STR is an ASCII representation of a nonzero
--- 412,418 ----
        endgrent ();
      }
    else
!     group_id = -1;		/* Use deafult */
  }
  
  /* Return nonzero if STR is an ASCII representation of a nonzero
*** /tmp/,RCSt1a01712	Fri Apr 10 16:59:33 1992
--- src/mv.c	Fri Apr 10 16:12:18 1992
***************
*** 16,21 ****
--- 16,23 ----
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
  /* Options:
+    -c, --chown-verbose	Report when chown fails to do it's work.
+ 
     -f, --force		Assume a 'y' answer to all questions it would
  			normally ask, and not ask the questions.
  
***************
*** 60,65 ****
--- 62,71 ----
  /* The name this program was run with. */
  char *program_name;
  
+ /* If nonzero, report when chown fails
+    to change ownership and/or group. */
+ int chown_verbose = 0;
+ 
  /* If nonzero, query the user before overwriting files. */
  int interactive;
  
***************
*** 80,85 ****
--- 86,92 ----
  struct option long_options[] =
  {
    {"backup", 0, NULL, 'b'},
+   {"chown-verbose", 0, NULL, 'c'},
    {"force", 0, NULL, 'f'},
    {"interactive", 0, NULL, 'i'},
    {"suffix", 1, NULL, 'S'},
***************
*** 107,113 ****
    interactive = override_mode = verbose = update = 0;
    errors = 0;
  
!   while ((c = getopt_long (argc, argv, "bfiuvS:V:", long_options, (int *) 0))
  	 != EOF)
      {
        switch (c)
--- 114,120 ----
    interactive = override_mode = verbose = update = 0;
    errors = 0;
  
!   while ((c = getopt_long (argc, argv, "bcfiuvS:V:", long_options, (int *) 0))
  	 != EOF)
      {
        switch (c)
***************
*** 117,122 ****
--- 124,132 ----
  	case 'b':
  	  make_backups = 1;
  	  break;
+ 	case 'c':
+ 	  chown_verbose = 1;
+ 	  break;
  	case 'f':
  	  interactive = 0;
  	  override_mode = 1;
***************
*** 312,321 ****
  copy (from, to)
       char *from, *to;
  {
!   int ifd;
!   int ofd;
!   char buf[1024 * 8];
!   int len;			/* Number of bytes read into `buf'. */
    
    if (!S_ISREG (from_stats.st_mode))
      {
--- 322,328 ----
  copy (from, to)
       char *from, *to;
  {
!   int err;
    
    if (!S_ISREG (from_stats.st_mode))
      {
***************
*** 330,407 ****
        return 1;
      }
  
!   ifd = open (from, O_RDONLY, 0);
!   if (ifd < 0)
!     {
!       error (0, errno, "%s", from);
!       return 1;
!     }
!   ofd = open (to, O_WRONLY | O_CREAT | O_TRUNC, 0600);
!   if (ofd < 0)
!     {
!       error (0, errno, "%s", to);
!       close (ifd);
!       return 1;
!     }
! #ifndef FCHMOD_MISSING
!   if (fchmod (ofd, from_stats.st_mode & 0777))
!     {
!       error (0, errno, "%s", to);
!       close (ifd);
!       close (ofd);
!       unlink (to);
!       return 1;
!     }
! #endif
!   
!   while ((len = read (ifd, buf, sizeof (buf))) > 0)
!     {
!       int wrote = 0;
!       char *bp = buf;
!       
!       do
! 	{
! 	  wrote = write (ofd, bp, len);
! 	  if (wrote < 0)
! 	    {
! 	      error (0, errno, "%s", to);
! 	      close (ifd);
! 	      close (ofd);
! 	      unlink (to);
! 	      return 1;
! 	    }
! 	  bp += wrote;
! 	  len -= wrote;
! 	} while (len > 0);
!     }
!   if (len < 0)
!     {
!       error (0, errno, "%s", from);
!       close (ifd);
!       close (ofd);
!       unlink (to);
!       return 1;
!     }
  
!   if (close (ifd) < 0)
!     {
!       error (0, errno, "%s", from);
!       close (ofd);
!       return 1;
!     }
!   if (close (ofd) < 0)
!     {
!       error (0, errno, "%s", to);
!       return 1;
!     }
!   
! #ifdef FCHMOD_MISSING
    if (chmod (to, from_stats.st_mode & 0777))
      {
        error (0, errno, "%s", to);
        return 1;
      }
- #endif
  
    /* Try to copy the old file's modtime and access time.  */
    {
--- 337,360 ----
        return 1;
      }
  
!   if (copy_reg (from, to))
!     return 1;
  
!   /* chown must precede chmod because on some systems,
!      chown clears the set[ug]id bits for non-superusers,
!      resulting in incorrect permissions.
!      Always attempt to do a chmod anyway so that the created
!      file is not left with to weird mode bits. */
! 
!   err = 0;
!   if (chown (to, from_stats.st_uid, from_stats.st_gid) < 0 && chown_verbose)
!     err = errno;
! 
    if (chmod (to, from_stats.st_mode & 0777))
      {
        error (0, errno, "%s", to);
        return 1;
      }
  
    /* Try to copy the old file's modtime and access time.  */
    {
***************
*** 416,423 ****
        }
    }
  
!   if (chown (to, from_stats.st_uid, from_stats.st_gid) < 0 && errno != EPERM)
!     error (0, errno, "%s", to);
  
    return 0;
  }
--- 369,379 ----
        }
    }
  
!   if (err)
!     {
!       error (0, err, "chmod %s", to);
!       return 1;
!     }
  
    return 0;
  }
***************
*** 429,437 ****
  Usage: %s [options] source dest\n\
         %s [options] source... directory\n\
  Options:\n\
!        [-bfiuv] [-S backup-suffix] [-V {numbered,existing,simple}]\n\
         [--backup] [--force] [--interactive] [--update] [--verbose]\n\
!        [--suffix=backup-suffix] [--version-control={numbered,existing,simple}]\n",
  	   program_name, program_name);
    exit (1);
  }
--- 385,394 ----
  Usage: %s [options] source dest\n\
         %s [options] source... directory\n\
  Options:\n\
!        [-bcfiuv] [-S backup-suffix] [-V {numbered,existing,simple}]\n\
         [--backup] [--force] [--interactive] [--update] [--verbose]\n\
!        [--suffix=backup-suffix] [--chown-verbose]\n\
!        [--version-control={numbered,existing,simple}]\n",
  	   program_name, program_name);
    exit (1);
  }

Newsgroups: gnu.utils.bug