mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
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
This commit is contained in:
parent
c4dacfa7f4
commit
5e16809c95
|
@ -52,7 +52,7 @@ The following options are available:
|
||||||
Open all files and directories relative to
|
Open all files and directories relative to
|
||||||
.Ar chroot_directory .
|
.Ar chroot_directory .
|
||||||
.It Fl n
|
.It Fl n
|
||||||
Do not create or copy files.
|
Do not create or symlink files.
|
||||||
.It Fl r
|
.It Fl r
|
||||||
Reinstall the zoneinfo file installed last time.
|
Reinstall the zoneinfo file installed last time.
|
||||||
The name is obtained from
|
The name is obtained from
|
||||||
|
|
|
@ -744,109 +744,42 @@ static void message_zoneinfo_file(const char *title, char *prompt)
|
||||||
static int
|
static int
|
||||||
install_zoneinfo_file(const char *zoneinfo_file)
|
install_zoneinfo_file(const char *zoneinfo_file)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
|
||||||
char prompt[SILLY_BUFFER_SIZE];
|
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
|
#ifdef VERBOSE
|
||||||
if (copymode)
|
snprintf(prompt, sizeof(prompt), "Creating symbolic link %s to %s",
|
||||||
snprintf(prompt, sizeof(prompt),
|
path_localtime, zoneinfo_file);
|
||||||
"Copying %s to %s", zoneinfo_file, path_localtime);
|
|
||||||
else
|
|
||||||
snprintf(prompt, sizeof(prompt),
|
|
||||||
"Creating symbolic link %s to %s",
|
|
||||||
path_localtime, zoneinfo_file);
|
|
||||||
message_zoneinfo_file("Info", prompt);
|
message_zoneinfo_file("Info", prompt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (reallydoit) {
|
if (reallydoit) {
|
||||||
if (copymode) {
|
if (access(zoneinfo_file, R_OK) != 0) {
|
||||||
fd1 = open(zoneinfo_file, O_RDONLY, 0);
|
snprintf(prompt, sizeof(prompt),
|
||||||
if (fd1 < 0) {
|
"Cannot access %s: %s", zoneinfo_file,
|
||||||
snprintf(prompt, sizeof(prompt),
|
strerror(errno));
|
||||||
"Could not open %s: %s", zoneinfo_file,
|
message_zoneinfo_file("Error", prompt);
|
||||||
strerror(errno));
|
return (DITEM_FAILURE | DITEM_RECREATE);
|
||||||
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",
|
||||||
if (unlink(path_localtime) < 0 && errno != ENOENT) {
|
path_localtime, strerror(errno));
|
||||||
snprintf(prompt, sizeof(prompt),
|
message_zoneinfo_file("Error", prompt);
|
||||||
"Could not delete %s: %s",
|
return (DITEM_FAILURE | DITEM_RECREATE);
|
||||||
path_localtime, strerror(errno));
|
}
|
||||||
message_zoneinfo_file("Error", prompt);
|
if (symlink(zoneinfo_file, path_localtime) < 0) {
|
||||||
return (DITEM_FAILURE | DITEM_RECREATE);
|
snprintf(prompt, sizeof(prompt),
|
||||||
}
|
"Cannot create symbolic link %s to %s: %s",
|
||||||
|
path_localtime, zoneinfo_file,
|
||||||
fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY,
|
strerror(errno));
|
||||||
S_IRUSR | S_IRGRP | S_IROTH);
|
message_zoneinfo_file("Error", prompt);
|
||||||
if (fd2 < 0) {
|
return (DITEM_FAILURE | DITEM_RECREATE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
if (copymode)
|
snprintf(prompt, sizeof(prompt),
|
||||||
snprintf(prompt, sizeof(prompt),
|
"Created symbolic link from %s to %s", zoneinfo_file,
|
||||||
"Copied timezone file from %s to %s",
|
path_localtime);
|
||||||
zoneinfo_file, path_localtime);
|
|
||||||
else
|
|
||||||
snprintf(prompt, sizeof(prompt),
|
|
||||||
"Created symbolic link from %s to %s",
|
|
||||||
zoneinfo_file, path_localtime);
|
|
||||||
message_zoneinfo_file("Done", prompt);
|
message_zoneinfo_file("Done", prompt);
|
||||||
#endif
|
#endif
|
||||||
} /* reallydoit */
|
} /* reallydoit */
|
||||||
|
|
Loading…
Reference in a new issue