Fixed timezone detection on linux.
Fix originally proposed via IRC by myth0s Original changeset at https://paste.debian.net/hidden/0a03314a/
This commit is contained in:
parent
b3ae8cec8d
commit
1d9e886a7f
@ -95,13 +95,16 @@ static char* winpr_read_unix_timezone_identifier_from_file(FILE* fp)
|
||||
return tzid;
|
||||
}
|
||||
|
||||
static char* winpr_get_timezone_from_link(void)
|
||||
static char* winpr_get_timezone_from_link(const char* links[], size_t count)
|
||||
{
|
||||
const char* links[] = { "/etc/localtime", "/etc/TZ" };
|
||||
const char* _links[] = { "/etc/localtime", "/etc/TZ" };
|
||||
size_t x;
|
||||
ssize_t len;
|
||||
char buf[1024];
|
||||
char* tzid = NULL;
|
||||
|
||||
if (links == NULL)
|
||||
{
|
||||
links = _links;
|
||||
count = ARRAYSIZE(_links);
|
||||
}
|
||||
|
||||
/*
|
||||
* On linux distros such as Redhat or Archlinux, a symlink at /etc/localtime
|
||||
@ -110,42 +113,53 @@ static char* winpr_get_timezone_from_link(void)
|
||||
* Some distributions do have to symlink at /etc/TZ.
|
||||
*/
|
||||
|
||||
for (x = 0; x < sizeof(links) / sizeof(links[0]); x++)
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
char* tzid = NULL;
|
||||
const char* link = links[x];
|
||||
char* buf = realpath(link, NULL);
|
||||
|
||||
if ((len = readlink(link, buf, sizeof(buf) - 1)) != -1)
|
||||
if (buf)
|
||||
{
|
||||
int num = 0;
|
||||
size_t alloc;
|
||||
SSIZE_T pos = len;
|
||||
buf[len] = '\0';
|
||||
size_t i;
|
||||
size_t sep = 0;
|
||||
size_t alloc = 0;
|
||||
size_t pos = 0;
|
||||
size_t len = pos = strlen(buf);
|
||||
|
||||
/* find the position of the 2nd to last "/" */
|
||||
|
||||
while (num < 2)
|
||||
for (i = 1; i <= len; i++)
|
||||
{
|
||||
if (pos == 0)
|
||||
const size_t curpos = len - i;
|
||||
const char cur = buf[curpos];
|
||||
|
||||
if (cur == '/')
|
||||
sep++;
|
||||
if (sep >= 2)
|
||||
{
|
||||
alloc = i;
|
||||
pos = len - i + 1;
|
||||
break;
|
||||
|
||||
pos -= 1;
|
||||
|
||||
if (buf[pos] == '/')
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((len < 0) || (pos < 0) || (pos > len))
|
||||
return NULL;
|
||||
if ((len == 0) || (sep != 2))
|
||||
goto end;
|
||||
|
||||
alloc = (size_t)len - (size_t)pos;
|
||||
tzid = (char*)malloc(alloc + 1);
|
||||
tzid = (char*)calloc(alloc + 1, sizeof(char));
|
||||
|
||||
if (!tzid)
|
||||
return NULL;
|
||||
goto end;
|
||||
|
||||
strncpy(tzid, buf + pos + 1, alloc);
|
||||
return tzid;
|
||||
strncpy(tzid, &buf[pos], alloc);
|
||||
WLog_INFO(TAG, "winpr_get_timezone_from_link: tzid: %s", tzid);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
free(buf);
|
||||
if (tzid)
|
||||
return tzid;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -249,6 +263,8 @@ static char* winpr_get_unix_timezone_identifier_from_file(void)
|
||||
|
||||
tzid = winpr_read_unix_timezone_identifier_from_file(fp);
|
||||
fclose(fp);
|
||||
if (tzid != NULL)
|
||||
WLog_INFO(TAG, "winpr_get_unix_timezone_identifier_from_file: tzid: %s", tzid);
|
||||
return tzid;
|
||||
#endif
|
||||
}
|
||||
@ -284,7 +300,7 @@ static BOOL winpr_match_unix_timezone_identifier_with_list(const char* tzid, con
|
||||
static TIME_ZONE_ENTRY* winpr_detect_windows_time_zone(void)
|
||||
{
|
||||
size_t i, j;
|
||||
char* tzid = NULL;
|
||||
char *tzid = NULL, *ntzid = NULL;
|
||||
LPCSTR tz = "TZ";
|
||||
|
||||
DWORD nSize = GetEnvironmentVariableA(tz, NULL, 0);
|
||||
@ -302,11 +318,29 @@ static TIME_ZONE_ENTRY* winpr_detect_windows_time_zone(void)
|
||||
tzid = winpr_get_unix_timezone_identifier_from_file();
|
||||
|
||||
if (tzid == NULL)
|
||||
tzid = winpr_get_timezone_from_link();
|
||||
{
|
||||
tzid = winpr_get_timezone_from_link(NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* zipath = "/usr/share/zoneinfo/";
|
||||
char buf[1024] = { 0 };
|
||||
const char* links[] = { buf };
|
||||
|
||||
snprintf(buf, ARRAYSIZE(buf), "%s%s", zipath, tzid);
|
||||
ntzid = winpr_get_timezone_from_link(links, 1);
|
||||
if (ntzid != NULL)
|
||||
{
|
||||
free(tzid);
|
||||
tzid = ntzid;
|
||||
}
|
||||
}
|
||||
|
||||
if (tzid == NULL)
|
||||
return NULL;
|
||||
|
||||
WLog_INFO(TAG, "tzid: %s", tzid);
|
||||
|
||||
for (i = 0; i < TimeZoneTableNrElements; i++)
|
||||
{
|
||||
const TIME_ZONE_ENTRY* tze = &TimeZoneTable[i];
|
||||
|
Loading…
Reference in New Issue
Block a user