398 lines
14 KiB
Diff
398 lines
14 KiB
Diff
|
unlike symlink_or_copy_atomic(), this function creates a symlink even if the
|
||
|
oldname and newname (from and to) are on differn't devices. (stat.st_dev)
|
||
|
---
|
||
|
src/shared/util.c | 19 +++++++++++++++++--
|
||
|
src/shared/util.h | 1 +
|
||
|
2 files changed, 18 insertions(+), 2 deletions(-)
|
||
|
|
||
|
Index: systemd-44/src/util.c
|
||
|
===================================================================
|
||
|
--- systemd-44.orig/src/util.c
|
||
|
+++ systemd-44/src/util.c
|
||
|
@@ -5352,7 +5352,7 @@ finish:
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
-int symlink_or_copy_atomic(const char *from, const char *to) {
|
||
|
+static int symlink_atomic_raw(const char *from, const char *to, bool allow_copy) {
|
||
|
char *t, *x;
|
||
|
const char *fn;
|
||
|
size_t k;
|
||
|
@@ -5381,7 +5381,14 @@ int symlink_or_copy_atomic(const char *f
|
||
|
|
||
|
*x = 0;
|
||
|
|
||
|
- r = symlink_or_copy(from, t);
|
||
|
+ if (allow_copy)
|
||
|
+ r = symlink_or_copy(from, t);
|
||
|
+ else {
|
||
|
+ r = symlink(from, t);
|
||
|
+ if (r < 0)
|
||
|
+ r = -errno;
|
||
|
+ }
|
||
|
+
|
||
|
if (r < 0) {
|
||
|
unlink(t);
|
||
|
free(t);
|
||
|
@@ -5482,6 +5489,14 @@ int audit_loginuid_from_pid(pid_t pid, u
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+int symlink_or_copy_atomic(const char *from, const char *to) {
|
||
|
+ return symlink_atomic_raw(from, to, true);
|
||
|
+}
|
||
|
+
|
||
|
+int symlink_atomic(const char *from, const char *to) {
|
||
|
+ return symlink_atomic_raw(from, to, false);
|
||
|
+}
|
||
|
+
|
||
|
bool display_is_local(const char *display) {
|
||
|
assert(display);
|
||
|
|
||
|
Index: systemd-44/src/util.h
|
||
|
===================================================================
|
||
|
--- systemd-44.orig/src/util.h
|
||
|
+++ systemd-44/src/util.h
|
||
|
@@ -448,6 +448,7 @@ int vt_disallocate(const char *name);
|
||
|
int copy_file(const char *from, const char *to);
|
||
|
int symlink_or_copy(const char *from, const char *to);
|
||
|
int symlink_or_copy_atomic(const char *from, const char *to);
|
||
|
+int symlink_atomic(const char *from, const char *to);
|
||
|
|
||
|
int fchmod_umask(int fd, mode_t mode);
|
||
|
|
||
|
Index: systemd-44/Makefile.am
|
||
|
===================================================================
|
||
|
--- systemd-44.orig/Makefile.am
|
||
|
+++ systemd-44/Makefile.am
|
||
|
@@ -690,7 +690,7 @@ MANPAGES = \
|
||
|
man/systemd.conf.5 \
|
||
|
man/tmpfiles.d.5 \
|
||
|
man/hostname.5 \
|
||
|
- man/timezone.5 \
|
||
|
+ man/localtime.5 \
|
||
|
man/machine-id.5 \
|
||
|
man/locale.conf.5 \
|
||
|
man/os-release.5 \
|
||
|
Index: systemd-44/man/timezone.xml
|
||
|
===================================================================
|
||
|
--- systemd-44.orig/man/timezone.xml
|
||
|
+++ /dev/null
|
||
|
@@ -1,90 +0,0 @@
|
||
|
-<?xml version='1.0'?> <!--*-nxml-*-->
|
||
|
-<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
|
||
|
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||
|
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||
|
-
|
||
|
-<!--
|
||
|
- This file is part of systemd.
|
||
|
-
|
||
|
- Copyright 2010 Lennart Poettering
|
||
|
-
|
||
|
- systemd is free software; you can redistribute it and/or modify it
|
||
|
- under the terms of the GNU General Public License as published by
|
||
|
- the Free Software Foundation; either version 2 of the License, or
|
||
|
- (at your option) any later version.
|
||
|
-
|
||
|
- systemd is distributed in the hope that it will be useful, but
|
||
|
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
- General Public License for more details.
|
||
|
-
|
||
|
- You should have received a copy of the GNU General Public License
|
||
|
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||
|
--->
|
||
|
-
|
||
|
-<refentry id="timezone">
|
||
|
- <refentryinfo>
|
||
|
- <title>/etc/timezone</title>
|
||
|
- <productname>systemd</productname>
|
||
|
-
|
||
|
- <authorgroup>
|
||
|
- <author>
|
||
|
- <contrib>Developer</contrib>
|
||
|
- <firstname>Lennart</firstname>
|
||
|
- <surname>Poettering</surname>
|
||
|
- <email>lennart@poettering.net</email>
|
||
|
- </author>
|
||
|
- </authorgroup>
|
||
|
- </refentryinfo>
|
||
|
-
|
||
|
- <refmeta>
|
||
|
- <refentrytitle>timezone</refentrytitle>
|
||
|
- <manvolnum>5</manvolnum>
|
||
|
- </refmeta>
|
||
|
-
|
||
|
- <refnamediv>
|
||
|
- <refname>timezone</refname>
|
||
|
- <refpurpose>Local time zone configuration file</refpurpose>
|
||
|
- </refnamediv>
|
||
|
-
|
||
|
- <refsynopsisdiv>
|
||
|
- <para><filename>/etc/timezone</filename></para>
|
||
|
- </refsynopsisdiv>
|
||
|
-
|
||
|
- <refsect1>
|
||
|
- <title>Description</title>
|
||
|
-
|
||
|
- <para>The <filename>/etc/timezone</filename> file
|
||
|
- configures the system-wide time zone of the local
|
||
|
- system that is used by applications for presentation
|
||
|
- to the user. It should contain a single
|
||
|
- newline-terminated line consisting of a time zone
|
||
|
- identifier such as
|
||
|
- <literal>Europe/Berlin</literal>. The file
|
||
|
- <filename>/etc/localtime</filename> corresponds with
|
||
|
- <filename>/etc/timezone</filename> and contains the
|
||
|
- binary time zone data for the time zone. These files
|
||
|
- should always be changed simultaneously and kept in
|
||
|
- sync.</para>
|
||
|
-
|
||
|
- <para>The time zone may be overridden for individual
|
||
|
- programs by using the TZ environment variable. See
|
||
|
- <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||
|
- </refsect1>
|
||
|
-
|
||
|
- <refsect1>
|
||
|
- <title>History</title>
|
||
|
-
|
||
|
- <para>The simple configuration file format of
|
||
|
- <filename>/etc/timezone</filename> originates from
|
||
|
- Debian GNU/Linux.</para>
|
||
|
- </refsect1>
|
||
|
-
|
||
|
- <refsect1>
|
||
|
- <title>See Also</title>
|
||
|
- <para>
|
||
|
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||
|
- </para>
|
||
|
- </refsect1>
|
||
|
-
|
||
|
-</refentry>
|
||
|
Index: systemd-44/man/localtime.xml
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ systemd-44/man/localtime.xml
|
||
|
@@ -0,0 +1,93 @@
|
||
|
+<?xml version='1.0'?> <!--*-nxml-*-->
|
||
|
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
|
||
|
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||
|
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||
|
+
|
||
|
+<!--
|
||
|
+ This file is part of systemd.
|
||
|
+
|
||
|
+ Copyright 2010 Lennart Poettering
|
||
|
+ Copyright 2012 Shawn Landden
|
||
|
+
|
||
|
+ systemd is free software; you can redistribute it and/or modify it
|
||
|
+ under the terms of the GNU General Public License as published by
|
||
|
+ the Free Software Foundation; either version 2 of the License, or
|
||
|
+ (at your option) any later version.
|
||
|
+
|
||
|
+ systemd is distributed in the hope that it will be useful, but
|
||
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU General Public License
|
||
|
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||
|
+-->
|
||
|
+
|
||
|
+<refentry id="localtime">
|
||
|
+ <refentryinfo>
|
||
|
+ <title>/etc/localtime</title>
|
||
|
+ <productname>systemd</productname>
|
||
|
+
|
||
|
+ <authorgroup>
|
||
|
+ <author>
|
||
|
+ <contrib>Developer</contrib>
|
||
|
+ <firstname>Lennart</firstname>
|
||
|
+ <surname>Poettering</surname>
|
||
|
+ <email>lennart@poettering.net</email>
|
||
|
+ </author>
|
||
|
+ <author>
|
||
|
+ <contrib>Developer</contrib>
|
||
|
+ <firstname>Shawn</firstname>
|
||
|
+ <surname>Landden</surname>
|
||
|
+ <email>shawnlandden@gmail.com</email>
|
||
|
+ </author>
|
||
|
+ </authorgroup>
|
||
|
+ </refentryinfo>
|
||
|
+
|
||
|
+ <refmeta>
|
||
|
+ <refentrytitle>localtime</refentrytitle>
|
||
|
+ <manvolnum>5</manvolnum>
|
||
|
+ </refmeta>
|
||
|
+
|
||
|
+ <refnamediv>
|
||
|
+ <refname>localtime</refname>
|
||
|
+ <refpurpose>Local time zone configuration file</refpurpose>
|
||
|
+ </refnamediv>
|
||
|
+
|
||
|
+ <refsynopsisdiv>
|
||
|
+ <para><filename>/etc/localtime</filename> -> <filename>/usr/share/zoneinfo/…</filename></para>
|
||
|
+ </refsynopsisdiv>
|
||
|
+
|
||
|
+ <refsect1>
|
||
|
+ <title>Description</title>
|
||
|
+
|
||
|
+ <para>The <filename>/etc/localtime</filename> file
|
||
|
+ configures the system-wide time zone of the local
|
||
|
+ system that is used by applications for presentation
|
||
|
+ to the user. It should be an absolute symbolic link
|
||
|
+ with a destination of <filename>/usr/share/zoneinfo/</filename>,
|
||
|
+ fallowed by a time zone identifier such as
|
||
|
+ <literal>Europe/Berlin</literal> or <literal>Etc/UTC</literal>.
|
||
|
+ The resulting link should point to the corresponding binary
|
||
|
+ <citerefentry><refentrytitle>tzfile</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||
|
+ time zone data for the configured time zone.</para>
|
||
|
+
|
||
|
+ <para>As the time zone identifier is extracted from the name of
|
||
|
+ the target of <filename>/etc/localtime</filename> this file may
|
||
|
+ not be a normal file or hardlink.</para>
|
||
|
+
|
||
|
+ <para>The time zone may be overridden for individual
|
||
|
+ programs by using the TZ environment variable. See
|
||
|
+ <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||
|
+ </refsect1>
|
||
|
+
|
||
|
+ <refsect1>
|
||
|
+ <title>See Also</title>
|
||
|
+ <para>
|
||
|
+ <citerefentry><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||
|
+ <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||
|
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||
|
+ </para>
|
||
|
+ </refsect1>
|
||
|
+
|
||
|
+</refentry>
|
||
|
Index: systemd-44/src/timedate/timedated.c
|
||
|
===================================================================
|
||
|
--- systemd-44.orig/src/timedate/timedated.c
|
||
|
+++ systemd-44/src/timedate/timedated.c
|
||
|
@@ -72,6 +72,9 @@
|
||
|
BUS_GENERIC_INTERFACES_LIST \
|
||
|
"org.freedesktop.timedate1\0"
|
||
|
|
||
|
+/* Must start and end with '/' */
|
||
|
+#define ZONEINFO_PATH "/usr/share/zoneinfo/"
|
||
|
+
|
||
|
const char timedate_interface[] _introspect_("timedate1") = INTERFACE;
|
||
|
|
||
|
typedef struct TZ {
|
||
|
@@ -125,7 +128,7 @@ static bool valid_timezone(const char *n
|
||
|
if (slash)
|
||
|
return false;
|
||
|
|
||
|
- t = strappend("/usr/share/zoneinfo/", name);
|
||
|
+ t = strappend(ZONEINFO_PATH, name);
|
||
|
if (!t)
|
||
|
return false;
|
||
|
|
||
|
@@ -149,17 +152,17 @@ static void verify_timezone(void) {
|
||
|
if (!tz.zone)
|
||
|
return;
|
||
|
|
||
|
- p = strappend("/usr/share/zoneinfo/", tz.zone);
|
||
|
+ p = strappend(ZONEINFO_PATH, tz.zone);
|
||
|
if (!p) {
|
||
|
log_error("Out of memory");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- j = read_full_file("/etc/localtime", &a, &l);
|
||
|
k = read_full_file(p, &b, &q);
|
||
|
-
|
||
|
free(p);
|
||
|
|
||
|
+ j = read_full_file("/etc/localtime", &a, &l);
|
||
|
+
|
||
|
if (j < 0 || k < 0 || l != q || memcmp(a, b, l)) {
|
||
|
log_warning("/etc/localtime and /etc/timezone out of sync.");
|
||
|
free(tz.zone);
|
||
|
@@ -172,9 +175,36 @@ static void verify_timezone(void) {
|
||
|
|
||
|
static int read_data(void) {
|
||
|
int r;
|
||
|
+ char *t = NULL;
|
||
|
|
||
|
free_data();
|
||
|
|
||
|
+ r = readlink_malloc("/etc/localtime", &t);
|
||
|
+ if (r < 0) {
|
||
|
+ if (r == -EINVAL)
|
||
|
+ log_warning("/etc/localtime should be a symbolic link to a timezone data file in " ZONEINFO_PATH);
|
||
|
+ else
|
||
|
+ log_warning("Failed to get target of %s: %s", "/etc/localtime", strerror(-r));
|
||
|
+ } else {
|
||
|
+ /* we only support the trivial relative link of (/etc/)..$ABSOLUTE */
|
||
|
+ int rel_link_offset = startswith(t, "..") ? strlen("..") : 0;
|
||
|
+
|
||
|
+ if (!startswith(t + rel_link_offset, ZONEINFO_PATH))
|
||
|
+ log_warning("/etc/localtime should be a symbolic link to a timezone data file in " ZONEINFO_PATH);
|
||
|
+ else {
|
||
|
+ tz.zone = strdup(t + rel_link_offset + strlen(ZONEINFO_PATH));
|
||
|
+ free(t);
|
||
|
+ if (!tz.zone) {
|
||
|
+ log_error("Out of memory");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ goto have_timezone;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ free(t);
|
||
|
+
|
||
|
r = read_one_line_file("/etc/timezone", &tz.zone);
|
||
|
if (r < 0) {
|
||
|
if (r != -ENOENT)
|
||
|
@@ -190,6 +220,7 @@ static int read_data(void) {
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+have_timezone:
|
||
|
if (isempty(tz.zone)) {
|
||
|
free(tz.zone);
|
||
|
tz.zone = NULL;
|
||
|
@@ -205,6 +236,7 @@ static int read_data(void) {
|
||
|
static int write_data_timezone(void) {
|
||
|
int r = 0;
|
||
|
char *p;
|
||
|
+ struct stat st;
|
||
|
|
||
|
if (!tz.zone) {
|
||
|
if (unlink("/etc/timezone") < 0 && errno != ENOENT)
|
||
|
@@ -216,21 +248,24 @@ static int write_data_timezone(void) {
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
- p = strappend("/usr/share/zoneinfo/", tz.zone);
|
||
|
+ p = strappend(ZONEINFO_PATH, tz.zone);
|
||
|
if (!p) {
|
||
|
log_error("Out of memory");
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
|
||
|
- r = symlink_or_copy_atomic(p, "/etc/localtime");
|
||
|
+ r = symlink_atomic(p, "/etc/localtime");
|
||
|
+
|
||
|
free(p);
|
||
|
|
||
|
if (r < 0)
|
||
|
- return r;
|
||
|
+ return -errno;
|
||
|
|
||
|
- r = write_one_line_file_atomic("/etc/timezone", tz.zone);
|
||
|
- if (r < 0)
|
||
|
- return r;
|
||
|
+ if (stat("/etc/timezone", &st) == 0 && S_ISREG(st.st_mode)) {
|
||
|
+ r = write_one_line_file_atomic("/etc/timezone", tz.zone);
|
||
|
+ if (r < 0)
|
||
|
+ return r;
|
||
|
+ }
|
||
|
|
||
|
return 0;
|
||
|
}
|