]> Savannah Git Hosting - gnulib.git/commitdiff
copy-file: Add functions for copying non-confidential files.
authorBruno Haible <bruno@clisp.org>
Sat, 24 Aug 2024 18:52:28 +0000 (20:52 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 24 Aug 2024 20:45:38 +0000 (22:45 +0200)
Reported by Patrice Dumas <pertusus@free.fr> in
<https://lists.gnu.org/archive/html/bug-gnulib/2024-08/msg00142.html>.

* lib/copy-file.h (copy_file_to, xcopy_file_to): New declarations.
* lib/copy-file.c (copy_file_internal): New function, extracted from
qcopy_file_preserving.
(qcopy_file_preserving): Invoke it.
(copy_file_to): New function.
(handle_error_code): New function, extracted from xcopy_file_preserving.
(xcopy_file_preserving): Invoke it.
(xcopy_file_to): New function.

ChangeLog
lib/copy-file.c
lib/copy-file.h

index 7aff116c4d0df1e72eb129d28ebd71d7c80b21c8..dd0b9a5d2fdd9ec965996df6e40391cd553bc5dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-08-24  Bruno Haible  <bruno@clisp.org>
+
+       copy-file: Add functions for copying non-confidential files.
+       Reported by Patrice Dumas <pertusus@free.fr> in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2024-08/msg00142.html>.
+       * lib/copy-file.h (copy_file_to, xcopy_file_to): New declarations.
+       * lib/copy-file.c (copy_file_internal): New function, extracted from
+       qcopy_file_preserving.
+       (qcopy_file_preserving): Invoke it.
+       (copy_file_to): New function.
+       (handle_error_code): New function, extracted from xcopy_file_preserving.
+       (xcopy_file_preserving): Invoke it.
+       (xcopy_file_to): New function.
+
 2024-08-24  Bruno Haible  <bruno@clisp.org>
 
        copy-file: First step towards more consistent function names.
index 13fb0fe2e39b39dbc2a66a88634c156b9cb050a9..60d913e181a952b3348280e07569d1e571ac818b 100644 (file)
@@ -43,8 +43,9 @@
 
 enum { IO_SIZE = 32 * 1024 };
 
-int
-qcopy_file_preserving (const char *src_filename, const char *dest_filename)
+static int
+copy_file_internal (const char *src_filename, const char *dest_filename,
+                    bool preserve)
 {
   int err = 0;
   int src_fd;
@@ -67,7 +68,11 @@ qcopy_file_preserving (const char *src_filename, const char *dest_filename)
 
   dest_fd = open (dest_filename,
                   O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC,
-                  0600);
+                  /* If preserve is true, we must assume that the file may
+                     have confidential contents.  Therefore open it with mode
+                     0600 and assign the permissions at the end.
+                     If preserve is false, open it with mode 0666 & ~umask.  */
+                  preserve ? 0600 : 0666);
   if (dest_fd < 0)
     {
       err = GL_COPY_ERR_OPEN_BACKUP_WRITE;
@@ -132,34 +137,37 @@ qcopy_file_preserving (const char *src_filename, const char *dest_filename)
     return GL_COPY_ERR_AFTER_READ;
 #endif
 
-  /* Preserve the access and modification times.  */
-  {
-    struct timespec ts[2];
+  if (preserve)
+    {
+      /* Preserve the access and modification times.  */
+      {
+        struct timespec ts[2];
 
-    ts[0] = get_stat_atime (&statbuf);
-    ts[1] = get_stat_mtime (&statbuf);
-    utimens (dest_filename, ts);
-  }
+        ts[0] = get_stat_atime (&statbuf);
+        ts[1] = get_stat_mtime (&statbuf);
+        utimens (dest_filename, ts);
+      }
 
 #if HAVE_CHOWN
-  /* Preserve the owner and group.  */
-  ignore_value (chown (dest_filename, statbuf.st_uid, statbuf.st_gid));
+      /* Preserve the owner and group.  */
+      ignore_value (chown (dest_filename, statbuf.st_uid, statbuf.st_gid));
 #endif
 
-  /* Preserve the access permissions.  */
+      /* Preserve the access permissions.  */
 #if USE_ACL
-  switch (qcopy_acl (src_filename, src_fd, dest_filename, dest_fd, mode))
-    {
-    case -2:
-      err = GL_COPY_ERR_GET_ACL;
-      goto error_src_dest;
-    case -1:
-      err = GL_COPY_ERR_SET_ACL;
-      goto error_src_dest;
-    }
+      switch (qcopy_acl (src_filename, src_fd, dest_filename, dest_fd, mode))
+        {
+        case -2:
+          err = GL_COPY_ERR_GET_ACL;
+          goto error_src_dest;
+        case -1:
+          err = GL_COPY_ERR_SET_ACL;
+          goto error_src_dest;
+        }
 #else
-  chmod (dest_filename, mode);
+      chmod (dest_filename, mode);
 #endif
+    }
 
 #if USE_ACL
   if (close (dest_fd) < 0)
@@ -180,10 +188,22 @@ qcopy_file_preserving (const char *src_filename, const char *dest_filename)
   return err;
 }
 
-void
-xcopy_file_preserving (const char *src_filename, const char *dest_filename)
+int
+qcopy_file_preserving (const char *src_filename, const char *dest_filename)
+{
+  return copy_file_internal (src_filename, dest_filename, true);
+}
+
+int
+copy_file_to (const char *src_filename, const char *dest_filename)
 {
-  switch (qcopy_file_preserving (src_filename, dest_filename))
+  return copy_file_internal (src_filename, dest_filename, false);
+}
+
+static void
+handle_error_code (int err, const char *src_filename, const char *dest_filename)
+{
+  switch (err)
     {
     case 0:
       return;
@@ -220,8 +240,22 @@ xcopy_file_preserving (const char *src_filename, const char *dest_filename)
     }
 }
 
+void
+xcopy_file_preserving (const char *src_filename, const char *dest_filename)
+{
+  int err = qcopy_file_preserving (src_filename, dest_filename);
+  handle_error_code (err, src_filename, dest_filename);
+}
+
 void
 copy_file_preserving (const char *src_filename, const char *dest_filename)
 {
   xcopy_file_preserving (src_filename, dest_filename);
 }
+
+void
+xcopy_file_to (const char *src_filename, const char *dest_filename)
+{
+  int err = copy_file_to (src_filename, dest_filename);
+  handle_error_code (err, src_filename, dest_filename);
+}
index cc096c49fe8a56fb74ea0d6ffb565d14f9b4daef..3f5aa72d0ff47e0e9c325c97bafe12232aab772c 100644 (file)
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 
-/* Error codes returned by qcopy_file_preserving.  */
+/* Error codes returned by qcopy_file_preserving or copy_file_to.  */
 enum
 {
   GL_COPY_ERR_OPEN_READ = -1,
@@ -38,10 +38,11 @@ enum
   GL_COPY_ERR_SET_ACL = -7
 };
 
+
 /* Copy a regular file: from src_filename to dest_filename.
    The destination file is assumed to be a backup file.
    Modification times, owner, group and access permissions are preserved as
-   far as possible.
+   far as possible (similarly to what 'cp -p SRC DEST' would do).
    Return 0 if successful, otherwise set errno and return one of the error
    codes above.  */
 extern int qcopy_file_preserving (const char *src_filename, const char *dest_filename);
@@ -49,7 +50,7 @@ extern int qcopy_file_preserving (const char *src_filename, const char *dest_fil
 /* Copy a regular file: from src_filename to dest_filename.
    The destination file is assumed to be a backup file.
    Modification times, owner, group and access permissions are preserved as
-   far as possible.
+   far as possible (similarly to what 'cp -p SRC DEST' would do).
    Exit upon failure.  */
 extern void xcopy_file_preserving (const char *src_filename, const char *dest_filename);
 
@@ -57,6 +58,26 @@ extern void xcopy_file_preserving (const char *src_filename, const char *dest_fi
 _GL_ATTRIBUTE_DEPRECATED void copy_file_preserving (const char *src_filename, const char *dest_filename);
 
 
+/* Copy a regular file: from src_filename to dest_filename.
+   The source file is assumed to be not confidential.
+   Modification times, owner, group and access permissions of src_filename
+   are *not* copied over to dest_filename (similarly to what 'cat SRC > DEST'
+   would do; if DEST already exists, this is the same as what 'cp SRC DEST'
+   would do.)
+   Return 0 if successful, otherwise set errno and return one of the error
+   codes above.  */
+extern int copy_file_to (const char *src_filename, const char *dest_filename);
+
+/* Copy a regular file: from src_filename to dest_filename.
+   The source file is assumed to be not confidential.
+   Modification times, owner, group and access permissions of src_filename
+   are *not* copied over to dest_filename (similarly to what 'cat SRC > DEST'
+   would do; if DEST already exists, this is the same as what 'cp SRC DEST'
+   would do.)
+   Exit upon failure.  */
+extern void xcopy_file_to (const char *src_filename, const char *dest_filename);
+
+
 #ifdef __cplusplus
 }
 #endif