From: Bruno Haible Date: Sat, 24 Aug 2024 18:52:28 +0000 (+0200) Subject: copy-file: Add functions for copying non-confidential files. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=3fef5edc95b855a4ea3326926c69641b2fe205b3;p=gnulib.git copy-file: Add functions for copying non-confidential files. Reported by Patrice Dumas in . * 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. --- diff --git a/ChangeLog b/ChangeLog index 7aff116c4d..dd0b9a5d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2024-08-24 Bruno Haible + + copy-file: Add functions for copying non-confidential files. + Reported by Patrice Dumas in + . + * 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 copy-file: First step towards more consistent function names. diff --git a/lib/copy-file.c b/lib/copy-file.c index 13fb0fe2e3..60d913e181 100644 --- a/lib/copy-file.c +++ b/lib/copy-file.c @@ -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); +} diff --git a/lib/copy-file.h b/lib/copy-file.h index cc096c49fe..3f5aa72d0f 100644 --- a/lib/copy-file.h +++ b/lib/copy-file.h @@ -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