+ g_main_loop_run(timedated_loop);
+ /* runs until single g_main_loop_quit() call is raised inside <interface>_mem_clean() */
+ g_main_loop_unref(timedated_loop);
+
+ /* guaranteed unownable */
+ g_bus_unown_name(bus_descriptor);
+
+ /* at this point no operations can occur with our data, it is safe to free it + its container */
+ g_ptr_array_free(timedated_freeable, TRUE);
+
+ return 0;
+}
+
+static struct timezone_checksum_pair parse_timezone_path(gchar **pair) {
+
+ gchar *prefix_pattern, *right_prefix_pattern, *posix_prefix_pattern, *lean_path;
+ GRegex *prefix, *posix, *right;
+ GError *err = NULL;
+ struct timezone_checksum_pair ret = { NULL, NULL, FALSE, FALSE };
+
+ if(!pair[0])
+ return ret;
+
+ prefix_pattern = (gchar *) g_malloc0(4096);
+ right_prefix_pattern = (gchar *) g_malloc0(4096);
+ posix_prefix_pattern = (gchar *) g_malloc0(4096);
+
+ g_sprintf(prefix_pattern, "%s/", OS_TIMEZONE_PATH);
+ g_sprintf(posix_prefix_pattern, "%s/posix/", OS_TIMEZONE_PATH);
+ g_sprintf(right_prefix_pattern, "%s/right/", OS_TIMEZONE_PATH);
+
+ prefix = g_regex_new(prefix_pattern, 0, 0, &err);
+ posix = g_regex_new(posix_prefix_pattern, 0, 0, &err);
+ right = g_regex_new(right_prefix_pattern, 0, 0, &err);
+
+ if(g_regex_match_full(posix, pair[0], -1, 0, G_REGEX_MATCH_NOTEMPTY, NULL, NULL)) {
+
+ ret.posix = TRUE;
+ lean_path = g_regex_replace_literal(posix, pair[0], -1, 0, "", G_REGEX_MATCH_NOTEMPTY, NULL);
+
+ } else if(g_regex_match_full(right, pair[0], -1, 0, G_REGEX_MATCH_NOTEMPTY, NULL, NULL)) {
+
+ ret.right = TRUE;
+ lean_path = g_regex_replace_literal(right, pair[0], -1, 0, "", G_REGEX_MATCH_NOTEMPTY, NULL);
+
+ } else
+ lean_path = g_regex_replace_literal(prefix, pair[0], -1, 0, "", G_REGEX_MATCH_NOTEMPTY, NULL);
+
+ ret.path = lean_path;
+
+ ret.sum = g_malloc0(256);
+ g_strlcpy(ret.sum, pair[1], 66);
+
+ g_regex_unref(prefix);
+ g_regex_unref(right);
+ g_regex_unref(posix);
+
+ return ret;
+}
+
+/* TODO need to deconstruct tz_table on exit */
+static gboolean build_lookup_table() {
+
+ gchar *find_cmd, **map_pairs, *find_output, *path_buf, *sum_buf, **entry_buf;
+ GError *err;
+ gboolean ret;
+ gint i;
+
+ i = 0;
+ err = NULL;
+ ret = TRUE;
+
+ find_cmd = (gchar *) g_malloc0(4096);
+ find_output = (gchar *) g_malloc0(1000000);
+
+ g_sprintf(find_cmd, "/bin/sh -c \"find %s -type f -exec cksum -a sha256 {} \\; | sed -E 's/SHA256 \\(//g' | sed -E 's/\\) = /=/g'\"", OS_TIMEZONE_PATH);
+
+ if(!g_spawn_command_line_sync(find_cmd, &find_output, NULL, NULL, &err)) {
+
+ g_printf("error running `%s`\n", find_cmd);
+ ret = FALSE;
+ }
+
+ map_pairs = g_strsplit(find_output, "\n", INT_MAX);
+
+ while(map_pairs[i] && (entry_buf = g_strsplit(map_pairs[i], "=", INT_MAX))) {
+
+ tz_table[i] = parse_timezone_path(entry_buf);
+
+ g_strfreev(entry_buf);
+ i++;
+ }
+
+ g_free(find_output);
+ g_free(find_cmd);
+ g_free(map_pairs);
+
+ return ret;
+}
+
+static gchar *lookup_hash(gchar *hash) {