head 1.9; access; symbols LMTP2NNTP_1_4_0:1.1.1.1 LMTP2NNTP_1_3_0:1.8 LMTP2NNTP_1_3b2:1.8 LMTP2NNTP_1_3b1:1.8 LMTP2NNTP_1_3a3:1.8 LMTP2NNTP_1_3a2:1.8 LMTP2NNTP_1_3a1:1.8 LMTP2NNTP_1_2_0:1.7 LMTP2NNTP_1_2b4:1.7 LMTP2NNTP_1_2b3:1.7 LMTP2NNTP_1_2b2:1.7 LMTP2NNTP_1_2b1:1.7 LMTP2NNTP_1_2a8:1.7 LMTP2NNTP_1_2a7:1.7 LMTP2NNTP_1_2a6:1.7 LMTP2NNTP_1_2a5:1.5 TAI_0_0_0:1.1.1.1 VENDOR:1.1.1; locks; strict; comment @ * @; 1.9 date 2005.01.24.11.04.07; author rse; state Exp; branches; next 1.8; 1.8 date 2003.03.23.18.00.29; author rse; state Exp; branches; next 1.7; 1.7 date 2002.08.14.14.28.27; author rse; state Exp; branches; next 1.6; 1.6 date 2002.08.14.13.34.01; author rse; state Exp; branches; next 1.5; 1.5 date 2002.05.29.08.32.53; author thl; state Exp; branches; next 1.4; 1.4 date 2002.05.01.18.48.34; author rse; state Exp; branches; next 1.3; 1.3 date 2002.04.29.19.24.41; author rse; state Exp; branches; next 1.2; 1.2 date 2002.04.24.09.07.24; author thl; state Exp; branches; next 1.1; 1.1 date 2002.04.18.09.10.45; author rse; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2002.04.18.09.10.45; author rse; state Exp; branches; next ; desc @@ 1.9 log @flush pending changes related to TAI to calendar transformations @ text @/* ** OSSP tai - Time Handling ** Copyright (c) 2002-2003 Ralf S. Engelschall ** Copyright (c) 2002-2003 The OSSP Project ** Copyright (c) 2002-2003 Cable & Wireless Deutschland ** ** This file is part of OSSP tai, a time handling library ** which can be found at http://www.ossp.org/pkg/lib/tai/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** tai_lib.c: API implementation */ #include #include #include #include #include #include "tai.h" #include "tai_p.h" tai_rc_t tai_create(tai_t **ptai) { tai_t *tai; tai_rc_t rv; if ((tai = (tai_t *)malloc(sizeof(tai_t))) == NULL) return TAI_ERR_SYS; if ((rv = tai_import(tai, TAI_TYPE_TIMET, 0)) != TAI_OK) { free(tai); return rv; } *ptai = tai; return TAI_OK; } tai_rc_t tai_destroy(tai_t *tai) { if (tai == NULL) return TAI_ERR_ARG; free(tai); return TAI_OK; } #if 0 static time_t tai_utcoffset(void) { time_t tL, tU; struct tm *tmL, *tmU; time_t offset; /* determine local time (UTC based) */ tL = time(NULL); /* theoretically this could be a constant value, too */ /* unpack local time (local time based) */ tmL = localtime(&tL); /* unpack local time (UTC based) */ tmU = gmtime(&tL); /* pack UTC-based local time back into local time */ tU = mktime(tmU); /* local time adjustment for Daylight Saving Time (DST) */ if (tmL->tm_isdst) tL += (60*60); /* finally calculate the UTC offset */ offset = (tL - tU); return offset; } #endif tai_rc_t tai_import(tai_t *tai, tai_type_t type, ...) { va_list ap; if (tai == NULL) return TAI_ERR_ARG; va_start(ap, type); if (type == TAI_TYPE_TIMET) { /* import from time_t */ #ifdef HAVE_GMTIME_R struct tm stmbuf; #endif struct tm *stm; time_t t; t = (time_t)va_arg(ap, long); #ifdef HAVE_GMTIME_R stm = gmtime_r(&t, &stmbuf); #else stm = gmtime(&t); #endif tai->tai_sec = stm->tm_sec; tai->tai_min = stm->tm_min; tai->tai_hour = stm->tm_hour; tai->tai_mday = stm->tm_mday; tai->tai_mon = stm->tm_mon; tai->tai_year = stm->tm_year; tai->tai_wday = stm->tm_wday; tai->tai_yday = stm->tm_yday; tai->tai_isdst = stm->tm_isdst; #ifdef HAVE_TM_GMTOFF tai->tai_gmtoff = stm->tm_gmtoff; /* implicitly 0 */ #else tai->tai_gmtoff = 0; /* explicitly 0 */ #endif } else if (type == TAI_TYPE_STRUCTTM) { /* import from struct tm */ struct tm *stm; stm = (struct tm *)va_arg(ap, void *); #define TM_ISRANGE(var,field,min,max) \ (var->tm_##field >= (min) && var->tm_##field <= (max)) if (!TM_ISRANGE(stm,sec,0,61) || !TM_ISRANGE(stm,min,0,59) || !TM_ISRANGE(stm,hour,0,23) || !TM_ISRANGE(stm,mday,1,31) || !TM_ISRANGE(stm,mon,0,11) || !TM_ISRANGE(stm,wday,0,6) || !TM_ISRANGE(stm,yday,0,365) || !TM_ISRANGE(stm,isdst,0,1)) return TAI_ERR_ARG; tai->tai_sec = stm->tm_sec; tai->tai_min = stm->tm_min; tai->tai_hour = stm->tm_hour; tai->tai_mday = stm->tm_mday; tai->tai_mon = stm->tm_mon; tai->tai_year = stm->tm_year; tai->tai_wday = stm->tm_wday; tai->tai_yday = stm->tm_yday; tai->tai_isdst = stm->tm_isdst; #ifdef HAVE_TM_GMTOFF tai->tai_gmtoff = stm->tm_gmtoff; #else tai->tai_gmtoff = 0; #endif } else if (type == TAI_TYPE_UNIX) { /* import from time(3) FIXME */ time_t t = time(NULL); tai->sec = ui64_n2i((unsigned long)t); tai->asec = ui64_n2i((unsigned long)0); tai_tai2cal(tai, 7200); } else return TAI_ERR_IMP; /* FIXME */ va_end(ap); return TAI_OK; } tai_rc_t tai_export(tai_t *tai, tai_type_t type, ...) { va_list ap; if (tai == NULL) return TAI_ERR_ARG; va_start(ap, type); if (type == TAI_TYPE_TIMET) { time_t *pt; struct tm stmbuf; struct tm *stm; #ifndef HAVE_TIMEGM time_t t; #endif pt = (time_t *)va_arg(ap, void *); stm = &stmbuf; stm->tm_sec = tai->tai_sec; stm->tm_min = tai->tai_min; stm->tm_hour = tai->tai_hour; stm->tm_mday = tai->tai_mday; stm->tm_mon = tai->tai_mon; stm->tm_year = tai->tai_year; stm->tm_wday = tai->tai_wday; stm->tm_yday = tai->tai_yday; stm->tm_isdst = tai->tai_isdst; #ifdef HAVE_TM_GMTOFF stm->tm_gmtoff = tai->tai_gmtoff; #endif #ifdef HAVE_TIMEGM /* non-standard timegm(3) makes our life easy */ *pt = timegm(stm); #else /* standard mktime(3) calculated relative to local timezone, so we have to post-adjust result */ *pt = mktime(stm); t = 12*60*60*2; /* max offset of 12 hours plus safety */ *pt += (mktime(localtime(&t)) - mktime(gmtime(&t))); #endif } else if (type == TAI_TYPE_STRUCTTM) { struct tm *stm; stm = (struct tm *)va_arg(ap, void *); stm->tm_sec = tai->tai_sec; stm->tm_min = tai->tai_min; stm->tm_hour = tai->tai_hour; stm->tm_mday = tai->tai_mday; stm->tm_mon = tai->tai_mon; stm->tm_year = tai->tai_year; stm->tm_wday = tai->tai_wday; stm->tm_yday = tai->tai_yday; stm->tm_isdst = tai->tai_isdst; #ifdef HAVE_TM_GMTOFF stm->tm_gmtoff = tai->tai_gmtoff; #endif } else return TAI_ERR_IMP; /* FIXME */ va_end(ap); return TAI_OK; } tai_rc_t tai_format(tai_t *tai, char *buf_ptr, size_t buf_len, const char *fmt) { struct tm stm; tai_rc_t rv; if (tai == NULL || buf_ptr == NULL || buf_len == 0 || fmt == NULL) return TAI_ERR_ARG; if ((rv = tai_export(tai, TAI_TYPE_STRUCTTM, &stm)) != TAI_OK) return rv; if (tai_format_int(buf_ptr, buf_len, fmt, &stm) == 0) return TAI_ERR_FMT; return TAI_OK; } tai_rc_t tai_parse(tai_t *tai, const char *buf_ptr, size_t buf_len, const char *fmt) { struct tm stm; char *cp; char *cp2; tai_rc_t rv; if (tai == NULL || buf_ptr == NULL || buf_len == 0 || fmt == NULL) return TAI_ERR_ARG; if ((cp = malloc(buf_len+1)) == NULL) return TAI_ERR_SYS; memmove(cp, buf_ptr, buf_len); cp[buf_len] = '\0'; memset(&stm, 0, sizeof(struct tm)); cp2 = tai_parse_int(cp, fmt, &stm); free(cp); if (cp2 == NULL) return TAI_ERR_PRS; if ((rv = tai_import(tai, TAI_TYPE_STRUCTTM, &stm)) != TAI_OK) return rv; return TAI_OK; } tai_rc_t tai_op(tai_t *tai, tai_op_t op, ...) { tai_rc_t rc = TAI_ERR_IMP; va_list ap; if (tai == NULL) return TAI_ERR_ARG; va_start(ap, op); if ((op == TAI_OP_NE) || (op == TAI_OP_EQ) || (op == TAI_OP_LT) || (op == TAI_OP_LE) || (op == TAI_OP_GT) || (op == TAI_OP_GE)) { tai_t *tai1, *tai2; unsigned long s1, s2; tai1 = tai; tai2 = (tai_t *)va_arg(ap, void *); s1 = tai1->tai_sec + (60 * tai1->tai_min) + (60 * 60 * tai1->tai_hour) + (60 * 60 * 24 * tai1->tai_yday) + (60 * 60 * 24 * 365 * tai1->tai_year) + tai1->tai_gmtoff; s2 = tai2->tai_sec + (60 * tai2->tai_min) + (60 * 60 * tai2->tai_hour) + (60 * 60 * 24 * tai2->tai_yday) + (60 * 60 * 24 * 365 * tai2->tai_year) + tai2->tai_gmtoff; switch (op) { case TAI_OP_NE: rc = (s2 != s1 ? TAI_OK : TAI_FALSE); break; case TAI_OP_EQ: rc = (s2 == s1 ? TAI_OK : TAI_FALSE); break; case TAI_OP_LT: rc = (s2 < s1 ? TAI_OK : TAI_FALSE); break; case TAI_OP_LE: rc = (s2 <= s1 ? TAI_OK : TAI_FALSE); break; case TAI_OP_GT: rc = (s2 > s1 ? TAI_OK : TAI_FALSE); break; case TAI_OP_GE: rc = (s2 >= s1 ? TAI_OK : TAI_FALSE); break; default: break; /* FIXME */ } } va_end(ap); return rc; } @ 1.8 log @bump copyright year @ text @d161 2 a162 2 tai->sec = tai_ui64_n2i((unsigned long)t); tai->asec = tai_ui64_n2i((unsigned long)0); @ 1.7 log @hacking wild to get OSSP tai (just) working on Solaris @ text @d3 3 a5 3 ** Copyright (c) 2002 Ralf S. Engelschall ** Copyright (c) 2002 The OSSP Project ** Copyright (c) 2002 Cable & Wireless Deutschland @ 1.6 log @fix tai_op() and add support for gmtime_r under Solaris @ text @a58 2 if (tai->tai_zone != NULL) free(tai->tai_zone); d63 30 d122 5 a126 5 tai->tai_gmtoff = stm->tm_gmtoff; if (stm->tm_zone == NULL) tai->tai_zone = strdup(""); else tai->tai_zone = strdup(stm->tm_zone); d152 1 d154 3 a156 4 if (stm->tm_zone == NULL) tai->tai_zone = strdup(""); else tai->tai_zone = strdup(stm->tm_zone); d196 1 d198 1 a198 1 stm->tm_zone = tai->tai_zone; d223 1 d225 1 a225 1 stm->tm_zone = strdup(tai->tai_zone); @ 1.5 log @ugly hacks to allow lmtp2nntp to compile; comparison does not even work, yet @ text @d257 7 a263 6 case TAI_OP_NE: rc = s2 != s1 ? TAI_OK: TAI_FALSE; case TAI_OP_EQ: rc = s2 == s1 ? TAI_OK: TAI_FALSE; case TAI_OP_LT: rc = s2 < s1 ? TAI_OK: TAI_FALSE; case TAI_OP_LE: rc = s2 <= s1 ? TAI_OK: TAI_FALSE; case TAI_OP_GT: rc = s2 > s1 ? TAI_OK: TAI_FALSE; case TAI_OP_GE: rc = s2 >= s1 ? TAI_OK: TAI_FALSE; @ 1.4 log @flush todays work @ text @d242 1 d248 17 d266 1 a266 1 return TAI_ERR_IMP; @ 1.3 log @move to correct position and start with ui64_t integration @ text @d28 1 a28 1 ** tm.c: API implementation d129 7 @ 1.2 log @added a tai_op stub @ text @a39 20 struct tai_st { int tai_sec; /* seconds after the minute [0-61] */ int tai_min; /* minutes after the hour [0-59] */ int tai_hour; /* hours since midnight [0-23] */ int tai_mday; /* day of the month [1-31] */ int tai_mon; /* months since January [0-11] */ int tai_year; /* years since 1900 */ int tai_wday; /* days since Sunday [0-6] */ int tai_yday; /* days since January 1 [0-365] */ int tai_isdst; /* Daylight Savings Time flag */ long tai_gmtoff; /* offset from CUT in seconds */ char *tai_zone; /* timezone abbreviation */ #if 0 int sign; unsigned long long sec; unsigned long nsec; unsigned long asec; #endif }; @ 1.1 log @Initial revision @ text @d253 10 @ 1.1.1.1 log @Import first cut for OSSP tai @ text @@