Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
libSslSupport/timeStr.cpp
/* |
File: timeStr.h |
Contains: time string routines |
Copyright: © Copyright 2002 Apple Computer, Inc. All rights reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Change History (most recent first): |
11/4/02 1.0d1 |
*/ |
#include "timeStr.h" |
#include <string.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <ctype.h> |
/* |
* Given a string containing either a UTC-style or "generalized time" |
* time string, convert to a struct tm (in GMT/UTC). Returns nonzero on |
* error. |
*/ |
int appTimeStringToTm( |
const char *str, |
unsigned len, |
struct tm *tmp) |
{ |
char szTemp[5]; |
unsigned isUtc; |
unsigned x; |
unsigned i; |
char *cp; |
if((str == NULL) || (len == 0) || (tmp == NULL)) { |
return 1; |
} |
/* tolerate NULL terminated or not */ |
if(str[len - 1] == '\0') { |
len--; |
} |
switch(len) { |
case UTC_TIME_STRLEN: // 2-digit year, not Y2K compliant |
isUtc = 1; |
break; |
case GENERALIZED_TIME_STRLEN: // 4-digit year |
isUtc = 0; |
break; |
default: // unknown format |
return 1; |
} |
cp = (char *)str; |
/* check that all characters except last are digits */ |
for(i=0; i<(len - 1); i++) { |
if ( !(isdigit(cp[i])) ) { |
return 1; |
} |
} |
/* check last character is a 'Z' */ |
if(cp[len - 1] != 'Z' ) { |
return 1; |
} |
/* YEAR */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
if(!isUtc) { |
/* two more digits */ |
szTemp[2] = *cp++; |
szTemp[3] = *cp++; |
szTemp[4] = '\0'; |
} |
else { |
szTemp[2] = '\0'; |
} |
x = atoi( szTemp ); |
if(isUtc) { |
/* |
* 2-digit year. |
* 0 <= year < 50 : assume century 21 |
* 50 <= year < 70 : illegal per PKIX |
* 70 < year <= 99 : assume century 20 |
*/ |
if(x < 50) { |
x += 2000; |
} |
else if(x < 70) { |
return 1; |
} |
else { |
/* century 20 */ |
x += 1900; |
} |
} |
/* by definition - tm_year is year - 1900 */ |
tmp->tm_year = x - 1900; |
/* MONTH */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
szTemp[2] = '\0'; |
x = atoi( szTemp ); |
/* in the string, months are from 1 to 12 */ |
if((x > 12) || (x <= 0)) { |
return 1; |
} |
/* in a tm, 0 to 11 */ |
tmp->tm_mon = x - 1; |
/* DAY */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
szTemp[2] = '\0'; |
x = atoi( szTemp ); |
/* 1..31 in both formats */ |
if((x > 31) || (x <= 0)) { |
return 1; |
} |
tmp->tm_mday = x; |
/* HOUR */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
szTemp[2] = '\0'; |
x = atoi( szTemp ); |
if((x > 23) || (x < 0)) { |
return 1; |
} |
tmp->tm_hour = x; |
/* MINUTE */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
szTemp[2] = '\0'; |
x = atoi( szTemp ); |
if((x > 59) || (x < 0)) { |
return 1; |
} |
tmp->tm_min = x; |
/* SECOND */ |
szTemp[0] = *cp++; |
szTemp[1] = *cp++; |
szTemp[2] = '\0'; |
x = atoi( szTemp ); |
if((x > 59) || (x < 0)) { |
return 1; |
} |
tmp->tm_sec = x; |
return 0; |
} |
/* common time routine used by utcAtNowPlus and genTimeAtNowPlus */ |
#define MAX_TIME_STR_LEN 30 |
typedef enum { |
TIME_UTC, |
TIME_GEN |
} timeSpec; |
static char *timeAtNowPlus(unsigned secFromNow, |
timeSpec spec) |
{ |
struct tm utc; |
char *outStr; |
time_t baseTime; |
baseTime = time(NULL); |
baseTime += (time_t)secFromNow; |
utc = *gmtime(&baseTime); |
outStr = (char *)malloc(MAX_TIME_STR_LEN); |
if(spec == TIME_UTC) { |
/* UTC - 2 year digits - code which parses this assumes that |
* (2-digit) years between 0 and 49 are in century 21 */ |
if(utc.tm_year >= 100) { |
utc.tm_year -= 100; |
} |
sprintf(outStr, "%02d%02d%02d%02d%02d%02dZ", |
utc.tm_year /* + 1900 */, utc.tm_mon + 1, |
utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); |
} |
else { |
sprintf(outStr, "%04d%02d%02d%02d%02d%02dZ", |
/* note year is relative to 1900, hopefully it'll have four valid |
* digits! */ |
utc.tm_year + 1900, utc.tm_mon + 1, |
utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); |
} |
return outStr; |
} |
/* |
* Malloc and return UTC (2-digit year) time string, for time with specified |
* offset from present. This uses the stdlib gmtime(), which is not thread safe. |
* Even though this function protects the call with a lock, the TP also uses |
* gmtime. It also does the correct locking for its own calls to gmtime()Êbut |
* the is no way to synchronize TP's calls to gmtime() with the calls to this |
* one other than only using this one when no threads might be performing TP ops. |
*/ |
char *utcAtNowPlus(unsigned secFromNow) |
{ |
return timeAtNowPlus(secFromNow, TIME_UTC); |
} |
/* |
* Same thing, generalized time (4-digit year). |
*/ |
char *genTimeAtNowPlus(unsigned secFromNow) |
{ |
return timeAtNowPlus(secFromNow, TIME_GEN); |
} |
/* |
* Free the string obtained from the above. |
*/ |
void freeTimeString(char *timeStr) |
{ |
free(timeStr); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14