int
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
{
- struct tm *tm;
+ struct tm tm;
const size_t len = gtimep ? 15 : 13;
s->data = malloc(len + 1);
if (s->data == NULL)
return ENOMEM;
s->length = len;
- tm = gmtime (&t);
+ _der_gmtime(t, &tm);
if (gtimep)
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
else
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
- tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
return 0;
}
return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
}
+static const unsigned ndays[2][12] ={
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+
/*
* This is a simplifed version of timegm(3) that doesn't accept out of
* bound values that timegm(3) normally accepts but those are not
time_t
_der_timegm (struct tm *tm)
{
- static const unsigned ndays[2][12] ={
- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
time_t res = 0;
unsigned i;
res += tm->tm_sec;
return res;
}
+
+struct tm *
+_der_gmtime(time_t t, struct tm *tm)
+{
+ time_t secday = t % (3600 * 24);
+ time_t days = t / (3600 * 24);
+
+ memset(tm, 0, sizeof(*tm));
+
+ tm->tm_sec = secday % 60;
+ tm->tm_min = (secday % 3600) / 60;
+ tm->tm_hour = secday / 3600;
+
+ tm->tm_year = 70;
+ while(1) {
+ unsigned dayinyear = (is_leap(tm->tm_year) ? 366 : 365);
+ if (days < dayinyear)
+ break;
+ tm->tm_year += 1;
+ days -= dayinyear;
+ }
+ tm->tm_mon = 0;
+
+ while (1) {
+ unsigned daysinmonth = ndays[is_leap(tm->tm_year)][tm->tm_mon];
+ if (days < daysinmonth)
+ break;
+ days -= daysinmonth;
+ tm->tm_mon++;
+ }
+ tm->tm_mday = days + 1;
+
+ return tm;
+}