git: fc43a1b6842a - stable/14 - tzsetup: symlink /etc/localtime instead of copying
Date: Thu, 01 Aug 2024 15:38:19 UTC
The branch stable/14 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=fc43a1b6842afa806dfd7ba48de5bece63d04456 commit fc43a1b6842afa806dfd7ba48de5bece63d04456 Author: Ed Maste <emaste@FreeBSD.org> AuthorDate: 2022-10-14 16:44:35 +0000 Commit: Ed Maste <emaste@FreeBSD.org> CommitDate: 2024-08-01 15:11:45 +0000 tzsetup: symlink /etc/localtime instead of copying Using a symlink means that new timezone data (installed by an errata update, say) will be usable without having to be copied again. Reviewed by: bapt, kevans, philip Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D37005 (cherry picked from commit 5e16809c953f4cd19fadb1767469dec319de0353) --- usr.sbin/tzsetup/tzsetup.8 | 2 +- usr.sbin/tzsetup/tzsetup.c | 119 ++++++++++----------------------------------- 2 files changed, 27 insertions(+), 94 deletions(-) diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8 index bfa625a1af3a..499d25765541 100644 --- a/usr.sbin/tzsetup/tzsetup.8 +++ b/usr.sbin/tzsetup/tzsetup.8 @@ -52,7 +52,7 @@ The following options are available: Open all files and directories relative to .Ar chroot_directory . .It Fl n -Do not create or copy files. +Do not create or symlink files. .It Fl r Reinstall the zoneinfo file installed last time. The name is obtained from diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index 6cd2e16b607c..617de4efb765 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -744,109 +744,42 @@ static void message_zoneinfo_file(const char *title, char *prompt) static int install_zoneinfo_file(const char *zoneinfo_file) { - char buf[1024]; char prompt[SILLY_BUFFER_SIZE]; - struct stat sb; - ssize_t len; - int fd1, fd2, copymode; - - if (lstat(path_localtime, &sb) < 0) { - /* Nothing there yet... */ - copymode = 1; - } else if (S_ISLNK(sb.st_mode)) - copymode = 0; - else - copymode = 1; #ifdef VERBOSE - if (copymode) - snprintf(prompt, sizeof(prompt), - "Copying %s to %s", zoneinfo_file, path_localtime); - else - snprintf(prompt, sizeof(prompt), - "Creating symbolic link %s to %s", - path_localtime, zoneinfo_file); + snprintf(prompt, sizeof(prompt), "Creating symbolic link %s to %s", + path_localtime, zoneinfo_file); message_zoneinfo_file("Info", prompt); #endif if (reallydoit) { - if (copymode) { - fd1 = open(zoneinfo_file, O_RDONLY, 0); - if (fd1 < 0) { - snprintf(prompt, sizeof(prompt), - "Could not open %s: %s", zoneinfo_file, - strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - if (unlink(path_localtime) < 0 && errno != ENOENT) { - snprintf(prompt, sizeof(prompt), - "Could not delete %s: %s", - path_localtime, strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY, - S_IRUSR | S_IRGRP | S_IROTH); - if (fd2 < 0) { - snprintf(prompt, sizeof(prompt), - "Could not open %s: %s", - path_localtime, strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - while ((len = read(fd1, buf, sizeof(buf))) > 0) - if ((len = write(fd2, buf, len)) < 0) - break; - - if (len == -1) { - snprintf(prompt, sizeof(prompt), - "Error copying %s to %s %s", zoneinfo_file, - path_localtime, strerror(errno)); - message_zoneinfo_file("Error", prompt); - /* Better to leave none than a corrupt one. */ - unlink(path_localtime); - return (DITEM_FAILURE | DITEM_RECREATE); - } - close(fd1); - close(fd2); - } else { - if (access(zoneinfo_file, R_OK) != 0) { - snprintf(prompt, sizeof(prompt), - "Cannot access %s: %s", zoneinfo_file, - strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - if (unlink(path_localtime) < 0 && errno != ENOENT) { - snprintf(prompt, sizeof(prompt), - "Could not delete %s: %s", - path_localtime, strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - if (symlink(zoneinfo_file, path_localtime) < 0) { - snprintf(prompt, sizeof(prompt), - "Cannot create symbolic link %s to %s: %s", - path_localtime, zoneinfo_file, - strerror(errno)); - message_zoneinfo_file("Error", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } + if (access(zoneinfo_file, R_OK) != 0) { + snprintf(prompt, sizeof(prompt), + "Cannot access %s: %s", zoneinfo_file, + strerror(errno)); + message_zoneinfo_file("Error", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); } - -#ifdef VERBOSE - if (copymode) + if (unlink(path_localtime) < 0 && errno != ENOENT) { snprintf(prompt, sizeof(prompt), - "Copied timezone file from %s to %s", - zoneinfo_file, path_localtime); - else + "Could not delete %s: %s", + path_localtime, strerror(errno)); + message_zoneinfo_file("Error", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + if (symlink(zoneinfo_file, path_localtime) < 0) { snprintf(prompt, sizeof(prompt), - "Created symbolic link from %s to %s", - zoneinfo_file, path_localtime); + "Cannot create symbolic link %s to %s: %s", + path_localtime, zoneinfo_file, + strerror(errno)); + message_zoneinfo_file("Error", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + +#ifdef VERBOSE + snprintf(prompt, sizeof(prompt), + "Created symbolic link from %s to %s", zoneinfo_file, + path_localtime); message_zoneinfo_file("Done", prompt); #endif } /* reallydoit */