X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilctime.c;h=4dc7f2172ec5470d0a78ff4736aefa5e38d2ffba;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=4444e4e8a5cb2e7074d1a8c02b19b7c35a97d3fa;hpb=8fd8212bcd16f2b53fbedff2a9b9a4e8c15b9695;p=silc.git diff --git a/lib/silcutil/silctime.c b/lib/silcutil/silctime.c index 4444e4e8..4dc7f217 100644 --- a/lib/silcutil/silctime.c +++ b/lib/silcutil/silctime.c @@ -31,19 +31,19 @@ static SilcBool silc_time_fill(SilcTime time, unsigned int msec) { if (year > (1 << 15)) - return FALSE; + goto err; if (month < 1 || month > 12) - return FALSE; + goto err; if (day < 1 || day > 31) - return FALSE; + goto err; if (hour > 23) - return FALSE; + goto err; if (minute > 60) - return FALSE; + goto err; if (second > 61) - return FALSE; + goto err; if (msec > 1000) - return FALSE; + goto err; time->year = year; time->month = month; @@ -54,6 +54,10 @@ static SilcBool silc_time_fill(SilcTime time, time->msecond = msec; return TRUE; + + err: + silc_set_errno(SILC_ERR_BAD_TIME); + return FALSE; } /* Return time since Epoch */ @@ -69,7 +73,8 @@ SilcInt64 silc_time_msec(void) { struct timeval curtime; silc_gettimeofday(&curtime); - return (curtime.tv_sec * 1000) + (curtime.tv_usec / 1000); + return (curtime.tv_sec * (SilcUInt64)1000) + + (curtime.tv_usec / (SilcUInt64)1000); } /* Return time since Epoch in microseconds */ @@ -77,8 +82,9 @@ SilcInt64 silc_time_msec(void) SilcInt64 silc_time_usec(void) { struct timeval curtime; - silc_gettimeofday(&curtime); - return (curtime.tv_sec * 1000000) + curtime.tv_usec; + if (silc_gettimeofday(&curtime)) + silc_set_errno_posix(errno); + return (curtime.tv_sec * (SilcUInt64)1000000) + curtime.tv_usec; } /* Returns time as string */ @@ -93,8 +99,10 @@ const char *silc_time_string(SilcInt64 time_val) else curtime = (time_t)time_val; return_time = ctime(&curtime); - if (!return_time) + if (!return_time) { + silc_set_errno(SILC_ERR_BAD_TIME); return NULL; + } return_time[strlen(return_time) - 1] = '\0'; return (const char *)return_time; @@ -104,9 +112,10 @@ const char *silc_time_string(SilcInt64 time_val) SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time) { - struct tm *time; + struct tm *t; unsigned int msec = 0; time_t timeval; + SilcInt32 ctz = 0; if (!ret_time) return TRUE; @@ -117,17 +126,20 @@ SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time) msec = (SilcUInt64)time_val % (SilcUInt64)1000; timeval = (time_t)((SilcUInt64)time_val / (SilcUInt64)1000); - time = localtime(&timeval); - if (!time) + t = localtime(&timeval); + if (!t) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } memset(ret_time, 0, sizeof(*ret_time)); - if (!silc_time_fill(ret_time, time->tm_year + 1900, time->tm_mon + 1, - time->tm_mday, time->tm_hour, time->tm_min, - time->tm_sec, msec)) + if (!silc_time_fill(ret_time, t->tm_year + 1900, t->tm_mon + 1, + t->tm_mday, t->tm_hour, t->tm_min, + t->tm_sec, msec)) return FALSE; - ret_time->dst = time->tm_isdst ? 1 : 0; + ret_time->dst = t->tm_isdst ? 1 : 0; + #ifdef SILC_WIN32 ret_time->utc_east = _timezone < 0 ? 1 : 0; ret_time->utc_hour = (ret_time->utc_east ? (-(_timezone)) / 3600 : @@ -135,15 +147,29 @@ SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time) ret_time->utc_minute = (ret_time->utc_east ? (-(_timezone)) % 3600 : _timezone % 3600); #else -#if defined(HAVE_TZSET) +#if defined(HAVE_TIMEZONE) ret_time->utc_east = timezone < 0 ? 1 : 0; - ret_time->utc_hour = (ret_time->utc_east ? (-(timezone)) / 3600 : - timezone / 3600); - ret_time->utc_minute = (ret_time->utc_east ? (-(timezone)) % 3600 : - timezone % 3600); -#endif /* HAVE_TZSET */ + ctz = timezone; + if (ret_time->dst) + ctz -= 3600; +#elif defined(HAVE_TM_GMTOFF) + ret_time->utc_east = t->tm_gmtoff > 0 ? 1 : 0; + ctz = -t->tm_gmtoff; +#elif defined(HAVE___TM_GMTOFF) + ret_time->utc_east = t->__tm_gmtoff > 0 ? 1 : 0; + ctz = -t->__tm_gmtoff; +#elif defined(HAVE___TM_GMTOFF__) + ret_time->utc_east = t->__tm_gmtoff__ > 0 ? 1 : 0; + ctz = -t->__tm_gmtoff__; +#endif /* HAVE_TIMEZONE */ + + ret_time->utc_hour = (ret_time->utc_east ? (-(ctz)) / 3600 : ctz / 3600); + ret_time->utc_minute = (ret_time->utc_east ? (-(ctz)) % 3600 : ctz % 3600); #endif /* SILC_WIN32 */ + if (ret_time->utc_minute) + ret_time->utc_minute /= 60; + return TRUE; } @@ -153,16 +179,18 @@ SilcBool silc_timezone(char *timezone, SilcUInt32 timezone_size) { SilcTimeStruct curtime; - if (timezone_size < 6) + if (timezone_size < 6) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; - + } + if (!silc_time_value(0, &curtime)) return FALSE; if (!curtime.utc_hour && curtime.utc_minute) silc_snprintf(timezone, timezone_size, "Z"); else if (curtime.utc_minute) - silc_snprintf(timezone, timezone_size, "%c%02d:%02d", + silc_snprintf(timezone, timezone_size, "%c%02d:%02d", curtime.utc_east ? '+' : '-', curtime.utc_hour, curtime.utc_minute); else @@ -189,6 +217,7 @@ SilcBool silc_time_universal(const char *universal_time, SilcTime ret_time) &day, &hour, &minute, &second, &z); if (ret < 3) { SILC_LOG_DEBUG(("Invalid UTC time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid UTC time string"); return FALSE; } @@ -204,19 +233,21 @@ SilcBool silc_time_universal(const char *universal_time, SilcTime ret_time) ret = sscanf(universal_time + (ret * 2) + 1, "%02u%02u", &hour, &minute); if (ret != 2) { SILC_LOG_DEBUG(("Malformed UTC time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Malformed UTC time string"); return FALSE; } - if (hour < 0 || hour > 23) - return FALSE; - if (minute < 0 || minute > 60) + if (hour > 23 || minute > 60) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } ret_time->utc_hour = hour; ret_time->utc_minute = minute; ret_time->utc_east = (z == '-') ? 0 : 1; } else if (z != 'Z') { SILC_LOG_DEBUG(("Invalid timezone")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid timezone"); return FALSE; } @@ -234,11 +265,12 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, SilcUInt32 ret_string_size) { int ret, len = 0; + memset(ret_string, 0, ret_string_size); ret = silc_snprintf(ret_string, ret_string_size - 1, - "%02u%02u%02u%02u%02u%02u", - time_val->year % 100, time_val->month, time_val->day, - time_val->hour, time_val->minute, time_val->second); + "%02u%02u%02u%02u%02u%02u", + time_val->year % 100, time_val->month, time_val->day, + time_val->hour, time_val->minute, time_val->second); if (ret < 0) return FALSE; len += ret; @@ -250,8 +282,8 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, len += ret; } else { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - "%c%02u%02u", time_val->utc_east ? '+' : '-', - time_val->utc_hour, time_val->utc_minute); + "%c%02u%02u", time_val->utc_east ? '+' : '-', + time_val->utc_hour, time_val->utc_minute); if (ret < 0) return FALSE; len += ret; @@ -278,6 +310,7 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) &day, &hour, &minute, &second); if (ret < 3) { SILC_LOG_DEBUG(("Invalid generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid generalized time string"); return FALSE; } @@ -293,6 +326,8 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) ret = sscanf(generalized_time + i, "%c", &z); if (ret != 1) { SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } @@ -303,6 +338,8 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) ret = sscanf(generalized_time + i, "%u%n", &msecond, &l); if (ret != 1) { SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } while (l > 4) { @@ -321,14 +358,16 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) if (z == '-' || z == '+') { ret = sscanf(generalized_time + i + 1, "%02u%02u", &hour, &minute); if (ret != 2) { - SILC_LOG_DEBUG(("Malformed UTC time string")); + SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } - if (hour < 0 || hour > 23) - return FALSE; - if (minute < 0 || minute > 60) + if (hour > 23 || minute > 60) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } ret_time->utc_hour = hour; ret_time->utc_minute = minute; @@ -346,16 +385,17 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, int len = 0, ret; memset(ret_string, 0, ret_string_size); ret = silc_snprintf(ret_string, ret_string_size - 1, - "%04u%02u%02u%02u%02u%02u", - time_val->year, time_val->month, time_val->day, time_val->hour, - time_val->minute, time_val->second); + "%04u%02u%02u%02u%02u%02u", + time_val->year, time_val->month, + time_val->day, time_val->hour, + time_val->minute, time_val->second); if (ret < 0) return FALSE; len += ret; if (time_val->msecond) { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - ".%lu", (unsigned long)time_val->msecond); + ".%lu", (unsigned long)time_val->msecond); if (ret < 0) return FALSE; len += ret; @@ -368,8 +408,8 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, len += ret; } else { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - "%c%02u%02u", time_val->utc_east ? '+' : '-', - time_val->utc_hour, time_val->utc_minute); + "%c%02u%02u", time_val->utc_east ? '+' : '-', + time_val->utc_hour, time_val->utc_minute); if (ret < 0) return FALSE; len += ret; @@ -380,13 +420,10 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, /* Return TRUE if `smaller' is smaller than `bigger'. */ -SilcBool silc_compare_timeval(struct timeval *smaller, - struct timeval *bigger) +int silc_compare_timeval(struct timeval *t1, struct timeval *t2) { - if ((smaller->tv_sec < bigger->tv_sec) || - ((smaller->tv_sec == bigger->tv_sec) && - (smaller->tv_usec < bigger->tv_usec))) - return TRUE; - - return FALSE; + SilcInt32 s = t1->tv_sec - t2->tv_sec; + if (!s) + return t1->tv_usec - t2->tv_usec; + return s; }