This option could changes the default system's time zone. The default time zone is /etc/localtime. If we want to use the specific path, we could use this option.
Change-Id: Iab7d8b2530d8632f57f3700fd6b5860242aee423 --- src/timedate/timedated.c | 79 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index c4a797a..1a351bd 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -22,6 +22,7 @@ #include <errno.h> #include <string.h> #include <unistd.h> +#include <getopt.h> #include "sd-id128.h" #include "sd-messages.h" @@ -50,6 +51,8 @@ typedef struct Context { Hashmap *polkit_registry; } Context; +static const char *arg_tz = "/etc/localtime"; + static void context_reset(Context *c) { assert(c); @@ -115,7 +118,7 @@ static bool valid_timezone(const char *name) { return true; } -static int context_read_data(Context *c) { +static int context_read_data(Context *c, const char *tz) { _cleanup_free_ char *t = NULL; int r; @@ -123,12 +126,12 @@ static int context_read_data(Context *c) { context_reset(c); - r = readlink_malloc("/etc/localtime", &t); + r = readlink_malloc(tz, &t); if (r < 0) { if (r == -EINVAL) - log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/."); + log_warning("%s should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.", tz); else - log_warning("Failed to get target of /etc/localtime: %s", strerror(-r)); + log_warning("Failed to get target of %s: %s", tz, strerror(-r)); } else { const char *e; @@ -137,7 +140,7 @@ static int context_read_data(Context *c) { e = path_startswith(t, "../usr/share/zoneinfo/"); if (!e) - log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/."); + log_warning("%s should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.", tz); else { c->zone = strdup(e); if (!c->zone) @@ -158,24 +161,24 @@ have_timezone: return 0; } -static int context_write_data_timezone(Context *c) { +static int context_write_data_timezone(Context *c, const char *tz) { _cleanup_free_ char *p = NULL; int r = 0; assert(c); if (isempty(c->zone)) { - if (unlink("/etc/localtime") < 0 && errno != ENOENT) + if (unlink(tz) < 0 && errno != ENOENT) r = -errno; return r; } - p = strappend("../usr/share/zoneinfo/", c->zone); + p = strappend("/usr/share/zoneinfo/", c->zone); if (!p) return log_oom(); - r = symlink_atomic(p, "/etc/localtime"); + r = symlink_atomic(p, tz); if (r < 0) return r; @@ -540,7 +543,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s c->zone = t; /* 1. Write new configuration file */ - r = context_write_data_timezone(c); + r = context_write_data_timezone(c, arg_tz); if (r < 0) { log_error("Failed to set timezone: %s", strerror(-r)); return sd_bus_error_set_errnof(error, r, "Failed to set timezone: %s", strerror(-r)); @@ -809,6 +812,56 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { return 0; } +static int help(void) { + + printf("%s [OPTIONS...] COMMAND ...\n\n" + "Control the system time and related settings.\n\n" + " -h --help Show this help\n" + " --timezone=PATH Set the default timezone\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_TZ = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "timezone", required_argument, NULL, ARG_TZ }, + {} + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + return help(); + + case ARG_TZ: + arg_tz = optarg; + break; + + case '?': + return -EINVAL; + + default: + assert_not_reached("Unhandled option"); + } + } + + return 1; +} + int main(int argc, char *argv[]) { Context context = { .zone = NULL, @@ -827,8 +880,8 @@ int main(int argc, char *argv[]) { umask(0022); - if (argc != 1) { - log_error("This program takes no arguments."); + r = parse_argv(argc, argv); + if (r <= 0) { r = -EINVAL; goto finish; } @@ -845,7 +898,7 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - r = context_read_data(&context); + r = context_read_data(&context, arg_tz); if (r < 0) { log_error("Failed to read timezone data: %s", strerror(-r)); goto finish; -- 1.7.9.5 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel