1 /*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
79
80 /*
81 * Returns a path name created from the given 'dir' and 'name' under
82 * UNIX. This function allocates memory for the pathname calling
83 * malloc(). NULL is returned if malloc() fails.
84 */
85 static char *
86 getPathName(const char *dir, const char *name) {
87 char *path;
88
89 path = (char *) malloc(strlen(dir) + strlen(name) + 2);
90 if (path == NULL) {
91 return NULL;
92 }
93 return strcat(strcat(strcpy(path, dir), "/"), name);
94 }
95
96 /*
97 * Scans the specified directory and its subdirectories to find a
98 * zoneinfo file which has the same content as /etc/localtime on Linux
99 * or /usr/share/lib/zoneinfo/localtime (most likely a symbolic link)
100 * on Solaris given in 'buf'. Returns a zone ID if found, otherwise,
101 * NULL is returned.
102 */
103 static char *
104 findZoneinfoFile(char *buf, size_t size, const char *dir)
105 {
106 DIR *dirp = NULL;
107 struct stat statbuf;
108 struct dirent *dp = NULL;
109 struct dirent *entry = NULL;
110 char *pathname = NULL;
111 int fd = -1;
112 char *dbuf = NULL;
113 char *tz = NULL;
114
115 dirp = opendir(dir);
116 if (dirp == NULL) {
117 return NULL;
118 }
119
120 entry = (struct dirent *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
121 if (entry == NULL) {
263 /*
264 * If it's a symlink, get the link name and its zone ID part. (The
265 * older versions of timeconfig created a symlink as described in
266 * the Red Hat man page. It was changed in 1999 to create a copy
267 * of a zoneinfo file. It's no longer possible to get the zone ID
268 * from /etc/localtime.)
269 */
270 if (S_ISLNK(statbuf.st_mode)) {
271 char linkbuf[PATH_MAX+1];
272 int len;
273
274 if ((len = readlink(DEFAULT_ZONEINFO_FILE, linkbuf, sizeof(linkbuf)-1)) == -1) {
275 jio_fprintf(stderr, (const char *) "can't get a symlink of %s\n",
276 DEFAULT_ZONEINFO_FILE);
277 return NULL;
278 }
279 linkbuf[len] = '\0';
280 tz = getZoneName(linkbuf);
281 if (tz != NULL) {
282 tz = strdup(tz);
283 }
284 return tz;
285 }
286
287 /*
288 * If it's a regular file, we need to find out the same zoneinfo file
289 * that has been copied as /etc/localtime.
290 */
291 size = (size_t) statbuf.st_size;
292 buf = (char *) malloc(size);
293 if (buf == NULL) {
294 return NULL;
295 }
296 if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
297 free((void *) buf);
298 return NULL;
299 }
300
301 if (read(fd, buf, size) != (ssize_t) size) {
302 (void) close(fd);
303 free((void *) buf);
304 return NULL;
305 }
306 (void) close(fd);
307
308 tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
309 free((void *) buf);
310 return tz;
311 }
312 #else
313 #ifdef __solaris__
314 #if !defined(__sparcv9) && !defined(amd64)
315
316 /*
317 * Those file* functions mimic the UNIX stream io functions. This is
318 * because of the limitation of the number of open files on Solaris
319 * (32-bit mode only) due to the System V ABI.
|
1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
79
80 /*
81 * Returns a path name created from the given 'dir' and 'name' under
82 * UNIX. This function allocates memory for the pathname calling
83 * malloc(). NULL is returned if malloc() fails.
84 */
85 static char *
86 getPathName(const char *dir, const char *name) {
87 char *path;
88
89 path = (char *) malloc(strlen(dir) + strlen(name) + 2);
90 if (path == NULL) {
91 return NULL;
92 }
93 return strcat(strcat(strcpy(path, dir), "/"), name);
94 }
95
96 /*
97 * Scans the specified directory and its subdirectories to find a
98 * zoneinfo file which has the same content as /etc/localtime on Linux
99 * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
100 * If file is symbolic link, then the contents it points to are in buf.
101 * Returns a zone ID if found, otherwise, NULL is returned.
102 */
103 static char *
104 findZoneinfoFile(char *buf, size_t size, const char *dir)
105 {
106 DIR *dirp = NULL;
107 struct stat statbuf;
108 struct dirent *dp = NULL;
109 struct dirent *entry = NULL;
110 char *pathname = NULL;
111 int fd = -1;
112 char *dbuf = NULL;
113 char *tz = NULL;
114
115 dirp = opendir(dir);
116 if (dirp == NULL) {
117 return NULL;
118 }
119
120 entry = (struct dirent *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
121 if (entry == NULL) {
263 /*
264 * If it's a symlink, get the link name and its zone ID part. (The
265 * older versions of timeconfig created a symlink as described in
266 * the Red Hat man page. It was changed in 1999 to create a copy
267 * of a zoneinfo file. It's no longer possible to get the zone ID
268 * from /etc/localtime.)
269 */
270 if (S_ISLNK(statbuf.st_mode)) {
271 char linkbuf[PATH_MAX+1];
272 int len;
273
274 if ((len = readlink(DEFAULT_ZONEINFO_FILE, linkbuf, sizeof(linkbuf)-1)) == -1) {
275 jio_fprintf(stderr, (const char *) "can't get a symlink of %s\n",
276 DEFAULT_ZONEINFO_FILE);
277 return NULL;
278 }
279 linkbuf[len] = '\0';
280 tz = getZoneName(linkbuf);
281 if (tz != NULL) {
282 tz = strdup(tz);
283 return tz;
284 }
285 }
286
287 /*
288 * If it's a regular file, we need to find out the same zoneinfo file
289 * that has been copied as /etc/localtime.
290 * If initial symbolic link resolution failed, we should treat target
291 * file as a regular file.
292 */
293 if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
294 return NULL;
295 }
296 if (fstat(fd, &statbuf) == -1) {
297 return NULL;
298 }
299 size = (size_t) statbuf.st_size;
300 buf = (char *) malloc(size);
301 if (buf == NULL) {
302 return NULL;
303 }
304
305 if (read(fd, buf, size) != (ssize_t) size) {
306 (void) close(fd);
307 free((void *) buf);
308 return NULL;
309 }
310 (void) close(fd);
311
312 tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
313 free((void *) buf);
314 return tz;
315 }
316 #else
317 #ifdef __solaris__
318 #if !defined(__sparcv9) && !defined(amd64)
319
320 /*
321 * Those file* functions mimic the UNIX stream io functions. This is
322 * because of the limitation of the number of open files on Solaris
323 * (32-bit mode only) due to the System V ABI.
|