/************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 1986 - 2006, All Rights Reserved. */ /* */ /* PROPRIETARY AND CONFIDENTIAL */ /* */ /* MODULE NAME : ard_time.c */ /* PRODUCT(S) : ASN1DE */ /* */ /* MODULE DESCRIPTION : */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ ------------------------------------------- */ /* 01/16/07 JRB 07 Fix err decoding time near "19700101000000Z" */ /* in timezone east of GMT by using usr_mkgmtime.*/ /* 03/23/06 EJV 06 Cast time_t var to (ST_ULONG) and use '%lu'. */ /* 07/26/02 EJV 05 Added code to skip fraction of a second. */ /* 12/20/01 JRB 04 Chg ASN1_CTXT to ASN1_DEC_CTXT. */ /* 11/19/01 EJV 03 Made asn1dec_figureDelta func static */ /* 09/13/99 MDE 02 Added SD_CONST modifiers */ /* 07/26/99 MDE 01 New module, derived from ad_time.c */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #include "asn1r.h" #include "asn1log.h" #include "time_str.h" /* for usr_mkgmtime */ /************************************************************************/ /* For debug version, use a static pointer to avoid duplication of */ /* __FILE__ strings. */ #ifdef DEBUG_SISCO SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; #endif /************************************************************************/ /* get_time */ /* Function to decode Generalized Time into MS-DOS time (= number of */ /* seconds since 00:00 Jan 1, 1970, GMT). */ /************************************************************************/ ST_RET asn1r_get_time (ASN1_DEC_CTXT *ac, time_t *decTimeTValue) { struct tm breakDown; struct tm gStruTime; ST_UCHAR *last_pos; ST_CHAR time_comp[6]; ST_BOOLEAN adjustmetPos; ST_INT adjust; time_t resultantTimeT; /* check to see if the pointer for returning is valid */ if (!decTimeTValue) { ALOG_ERR0 ("Required pointer passed to function is NULL, expecting non NULL time_t pointer"); return(SD_FAILURE); } ALOG_DEC0("Decode ASN1 generalized time string "); last_pos = ac->asn1r_field_ptr + ac->asn1r_elmnt_len; /* 1 + last pos'n in data el't */ /* Determine the Year in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[3] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[4] = 0; /* Convert the year to a integer string */ breakDown.tm_year = (ST_INT16) atoi(time_comp); breakDown.tm_year = breakDown.tm_year - 1900; /* Determine the month in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; /* Convert the month to a integer string */ breakDown.tm_mon = (ST_INT16) atoi(time_comp); breakDown.tm_mon = breakDown.tm_mon - 1; /* Determine the day of the month in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; /* Convert the day of the month to a integer string */ breakDown.tm_mday = (ST_INT16) atoi(time_comp); /* Determine the hour in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; /* Convert the hour to a integer string */ breakDown.tm_hour = (ST_INT16) atoi(time_comp); /* Determine the min in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; /* Convert the min to a integer string */ breakDown.tm_min = (ST_INT16) atoi(time_comp); /* Determine the sec in this generalized time string */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; /* Convert the sec to a integer string */ breakDown.tm_sec = (ST_INT16) atoi(time_comp); /* Check to see if we have overrun */ if (ac->asn1r_field_ptr > last_pos) return(SD_FAILURE); /* Broken Down Time component's */ ALOG_CDEC0(" Broken Down Component's so far"); ALOG_CDEC1(" tm_sec %d",breakDown.tm_sec); ALOG_CDEC1(" tm_min %d",breakDown.tm_min); ALOG_CDEC1(" tm_hour %d",breakDown.tm_hour); ALOG_CDEC1(" tm_mon %d",breakDown.tm_mon); ALOG_CDEC1(" tm_year %d",breakDown.tm_year); ALOG_CDEC1(" tm_mday %d",breakDown.tm_mday); /* There maybe be a fraction of a second in the generalized time. */ /* Ignore the fraction value since we can not pass it currently up. */ if (*ac->asn1r_field_ptr == '.') { ac->asn1r_field_ptr++; /* skip all digits after the period */ while (isdigit((ST_INT)(*ac->asn1r_field_ptr)) && ac->asn1r_field_ptr <= last_pos) ac->asn1r_field_ptr++; } /* Actually break down the date and time as a local time*/ if (ac->asn1r_field_ptr == last_pos) { /* Place the known data into the fields */ gStruTime.tm_sec = breakDown.tm_sec; gStruTime.tm_min = breakDown.tm_min; gStruTime.tm_hour = breakDown.tm_hour; gStruTime.tm_mon = breakDown.tm_mon; gStruTime.tm_year = breakDown.tm_year; gStruTime.tm_mday = breakDown.tm_mday; gStruTime.tm_yday = 0; gStruTime.tm_wday = 0; gStruTime.tm_isdst = 0; /* Ask for a make time */ resultantTimeT = mktime(&gStruTime); if (resultantTimeT == (time_t)-1) { ALOG_ERR0 ("mktime function returned -1 for time"); return(SD_FAILURE); } ALOG_CDEC1("Local time Decode : First Pass %lu ", (ST_ULONG) resultantTimeT); /* if the DST flag came up set, re run it with the DST flag */ if (gStruTime.tm_isdst == 1) { gStruTime.tm_sec = breakDown.tm_sec; gStruTime.tm_min = breakDown.tm_min; gStruTime.tm_hour = breakDown.tm_hour; gStruTime.tm_mon = breakDown.tm_mon; gStruTime.tm_year = breakDown.tm_year; gStruTime.tm_mday = breakDown.tm_mday; gStruTime.tm_yday = 0; gStruTime.tm_wday = 0; gStruTime.tm_isdst = 1; resultantTimeT = mktime(&gStruTime); if (resultantTimeT == (time_t)-1) { ALOG_ERR0 ("mktime function returned -1 for time"); return(SD_FAILURE); } ALOG_CDEC1("Local time Decode : Second Pass %lu ", (ST_ULONG) resultantTimeT); } ALOG_CDEC1("Local time Decode : Result %lu ", (ST_ULONG) resultantTimeT); /* Now factor the Difference between GMT and local */ *decTimeTValue = resultantTimeT; return (SD_SUCCESS); } /* Actually break down the date and time as a GMT based time with possible offset */ if ((*ac->asn1r_field_ptr == 'Z')||(*ac->asn1r_field_ptr == '+')||(*ac->asn1r_field_ptr == '-')) { /* Place the known data into the fields */ gStruTime.tm_sec = breakDown.tm_sec; gStruTime.tm_min = breakDown.tm_min; gStruTime.tm_hour = breakDown.tm_hour; gStruTime.tm_mon = breakDown.tm_mon; gStruTime.tm_year = breakDown.tm_year; gStruTime.tm_mday = breakDown.tm_mday; gStruTime.tm_yday = 0; gStruTime.tm_wday = 0; gStruTime.tm_isdst = 0; /* Ask for a make time */ /* Convert "tm" struct to "time_t" assuming struct represents GMT time.*/ resultantTimeT = usr_mkgmtime(&gStruTime); if (resultantTimeT == (time_t)-1) { ALOG_ERR0 ("usr_mkgmtime function returned -1 for time"); return(SD_FAILURE); } ALOG_CDEC1("GMT time Decode : Result %lu ", (ST_ULONG) resultantTimeT); /* Now factor the Difference between GMT and local */ *decTimeTValue = resultantTimeT; /* now if there are adjustment's to GMT */ if ((*ac->asn1r_field_ptr == '+')||(*ac->asn1r_field_ptr == '-')) { if (*ac->asn1r_field_ptr == '+') { ALOG_CDEC0("Doing a GMT based adjustment of (+) "); adjustmetPos = SD_TRUE; } else { ALOG_CDEC0("Doing a GMT based adjustment of (-) "); adjustmetPos = SD_FALSE; } ac->asn1r_field_ptr++; time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; adjust = atoi(time_comp); ALOG_CDEC1("Adjust by Hours %d ",adjust); if (adjustmetPos == SD_TRUE) *decTimeTValue += (time_t) (adjust*(60 * 60)); /* adjust hrs */ else *decTimeTValue -= (time_t) (adjust*(60 * 60)); /* adjust hrs */ time_comp[0] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[1] = (ST_CHAR)*ac->asn1r_field_ptr++; time_comp[2] = 0; adjust = atoi(time_comp); ALOG_CDEC1("Adjust by Minutes %d ",adjust); if (adjustmetPos == SD_TRUE) *decTimeTValue += (time_t) (adjust*(60)); /* adjust min */ else *decTimeTValue -= (time_t) (adjust*(60)); /* adjust min */ ALOG_CDEC1("GMT time Decode with offset : Result %lu ", (ST_ULONG) (*decTimeTValue)); return (SD_SUCCESS); } else { ac->asn1r_field_ptr++; /* Skip the 'Z' */ return (SD_SUCCESS); } } /* end of GMT based Time */ /* if the string to decode does not end in nothing, "Z", "+", "-" */ /* then return failure and dump the string */ ALOG_ERR0 ("Time string cannot be decoded by this ASN1 function"); return(SD_FAILURE); }