add _der_gmtime, use and test it

This commit is contained in:
Love Hornquist Astrand
2010-09-29 13:32:39 -07:00
parent f454f45fbf
commit 5fc132d888
5 changed files with 55 additions and 9 deletions

View File

@@ -58,6 +58,15 @@ test_timegm(void)
if (t != -1)
ret += 1;
_der_gmtime(1159696980, &tm);
if (tm.tm_year != 106 ||
tm.tm_mon != 9 ||
tm.tm_mday != 1 ||
tm.tm_hour != 10 ||
tm.tm_min != 3 ||
tm.tm_sec != 0)
errx(1, "tmtime failes");
return ret;
}

View File

@@ -56,6 +56,7 @@
#include "asn1-template.h"
time_t _der_timegm (struct tm *);
struct tm * _der_gmtime(time_t t, struct tm *);
size_t _heim_len_unsigned (unsigned);
size_t _heim_len_int (int);

View File

@@ -426,22 +426,22 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
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;
}

View File

@@ -8,6 +8,7 @@ EXPORTS
SAMFlags2int
TicketFlags2int
_der_timegm
_der_gmtime
_heim_der_set_sort
_heim_fix_dce
_heim_len_int

View File

@@ -42,6 +42,10 @@ is_leap(unsigned y)
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
@@ -51,9 +55,6 @@ is_leap(unsigned y)
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;
@@ -84,3 +85,37 @@ _der_timegm (struct tm *tm)
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;
}