1: /*
   2:  * Copyright (c) 1987 Regents of the University of California.
   3:  * This file may be freely redistributed provided that this
   4:  * notice remains attached.
   5:  */
   6: 
   7: #if defined(LIBC_SCCS) && !defined(lint)
   8: static char sccsid[] = "@(#)ctime.c	1.1 (Berkeley) 3/25/87";
   9: #endif LIBC_SCCS and not lint
  10: 
  11: #include "sys/param.h"
  12: #include "sys/time.h"
  13: #include "tzfile.h"
  14: 
  15: char *
  16: ctime(t)
  17: time_t *t;
  18: {
  19:     struct tm   *localtime();
  20:     char    *asctime();
  21: 
  22:     return(asctime(localtime(t)));
  23: }
  24: 
  25: /*
  26: ** A la X3J11
  27: */
  28: 
  29: char *
  30: asctime(timeptr)
  31: register struct tm *    timeptr;
  32: {
  33:     static char wday_name[DAYS_PER_WEEK][3] = {
  34:         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  35:     };
  36:     static char mon_name[MONS_PER_YEAR][3] = {
  37:         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  38:         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  39:     };
  40:     static char result[26];
  41: 
  42:     (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
  43:         wday_name[timeptr->tm_wday],
  44:         mon_name[timeptr->tm_mon],
  45:         timeptr->tm_mday, timeptr->tm_hour,
  46:         timeptr->tm_min, timeptr->tm_sec,
  47:         TM_YEAR_BASE + timeptr->tm_year);
  48:     return result;
  49: }
  50: 
  51: #ifndef TRUE
  52: #define TRUE        1
  53: #define FALSE       0
  54: #endif /* !TRUE */
  55: 
  56: extern char *       getenv();
  57: extern char *       strcpy();
  58: extern char *       strcat();
  59: struct tm *     offtime();
  60: 
  61: struct ttinfo {             /* time type information */
  62:     long        tt_gmtoff;  /* GMT offset in seconds */
  63:     int     tt_isdst;   /* used to set tm_isdst */
  64:     int     tt_abbrind; /* abbreviation list index */
  65: };
  66: 
  67: struct state {
  68:     int     timecnt;
  69:     int     typecnt;
  70:     int     charcnt;
  71:     time_t      ats[TZ_MAX_TIMES];
  72:     unsigned char   types[TZ_MAX_TIMES];
  73:     struct ttinfo   ttis[TZ_MAX_TYPES];
  74:     char        chars[TZ_MAX_CHARS + 1];
  75: };
  76: 
  77: static struct state s;
  78: 
  79: static int      tz_is_set;
  80: 
  81: char *          tzname[2] = {
  82:     "GMT",
  83:     "GMT"
  84: };
  85: 
  86: #ifdef USG_COMPAT
  87: time_t          timezone = 0;
  88: int         daylight = 0;
  89: #endif /* USG_COMPAT */
  90: 
  91: static long
  92: detzcode(codep)
  93: char *  codep;
  94: {
  95:     register long   result;
  96:     register int    i;
  97: 
  98:     result = 0;
  99:     for (i = 0; i < 4; ++i)
 100:         result = (result << 8) | (codep[i] & 0xff);
 101:     return result;
 102: }
 103: 
 104: static
 105: tzload(name)
 106: register char * name;
 107: {
 108:     register int    i;
 109:     register int    fid;
 110: 
 111:     if (name == 0 && (name = TZDEFAULT) == 0)
 112:         return -1;
 113:     {
 114:         register char * p;
 115:         register int    doaccess;
 116:         char        fullname[MAXPATHLEN];
 117: 
 118:         doaccess = name[0] == '/';
 119:         if (!doaccess) {
 120:             if ((p = TZDIR) == 0)
 121:                 return -1;
 122:             if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
 123:                 return -1;
 124:             (void) strcpy(fullname, p);
 125:             (void) strcat(fullname, "/");
 126:             (void) strcat(fullname, name);
 127:             /*
 128: 			** Set doaccess if '.' (as in "../") shows up in name.
 129: 			*/
 130:             while (*name != '\0')
 131:                 if (*name++ == '.')
 132:                     doaccess = TRUE;
 133:             name = fullname;
 134:         }
 135:         if (doaccess && access(name, 4) != 0)
 136:             return -1;
 137:         if ((fid = open(name, 0)) == -1)
 138:             return -1;
 139:     }
 140:     {
 141:         register char *         p;
 142:         register struct tzhead *    tzhp;
 143:         char                buf[sizeof s];
 144: 
 145:         i = read(fid, buf, sizeof buf);
 146:         if (close(fid) != 0 || i < sizeof *tzhp)
 147:             return -1;
 148:         tzhp = (struct tzhead *) buf;
 149:         s.timecnt = (int) detzcode(tzhp->tzh_timecnt);
 150:         s.typecnt = (int) detzcode(tzhp->tzh_typecnt);
 151:         s.charcnt = (int) detzcode(tzhp->tzh_charcnt);
 152:         if (s.timecnt > TZ_MAX_TIMES ||
 153:             s.typecnt == 0 ||
 154:             s.typecnt > TZ_MAX_TYPES ||
 155:             s.charcnt > TZ_MAX_CHARS)
 156:                 return -1;
 157:         if (i < sizeof *tzhp +
 158:             s.timecnt * (4 + sizeof (char)) +
 159:             s.typecnt * (4 + 2 * sizeof (char)) +
 160:             s.charcnt * sizeof (char))
 161:                 return -1;
 162:         p = buf + sizeof *tzhp;
 163:         for (i = 0; i < s.timecnt; ++i) {
 164:             s.ats[i] = detzcode(p);
 165:             p += 4;
 166:         }
 167:         for (i = 0; i < s.timecnt; ++i)
 168:             s.types[i] = (unsigned char) *p++;
 169:         for (i = 0; i < s.typecnt; ++i) {
 170:             register struct ttinfo *    ttisp;
 171: 
 172:             ttisp = &s.ttis[i];
 173:             ttisp->tt_gmtoff = detzcode(p);
 174:             p += 4;
 175:             ttisp->tt_isdst = (unsigned char) *p++;
 176:             ttisp->tt_abbrind = (unsigned char) *p++;
 177:         }
 178:         for (i = 0; i < s.charcnt; ++i)
 179:             s.chars[i] = *p++;
 180:         s.chars[i] = '\0';  /* ensure '\0' at end */
 181:     }
 182:     /*
 183: 	** Check that all the local time type indices are valid.
 184: 	*/
 185:     for (i = 0; i < s.timecnt; ++i)
 186:         if (s.types[i] >= s.typecnt)
 187:             return -1;
 188:     /*
 189: 	** Check that all abbreviation indices are valid.
 190: 	*/
 191:     for (i = 0; i < s.typecnt; ++i)
 192:         if (s.ttis[i].tt_abbrind >= s.charcnt)
 193:             return -1;
 194:     /*
 195: 	** Set tzname elements to initial values.
 196: 	*/
 197:     tzname[0] = tzname[1] = &s.chars[0];
 198: #ifdef USG_COMPAT
 199:     timezone = s.ttis[0].tt_gmtoff;
 200:     daylight = 0;
 201: #endif /* USG_COMPAT */
 202:     for (i = 1; i < s.typecnt; ++i) {
 203:         register struct ttinfo *    ttisp;
 204: 
 205:         ttisp = &s.ttis[i];
 206:         if (ttisp->tt_isdst) {
 207:             tzname[1] = &s.chars[ttisp->tt_abbrind];
 208: #ifdef USG_COMPAT
 209:             daylight = 1;
 210: #endif /* USG_COMPAT */
 211:         } else {
 212:             tzname[0] = &s.chars[ttisp->tt_abbrind];
 213: #ifdef USG_COMPAT
 214:             timezone = ttisp->tt_gmtoff;
 215: #endif /* USG_COMPAT */
 216:         }
 217:     }
 218:     return 0;
 219: }
 220: 
 221: static
 222: tzsetkernel()
 223: {
 224:     struct timeval  tv;
 225:     struct timezone tz;
 226:     char    *tztab();
 227: 
 228:     if (gettimeofday(&tv, &tz))
 229:         return -1;
 230:     s.timecnt = 0;      /* UNIX counts *west* of Greenwich */
 231:     s.ttis[0].tt_gmtoff = tz.tz_minuteswest * -SECS_PER_MIN;
 232:     s.ttis[0].tt_abbrind = 0;
 233:     (void)strcpy(s.chars, tztab(tz.tz_minuteswest, 0));
 234:     tzname[0] = tzname[1] = s.chars;
 235: #ifdef USG_COMPAT
 236:     timezone = tz.tz_minuteswest * 60;
 237:     daylight = tz.tz_dsttime;
 238: #endif /* USG_COMPAT */
 239:     return 0;
 240: }
 241: 
 242: static
 243: tzsetgmt()
 244: {
 245:     s.timecnt = 0;
 246:     s.ttis[0].tt_gmtoff = 0;
 247:     s.ttis[0].tt_abbrind = 0;
 248:     (void) strcpy(s.chars, "GMT");
 249:     tzname[0] = tzname[1] = s.chars;
 250: #ifdef USG_COMPAT
 251:     timezone = 0;
 252:     daylight = 0;
 253: #endif /* USG_COMPAT */
 254: }
 255: 
 256: void
 257: tzset()
 258: {
 259:     register char * name;
 260: 
 261:     tz_is_set = TRUE;
 262:     name = getenv("TZ");
 263:     if (!name || *name) {           /* did not request GMT */
 264:         if (name && !tzload(name))  /* requested name worked */
 265:             return;
 266:         if (!tzload((char *)0))     /* default name worked */
 267:             return;
 268:         if (!tzsetkernel())     /* kernel guess worked */
 269:             return;
 270:     }
 271:     tzsetgmt();             /* GMT is default */
 272: }
 273: 
 274: struct tm *
 275: localtime(timep)
 276: time_t *    timep;
 277: {
 278:     register struct ttinfo *    ttisp;
 279:     register struct tm *        tmp;
 280:     register int            i;
 281:     time_t              t;
 282: 
 283:     if (!tz_is_set)
 284:         (void) tzset();
 285:     t = *timep;
 286:     if (s.timecnt == 0 || t < s.ats[0]) {
 287:         i = 0;
 288:         while (s.ttis[i].tt_isdst)
 289:             if (++i >= s.timecnt) {
 290:                 i = 0;
 291:                 break;
 292:             }
 293:     } else {
 294:         for (i = 1; i < s.timecnt; ++i)
 295:             if (t < s.ats[i])
 296:                 break;
 297:         i = s.types[i - 1];
 298:     }
 299:     ttisp = &s.ttis[i];
 300:     /*
 301: 	** To get (wrong) behavior that's compatible with System V Release 2.0
 302: 	** you'd replace the statement below with
 303: 	**	tmp = offtime((time_t) (t + ttisp->tt_gmtoff), 0L);
 304: 	*/
 305:     tmp = offtime(&t, ttisp->tt_gmtoff);
 306:     tmp->tm_isdst = ttisp->tt_isdst;
 307:     tzname[tmp->tm_isdst] = &s.chars[ttisp->tt_abbrind];
 308:     tmp->tm_zone = &s.chars[ttisp->tt_abbrind];
 309:     return tmp;
 310: }
 311: 
 312: struct tm *
 313: gmtime(clock)
 314: time_t *    clock;
 315: {
 316:     register struct tm *    tmp;
 317: 
 318:     tmp = offtime(clock, 0L);
 319:     tzname[0] = "GMT";
 320:     tmp->tm_zone = "GMT";       /* UCT ? */
 321:     return tmp;
 322: }
 323: 
 324: static int  mon_lengths[2][MONS_PER_YEAR] = {
 325:     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
 326:     31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 327: };
 328: 
 329: static int  year_lengths[2] = {
 330:     DAYS_PER_NYEAR, DAYS_PER_LYEAR
 331: };
 332: 
 333: struct tm *
 334: offtime(clock, offset)
 335: time_t *    clock;
 336: long        offset;
 337: {
 338:     register struct tm *    tmp;
 339:     register long       days;
 340:     register long       rem;
 341:     register int        y;
 342:     register int        yleap;
 343:     register int *      ip;
 344:     static struct tm    tm;
 345: 
 346:     tmp = &tm;
 347:     days = *clock / SECS_PER_DAY;
 348:     rem = *clock % SECS_PER_DAY;
 349:     rem += offset;
 350:     while (rem < 0) {
 351:         rem += SECS_PER_DAY;
 352:         --days;
 353:     }
 354:     while (rem >= SECS_PER_DAY) {
 355:         rem -= SECS_PER_DAY;
 356:         ++days;
 357:     }
 358:     tmp->tm_hour = (int) (rem / SECS_PER_HOUR);
 359:     rem = rem % SECS_PER_HOUR;
 360:     tmp->tm_min = (int) (rem / SECS_PER_MIN);
 361:     tmp->tm_sec = (int) (rem % SECS_PER_MIN);
 362:     tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYS_PER_WEEK);
 363:     if (tmp->tm_wday < 0)
 364:         tmp->tm_wday += DAYS_PER_WEEK;
 365:     y = EPOCH_YEAR;
 366:     if (days >= 0)
 367:         for ( ; ; ) {
 368:             yleap = isleap(y);
 369:             if (days < (long) year_lengths[yleap])
 370:                 break;
 371:             ++y;
 372:             days = days - (long) year_lengths[yleap];
 373:         }
 374:     else do {
 375:         --y;
 376:         yleap = isleap(y);
 377:         days = days + (long) year_lengths[yleap];
 378:     } while (days < 0);
 379:     tmp->tm_year = y - TM_YEAR_BASE;
 380:     tmp->tm_yday = (int) days;
 381:     ip = mon_lengths[yleap];
 382:     for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
 383:         days = days - (long) ip[tmp->tm_mon];
 384:     tmp->tm_mday = (int) (days + 1);
 385:     tmp->tm_isdst = 0;
 386:     tmp->tm_zone = "";
 387:     tmp->tm_gmtoff = offset;
 388:     return tmp;
 389: }

Defined functions

ctime defined in line 15; used 201 times
detzcode defined in line 91; used 5 times
localtime defined in line 274; used 145 times
offtime defined in line 333; used 5 times
tzload defined in line 104; used 2 times
tzsetgmt defined in line 242; used 1 times
tzsetkernel defined in line 221; used 1 times

Defined variables

daylight defined in line 88; used 5 times
mon_lengths defined in line 324; used 1 times
s defined in line 77; used 52 times
sccsid defined in line 8; never used
timezone defined in line 87; used 4 times
tz_is_set defined in line 79; used 2 times
tzname defined in line 81; used 12 times
year_lengths defined in line 329; used 3 times

Defined struct's

state defined in line 67; used 2 times
  • in line 77(2)
ttinfo defined in line 61; used 8 times

Defined macros

FALSE defined in line 53; never used
TRUE defined in line 52; used 3 times
Last modified: 1987-04-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4249
Valid CSS Valid XHTML 1.0 Strict