mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-08 17:02:23 +00:00
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8545 d0543943-73ff-0310-b7d9-9358b9ac24b2
207 lines
5.1 KiB
C
207 lines
5.1 KiB
C
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#include "bool.h"
|
|
#include "int.h"
|
|
#include "xmlrpc-c/string_int.h"
|
|
#include "xmlrpc-c/time_int.h"
|
|
#include "xmlrpc-c/abyss.h"
|
|
|
|
#include "date.h"
|
|
|
|
/*********************************************************************
|
|
** Date
|
|
*********************************************************************/
|
|
|
|
static char *_DateDay[7]=
|
|
{
|
|
"Sun","Mon","Tue","Wed","Thu","Fri","Sat"
|
|
};
|
|
|
|
static char *_DateMonth[12]=
|
|
{
|
|
"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
|
|
};
|
|
|
|
|
|
|
|
void
|
|
DateToString(time_t const datetime,
|
|
const char ** const dateStringP) {
|
|
|
|
struct tm brokenTime;
|
|
|
|
xmlrpc_gmtime(datetime, &brokenTime);
|
|
|
|
if (mktime(&brokenTime) == (time_t)-1)
|
|
*dateStringP = NULL;
|
|
else
|
|
xmlrpc_asprintf(dateStringP, "%s, %02u %s %04u %02u:%02u:%02u UTC",
|
|
_DateDay[brokenTime.tm_wday],
|
|
brokenTime.tm_mday,
|
|
_DateMonth[brokenTime.tm_mon],
|
|
1900 + brokenTime.tm_year,
|
|
brokenTime.tm_hour,
|
|
brokenTime.tm_min,
|
|
brokenTime.tm_sec);
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
tzOffsetStr(struct tm const tm,
|
|
time_t const datetime) {
|
|
|
|
const char * retval;
|
|
time_t timeIfUtc;
|
|
const char * error;
|
|
|
|
xmlrpc_timegm(&tm, &timeIfUtc, &error);
|
|
|
|
if (error) {
|
|
xmlrpc_strfree(error);
|
|
xmlrpc_asprintf(&retval, "%s", "+????");
|
|
} else {
|
|
int const tzOffset = (int)(datetime - timeIfUtc);
|
|
|
|
assert(tzOffset == datetime - timeIfUtc);
|
|
|
|
xmlrpc_asprintf(&retval, "%+03d%02d",
|
|
tzOffset/3600, abs(tzOffset % 3600)/60);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
DateToLogString(time_t const datetime,
|
|
const char ** const dateStringP) {
|
|
|
|
const char * tzo;
|
|
struct tm tm;
|
|
|
|
xmlrpc_localtime(datetime, &tm);
|
|
|
|
tzo = tzOffsetStr(tm, datetime);
|
|
|
|
xmlrpc_asprintf(dateStringP, "%02d/%s/%04d:%02d:%02d:%02d %s",
|
|
tm.tm_mday, _DateMonth[tm.tm_mon],
|
|
1900 + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
tzo);
|
|
|
|
xmlrpc_strfree(tzo);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
DateDecode(const char * const dateString,
|
|
bool * const validP,
|
|
time_t * const datetimeP) {
|
|
/*----------------------------------------------------------------------------
|
|
Return the datetime represented by 'dateString', which is in the
|
|
format used in an HTTP header.
|
|
|
|
We assume that format is always UTC-based; I don't know if HTTP
|
|
actually requires that -- maybe it could be some local time.
|
|
-----------------------------------------------------------------------------*/
|
|
int rc;
|
|
const char * s;
|
|
unsigned int monthOff;
|
|
struct tm tm;
|
|
bool error;
|
|
|
|
s = &dateString[0];
|
|
|
|
/* Ignore spaces, day name and spaces */
|
|
while ((*s==' ') || (*s=='\t'))
|
|
++s;
|
|
|
|
while ((*s!=' ') && (*s!='\t'))
|
|
++s;
|
|
|
|
while ((*s==' ') || (*s=='\t'))
|
|
++s;
|
|
|
|
error = false; /* initial value */
|
|
|
|
/* try to recognize the date format */
|
|
rc = sscanf(s, "%*s %d %d:%d:%d %d%*s",
|
|
&tm.tm_mday, &tm.tm_hour,
|
|
&tm.tm_min, &tm.tm_sec, &tm.tm_year);
|
|
if (rc == 5)
|
|
monthOff = 0;
|
|
else {
|
|
int rc;
|
|
rc = sscanf(s, "%d %n%*s %d %d:%d:%d GMT%*s",
|
|
&tm.tm_mday, &monthOff, &tm.tm_year,
|
|
&tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
|
if (rc != 5) {
|
|
int rc;
|
|
rc = sscanf(s, "%d-%n%*[A-Za-z]-%d %d:%d:%d GMT%*s",
|
|
&tm.tm_mday, &monthOff, &tm.tm_year,
|
|
&tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
|
if (rc != 5)
|
|
error = true;
|
|
}
|
|
}
|
|
if (!error) {
|
|
const char * monthName = s + monthOff;
|
|
/* This is actually just the point in 'dateString' where
|
|
the month name begins -- it's not a nul-terminated string
|
|
*/
|
|
|
|
unsigned int i;
|
|
bool gotMonth;
|
|
|
|
for (i = 0, gotMonth = false; i < 12; ++i) {
|
|
const char * p;
|
|
|
|
p =_DateMonth[i];
|
|
|
|
if (tolower(*p++) == tolower(monthName[0]))
|
|
if (*p++ == tolower(monthName[1]))
|
|
if (*p == tolower(monthName[2])) {
|
|
gotMonth = true;
|
|
tm.tm_mon = i;
|
|
}
|
|
}
|
|
|
|
if (!gotMonth)
|
|
error = true;
|
|
else {
|
|
if (tm.tm_year > 1900)
|
|
tm.tm_year -= 1900;
|
|
else {
|
|
if (tm.tm_year < 70)
|
|
tm.tm_year += 100;
|
|
}
|
|
tm.tm_isdst = 0;
|
|
|
|
{
|
|
const char * timeError;
|
|
xmlrpc_timegm(&tm, datetimeP, &timeError);
|
|
|
|
if (timeError) {
|
|
error = TRUE;
|
|
xmlrpc_strfree(timeError);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*validP = !error;
|
|
}
|
|
|
|
|
|
|
|
abyss_bool
|
|
DateInit(void) {
|
|
|
|
return true;
|
|
}
|