Annotation of embedaddon/php/ext/fileinfo/libmagic/cdf_time.c, revision 1.1
1.1 ! misho 1: /*-
! 2: * Copyright (c) 2008 Christos Zoulas
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: *
! 14: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 15: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 16: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 17: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 18: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 19: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 20: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 21: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 22: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 23: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 24: * POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: #include "file.h"
! 28:
! 29: #ifndef lint
! 30: FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $")
! 31: #endif
! 32:
! 33: #include <time.h>
! 34: #ifdef TEST
! 35: #include <err.h>
! 36: #endif
! 37: #include <string.h>
! 38:
! 39: #include "cdf.h"
! 40:
! 41: #define isleap(y) ((((y) % 4) == 0) && \
! 42: ((((y) % 100) != 0) || (((y) % 400) == 0)))
! 43:
! 44: static const int mdays[] = {
! 45: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
! 46: };
! 47:
! 48: /*
! 49: * Return the number of days between jan 01 1601 and jan 01 of year.
! 50: */
! 51: static int
! 52: cdf_getdays(int year)
! 53: {
! 54: int days = 0;
! 55: int y;
! 56:
! 57: for (y = CDF_BASE_YEAR; y < year; y++)
! 58: days += isleap(y) + 365;
! 59:
! 60: return days;
! 61: }
! 62:
! 63: /*
! 64: * Return the day within the month
! 65: */
! 66: static int
! 67: cdf_getday(int year, int days)
! 68: {
! 69: size_t m;
! 70:
! 71: for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
! 72: int sub = mdays[m] + (m == 1 && isleap(year));
! 73: if (days < sub)
! 74: return days;
! 75: days -= sub;
! 76: }
! 77: return days;
! 78: }
! 79:
! 80: /*
! 81: * Return the 0...11 month number.
! 82: */
! 83: static int
! 84: cdf_getmonth(int year, int days)
! 85: {
! 86: size_t m;
! 87:
! 88: for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
! 89: days -= mdays[m];
! 90: if (m == 1 && isleap(year))
! 91: days--;
! 92: if (days <= 0)
! 93: return (int)m;
! 94: }
! 95: return (int)m;
! 96: }
! 97:
! 98: int
! 99: cdf_timestamp_to_timespec(struct timeval *ts, cdf_timestamp_t t)
! 100: {
! 101: struct tm tm;
! 102: #ifdef HAVE_STRUCT_TM_TM_ZONE
! 103: static char UTC[] = "UTC";
! 104: #endif
! 105: int rdays;
! 106:
! 107: /* Time interval, in microseconds */
! 108: ts->tv_usec = (t % CDF_TIME_PREC) * CDF_TIME_PREC;
! 109:
! 110: t /= CDF_TIME_PREC;
! 111: tm.tm_sec = t % 60;
! 112: t /= 60;
! 113:
! 114: tm.tm_min = t % 60;
! 115: t /= 60;
! 116:
! 117: tm.tm_hour = t % 24;
! 118: t /= 24;
! 119:
! 120: /* XXX: Approx */
! 121: tm.tm_year = CDF_BASE_YEAR + (t / 365);
! 122:
! 123: rdays = cdf_getdays(tm.tm_year);
! 124: t -= rdays;
! 125: tm.tm_mday = cdf_getday(tm.tm_year, t);
! 126: tm.tm_mon = cdf_getmonth(tm.tm_year, t);
! 127: tm.tm_wday = 0;
! 128: tm.tm_yday = 0;
! 129: tm.tm_isdst = 0;
! 130: #ifdef HAVE_STRUCT_TM_TM_GMTOFF
! 131: tm.tm_gmtoff = 0;
! 132: #endif
! 133: #ifdef HAVE_STRUCT_TM_TM_ZONE
! 134: tm.tm_zone = UTC;
! 135: #endif
! 136: tm.tm_year -= 1900;
! 137: ts->tv_sec = mktime(&tm);
! 138: if (ts->tv_sec == -1) {
! 139: errno = EINVAL;
! 140: return -1;
! 141: }
! 142: return 0;
! 143: }
! 144:
! 145: int
! 146: cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timeval *ts)
! 147: {
! 148: (void)&t;
! 149: (void)&ts;
! 150: #ifdef notyet
! 151: struct tm tm;
! 152: if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
! 153: errno = EINVAL;
! 154: return -1;
! 155: }
! 156: *t = (ts->ts_usec / CDF_TIME_PREC) * CDF_TIME_PREC;
! 157: *t = tm.tm_sec;
! 158: *t += tm.tm_min * 60;
! 159: *t += tm.tm_hour * 60 * 60;
! 160: *t += tm.tm_mday * 60 * 60 * 24;
! 161: #endif
! 162: return 0;
! 163: }
! 164:
! 165:
! 166: #ifdef TEST
! 167: int
! 168: main(int argc, char *argv[])
! 169: {
! 170: struct timeval ts;
! 171: static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
! 172: static const char *ref = "Sat Apr 23 01:30:00 1977";
! 173: char *p, *q;
! 174:
! 175: cdf_timestamp_to_timespec(&ts, tst);
! 176: p = ctime(&ts.tv_sec);
! 177: if ((q = strchr(p, '\n')) != NULL)
! 178: *q = '\0';
! 179: if (strcmp(ref, p) != 0)
! 180: errx(1, "Error date %s != %s\n", ref, p);
! 181: return 0;
! 182: }
! 183: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>