+static int load_clock_timestamp(uid_t uid, gid_t gid) {
+ _cleanup_close_ int fd = -1;
+ usec_t min = TIME_EPOCH * USEC_PER_SEC;
+ usec_t ct;
+ int r;
+
+ /* Let's try to make sure that the clock is always
+ * monotonically increasing, by saving the clock whenever we
+ * have a new NTP time, or when we shut down, and restoring it
+ * when we start again. This is particularly helpful on
+ * systems lacking a battery backed RTC. We also will adjust
+ * the time to at least the build time of systemd. */
+
+ fd = open("/var/lib/systemd/clock", O_RDWR|O_CLOEXEC, 0644);
+ if (fd >= 0) {
+ struct stat st;
+ usec_t stamp;
+
+ /* check if the recorded time is later than the compiled-in one */
+ r = fstat(fd, &st);
+ if (r >= 0) {
+ stamp = timespec_load(&st.st_mtim);
+ if (stamp > min)
+ min = stamp;
+ }
+
+ /* Try to fix the access mode, so that we can still
+ touch the file after dropping priviliges */
+ fchmod(fd, 0644);
+ fchown(fd, uid, gid);
+
+ } else
+ /* create stamp file with the compiled-in date */
+ touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644);
+
+ ct = now(CLOCK_REALTIME);
+ if (ct < min) {
+ struct timespec ts;
+ char date[FORMAT_TIMESTAMP_MAX];
+
+ log_info("System clock time unset or jumped backwards, restoring from recorded timestamp: %s",
+ format_timestamp(date, sizeof(date), min));
+
+ if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, min)) < 0)
+ log_error("Failed to restore system clock: %m");
+ }
+
+ return 0;
+}
+
+static int manager_timeout(sd_event_source *source, usec_t usec, void *userdata) {
+ _cleanup_free_ char *pretty = NULL;
+ Manager *m = userdata;
+
+ assert(m);
+ assert(m->current_server_name);
+ assert(m->current_server_address);
+
+ server_address_pretty(m->current_server_address, &pretty);
+ log_info("Timed out waiting for reply from %s (%s).", strna(pretty), m->current_server_name->string);
+
+ return manager_connect(m);
+}
+
+static int manager_send_request(Manager *m) {
+ _cleanup_free_ char *pretty = NULL;
+ struct ntp_msg ntpmsg = {
+ /*
+ * "The client initializes the NTP message header, sends the request
+ * to the server, and strips the time of day from the Transmit
+ * Timestamp field of the reply. For this purpose, all the NTP
+ * header fields are set to 0, except the Mode, VN, and optional
+ * Transmit Timestamp fields."
+ */
+ .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
+ };