+do_null_bootstrap_check(notify_tz_t *p)
+{
+ /*
+ * If we're running in a null bootstrap context (e.g. the bootstrap server),
+ * we will not be able to contact the notify server. In this case we want to
+ * avoid opening /etc/localtime every time the process does a asctime_r(3)
+ * or similar. But we have to do this once to get the right time zone.
+ *
+ * So first time through, we set a bit to indicate that we're in the null
+ * bootstrap context. The second time through, we force the "set" bit in the
+ * notify_tz_t structure to -1 and avoid the path where it can be set to
+ * zero (which would trigger opening and reloading the timezone file).
+ */
+ if (bootstrap_port != MACH_PORT_NULL) {
+ return -1;
+ }
+
+ if (!p->null_bootstrap) {
+ p->null_bootstrap = 1;
+ p->is_set = 0;
+ return -1;
+ }
+
+ p->is_set = -1;
+ return 0;
+}
+
+static void
+notify_check_tz(notify_tz_t *p)
+{
+ unsigned int nstat;
+ int ncheck;
+
+ if (p->token < 0)
+ return;
+ if (do_null_bootstrap_check(p) == 0) {
+ return;
+ }
+ nstat = notify_check(p->token, &ncheck);
+ if (nstat || ncheck) {
+ p->is_set = 0;
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("notify_check_tz: %s changed\n", (p == &lcl_notify) ? "lcl" : "gmt");
+#endif /* NOTIFY_TZ_DEBUG */
+ }
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("notify_check_tz: %s unchanged\n", (p == &lcl_notify) ? "lcl" : "gmt");
+#endif /* NOTIFY_TZ_DEBUG */
+}
+
+extern uint32_t notify_monitor_file(int token, char *path, int flags);
+
+static void
+notify_register_tz(char *file, notify_tz_t *p)
+{
+ char *name;
+ unsigned int nstat;
+ int ncheck;
+
+ if (do_null_bootstrap_check(p) == 0) {
+ return;
+ }
+
+ /*----------------------------------------------------------------
+ * Since we don't record the last time zone filename, just cancel
+ * (which should remove the file monitor) and setup from scratch
+ *----------------------------------------------------------------*/
+ if (p->token >= 0)
+ notify_cancel(p->token);
+ if (!file || *file == 0) {
+ /* no time zone file to monitor */
+ p->token = -1;
+ return;
+ }
+ /*----------------------------------------------------------------
+ * Just use com.apple.system.timezone if the path is /etc/localtime.
+ * Otherwise use com.apple.system.timezone.<fullpath>
+ *----------------------------------------------------------------*/
+ if (TZDEFAULT && strcmp(file, TZDEFAULT) == 0)
+ name = (char *)notify_tz_name;
+ else {
+ name = alloca(sizeof(notify_tz_name) + strlen(file) + 1);
+ if (name == NULL) {
+ p->token = -1;
+ return;
+ }
+ strcpy(name, notify_tz_name);
+ strcat(name, ".");
+ strcat(name, file);
+ }
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("notify_register_tz: file=%s name=%s\n", file, name);
+#endif /* NOTIFY_TZ_DEBUG */
+ nstat = notify_register_check(name, &p->token);
+ if (nstat != 0) {
+ p->token = -1;
+ p->is_set = 0;
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("***notify_register_tz: notify_register_check failed: %u\n", nstat);
+#endif /* NOTIFY_TZ_DEBUG */
+#ifdef NOTIFY_TZ_LOG
+ NOTIFY_LOG("notify_register_check(%s) failed: %u\n", name, nstat);
+#endif /* NOTIFY_TZ_LOG */
+ return;
+ }
+ /* don't need to request monitoring /etc/localtime */
+ if (name != notify_tz_name) {
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("notify_register_tz: monitor %s\n", file);
+#endif /* NOTIFY_TZ_DEBUG */
+ nstat = notify_monitor_file(p->token, file, 0);
+ if (nstat != 0) {
+ notify_cancel(p->token);
+ p->token = -1;
+ p->is_set = 0;
+#ifdef NOTIFY_TZ_DEBUG
+ NOTIFY_TZ_PRINTF("***notify_register_tz: notify_monitor_file failed: %u\n", nstat);
+#endif /* NOTIFY_TZ_DEBUG */
+#ifdef NOTIFY_TZ_LOG
+ NOTIFY_LOG("notify_monitor_file(%s) failed: %u\n", file, nstat);
+#endif /* NOTIFY_TZ_LOG */
+ return;
+ }
+ }
+ notify_check(p->token, &ncheck); /* this always returns true */
+}
+#endif /* NOTIFY_TZ */
+
+static int
+differ_by_repeat(const time_t t1, const time_t t0)
+{
+ int_fast64_t _t0 = t0;
+ int_fast64_t _t1 = t1;
+
+ if (TYPE_INTEGRAL(time_t) &&
+ TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
+ return 0;
+ //turn ((int_fast64_t)(t1 - t0) == SECSPERREPEAT);
+ return _t1 - _t0 == SECSPERREPEAT;
+}
+
+static int
+#ifdef NOTIFY_TZ
+tzload(name, sp, path, doextend)
+#else /* ! NOTIFY_TZ */
+tzload(name, sp, doextend)
+#endif /* NOTIFY_TZ */