Annotation of 43BSDTahoe/lib/libc/gen/ctime.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.