/* * Load a timezone from file or from cache. * Does not verify that the timezone is acceptable! */ struct pg_tz * pg_tzset(const char *name) { pg_tz_cache *tzp; struct state tzstate; char uppername[TZ_STRLEN_MAX + 1]; char canonname[TZ_STRLEN_MAX + 1]; char *p; if (strlen(name) > TZ_STRLEN_MAX) return NULL; /* not going to fit */ if (!timezone_cache) if (!init_timezone_hashtable()) return NULL; /* * Upcase the given name to perform a case-insensitive hashtable search. * (We could alternatively downcase it, but we prefer upcase so that we * can get consistently upcased results from tzparse() in case the name is * a POSIX-style timezone spec.) */ p = uppername; while (*name) *p++ = pg_toupper((unsigned char) *name++); *p = '\0'; tzp = (pg_tz_cache *) hash_search(timezone_cache, uppername, HASH_FIND, NULL); if (tzp) { /* Timezone found in cache, nothing more to do */ return &tzp->tz; } if (tzload(uppername, canonname, &tzstate, TRUE) != 0) { if (uppername[0] == ':' || tzparse(uppername, &tzstate, FALSE) != 0) { /* Unknown timezone. Fail our call instead of loading GMT! */ return NULL; } /* For POSIX timezone specs, use uppercase name as canonical */ strcpy(canonname, uppername); } /* Save timezone in the cache */ tzp = (pg_tz_cache *) hash_search(timezone_cache, uppername, HASH_ENTER, NULL); /* hash_search already copied uppername into the hash key */ strcpy(tzp->tz.TZname, canonname); memcpy(&tzp->tz.state, &tzstate, sizeof(tzstate)); return &tzp->tz; }
/* * Load a timezone from file or from cache. * Does not verify that the timezone is acceptable! */ struct pg_tz * pg_tzset(const char *name) { pg_tz *tzp; pg_tz tz; if (strlen(name) > TZ_STRLEN_MAX) return NULL; /* not going to fit */ if (!timezone_cache) if (!init_timezone_hashtable()) return NULL; tzp = (pg_tz *) hash_search(timezone_cache, name, HASH_FIND, NULL); if (tzp) { /* Timezone found in cache, nothing more to do */ return tzp; } if (tzload(name, &tz.state) != 0) { if (name[0] == ':' || tzparse(name, &tz.state, FALSE) != 0) { /* Unknown timezone. Fail our call instead of loading GMT! */ return NULL; } } strcpy(tz.TZname, name); /* Save timezone in the cache */ tzp = hash_search(timezone_cache, name, HASH_ENTER, NULL); strcpy(tzp->TZname, tz.TZname); memcpy(&tzp->state, &tz.state, sizeof(tz.state)); return tzp; }