#include #include #define TZSIZE 150 static void readtimezone(void); static int rd_name(char**, char*); static int rd_long(char**, long*); static struct { char stname[4]; char dlname[4]; long stdiff; long dldiff; long dlpairs[TZSIZE]; } timezone; #define SEC2MIN 60L #define SEC2HOUR (60L*SEC2MIN) #define SEC2DAY (24L*SEC2HOUR) /* * days per month plus days/year */ static int dmsize[] = { 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int ldmsize[] = { 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* * return the days/month for the given year */ static int * yrsize(int y) { if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0)) return ldmsize; else return dmsize; } /* * compute seconds since Jan 1 1970 GMT * and convert to our timezone. */ long tm2sec(Tm *tm) { long secs, *p; int i, year, *d2m; if(strcmp(tm->zone, "GMT") != 0 && timezone.stname[0] == 0) readtimezone(); secs = 0; /* * seconds per year */ year = tm->year + 1900; for(i = 1970; i < year; i++){ d2m = yrsize(i); secs += d2m[0] * SEC2DAY; } /* * seconds per month */ d2m = yrsize(year); for(i = 0; i < tm->mon; i++) secs += d2m[i+1] * SEC2DAY; /* * secs in last month */ secs += (tm->mday-1) * SEC2DAY; /* * hours, minutes, seconds */ secs += tm->hour * SEC2HOUR; secs += tm->min * SEC2MIN; secs += tm->sec; /* * the daylight time array * is pairs of standard times * that daylight turns on and off */ if(strcmp(tm->zone, "GMT") == 0) return secs; if(secs - timezone.stdiff < 0) return 0; for(p = timezone.dlpairs; *p; p += 2) if(secs >= p[0] && secs < p[1]) return secs - timezone.dldiff; return secs - timezone.stdiff; } static void readtimezone(void) { char buf[TZSIZE*11+30], *p; int i; memset(buf, 0, sizeof(buf)); i = open("/env/timezone", 0); if(i < 0) goto error; if(read(i, buf, sizeof(buf)) >= sizeof(buf)) goto error; close(i); p = buf; if(rd_name(&p, timezone.stname)) goto error; if(rd_long(&p, &timezone.stdiff)) goto error; if(rd_name(&p, timezone.dlname)) goto error; if(rd_long(&p, &timezone.dldiff)) goto error; for(i=0; i '9') return 1; l = l*10 + c-'0'; c = *(*f)++; } if(s) l = -l; *p = l; return 0; }