5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #define ETC_LOCALTIME "/etc/localtime"
38 #define ETC_SYSCONFIG_CLOCK "/etc/sysconfig/clock"
39 #define USR_SHARE_ZONEINFO "/usr/share/zoneinfo"
41 static char *read_key_file(const char *pathname, const char *key)
44 char *map, *ptr, *str;
48 fd = open(pathname, O_RDONLY);
52 if (fstat(fd, &st) < 0) {
57 map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
58 if (map == NULL || map == MAP_FAILED) {
67 while (ptrlen > keylen + 1) {
68 int cmp = strncmp(ptr, key, keylen);
74 if (*(ptr - 1) == '\n' && *(ptr + keylen) == '=')
78 ptr = memchr(ptr + 1, key[0], ptrlen - 1);
82 ptrlen = st.st_size - (ptr - map);
88 ptrlen = st.st_size - (ptr - map);
90 end = memchr(ptr, '\n', ptrlen);
94 val = memchr(ptr, '"', ptrlen);
96 end = memchr(val + 1, '"', end - val - 1);
98 str = strndup(val + 1, end - val - 1);
102 str = strndup(ptr + keylen + 1, ptrlen - keylen - 1);
106 munmap(map, st.st_size);
113 static int compare_file(void *src_map, struct stat *src_st,
114 const char *pathname)
120 fd = open(pathname, O_RDONLY);
124 if (fstat(fd, &dst_st) < 0) {
129 if (src_st->st_size != dst_st.st_size) {
134 dst_map = mmap(0, dst_st.st_size, PROT_READ, MAP_SHARED, fd, 0);
135 if (dst_map == NULL || dst_map == MAP_FAILED) {
140 result = memcmp(src_map, dst_map, src_st->st_size);
142 munmap(dst_map, dst_st.st_size);
149 static char *find_origin(void *src_map, struct stat *src_st,
150 const char *basepath)
154 char *str, pathname[PATH_MAX];
156 dir = opendir(basepath);
160 while ((d = readdir(dir))) {
161 if (strcmp(d->d_name, ".") == 0 ||
162 strcmp(d->d_name, "..") == 0 ||
163 strcmp(d->d_name, "posix") == 0 ||
164 strcmp(d->d_name, "right") == 0)
167 snprintf(pathname, PATH_MAX, "%s/%s", basepath, d->d_name);
171 if (compare_file(src_map, src_st, pathname) == 0) {
173 return strdup(d->d_name);
177 str = find_origin(src_map, src_st, pathname);
191 char *__connman_timezone_lookup(void)
198 zone = read_key_file(ETC_SYSCONFIG_CLOCK, "ZONE");
200 DBG("sysconfig zone %s", zone);
202 fd = open(ETC_LOCALTIME, O_RDONLY);
208 if (fstat(fd, &st) < 0)
211 if (S_ISREG(st.st_mode)) {
212 map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
213 if (map == NULL || map == MAP_FAILED) {
221 char pathname[PATH_MAX];
223 snprintf(pathname, PATH_MAX, "%s/%s",
224 USR_SHARE_ZONEINFO, zone);
226 if (compare_file(map, &st, pathname) != 0) {
233 zone = find_origin(map, &st, USR_SHARE_ZONEINFO);
235 munmap(map, st.st_size);
244 DBG("localtime zone %s", zone);