diff options
Diffstat (limited to 'winsup/utils/tzset.c')
-rw-r--r-- | winsup/utils/tzset.c | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/winsup/utils/tzset.c b/winsup/utils/tzset.c deleted file mode 100644 index 2b3f413be..000000000 --- a/winsup/utils/tzset.c +++ /dev/null @@ -1,243 +0,0 @@ -/* tzset.c: Convert current Windows timezone to POSIX timezone information. - - Copyright 2012, 2013, 2014 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include <errno.h> -#include <stdio.h> -#include <inttypes.h> -#include <wchar.h> -#include <locale.h> -#include <getopt.h> -#include <cygwin/version.h> -#include <windows.h> - -#ifndef GEOID_NOT_AVAILABLE -#define GEOID_NOT_AVAILABLE -1 -#endif - -/* The auto-generated tzmap.h contains the mapping table from Windows timezone - and country per ISO 3166-1 to POSIX timezone. For more info, see the file - itself. */ -#include "tzmap.h" - -#define TZMAP_SIZE (sizeof tzmap / sizeof tzmap[0]) - -static struct option longopts[] = -{ - {"help", no_argument, NULL, 'h' }, - {"version", no_argument, NULL, 'V'}, - {NULL, 0, NULL, 0} -}; - -static char opts[] = "hV"; - -#define REG_TZINFO L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation" -#define REG_TZDB L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones" - -static inline HKEY -reg_open (HKEY pkey, PCWSTR path, const char *msg) -{ - LONG ret; - HKEY hkey; - - ret = RegOpenKeyExW (pkey, path, 0, KEY_READ, &hkey); - if (ret == ERROR_SUCCESS) - return hkey; - if (msg) - fprintf (stderr, "%s: cannot open registry %s, error code %" PRIu32 "\n", - program_invocation_short_name, msg, (unsigned int) ret); - return NULL; -} - -/* For symmetry */ -#define reg_close(hkey) RegCloseKey(hkey) - -static inline BOOL -reg_query (HKEY hkey, PCWSTR value, PWCHAR buf, DWORD size, const char *msg) -{ - LONG ret; - DWORD type; - - ret = RegQueryValueExW (hkey, value, 0, &type, (LPBYTE) buf, &size); - if (ret == ERROR_SUCCESS) - return TRUE; - if (msg) - fprintf (stderr, "%s: cannot query registry %s, error code %" PRIu32 "\n", - program_invocation_short_name, msg, (unsigned int) ret); - return FALSE; -} - -static inline BOOL -reg_enum (HKEY hkey, int idx, PWCHAR name, DWORD size) -{ - return RegEnumKeyExW (hkey, idx, name, &size, NULL, NULL, NULL, NULL) - == ERROR_SUCCESS; -} - -static void -usage (FILE *stream) -{ - fprintf (stream, "" - "Usage: %1$s [OPTION]\n" - "\n" - "Print POSIX-compatible timezone ID from current Windows timezone setting\n" - "\n" - "Options:\n" - " -h, --help output usage information and exit.\n" - " -V, --version output version information and exit.\n" - "\n" - "Use %1$s to set your TZ variable. In POSIX-compatible shells like bash,\n" - "dash, mksh, or zsh:\n" - "\n" - " export TZ=$(%1$s)\n" - "\n" - "In csh-compatible shells like tcsh:\n" - "\n" - " setenv TZ `%1$s`\n" - "\n", program_invocation_short_name); -}; - -static void -print_version () -{ - printf ("tzset (cygwin) %d.%d.%d\n" - "POSIX-timezone generator\n" - "Copyright (C) 2012 - %s Red Hat, Inc.\n" - "This is free software; see the source for copying conditions. There is NO\n" - "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", - CYGWIN_VERSION_DLL_MAJOR / 1000, - CYGWIN_VERSION_DLL_MAJOR % 1000, - CYGWIN_VERSION_DLL_MINOR, - strrchr (__DATE__, ' ') + 1); -} - -int -main (int argc, char **argv) -{ - BOOL ret; - HKEY hkey, skey; - WCHAR keyname[256], stdname[256], std2name[256], country[10], *spc; - GEOID geo; - int opt, idx, gotit = -1; - - setlocale (LC_ALL, ""); - while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) - switch (opt) - { - case 'h': - usage (stdout); - return 0; - case 'V': - print_version (); - return 0; - default: - fprintf (stderr, "Try `%s --help' for more information.\n", - program_invocation_short_name); - return 1; - } - if (optind < argc) - { - usage (stderr); - return 1; - } - - /* First fetch current timezone information from registry. */ - hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZINFO, "timezone information"); - if (!hkey) - return 1; - /* Vista introduced the TimeZoneKeyName value, which simplifies the - job a lot. */ - if (!reg_query (hkey, L"TimeZoneKeyName", keyname, sizeof keyname, NULL)) - { - /* Pre-Vista we have a lot more to do. First fetch the name of the - Standard (non-DST) timezone. If we can't get that, give up. */ - if (!reg_query (hkey, L"StandardName", stdname, sizeof stdname, - "timezone information")) - { - reg_close (hkey); - return 1; - } - reg_close (hkey); - /* Now open the timezone database registry key. Every subkey is a - timezone. The key name is what we're after, but to find the right - one, we have to compare the name of the previously fetched - "StandardName" with the "Std" value in the timezone info... */ - hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZDB, "timezone database"); - if (!hkey) - return 1; - for (idx = 0; reg_enum (hkey, idx, keyname, sizeof keyname); ++idx) - { - skey = reg_open (hkey, keyname, NULL); - if (skey) - { - /* ...however, on MUI-enabled machines, the names are not stored - directly in the above StandardName, rather it is a resource - pointer into tzres.dll. This is stored in MUI_Std. - Fortunately it's easy to recognize this situation: If - StandardName starts with @, it's a resource pointer, otherwise - it's the cleartext value. */ - ret = reg_query (skey, stdname[0] == L'@' ? L"MUI_Std" : L"Std", - std2name, sizeof std2name, NULL); - reg_close (skey); - if (ret && !wcscmp (stdname, std2name)) - break; - } - } - } - reg_close (hkey); - - /* We fetch the current Geo-location of the user and convert it to an - ISO 3166-1 compatible nation code. */ - *country = L'\0'; - geo = GetUserGeoID (GEOCLASS_NATION); - if (geo != GEOID_NOT_AVAILABLE) - GetGeoInfoW (geo, GEO_ISO2, country, sizeof country, 0); - /* If, for some reason, the Geo-location isn't available, we use the locale - setting instead. */ - if (!*country) - GetLocaleInfoW (LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, - country, sizeof country); - - /* Now iterate over the mapping table and find the right entry. */ - for (idx = 0; idx < TZMAP_SIZE; ++idx) - { - if (!wcscmp (keyname, tzmap[idx].win_tzkey)) - { - if (gotit < 0) - gotit = idx; - if (!wcscmp (country, tzmap[idx].country)) - break; - } - else if (gotit >= 0) - { - idx = gotit; - break; - } - } - if (idx >= TZMAP_SIZE) - { - if (gotit < 0) - { - fprintf (stderr, - "%s: can't find matching POSIX timezone for " - "Windows timezone \"%ls\"\n", - program_invocation_short_name, keyname); - return 1; - } - idx = gotit; - } - /* Got one. Print it. - Note: The tzmap array is in the R/O data section on x86_64. Don't - try to overwrite the space, as the code did originally. */ - spc = wcschr (tzmap[idx].posix_tzid, L' '); - if (!spc) - spc = wcschr (tzmap[idx].posix_tzid, L'\0'); - printf ("%.*ls\n", (int) (spc - tzmap[idx].posix_tzid), tzmap[idx].posix_tzid); - return 0; -} |