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
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <strings.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <errno.h>
32 #include <stddef.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <string.h>
36 #include <dirent.h>
37 #include <unistd.h>
38 #if defined(__solaris__)
39 #include <libscf.h>
40 #endif
41
42 #include "jvm.h"
43 #include "TimeZone_md.h"
44
45 static char *isFileIdentical(char* buf, size_t size, char *pathname);
46
47 #define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
48
49 #define RESTARTABLE(_cmd, _result) do { \
50 do { \
51 _result = _cmd; \
52 } while((_result == -1) && (errno == EINTR)); \
53 } while(0)
54
55 #if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
56 #define fileopen fopen
57 #define filegets fgets
58 #define fileclose fclose
59 #endif
60
61 #if defined(_ALLBSD_SOURCE)
62 #define stat64 stat
63 #define lstat64 lstat
64 #define fstat64 fstat
65 #endif
66
67 #if defined(__linux__) || defined(_ALLBSD_SOURCE)
68 static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
69 static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
70 static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
71 #else
72 static const char *SYS_INIT_FILE = "/etc/default/init";
73 static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
74 static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
75 #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
76
77 static const char popularZones[][4] = {"UTC", "GMT"};
78
79 #if defined(_AIX)
80 static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
81 #endif
82
83 #if defined(__linux__) || defined(MACOSX) || defined(__solaris__)
84
85 /*
86 * Returns a pointer to the zone ID portion of the given zoneinfo file
87 * name, or NULL if the given string doesn't contain "zoneinfo/".
88 */
89 static char *
90 getZoneName(char *str)
91 {
92 static const char *zidir = "zoneinfo/";
93
94 char *pos = strstr((const char *)str, zidir);
95 if (pos == NULL) {
96 return NULL;
97 }
98 return pos + strlen(zidir);
99 }
100
101 /*
102 * Returns a path name created from the given 'dir' and 'name' under
103 * UNIX. This function allocates memory for the pathname calling
147 }
148
149 dirp = opendir(dir);
150 if (dirp == NULL) {
151 return NULL;
152 }
153
154 while ((dp = readdir(dirp)) != NULL) {
155 /*
156 * Skip '.' and '..' (and possibly other .* files)
157 */
158 if (dp->d_name[0] == '.') {
159 continue;
160 }
161
162 /*
163 * Skip "ROC", "posixrules", and "localtime".
164 */
165 if ((strcmp(dp->d_name, "ROC") == 0)
166 || (strcmp(dp->d_name, "posixrules") == 0)
167 #if defined(__solaris__)
168 /*
169 * Skip the "src" and "tab" directories on Solaris.
170 */
171 || (strcmp(dp->d_name, "src") == 0)
172 || (strcmp(dp->d_name, "tab") == 0)
173 #endif
174 || (strcmp(dp->d_name, "localtime") == 0)) {
175 continue;
176 }
177
178 pathname = getPathName(dir, dp->d_name);
179 if (pathname == NULL) {
180 break;
181 }
182
183 tz = isFileIdentical(buf, size, pathname);
184 free((void *) pathname);
185 pathname = NULL;
186 if (tz != NULL) {
187 break;
188 }
189 }
190
191 if (dirp != NULL) {
192 (void) closedir(dirp);
193 }
225 if (fd == -1) {
226 goto freedata;
227 }
228 RESTARTABLE(read(fd, dbuf, size), res);
229 if (res != (ssize_t) size) {
230 goto freedata;
231 }
232 if (memcmp(buf, dbuf, size) == 0) {
233 possibleMatch = getZoneName(pathname);
234 if (possibleMatch != NULL) {
235 possibleMatch = strdup(possibleMatch);
236 }
237 }
238 freedata:
239 free((void *) dbuf);
240 (void) close(fd);
241 }
242 return possibleMatch;
243 }
244
245 #if defined(__linux__) || defined(MACOSX)
246
247 /*
248 * Performs Linux specific mapping and returns a zone ID
249 * if found. Otherwise, NULL is returned.
250 */
251 static char *
252 getPlatformTimeZoneID()
253 {
254 struct stat64 statbuf;
255 char *tz = NULL;
256 FILE *fp;
257 int fd;
258 char *buf;
259 size_t size;
260 int res;
261
262 #if defined(__linux__)
263 /*
264 * Try reading the /etc/timezone file for Debian distros. There's
265 * no spec of the file format available. This parsing assumes that
266 * there's one line of an Olson tzid followed by a '\n', no
336 size = (size_t) statbuf.st_size;
337 buf = (char *) malloc(size);
338 if (buf == NULL) {
339 (void) close(fd);
340 return NULL;
341 }
342
343 RESTARTABLE(read(fd, buf, size), res);
344 if (res != (ssize_t) size) {
345 (void) close(fd);
346 free((void *) buf);
347 return NULL;
348 }
349 (void) close(fd);
350
351 tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
352 free((void *) buf);
353 return tz;
354 }
355
356 #elif defined(__solaris__)
357
358 #if !defined(__sparcv9) && !defined(amd64)
359
360 /*
361 * Those file* functions mimic the UNIX stream io functions. This is
362 * because of the limitation of the number of open files on Solaris
363 * (32-bit mode only) due to the System V ABI.
364 */
365
366 #define BUFFER_SIZE 4096
367
368 static struct iobuffer {
369 int magic; /* -1 to distinguish from the real FILE */
370 int fd; /* file descriptor */
371 char *buffer; /* pointer to buffer */
372 char *ptr; /* current read pointer */
373 char *endptr; /* end pointer */
374 };
375
376 static int
377 fileclose(FILE *stream)
378 {
379 struct iobuffer *iop = (struct iobuffer *) stream;
380
381 if (iop->magic != -1) {
382 return fclose(stream);
383 }
384
385 if (iop == NULL) {
386 return 0;
387 }
388 close(iop->fd);
389 free((void *)iop->buffer);
390 free((void *)iop);
391 return 0;
392 }
393
394 static FILE *
395 fileopen(const char *fname, const char *fmode)
396 {
397 FILE *fp;
398 int fd;
399 struct iobuffer *iop;
400
401 if ((fp = fopen(fname, fmode)) != NULL) {
402 return fp;
403 }
404
405 /*
406 * It assumes read open.
407 */
408 RESTARTABLE(open(fname, O_RDONLY), fd);
409 if (fd == -1) {
410 return NULL;
411 }
412
413 /*
414 * Allocate struct iobuffer and its buffer
415 */
416 iop = malloc(sizeof(struct iobuffer));
417 if (iop == NULL) {
418 (void) close(fd);
419 errno = ENOMEM;
420 return NULL;
421 }
422 iop->magic = -1;
423 iop->fd = fd;
424 iop->buffer = malloc(BUFFER_SIZE);
425 if (iop->buffer == NULL) {
426 (void) close(fd);
427 free((void *) iop);
428 errno = ENOMEM;
429 return NULL;
430 }
431 iop->ptr = iop->buffer;
432 iop->endptr = iop->buffer;
433 return (FILE *)iop;
434 }
435
436 /*
437 * This implementation assumes that n is large enough and the line
438 * separator is '\n'.
439 */
440 static char *
441 filegets(char *s, int n, FILE *stream)
442 {
443 struct iobuffer *iop = (struct iobuffer *) stream;
444 char *p;
445
446 if (iop->magic != -1) {
447 return fgets(s, n, stream);
448 }
449
450 p = s;
451 for (;;) {
452 char c;
453
454 if (iop->ptr == iop->endptr) {
455 ssize_t len;
456
457 RESTARTABLE(read(iop->fd, (void *)iop->buffer, BUFFER_SIZE), len);
458 if (len == -1) {
459 return NULL;
460 }
461 if (len == 0) {
462 *p = 0;
463 if (s == p) {
464 return NULL;
465 }
466 return s;
467 }
468 iop->ptr = iop->buffer;
469 iop->endptr = iop->buffer + len;
470 }
471 c = *iop->ptr++;
472 *p++ = c;
473 if ((p - s) == (n - 1)) {
474 *p = 0;
475 return s;
476 }
477 if (c == '\n') {
478 *p = 0;
479 return s;
480 }
481 }
482 /*NOTREACHED*/
483 }
484 #endif /* !defined(__sparcv9) && !defined(amd64) */
485
486 /*
487 * Performs Solaris dependent mapping. Returns a zone ID if
488 * found. Otherwise, NULL is returned. Solaris libc looks up
489 * "/etc/default/init" to get the default TZ value if TZ is not defined
490 * as an environment variable.
491 */
492 static char *
493 getPlatformTimeZoneID()
494 {
495 char *tz = NULL;
496 FILE *fp;
497
498 /*
499 * Try the TZ entry in /etc/default/init.
500 */
501 if ((fp = fileopen(SYS_INIT_FILE, "r")) != NULL) {
502 char line[256];
503 char quote = '\0';
504
505 while (filegets(line, sizeof(line), fp) != NULL) {
506 char *p = line;
507 char *s;
508 char c;
509
510 /* quick check for comment lines */
511 if (*p == '#') {
512 continue;
513 }
514 if (strncmp(p, "TZ=", 3) == 0) {
515 p += 3;
516 SKIP_SPACE(p);
517 c = *p;
518 if (c == '"' || c == '\'') {
519 quote = c;
520 p++;
521 }
522
523 /*
524 * PSARC/2001/383: quoted string support
525 */
526 for (s = p; (c = *s) != '\0' && c != '\n'; s++) {
527 /* No '\\' is supported here. */
528 if (c == quote) {
529 quote = '\0';
530 break;
531 }
532 if (c == ' ' && quote == '\0') {
533 break;
534 }
535 }
536 if (quote != '\0') {
537 jio_fprintf(stderr, "ZoneInfo: unterminated time zone name in /etc/TIMEZONE\n");
538 }
539 *s = '\0';
540 tz = strdup(p);
541 break;
542 }
543 }
544 (void) fileclose(fp);
545 }
546 return tz;
547 }
548
549 #define TIMEZONE_FMRI "svc:/system/timezone:default"
550 #define TIMEZONE_PG "timezone"
551 #define LOCALTIME_PROP "localtime"
552
553 static void
554 cleanupScf(scf_handle_t *h,
555 scf_snapshot_t *snap,
556 scf_instance_t *inst,
557 scf_propertygroup_t *pg,
558 scf_property_t *prop,
559 scf_value_t *val,
560 char *buf) {
561 if (buf != NULL) {
562 free(buf);
563 }
564 if (snap != NULL) {
565 scf_snapshot_destroy(snap);
566 }
567 if (val != NULL) {
568 scf_value_destroy(val);
569 }
570 if (prop != NULL) {
571 scf_property_destroy(prop);
572 }
573 if (pg != NULL) {
574 scf_pg_destroy(pg);
575 }
576 if (inst != NULL) {
577 scf_instance_destroy(inst);
578 }
579 if (h != NULL) {
580 scf_handle_destroy(h);
581 }
582 }
583
584 /*
585 * Returns a zone ID of Solaris when the TZ value is "localtime".
586 * First, it tries scf. If scf fails, it looks for the same file as
587 * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/.
588 */
589 static char *
590 getSolarisDefaultZoneID() {
591 char *tz = NULL;
592 struct stat64 statbuf;
593 size_t size;
594 char *buf;
595 int fd;
596 int res;
597 /* scf specific variables */
598 scf_handle_t *h = NULL;
599 scf_snapshot_t *snap = NULL;
600 scf_instance_t *inst = NULL;
601 scf_propertygroup_t *pg = NULL;
602 scf_property_t *prop = NULL;
603 scf_value_t *val = NULL;
604
605 if ((h = scf_handle_create(SCF_VERSION)) != NULL
606 && scf_handle_bind(h) == 0
607 && (inst = scf_instance_create(h)) != NULL
608 && (snap = scf_snapshot_create(h)) != NULL
609 && (pg = scf_pg_create(h)) != NULL
610 && (prop = scf_property_create(h)) != NULL
611 && (val = scf_value_create(h)) != NULL
612 && scf_handle_decode_fmri(h, TIMEZONE_FMRI, NULL, NULL, inst,
613 NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) == 0
614 && scf_instance_get_snapshot(inst, "running", snap) == 0
615 && scf_instance_get_pg_composed(inst, snap, TIMEZONE_PG, pg) == 0
616 && scf_pg_get_property(pg, LOCALTIME_PROP, prop) == 0
617 && scf_property_get_value(prop, val) == 0) {
618 ssize_t len;
619
620 /* Gets the length of the zone ID string */
621 len = scf_value_get_astring(val, NULL, 0);
622 if (len != -1) {
623 tz = malloc(++len); /* +1 for a null byte */
624 if (tz != NULL && scf_value_get_astring(val, tz, len) != -1) {
625 cleanupScf(h, snap, inst, pg, prop, val, NULL);
626 return tz;
627 }
628 }
629 }
630 cleanupScf(h, snap, inst, pg, prop, val, tz);
631
632 RESTARTABLE(stat64(DEFAULT_ZONEINFO_FILE, &statbuf), res);
633 if (res == -1) {
634 return NULL;
635 }
636 size = (size_t) statbuf.st_size;
637 buf = malloc(size);
638 if (buf == NULL) {
639 return NULL;
640 }
641 RESTARTABLE(open(DEFAULT_ZONEINFO_FILE, O_RDONLY), fd);
642 if (fd == -1) {
643 free((void *) buf);
644 return NULL;
645 }
646
647 RESTARTABLE(read(fd, buf, size), res);
648 if (res != (ssize_t) size) {
649 (void) close(fd);
650 free((void *) buf);
651 return NULL;
652 }
653 (void) close(fd);
654 tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
655 free((void *) buf);
656 return tz;
657 }
658
659 #endif /* defined(__solaris__) */
660
661 #elif defined(_AIX)
662
663 static char *
664 getPlatformTimeZoneID()
665 {
666 FILE *fp;
667 char *tz = NULL;
668 char *tz_key = "TZ=";
669 char line[256];
670 size_t tz_key_len = strlen(tz_key);
671
672 if ((fp = fopen(ETC_ENVIRONMENT_FILE, "r")) != NULL) {
673 while (fgets(line, sizeof(line), fp) != NULL) {
674 char *p = strchr(line, '\n');
675 if (p != NULL) {
676 *p = '\0';
677 }
678 if (0 == strncmp(line, tz_key, tz_key_len)) {
679 tz = strdup(line + tz_key_len);
680 break;
807
808 if (tz != NULL) {
809 /* Ignore preceding ':' */
810 if (*tz == ':') {
811 tz++;
812 }
813 #if defined(__linux__)
814 /* Ignore "posix/" prefix on Linux. */
815 if (strncmp(tz, "posix/", 6) == 0) {
816 tz += 6;
817 }
818 #endif
819
820 #if defined(_AIX)
821 /* On AIX do the platform to Java mapping. */
822 javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
823 if (freetz != NULL) {
824 free((void *) freetz);
825 }
826 #else
827 #if defined(__solaris__)
828 /* Solaris might use localtime, so handle it here. */
829 if (strcmp(tz, "localtime") == 0) {
830 javatz = getSolarisDefaultZoneID();
831 if (freetz != NULL) {
832 free((void *) freetz);
833 }
834 } else
835 #endif
836 if (freetz == NULL) {
837 /* strdup if we are still working on getenv result. */
838 javatz = strdup(tz);
839 } else if (freetz != tz) {
840 /* strdup and free the old buffer, if we moved the pointer. */
841 javatz = strdup(tz);
842 free((void *) freetz);
843 } else {
844 /* we are good if we already work on a freshly allocated buffer. */
845 javatz = tz;
846 }
847 #endif
848 }
849
850 return javatz;
851 }
852
853 /**
854 * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
855 */
873 return strdup("GMT");
874 }
875 if (offset > 0) {
876 sign = '+';
877 } else {
878 offset = -offset;
879 sign = '-';
880 }
881 sprintf(buf, (const char *)"GMT%c%02d:%02d",
882 sign, (int)(offset/3600), (int)((offset%3600)/60));
883 return strdup(buf);
884 }
885
886 #else
887
888 char *
889 getGMTOffsetID()
890 {
891 time_t offset;
892 char sign, buf[32];
893 #if defined(__solaris__)
894 struct tm localtm;
895 time_t currenttime;
896
897 currenttime = time(NULL);
898 if (localtime_r(¤ttime, &localtm) == NULL) {
899 return strdup("GMT");
900 }
901
902 offset = localtm.tm_isdst ? altzone : timezone;
903 #else
904 offset = timezone;
905 #endif
906
907 if (offset == 0) {
908 return strdup("GMT");
909 }
910
911 /* Note that the time offset direction is opposite. */
912 if (offset > 0) {
913 sign = '-';
914 } else {
915 offset = -offset;
916 sign = '+';
917 }
918 sprintf(buf, (const char *)"GMT%c%02d:%02d",
919 sign, (int)(offset/3600), (int)((offset%3600)/60));
920 return strdup(buf);
921 }
922 #endif /* MACOSX */
|
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
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <strings.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <errno.h>
32 #include <stddef.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <string.h>
36 #include <dirent.h>
37 #include <unistd.h>
38
39 #include "jvm.h"
40 #include "TimeZone_md.h"
41
42 static char *isFileIdentical(char* buf, size_t size, char *pathname);
43
44 #define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
45
46 #define RESTARTABLE(_cmd, _result) do { \
47 do { \
48 _result = _cmd; \
49 } while((_result == -1) && (errno == EINTR)); \
50 } while(0)
51
52 #define fileopen fopen
53 #define filegets fgets
54 #define fileclose fclose
55
56 #if defined(_ALLBSD_SOURCE)
57 #define stat64 stat
58 #define lstat64 lstat
59 #define fstat64 fstat
60 #endif
61
62 #if defined(__linux__) || defined(_ALLBSD_SOURCE)
63 static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
64 static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
65 static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
66 #else
67 static const char *SYS_INIT_FILE = "/etc/default/init";
68 static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
69 static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
70 #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
71
72 static const char popularZones[][4] = {"UTC", "GMT"};
73
74 #if defined(_AIX)
75 static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
76 #endif
77
78 #if defined(__linux__) || defined(MACOSX)
79
80 /*
81 * Returns a pointer to the zone ID portion of the given zoneinfo file
82 * name, or NULL if the given string doesn't contain "zoneinfo/".
83 */
84 static char *
85 getZoneName(char *str)
86 {
87 static const char *zidir = "zoneinfo/";
88
89 char *pos = strstr((const char *)str, zidir);
90 if (pos == NULL) {
91 return NULL;
92 }
93 return pos + strlen(zidir);
94 }
95
96 /*
97 * Returns a path name created from the given 'dir' and 'name' under
98 * UNIX. This function allocates memory for the pathname calling
142 }
143
144 dirp = opendir(dir);
145 if (dirp == NULL) {
146 return NULL;
147 }
148
149 while ((dp = readdir(dirp)) != NULL) {
150 /*
151 * Skip '.' and '..' (and possibly other .* files)
152 */
153 if (dp->d_name[0] == '.') {
154 continue;
155 }
156
157 /*
158 * Skip "ROC", "posixrules", and "localtime".
159 */
160 if ((strcmp(dp->d_name, "ROC") == 0)
161 || (strcmp(dp->d_name, "posixrules") == 0)
162 || (strcmp(dp->d_name, "localtime") == 0)) {
163 continue;
164 }
165
166 pathname = getPathName(dir, dp->d_name);
167 if (pathname == NULL) {
168 break;
169 }
170
171 tz = isFileIdentical(buf, size, pathname);
172 free((void *) pathname);
173 pathname = NULL;
174 if (tz != NULL) {
175 break;
176 }
177 }
178
179 if (dirp != NULL) {
180 (void) closedir(dirp);
181 }
213 if (fd == -1) {
214 goto freedata;
215 }
216 RESTARTABLE(read(fd, dbuf, size), res);
217 if (res != (ssize_t) size) {
218 goto freedata;
219 }
220 if (memcmp(buf, dbuf, size) == 0) {
221 possibleMatch = getZoneName(pathname);
222 if (possibleMatch != NULL) {
223 possibleMatch = strdup(possibleMatch);
224 }
225 }
226 freedata:
227 free((void *) dbuf);
228 (void) close(fd);
229 }
230 return possibleMatch;
231 }
232
233 /*
234 * Performs Linux specific mapping and returns a zone ID
235 * if found. Otherwise, NULL is returned.
236 */
237 static char *
238 getPlatformTimeZoneID()
239 {
240 struct stat64 statbuf;
241 char *tz = NULL;
242 FILE *fp;
243 int fd;
244 char *buf;
245 size_t size;
246 int res;
247
248 #if defined(__linux__)
249 /*
250 * Try reading the /etc/timezone file for Debian distros. There's
251 * no spec of the file format available. This parsing assumes that
252 * there's one line of an Olson tzid followed by a '\n', no
322 size = (size_t) statbuf.st_size;
323 buf = (char *) malloc(size);
324 if (buf == NULL) {
325 (void) close(fd);
326 return NULL;
327 }
328
329 RESTARTABLE(read(fd, buf, size), res);
330 if (res != (ssize_t) size) {
331 (void) close(fd);
332 free((void *) buf);
333 return NULL;
334 }
335 (void) close(fd);
336
337 tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
338 free((void *) buf);
339 return tz;
340 }
341
342 #elif defined(_AIX)
343
344 static char *
345 getPlatformTimeZoneID()
346 {
347 FILE *fp;
348 char *tz = NULL;
349 char *tz_key = "TZ=";
350 char line[256];
351 size_t tz_key_len = strlen(tz_key);
352
353 if ((fp = fopen(ETC_ENVIRONMENT_FILE, "r")) != NULL) {
354 while (fgets(line, sizeof(line), fp) != NULL) {
355 char *p = strchr(line, '\n');
356 if (p != NULL) {
357 *p = '\0';
358 }
359 if (0 == strncmp(line, tz_key, tz_key_len)) {
360 tz = strdup(line + tz_key_len);
361 break;
488
489 if (tz != NULL) {
490 /* Ignore preceding ':' */
491 if (*tz == ':') {
492 tz++;
493 }
494 #if defined(__linux__)
495 /* Ignore "posix/" prefix on Linux. */
496 if (strncmp(tz, "posix/", 6) == 0) {
497 tz += 6;
498 }
499 #endif
500
501 #if defined(_AIX)
502 /* On AIX do the platform to Java mapping. */
503 javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
504 if (freetz != NULL) {
505 free((void *) freetz);
506 }
507 #else
508 if (freetz == NULL) {
509 /* strdup if we are still working on getenv result. */
510 javatz = strdup(tz);
511 } else if (freetz != tz) {
512 /* strdup and free the old buffer, if we moved the pointer. */
513 javatz = strdup(tz);
514 free((void *) freetz);
515 } else {
516 /* we are good if we already work on a freshly allocated buffer. */
517 javatz = tz;
518 }
519 #endif
520 }
521
522 return javatz;
523 }
524
525 /**
526 * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
527 */
545 return strdup("GMT");
546 }
547 if (offset > 0) {
548 sign = '+';
549 } else {
550 offset = -offset;
551 sign = '-';
552 }
553 sprintf(buf, (const char *)"GMT%c%02d:%02d",
554 sign, (int)(offset/3600), (int)((offset%3600)/60));
555 return strdup(buf);
556 }
557
558 #else
559
560 char *
561 getGMTOffsetID()
562 {
563 time_t offset;
564 char sign, buf[32];
565 offset = timezone;
566
567 if (offset == 0) {
568 return strdup("GMT");
569 }
570
571 /* Note that the time offset direction is opposite. */
572 if (offset > 0) {
573 sign = '-';
574 } else {
575 offset = -offset;
576 sign = '+';
577 }
578 sprintf(buf, (const char *)"GMT%c%02d:%02d",
579 sign, (int)(offset/3600), (int)((offset%3600)/60));
580 return strdup(buf);
581 }
582 #endif /* MACOSX */
|