src/solaris/native/java/util/TimeZone_md.c

Print this page




  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) {


 209         free((void *) dbuf);
 210     }
 211     return tz;
 212 }
 213 
 214 #if defined(__linux__) || defined(MACOSX)
 215 
 216 /*
 217  * Performs Linux specific mapping and returns a zone ID
 218  * if found. Otherwise, NULL is returned.
 219  */
 220 static char *
 221 getPlatformTimeZoneID()
 222 {
 223     struct stat statbuf;
 224     char *tz = NULL;
 225     FILE *fp;
 226     int fd;
 227     char *buf;
 228     size_t size;

 229 
 230 #ifdef __linux__
 231     /*
 232      * Try reading the /etc/timezone file for Debian distros. There's
 233      * no spec of the file format available. This parsing assumes that
 234      * there's one line of an Olson tzid followed by a '\n', no
 235      * leading or trailing spaces, no comments.
 236      */
 237     if ((fp = fopen(ETC_TIMEZONE_FILE, "r")) != NULL) {
 238         char line[256];
 239 
 240         if (fgets(line, sizeof(line), fp) != NULL) {
 241             char *p = strchr(line, '\n');
 242             if (p != NULL) {
 243                 *p = '\0';
 244             }
 245             if (strlen(line) > 0) {
 246                 tz = strdup(line);
 247             }
 248         }


 250         if (tz != NULL) {
 251             return tz;
 252         }
 253     }
 254 #endif /* __linux__ */
 255 
 256     /*
 257      * Next, try /etc/localtime to find the zone ID.
 258      */
 259     if (lstat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
 260         return NULL;
 261     }
 262 
 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 /*




  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) {


 209         free((void *) dbuf);
 210     }
 211     return tz;
 212 }
 213 
 214 #if defined(__linux__) || defined(MACOSX)
 215 
 216 /*
 217  * Performs Linux specific mapping and returns a zone ID
 218  * if found. Otherwise, NULL is returned.
 219  */
 220 static char *
 221 getPlatformTimeZoneID()
 222 {
 223     struct stat statbuf;
 224     char *tz = NULL;
 225     FILE *fp;
 226     int fd;
 227     char *buf;
 228     size_t size;
 229     char linkbuf[PATH_MAX+1];
 230 
 231 #ifdef __linux__
 232     /*
 233      * Try reading the /etc/timezone file for Debian distros. There's
 234      * no spec of the file format available. This parsing assumes that
 235      * there's one line of an Olson tzid followed by a '\n', no
 236      * leading or trailing spaces, no comments.
 237      */
 238     if ((fp = fopen(ETC_TIMEZONE_FILE, "r")) != NULL) {
 239         char line[256];
 240 
 241         if (fgets(line, sizeof(line), fp) != NULL) {
 242             char *p = strchr(line, '\n');
 243             if (p != NULL) {
 244                 *p = '\0';
 245             }
 246             if (strlen(line) > 0) {
 247                 tz = strdup(line);
 248             }
 249         }


 251         if (tz != NULL) {
 252             return tz;
 253         }
 254     }
 255 #endif /* __linux__ */
 256 
 257     /*
 258      * Next, try /etc/localtime to find the zone ID.
 259      */
 260     if (lstat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
 261         return NULL;
 262     }
 263 
 264     /*
 265      * If it's a symlink, get the link name and its zone ID part. (The
 266      * older versions of timeconfig created a symlink as described in
 267      * the Red Hat man page. It was changed in 1999 to create a copy
 268      * of a zoneinfo file. It's no longer possible to get the zone ID
 269      * from /etc/localtime.)
 270      */
 271     strcpy(linkbuf, DEFAULT_ZONEINFO_FILE);
 272     linkbuf[strlen(DEFAULT_ZONEINFO_FILE)] = '\0';
 273     if (S_ISLNK(statbuf.st_mode)) {

 274         int len;
 275 
 276         if ((len = readlink(DEFAULT_ZONEINFO_FILE, linkbuf, sizeof(linkbuf)-1)) == -1) {
 277             jio_fprintf(stderr, (const char *) "can't get a symlink of %s\n",
 278                         DEFAULT_ZONEINFO_FILE);
 279             return NULL;
 280         }
 281         linkbuf[len] = '\0';
 282         tz = getZoneName(linkbuf);
 283         if (tz != NULL) {
 284             tz = strdup(tz);

 285             return tz;
 286         }
 287     }
 288 
 289     /*
 290      * If it's a regular file, we need to find out the same zoneinfo file
 291      * that has been copied as /etc/localtime.
 292      * If initial symbolic link resolution failed, we should treat target 
 293      * file as a regular file. Obtain new statbuf for this (using stat)
 294      */
 295     if (stat(linkbuf, &statbuf) == -1) {
 296         return NULL;
 297     }
 298 
 299     size = (size_t) statbuf.st_size;
 300     buf = (char *) malloc(size);
 301     if (buf == NULL) {
 302         return NULL;
 303     }
 304     if ((fd = open(linkbuf, O_RDONLY)) == -1) {
 305         free((void *) buf);
 306         return NULL;
 307     }
 308 
 309     if (read(fd, buf, size) != (ssize_t) size) {
 310         (void) close(fd);
 311         free((void *) buf);
 312         return NULL;
 313     }
 314     (void) close(fd);
 315 
 316     tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
 317     free((void *) buf);
 318     return tz;
 319 }
 320 #else
 321 #ifdef __solaris__
 322 #if !defined(__sparcv9) && !defined(amd64)
 323 
 324 /*