aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2022-10-14 16:44:35 +0000
committerEd Maste <emaste@FreeBSD.org>2023-11-24 02:13:49 +0000
commit5e16809c953f4cd19fadb1767469dec319de0353 (patch)
treefccf91123bb9fc6721630181130bf0a81cc79787
parentc4dacfa7f4b82f23ec0924d9db772860b2066f9b (diff)
downloadsrc-5e16809c953f4cd19fadb1767469dec319de0353.tar.gz
src-5e16809c953f4cd19fadb1767469dec319de0353.zip
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
-rw-r--r--usr.sbin/tzsetup/tzsetup.82
-rw-r--r--usr.sbin/tzsetup/tzsetup.c119
2 files changed, 27 insertions, 94 deletions
diff --git a/usr.sbin/tzsetup/tzsetup.8 b/usr.sbin/tzsetup/tzsetup.8
index 109a52beb164..60461363da9a 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 f6440a0ea736..9610023ec3ea 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 */