static void readtimezone(void) { char *tmp; z.timecnt = 0; if(zonefile==nil) { if ((tmp=getenv("timezone"))!=nil) { tzdata = readtzfile(tmp); free(tmp); goto havedata; } zonefile = "/etc/localtime"; } tzdata = readtzfile(zonefile); if (tzdata==nil) return; havedata: if (strncmp("TZif", (char*)tzdata, 4)!=0) goto errfree; if (parsehead()==-1) { errfree: free(tzdata); tzdata = nil; z.timecnt = 0; return; } }
static void readtimezone(void) { char *tmp; z.timecnt = 0; switch (zonefile==nil) { default: if ((tmp=getenv("timezone"))!=nil) { tzdata = readtzfile(tmp); free(tmp); break; } zonefile = "/etc/localtime"; /* fall through */ case 0: tzdata = readtzfile(zonefile); } if (tzdata==nil) return; if (strncmp("TZif", (char*)tzdata, 4)!=0) goto errfree; if (parsehead()==-1) { errfree: free(tzdata); tzdata = nil; z.timecnt = 0; return; } }
uLong oz_knl_tzconv_setdefault (const char *tzname) { int si; OZ_Handle h_iochan; OZ_IO_fs_open fs_open; OZ_Threadlock *threadlock; Tzfile *newtzfile, *oldtzfile; uLong sts; si = oz_hw_cpu_setsoftint (0); // prevent thread from being aborted /* Open the given timezone file */ memset (&fs_open, 0, sizeof fs_open); fs_open.name = tzname; fs_open.lockmode = OZ_LOCKMODE_PR; sts = oz_sys_io_fs_open2 (sizeof fs_open, &fs_open, 0, "OZ_TIMEZONE_DIR", &h_iochan); if (sts != OZ_SUCCESS) goto rtnsts; /* Create a Tzfile struct for it */ sts = readtzfile (h_iochan, OZ_PROCMODE_SYS, &newtzfile); // read the new timezone file into system global paged memory oz_sys_handle_release (OZ_PROCMODE_KNL, h_iochan); // close the file if (sts != OZ_SUCCESS) goto rtnsts; // if failure, return error status /* If there is no threadlock, create one */ if (defaultzlock == NULL) { sts = oz_knl_threadlock_create ("default tzlock", &threadlock); if (sts != OZ_SUCCESS) goto rtnsts; if (!oz_hw_atomic_setif_ptr (&defaultzlock, threadlock, NULL)) oz_knl_threadlock_delete (threadlock); } /* Set new zone as the new default, close out any old default tzfile */ oz_knl_threadlock_ex (defaultzlock); // block out any readers oldtzfile = defaultzfile; // save old file so we can close it defaultzfile = newtzfile; // set up new file oz_knl_threadunlk_ex (defaultzlock); // release so it can be used if (oldtzfile != NULL) closetzfile (oldtzfile); // close old file rtnsts: oz_hw_cpu_setsoftint (si); // it's ok to be aborted now return (sts); }
OZ_HW_SYSCALL_DEF_6 (tzconv, OZ_Datebin_tzconv, tzconvtype, OZ_Datebin, in, OZ_Handle, h_tzfilein, OZ_Datebin *, out, int, tznameoutl, char *, tznameout) { const char *p; int si; Long i, tzseq; Tzfile *tzfile; uByte j; uLong sts; if ((tzconvtype != OZ_DATEBIN_TZCONV_UTC2LCL) && (tzconvtype != OZ_DATEBIN_TZCONV_LCL2UTC)) return (OZ_BADPARAM); si = oz_hw_cpu_setsoftint (0); /* Get pointer to timezone file in memory */ if (h_tzfilein != 0) { // see if caller supplied a timezone file sts = readtzfile (h_tzfilein, OZ_PROCMODE_KNL, &tzfile); // if so, try to read it into proc private knl memory if (sts != OZ_SUCCESS) goto rtnsts; } else { sts = OZ_BADTZFILE; // if not, assume it's not set up yet if (defaultzlock == NULL) goto rtnsts; oz_knl_threadlock_pr (defaultzlock); // ... then lock default from changing tzfile = defaultzfile; if (tzfile == NULL) { oz_knl_threadunlk_pr (defaultzlock); // ... no default set up yet goto rtnsts; } } /* Scan quadtransitiontimes array for timerange to be converted */ if (tzconvtype == OZ_DATEBIN_TZCONV_UTC2LCL) { // UTC -> LCL transformation for (i = tzfile -> tzh_timecnt; --i > 0;) { // scan the table if (in >= tzfile -> quadtransitiontimes[i]) break; // for first entry that matches } j = tzfile -> transitionindxs[i]; // get type array index in += tzfile -> quadgmtoffs[j]; // convert UTC to LCL } if (tzconvtype == OZ_DATEBIN_TZCONV_LCL2UTC) { // LCL -> UTC transformation for (i = tzfile -> tzh_timecnt; --i > 0;) { // scan the table j = tzfile -> transitionindxs[i]; // get type array index if (in - tzfile -> quadgmtoffs[j] >= tzfile -> quadtransitiontimes[i]) break; // for first entry that would match } in -= tzfile -> quadgmtoffs[j]; // ok, convert LCL to UTC } /* Return conversion results */ sts = OZ_SUCCESS; // assume all outputs successful if (out != NULL) sts = oz_knl_section_uput (cprocmode, sizeof *out, &in, out); if ((sts == OZ_SUCCESS) && (tznameoutl > 0)) { p = tzfile -> zonenames + tzfile -> zoneinfos[j].nameidx; i = strnlen (p, tznameoutl - 1) + 1; sts = oz_knl_section_uput (cprocmode, i, p, tznameout); } /* Close or unlock file */ if (h_tzfilein != 0) closetzfile (tzfile); else oz_knl_threadunlk_pr (defaultzlock); rtnsts: oz_hw_cpu_setsoftint (si); return (sts); }