Bug Summary

File:capplets/time-admin/src/time-zone.c
Warning:line 147, column 13
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name time-zone.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/capplets/time-admin/src -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../../.. -I ../../../capplets/common -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I ../../../ -D G_LOG_DOMAIN="time-admin-properties" -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/polkit-1 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -D TIMPZONEDIR="/usr/share/cafe-time-admin/map/" -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/capplets/time-admin/src -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-01-21-120652-112879-1 -x c time-zone.c
1/*
2 * Copyright (C) 2022 Pablo Barciela
3 * Copyright (C) 2019-2020 MATE Developers
4 * Copyright (C) 2018, 2019 zhuyaliang https://github.com/zhuyaliang/
5 * Copyright (C) 2010-2018 The GNOME Project
6 * Copyright (C) 2010 Intel, Inc
7 *
8 * Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd.
9 * Written by Evan Dandrea <evand@ubuntu.com>
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 *
24 * Author: Thomas Wood <thomas.wood@intel.com>
25 *
26 */
27
28#ifdef HAVE_CONFIG_H1
29#include "config.h"
30#endif
31#include "time-zone.h"
32#include "time-map.h"
33#include "time-tool.h"
34#include <math.h>
35#define CAFE_DESKTOP_USE_UNSTABLE_API
36
37#include <string.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <libintl.h>
41#include <glib/gi18n.h>
42
43#include <libcafe-desktop/cafe-languages.h>
44
45#define DEFAULT_TZ"Europe/London" "Europe/London"
46#define BACKFILE"/usr/share/cafe-time-admin/map/" "backward" TIMPZONEDIR"/usr/share/cafe-time-admin/map/" "backward"
47
48static void LocationChanged(TimezoneMap *map,
49 TzLocation *location,
50 TimeAdmin *ta);
51
52enum {
53 CITY_COL_CITY_HUMAN_READABLE,
54 CITY_COL_ZONE,
55 CITY_NUM_COLS
56};
57
58static gchar*
59tz_data_file_get (void)
60{
61 gchar *file;
62
63 file = g_strdup (TZ_DATA_FILE)g_strdup_inline ("/usr/share/zoneinfo/zone.tab");
64
65 return file;
66}
67
68static float
69convert_pos (gchar *pos, int digits)
70{
71 gchar whole[10], *fraction;
72 gint i;
73 float t1, t2;
74
75 if (!pos || strlen(pos) < 4 || digits > 9)
76 return 0.0;
77
78 for (i = 0; i < digits + 1; i++)
79 whole[i] = pos[i];
80
81 whole[i] = '\0';
82 fraction = pos + digits + 1;
83
84 t1 = g_strtod (whole, NULL((void*)0));
85 t2 = g_strtod (fraction, NULL((void*)0));
86
87 if (t1 >= 0.0)
88 return t1 + t2/pow (10.0, strlen(fraction));
89 else
90 return t1 - t2/pow (10.0, strlen(fraction));
91}
92
93static int compare_country_names (const void *a, const void *b)
94{
95 const TzLocation *tza = * (TzLocation **) a;
96 const TzLocation *tzb = * (TzLocation **) b;
97
98 return strcmp (tza->zone, tzb->zone);
99}
100
101static void sort_locations_by_country (GPtrArray *locations)
102{
103 qsort (locations->pdata, locations->len, sizeof (gpointer),
104 compare_country_names);
105}
106static void load_backward_tz (TzDB *tz_db)
107{
108 FILE *fp;
109 char buf[128] = { 0 };
110
111 tz_db->backward = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
112
113 fp = fopen(BACKFILE"/usr/share/cafe-time-admin/map/" "backward","r");
114 if(fp == NULL((void*)0))
9
Assuming 'fp' is not equal to NULL
10
Taking false branch
115 {
116 g_error("%s does not exist\r\n",BACKFILE"/usr/share/cafe-time-admin/map/" "backward");
117
118 }
119 while(fgets(buf,128,fp))
11
Loop condition is true. Entering loop body
120 {
121 g_auto(GStrv)__attribute__((cleanup(glib_auto_cleanup_GStrv))) GStrv items = NULL((void*)0);
122 guint j;
123 char *real, *alias;
124
125 if (g_ascii_strncasecmp (buf, "Link\t", 5) != 0)
12
Assuming the condition is false
13
Taking false branch
126 continue;
127
128 items = g_strsplit (buf, "\t", -1);
129 real = NULL((void*)0);
14
Null pointer value stored to 'real'
130 alias = NULL((void*)0);
131 for (j = 1; items[j] != NULL((void*)0); j++)
15
Assuming the condition is false
132 {
133 if (items[j][0] == '\0')
134 continue;
135 if (real == NULL((void*)0))
136 {
137 real = items[j];
138 continue;
139 }
140 alias = items[j];
141 break;
142 }
143 if (real
15.1
'real' is equal to NULL
== NULL((void*)0) || alias == NULL((void*)0))
144 g_warning ("Could not parse line: %s", buf);
145
146 /* We don't need more than one name for it */
147 if (g_str_equal (real, "Etc/UTC")(strcmp ((const char *) (real), (const char *) ("Etc/UTC")) ==
0)
||
16
Null pointer passed to 1st parameter expecting 'nonnull'
148 g_str_equal (real, "Etc/UCT")(strcmp ((const char *) (real), (const char *) ("Etc/UCT")) ==
0)
)
149 real = "Etc/GMT";
150
151 g_hash_table_insert (tz_db->backward, g_strdup (alias)g_strdup_inline (alias), g_strdup (real)g_strdup_inline (real));
152
153 }
154 fclose(fp);
155}
156
157TzDB *tz_load_db (void)
158{
159 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *tz_data_file = NULL((void*)0);
160 TzDB *tz_db;
161 FILE *tzfile;
162 char buf[4096];
163
164 tz_data_file = tz_data_file_get ();
165 if (!tz_data_file)
3
Assuming 'tz_data_file' is non-null
4
Taking false branch
166 {
167 g_warning ("Could not get the TimeZone data file name");
168 return NULL((void*)0);
169 }
170 tzfile = fopen (tz_data_file, "r");
171 if (!tzfile)
5
Assuming 'tzfile' is non-null
6
Taking false branch
172 {
173 g_warning ("Could not open *%s*\n", tz_data_file);
174 return NULL((void*)0);
175 }
176
177 tz_db = g_new0 (TzDB, 1)((TzDB *) g_malloc0_n ((1), sizeof (TzDB)));
178 tz_db->locations = g_ptr_array_new ();
179
180 while (fgets (buf, sizeof(buf), tzfile))
7
Loop condition is false. Execution continues on line 230
181 {
182 g_auto(GStrv)__attribute__((cleanup(glib_auto_cleanup_GStrv))) GStrv tmpstrarr = NULL((void*)0);
183 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *latstr = NULL((void*)0);
184 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *lngstr = NULL((void*)0);
185 gchar *p;
186 TzLocation *loc;
187
188 if (*buf == '#')
189 continue;
190
191 g_strchomp(buf);
192 tmpstrarr = g_strsplit(buf,"\t", 6);
193
194 latstr = g_strdup (tmpstrarr[1])g_strdup_inline (tmpstrarr[1]);
195 p = latstr + 1;
196 while (*p != '-' && *p != '+')
197 p++;
198 lngstr = g_strdup (p)g_strdup_inline (p);
199 *p = '\0';
200
201 loc = g_new0 (TzLocation, 1)((TzLocation *) g_malloc0_n ((1), sizeof (TzLocation)));
202 loc->country = g_strdup (tmpstrarr[0])g_strdup_inline (tmpstrarr[0]);
203 loc->zone = g_strdup (tmpstrarr[2])g_strdup_inline (tmpstrarr[2]);
204 loc->latitude = convert_pos (latstr, 2);
205 loc->longitude = convert_pos (lngstr, 3);
206
207#ifdef __sun
208 if (tmpstrarr[3] && *tmpstrarr[3] == '-' && tmpstrarr[4])
209 loc->comment = g_strdup (tmpstrarr[4])g_strdup_inline (tmpstrarr[4]);
210
211 if (tmpstrarr[3] && *tmpstrarr[3] != '-' && !islower(loc->zone))
212 {
213 TzLocation *locgrp;
214 locgrp = g_new0 (TzLocation, 1)((TzLocation *) g_malloc0_n ((1), sizeof (TzLocation)));
215 locgrp->country = g_strdup (tmpstrarr[0])g_strdup_inline (tmpstrarr[0]);
216 locgrp->zone = g_strdup (tmpstrarr[3])g_strdup_inline (tmpstrarr[3]);
217 locgrp->latitude = convert_pos (latstr, 2);
218 locgrp->longitude = convert_pos (lngstr, 3);
219 locgrp->comment = (tmpstrarr[4]) ? g_strdup (tmpstrarr[4])g_strdup_inline (tmpstrarr[4]) : NULL((void*)0);
220
221 g_ptr_array_add (tz_db->locations, (gpointer) locgrp);
222 }
223#else
224 loc->comment = (tmpstrarr[3]) ? g_strdup(tmpstrarr[3])g_strdup_inline (tmpstrarr[3]) : NULL((void*)0);
225#endif
226
227 g_ptr_array_add (tz_db->locations, (gpointer) loc);
228 }
229
230 fclose (tzfile);
231
232 /* now sort by country */
233 sort_locations_by_country (tz_db->locations);
234
235 /* Load up the hashtable of backward links */
236 load_backward_tz (tz_db);
8
Calling 'load_backward_tz'
237
238 return tz_db;
239}
240
241static CtkWidget*
242GetTimeZoneMap(TimeAdmin *ta)
243{
244 CtkWidget *map;
245 g_autoptr(CtkEntryCompletion)__attribute__((cleanup(glib_autoptr_cleanup_CtkEntryCompletion
))) CtkEntryCompletion_autoptr
completion = NULL((void*)0);
246
247 map = (CtkWidget *) timezone_map_new ();
248 g_signal_connect (map,g_signal_connect_data ((map), ("location-changed"), (((GCallback
) (LocationChanged))), (ta), ((void*)0), (GConnectFlags) 0)
249 "location-changed",g_signal_connect_data ((map), ("location-changed"), (((GCallback
) (LocationChanged))), (ta), ((void*)0), (GConnectFlags) 0)
250 G_CALLBACK (LocationChanged),g_signal_connect_data ((map), ("location-changed"), (((GCallback
) (LocationChanged))), (ta), ((void*)0), (GConnectFlags) 0)
251 ta)g_signal_connect_data ((map), ("location-changed"), (((GCallback
) (LocationChanged))), (ta), ((void*)0), (GConnectFlags) 0)
;
252
253 completion = ctk_entry_completion_new ();
254 ctk_entry_set_completion (CTK_ENTRY (ta->TimezoneEntry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TimezoneEntry)), ((ctk_entry_get_type ()))))))
, completion);
255 ctk_entry_completion_set_model (completion, CTK_TREE_MODEL (ta->CityListStore)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->CityListStore)), ((ctk_tree_model_get_type ()))))
))
);
256 ctk_entry_completion_set_text_column (completion, CITY_COL_CITY_HUMAN_READABLE);
257
258 return map;
259}
260static char *
261translated_city_name (TzLocation *loc)
262{
263 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *zone_translated = NULL((void*)0);
264 g_auto(GStrv)__attribute__((cleanup(glib_auto_cleanup_GStrv))) GStrv split_translated = NULL((void*)0);
265 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *country = NULL((void*)0);
266 gchar *name;
267 gint length;
268
269 zone_translated = g_strdup (_(loc->zone))g_strdup_inline (gettext (loc->zone));
270 g_strdelimit (zone_translated, "_", ' ');
271 split_translated = g_regex_split_simple ("[\\x{2044}\\x{2215}\\x{29f8}\\x{ff0f}/]",
272 zone_translated,
273 0, 0);
274
275 length = g_strv_length (split_translated);
276
277 country = cafe_get_country_from_code (loc->country, NULL((void*)0));
278 name = g_strdup_printf (C_("timezone loc", "%s, %s")g_dpgettext (((void*)0), "timezone loc" "\004" "%s, %s", strlen
("timezone loc") + 1)
,
279 split_translated[length-1],
280 country);
281
282 return name;
283}
284
285static void
286update_timezone (TimezoneMap *map)
287{
288 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *bubble_text = NULL((void*)0);
289 g_autoptr(GDateTime)__attribute__((cleanup(glib_autoptr_cleanup_GDateTime))) GDateTime_autoptr current_date = NULL((void*)0);
290 g_autoptr(GTimeZone)__attribute__((cleanup(glib_autoptr_cleanup_GTimeZone))) GTimeZone_autoptr timezone = NULL((void*)0);
291 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *city_country = NULL((void*)0);
292 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *utc_label = NULL((void*)0);
293 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *time_label = NULL((void*)0);
294 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *tz_desc = NULL((void*)0);
295 TzLocation *current_location;
296 GDateTime *date;
297
298 current_location = timezone_map_get_location (TIMEZONEMAP (map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((map)), ((timezone_map_get_type ()))))))
);
299 city_country = translated_city_name (current_location);
300
301 timezone = g_time_zone_new (current_location->zone);
302 current_date = g_date_time_new_now_local ();
303 date = g_date_time_to_timezone (current_date, timezone);
304
305 utc_label = g_date_time_format (date, _("UTC%:::z")gettext ("UTC%:::z"));
306
307 tz_desc = g_strdup_printf ( "%s (%s)",
308 g_date_time_get_timezone_abbreviation (date),
309 utc_label);
310 time_label = g_date_time_format (date, _("%R")gettext ("%R"));
311
312 bubble_text = g_strdup_printf ("<b>%s</b>\n"
313 "<small>%s</small>\n"
314 "<b>%s</b>",
315 tz_desc,
316 city_country,
317 time_label);
318 timezone_map_set_bubble_text (TIMEZONEMAP (map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((map)), ((timezone_map_get_type ()))))))
, bubble_text);
319 g_date_time_unref(date);
320}
321
322static void
323LocationChanged(TimezoneMap *map,
324 TzLocation *location,
325 TimeAdmin *ta)
326{
327 update_timezone (map);
328}
329
330static void
331get_initial_timezone (TimeAdmin *ta)
332{
333 const gchar *timezone;
334
335 timezone = GetTimeZone(ta);
336
337 if (timezone == NULL((void*)0) ||
338 !timezone_map_set_timezone (TIMEZONEMAP (ta->map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->map)), ((timezone_map_get_type ()))))))
, timezone))
339 {
340 g_warning ("Timezone '%s' is unhandled,setting %s as default", timezone ? timezone : "(null)", DEFAULT_TZ"Europe/London");
341 timezone_map_set_timezone (TIMEZONEMAP (ta->map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->map)), ((timezone_map_get_type ()))))))
, DEFAULT_TZ"Europe/London");
342 }
343 update_timezone (TIMEZONEMAP(ta->map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->map)), ((timezone_map_get_type ()))))))
);
344}
345
346static void
347LoadCities (TzLocation *loc,
348 CtkListStore *CityStore)
349{
350 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *human_readable = NULL((void*)0);
351
352 human_readable = translated_city_name (loc);
353 ctk_list_store_insert_with_values (CityStore,
354 NULL((void*)0),
355 0,
356 CITY_COL_CITY_HUMAN_READABLE,
357 human_readable,
358 CITY_COL_ZONE,
359 loc->zone,
360 -1);
361}
362
363static void
364CreateCityList(TimeAdmin *ta)
365{
366 TzDB *db;
367 ta->CityListStore = ctk_list_store_new (CITY_NUM_COLS,G_TYPE_STRING((GType) ((16) << (2))),G_TYPE_STRING((GType) ((16) << (2))));
368 db = tz_load_db ();
2
Calling 'tz_load_db'
369 g_ptr_array_foreach (db->locations, (GFunc) LoadCities, ta->CityListStore);
370
371 TimeZoneDateBaseFree(db);
372}
373
374static CtkWidget*
375CreateZoneFrame(TimeAdmin *ta)
376{
377 CtkWidget *TimeZoneFrame;
378
379 TimeZoneFrame = ctk_frame_new (_("Time Zone")gettext ("Time Zone"));
380 ctk_widget_set_size_request(TimeZoneFrame,300,200);
381 ctk_frame_set_shadow_type(CTK_FRAME(TimeZoneFrame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((TimeZoneFrame)), ((ctk_frame_get_type ()))))))
,CTK_SHADOW_NONE);
382
383 return TimeZoneFrame;
384}
385
386static CtkWidget*
387CreateZoneScrolled(TimeAdmin *ta)
388{
389 CtkWidget *Scrolled;
390
391 Scrolled = ctk_scrolled_window_new (NULL((void*)0), NULL((void*)0));
392
393 ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (Scrolled)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((Scrolled)), ((ctk_scrolled_window_get_type
()))))))
,
394 CTK_POLICY_AUTOMATIC,
395 CTK_POLICY_AUTOMATIC);
396
397 ctk_scrolled_window_set_shadow_type (CTK_SCROLLED_WINDOW (Scrolled)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((Scrolled)), ((ctk_scrolled_window_get_type
()))))))
,
398 CTK_SHADOW_IN);
399
400 return Scrolled;
401}
402
403static void
404CreateZoneEntry(TimeAdmin *ta)
405{
406 CtkWidget *hbox;
407
408 ta->TimezoneEntry = ctk_search_entry_new ();
409 hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 10);
410 ctk_widget_set_halign (hbox, CTK_ALIGN_CENTER);
411 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, ta->TimezoneEntry, FALSE(0), FALSE(0), 0);
412
413 ta->SearchBar = ctk_search_bar_new ();
414 ctk_search_bar_connect_entry (CTK_SEARCH_BAR (ta->SearchBar)((((CtkSearchBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->SearchBar)), ((ctk_search_bar_get_type ()))))))
,
415 CTK_ENTRY (ta->TimezoneEntry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TimezoneEntry)), ((ctk_entry_get_type ()))))))
);
416 ctk_search_bar_set_show_close_button (CTK_SEARCH_BAR (ta->SearchBar)((((CtkSearchBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->SearchBar)), ((ctk_search_bar_get_type ()))))))
,FALSE(0));
417 ctk_container_add (CTK_CONTAINER (ta->SearchBar)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->SearchBar)), ((ctk_container_get_type ()))))))
, hbox);
418 ctk_search_bar_set_search_mode(CTK_SEARCH_BAR(ta->SearchBar)((((CtkSearchBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->SearchBar)), ((ctk_search_bar_get_type ()))))))
,TRUE(!(0)));
419}
420
421static gboolean
422CityChanged(CtkEntryCompletion *completion,
423 CtkTreeModel *model,
424 CtkTreeIter *iter,
425 TimeAdmin *self)
426{
427 CtkWidget *entry;
428 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *zone = NULL((void*)0);
429
430 ctk_tree_model_get (model,
431 iter,
432 CITY_COL_ZONE,
433 &zone,
434 -1);
435 timezone_map_set_timezone (TIMEZONEMAP (self->map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self->map)), ((timezone_map_get_type ()))))))
, zone);
436
437 entry = ctk_entry_completion_get_entry (completion);
438 ctk_entry_set_text (CTK_ENTRY (entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_entry_get_type ()))))))
, "");
439
440 return TRUE(!(0));
441}
442
443static void
444ChoooseTimezoneDone (CtkWidget *widget,
445 TimeAdmin *ta)
446{
447 TimezoneMap *map;
448
449 map = TIMEZONEMAP(ta->map)((((TimezoneMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->map)), ((timezone_map_get_type ()))))))
;
450 SetTimeZone(ta->proxy,map->location->zone);
451 ctk_entry_set_text (CTK_ENTRY (ta->TimeZoneEntry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TimeZoneEntry)), ((ctk_entry_get_type ()))))))
, _(map->location->zone)gettext (map->location->zone));
452 ctk_widget_hide_on_delete(CTK_WIDGET(ta->dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_widget_get_type ()))))))
);
453}
454
455static void
456ChoooseTimezoneClose(CtkWidget *widget,
457 TimeAdmin *ta)
458{
459 ctk_widget_hide_on_delete(CTK_WIDGET(ta->dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_widget_get_type ()))))))
);
460}
461
462void SetupTimezoneDialog(TimeAdmin *ta)
463{
464 CtkWidget *Vbox, *TimeZoneFrame, *Scrolled, *image;
465
466 ta->dialog = ctk_dialog_new_with_buttons (_("Time Zone Selection")gettext ("Time Zone Selection"),
467 NULL((void*)0),
468 CTK_DIALOG_DESTROY_WITH_PARENT,
469 NULL((void*)0),
470 NULL((void*)0));
471 ctk_window_set_default_size (CTK_WINDOW (ta->dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_window_get_type ()))))))
, 730, 520);
472
473 ta->TZclose = ctk_button_new_with_mnemonic (_("_Close")gettext ("_Close"));
474 image = ctk_image_new_from_icon_name ("window-close", CTK_ICON_SIZE_BUTTON);
475 ctk_button_set_image (CTK_BUTTON (ta->TZclose)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TZclose)), ((ctk_button_get_type ()))))))
, image);
476 ctk_button_set_use_underline (CTK_BUTTON (ta->TZclose)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TZclose)), ((ctk_button_get_type ()))))))
, TRUE(!(0)));
477 ctk_style_context_add_class (ctk_widget_get_style_context (ta->TZclose), "text-button");
478 ctk_widget_set_can_default (ta->TZclose, TRUE(!(0)));
479 ctk_dialog_add_action_widget (CTK_DIALOG (ta->dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_dialog_get_type ()))))))
, ta->TZclose, CTK_RESPONSE_CANCEL);
480
481 ta->TZconfire = ctk_button_new_with_mnemonic (_("Con_firm")gettext ("Con_firm"));
482 image = ctk_image_new_from_icon_name ("emblem-default", CTK_ICON_SIZE_BUTTON);
483 ctk_button_set_image (CTK_BUTTON (ta->TZconfire)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TZconfire)), ((ctk_button_get_type ()))))))
, image);
484 ctk_button_set_use_underline (CTK_BUTTON (ta->TZconfire)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->TZconfire)), ((ctk_button_get_type ()))))))
, TRUE(!(0)));
485 ctk_style_context_add_class (ctk_widget_get_style_context (ta->TZconfire), "text-button");
486 ctk_widget_set_can_default (ta->TZconfire, TRUE(!(0)));
487 ctk_dialog_add_action_widget (CTK_DIALOG (ta->dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_dialog_get_type ()))))))
, ta->TZconfire, CTK_RESPONSE_OK);
488
489 g_signal_connect (ta->TZconfire,g_signal_connect_data ((ta->TZconfire), ("clicked"), (((GCallback
) (ChoooseTimezoneDone))), (ta), ((void*)0), (GConnectFlags) 0
)
490 "clicked",g_signal_connect_data ((ta->TZconfire), ("clicked"), (((GCallback
) (ChoooseTimezoneDone))), (ta), ((void*)0), (GConnectFlags) 0
)
491 G_CALLBACK (ChoooseTimezoneDone),g_signal_connect_data ((ta->TZconfire), ("clicked"), (((GCallback
) (ChoooseTimezoneDone))), (ta), ((void*)0), (GConnectFlags) 0
)
492 ta)g_signal_connect_data ((ta->TZconfire), ("clicked"), (((GCallback
) (ChoooseTimezoneDone))), (ta), ((void*)0), (GConnectFlags) 0
)
;
493
494 g_signal_connect (ta->TZclose,g_signal_connect_data ((ta->TZclose), ("clicked"), (((GCallback
) (ChoooseTimezoneClose))), (ta), ((void*)0), (GConnectFlags)
0)
495 "clicked",g_signal_connect_data ((ta->TZclose), ("clicked"), (((GCallback
) (ChoooseTimezoneClose))), (ta), ((void*)0), (GConnectFlags)
0)
496 G_CALLBACK (ChoooseTimezoneClose),g_signal_connect_data ((ta->TZclose), ("clicked"), (((GCallback
) (ChoooseTimezoneClose))), (ta), ((void*)0), (GConnectFlags)
0)
497 ta)g_signal_connect_data ((ta->TZclose), ("clicked"), (((GCallback
) (ChoooseTimezoneClose))), (ta), ((void*)0), (GConnectFlags)
0)
;
498
499 Vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
500 ctk_style_context_add_class (ctk_widget_get_style_context (Vbox), "linked");
501
502
503 TimeZoneFrame = CreateZoneFrame(ta);
504 Scrolled = CreateZoneScrolled(ta);
505 ctk_container_add (CTK_CONTAINER (TimeZoneFrame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((TimeZoneFrame)), ((ctk_container_get_type ()))))))
, Scrolled);
506 CreateCityList(ta);
1
Calling 'CreateCityList'
507 CreateZoneEntry(ta);
508 ctk_box_pack_start (CTK_BOX (Vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((Vbox)), ((ctk_box_get_type ()))))))
, ta->SearchBar,FALSE(0),FALSE(0), 0);
509 ta->map = GetTimeZoneMap(ta);
510 ctk_widget_show (ta->map);
511 ctk_container_add (CTK_CONTAINER (Scrolled)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((Scrolled)), ((ctk_container_get_type ()))))))
,ta->map);
512 ctk_box_pack_start(CTK_BOX(Vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((Vbox)), ((ctk_box_get_type ()))))))
,TimeZoneFrame,TRUE(!(0)),TRUE(!(0)),10);
513 get_initial_timezone(ta);
514
515 g_signal_connect(ctk_entry_get_completion (CTK_ENTRY (ta->TimezoneEntry)),g_signal_connect_data ((ctk_entry_get_completion (((((CtkEntry
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((ta
->TimezoneEntry)), ((ctk_entry_get_type ())))))))), ("match-selected"
), (((GCallback) (CityChanged))), (ta), ((void*)0), (GConnectFlags
) 0)
516 "match-selected",g_signal_connect_data ((ctk_entry_get_completion (((((CtkEntry
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((ta
->TimezoneEntry)), ((ctk_entry_get_type ())))))))), ("match-selected"
), (((GCallback) (CityChanged))), (ta), ((void*)0), (GConnectFlags
) 0)
517 G_CALLBACK (CityChanged),g_signal_connect_data ((ctk_entry_get_completion (((((CtkEntry
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((ta
->TimezoneEntry)), ((ctk_entry_get_type ())))))))), ("match-selected"
), (((GCallback) (CityChanged))), (ta), ((void*)0), (GConnectFlags
) 0)
518 ta)g_signal_connect_data ((ctk_entry_get_completion (((((CtkEntry
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((ta
->TimezoneEntry)), ((ctk_entry_get_type ())))))))), ("match-selected"
), (((GCallback) (CityChanged))), (ta), ((void*)0), (GConnectFlags
) 0)
;
519
520 ctk_box_pack_start (CTK_BOX (ctk_dialog_get_content_area (CTK_DIALOG (ta->dialog)))((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_dialog_get_content_area (((((CtkDialog*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((ta->dialog)), ((ctk_dialog_get_type (
)))))))))), ((ctk_box_get_type ()))))))
,
521 Vbox,
522 TRUE(!(0)),
523 TRUE(!(0)), 8);
524}
525
526void tz_info_free (TzInfo *tzinfo)
527{
528 g_return_if_fail (tzinfo != NULL)do { if ((tzinfo != ((void*)0))) { } else { g_return_if_fail_warning
("time-admin-properties", ((const char*) (__func__)), "tzinfo != NULL"
); return; } } while (0)
;
529
530 if (tzinfo->tzname_normal) g_free (tzinfo->tzname_normal);
531 if (tzinfo->tzname_daylight) g_free (tzinfo->tzname_daylight);
532 g_free (tzinfo);
533}
534
535struct {
536 const char *orig;
537 const char *dest;
538} aliases[] = {
539 { "Asia/Istanbul", "Europe/Istanbul" }, /* Istanbul is in both Europe and Asia */
540 { "Europe/Nicosia", "Asia/Nicosia" }, /* Ditto */
541 { "EET", "Europe/Istanbul" }, /* Same tz as the 2 above */
542 { "HST", "Pacific/Honolulu" },
543 { "WET", "Europe/Brussels" }, /* Other name for the mainland Europe tz */
544 { "CET", "Europe/Brussels" }, /* ditto */
545 { "MET", "Europe/Brussels" },
546 { "Etc/Zulu", "Etc/GMT" },
547 { "Etc/UTC", "Etc/GMT" },
548 { "GMT", "Etc/GMT" },
549 { "Greenwich", "Etc/GMT" },
550 { "Etc/UCT", "Etc/GMT" },
551 { "Etc/GMT0", "Etc/GMT" },
552 { "Etc/GMT+0", "Etc/GMT" },
553 { "Etc/GMT-0", "Etc/GMT" },
554 { "Etc/Universal", "Etc/GMT" },
555 { "PST8PDT", "America/Los_Angeles" }, /* Other name for the Atlantic tz */
556 { "EST", "America/New_York" }, /* Other name for the Eastern tz */
557 { "EST5EDT", "America/New_York" }, /* ditto */
558 { "CST6CDT", "America/Chicago" }, /* Other name for the Central tz */
559 { "MST", "America/Denver" }, /* Other name for the mountain tz */
560 { "MST7MDT", "America/Denver" }, /* ditto */
561};
562
563static gboolean
564compare_timezones (const char *a,
565 const char *b)
566{
567 if (g_str_equal (a, b)(strcmp ((const char *) (a), (const char *) (b)) == 0))
568 return TRUE(!(0));
569 if (strchr (b, '/') == NULL((void*)0)) {
570 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *prefixed = NULL((void*)0);
571
572 prefixed = g_strdup_printf ("/%s", b);
573 if (g_str_has_suffix (a, prefixed)(__builtin_constant_p (prefixed)? __extension__ ({ const char
* const __str = (a); const char * const __suffix = (prefixed
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (a, prefixed) )
)
574 return TRUE(!(0));
575 }
576
577 return FALSE(0);
578}
579
580char *tz_info_get_clean_name (TzDB *tz_db,
581 const char *tz)
582{
583 char *ret;
584 const char *timezone;
585 guint i;
586 gboolean replaced;
587
588 /* Remove useless prefixes */
589 if (g_str_has_prefix (tz, "right/")(__builtin_constant_p ("right/")? __extension__ ({ const char
* const __str = (tz); const char * const __prefix = ("right/"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tz, "right/") )
)
590 tz = tz + strlen ("right/");
591 else if (g_str_has_prefix (tz, "posix/")(__builtin_constant_p ("posix/")? __extension__ ({ const char
* const __str = (tz); const char * const __prefix = ("posix/"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tz, "posix/") )
)
592 tz = tz + strlen ("posix/");
593
594 /* Here start the crazies */
595 replaced = FALSE(0);
596
597 for (i = 0; i < G_N_ELEMENTS (aliases)(sizeof (aliases) / sizeof ((aliases)[0])); i++) {
598 if (compare_timezones (tz, aliases[i].orig)) {
599 replaced = TRUE(!(0));
600 timezone = aliases[i].dest;
601 break;
602 }
603 }
604
605 /* Try again! */
606 if (!replaced) {
607 /* Ignore crazy solar times from the '80s */
608 if (g_str_has_prefix (tz, "Asia/Riyadh")(__builtin_constant_p ("Asia/Riyadh")? __extension__ ({ const
char * const __str = (tz); const char * const __prefix = ("Asia/Riyadh"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tz, "Asia/Riyadh") )
||
609 g_str_has_prefix (tz, "Mideast/Riyadh")(__builtin_constant_p ("Mideast/Riyadh")? __extension__ ({ const
char * const __str = (tz); const char * const __prefix = ("Mideast/Riyadh"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tz, "Mideast/Riyadh") )
) {
610 timezone = "Asia/Riyadh";
611 replaced = TRUE(!(0));
612 }
613 }
614
615 if (!replaced)
616 timezone = tz;
617
618 ret = g_hash_table_lookup (tz_db->backward, timezone);
619 if (ret == NULL((void*)0))
620 return g_strdup (timezone)g_strdup_inline (timezone);
621 return g_strdup (ret)g_strdup_inline (ret);
622}
623
624TzInfo *tz_info_from_location (TzLocation *loc)
625{
626 TzInfo *tzinfo;
627 time_t curtime;
628 struct tm *curzone;
629 g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *tz_env_value = NULL((void*)0);
630
631 g_return_val_if_fail (loc != NULL, NULL)do { if ((loc != ((void*)0))) { } else { g_return_if_fail_warning
("time-admin-properties", ((const char*) (__func__)), "loc != NULL"
); return (((void*)0)); } } while (0)
;
632 g_return_val_if_fail (loc->zone != NULL, NULL)do { if ((loc->zone != ((void*)0))) { } else { g_return_if_fail_warning
("time-admin-properties", ((const char*) (__func__)), "loc->zone != NULL"
); return (((void*)0)); } } while (0)
;
633
634 tz_env_value = g_strdup (getenv ("TZ"))g_strdup_inline (getenv ("TZ"));
635 setenv ("TZ", loc->zone, 1);
636
637#if 0
638 tzset ();
639#endif
640 tzinfo = g_new0 (TzInfo, 1)((TzInfo *) g_malloc0_n ((1), sizeof (TzInfo)));
641
642 curtime = time (NULL((void*)0));
643 curzone = localtime (&curtime);
644
645#ifndef __sun
646 tzinfo->tzname_normal = g_strdup (curzone->tm_zone)g_strdup_inline (curzone->tm_zone);
647 if (curzone->tm_isdst)
648 tzinfo->tzname_daylight =
649 g_strdup (&curzone->tm_zone[curzone->tm_isdst])g_strdup_inline (&curzone->tm_zone[curzone->tm_isdst
])
;
650 else
651 tzinfo->tzname_daylight = NULL((void*)0);
652
653 tzinfo->utc_offset = curzone->tm_gmtoff;
654#else
655 tzinfo->tzname_normal = NULL((void*)0);
656 tzinfo->tzname_daylight = NULL((void*)0);
657 tzinfo->utc_offset = 0;
658#endif
659
660 tzinfo->daylight = curzone->tm_isdst;
661
662 if (tz_env_value)
663 setenv ("TZ", tz_env_value, 1);
664 else
665 unsetenv ("TZ");
666
667 return tzinfo;
668}
669
670glong tz_location_get_utc_offset (TzLocation *loc)
671{
672 TzInfo *tz_info;
673 glong offset;
674
675 tz_info = tz_info_from_location (loc);
676 offset = tz_info->utc_offset;
677 tz_info_free (tz_info);
678
679 return offset;
680}
681
682void RunTimeZoneDialog (CtkButton *button,
683 gpointer data)
684{
685 TimeAdmin *ta = (TimeAdmin *)data;
686
687 ctk_widget_show_all(CTK_WIDGET(ta->dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ta->dialog)), ((ctk_widget_get_type ()))))))
);
688}
689
690static void
691tz_location_free (TzLocation *loc, gpointer data)
692{
693 g_free (loc->country);
694 g_free (loc->zone);
695 g_free (loc->comment);
696 g_free (loc);
697}
698
699void TimeZoneDateBaseFree (TzDB *db)
700{
701 g_ptr_array_foreach (db->locations, (GFunc) tz_location_free, NULL((void*)0));
702 g_ptr_array_free (db->locations, TRUE(!(0)));
703 g_hash_table_destroy (db->backward);
704 g_free (db);
705}
706
707GPtrArray *tz_get_locations (TzDB *db)
708{
709 return db->locations;
710}