/* * Author: Chris Lord * * Copyright (c) 2007 OpenedHand Ltd - http://www.openedhand.com/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ /** * SECTION:jana-ecal-utils * @short_description: A set of utility functions for libjana-ecal * * jana-ecal-utils contains a set of libjana-ecal related utility functions. */ #include #include #include #include #include #include "jana-ecal-utils.h" /** * jana_ecal_utils_time_now: * @location: A full timezone name * * Creates a new #JanaEcalTime with the current time of the given location. * * Returns: A new #JanaEcalTime, cast as a #JanaTime. */ JanaTime * jana_ecal_utils_time_now (const gchar *location) { icaltimetype ical_time; const icaltimezone *zone; zone = (const icaltimezone *)icaltimezone_get_builtin_timezone ( location); ical_time = icaltime_current_time_with_zone (zone); icaltime_set_timezone (&ical_time, zone); return jana_ecal_time_new_from_icaltime (&ical_time); } /** * jana_ecal_utils_time_today: * @location: A full timezone name * * Creates a new #JanaEcalTime with the current date of the given location. * * Returns: A new #JanaEcalTime, cast as a #JanaTime. */ JanaTime * jana_ecal_utils_time_today (const gchar *location) { JanaTime *time; icaltimetype ical_time; const icaltimezone *zone; zone = (const icaltimezone *)icaltimezone_get_builtin_timezone ( location); ical_time = icaltime_current_time_with_zone (zone); icaltime_set_timezone (&ical_time, zone); time = jana_ecal_time_new_from_icaltime (&ical_time); jana_time_set_isdate (time, TRUE); return time; } /** * jana_ecal_utils_guess_location: * * Tries to guess the location by checking for common system files and * finally falling back on the first location that matches the current * system timezone. * * Returns: A newly allocated string with the guessed location. */ gchar * jana_ecal_utils_guess_location () { gint i; FILE *file; gchar *tzname; gchar string[128]; icaltimetype today; icalarray *builtin; time_t now_t = time (NULL); struct tm *now = localtime (&now_t); /* Debian systems have /etc/timezone */ if ((file = fopen ("/etc/timezone", "r"))) { if ((fgets (string, 128, file)) && (string[0] != '\0')) { gint c; fclose (file); for (c = 0; (string[c] != '\0') && (string[c] != '\n'); c++); string[c] = '\0'; return g_strdup (string); } fclose (file); } #if GLIB_CHECK_VERSION(2,14,0) /* OpenSuSE (and RH?) systems have /etc/sysconfig/clock */ if ((file = fopen ("/etc/sysconfig/clock", "r"))) { GRegex *regex; GError *error = NULL; regex = g_regex_new ("TIMEZONE *= *\".*\"", G_REGEX_OPTIMIZE, 0, &error); if (!regex) { g_warning ("Failed to create regex: %s", error->message); g_error_free (error); } else while (fgets (string, 128, file)) { GMatchInfo *match_info; if (g_regex_match (regex, string, 0, &match_info)) { gchar *zone; gchar *match = g_match_info_fetch ( match_info, 0); g_match_info_free (match_info); g_regex_unref (regex); fclose (file); if (match[strlen (match) - 2] == '\n') match[strlen (match)-2] = '\0'; else match[strlen (match)-1] = '\0'; zone = g_strdup (strchr (match, '\"') + 1); g_free (match); return zone; } g_match_info_free (match_info); } if (regex) g_regex_unref (regex); fclose (file); } #endif /* Fallback to first location that matches libc timezone and the * offset for the current time. */ today = icaltime_today (); tzname = jana_utils_get_local_tzname (); builtin = icaltimezone_get_builtin_timezones (); for (i = 0; i < builtin->num_elements; i++) { icaltimezone *zone = (icaltimezone *)icalarray_element_at ( builtin, i); gchar *zone_tz; int offset; offset = icaltimezone_get_utc_offset (zone, &today, NULL); zone_tz = icaltimezone_get_tznames (zone); if (zone_tz && (strcasecmp (tzname, zone_tz) == 0) && (offset == now->tm_gmtoff)) { g_free (tzname); return g_strdup (icaltimezone_get_display_name (zone)); } } g_free (tzname); /* No matching timezone found, fall back to UTC */ return g_strdup ("UTC"); } /** * jana_ecal_utils_get_locations: * * Retrieves the built-in list of timezone locations from libecal. * * Returns: A newly allocated string array, to be freed with g_strfreev(). */ gchar ** jana_ecal_utils_get_locations () { gint i, z; icalarray *builtin; gchar **locations; builtin = icaltimezone_get_builtin_timezones (); locations = g_new0 (gchar *, builtin->num_elements + 1); for (i = 0, z = 0; i < builtin->num_elements; i++) { icaltimezone *zone = (icaltimezone *)icalarray_element_at ( builtin, i); /* Don't return zones that don't have a tzname */ if (icaltimezone_get_tznames (zone)) { locations[z] = g_strdup ( icaltimezone_get_display_name (zone)); z++; } } return locations; }