date.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: date.c,v 1.12 2008/12/17 08:40:53 tho Exp $
00009  */
00010 
00011 #include "klone_conf.h"
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <time.h>
00015 #include <ctype.h>
00016 #include <fcntl.h>
00017 #include <unistd.h>
00018 #include <dirent.h>
00019 #include <sys/stat.h>
00020 #include <u/libu.h>
00021 #include <klone/os.h>
00022 #include <klone/utils.h>
00023 
00029 static const char* days3[] = { 
00030     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 
00031 };
00032 
00033 static const char* months[] = { 
00034     "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
00035     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
00036 };
00037 
00038 static int month_idx(const char *mon)
00039 {
00040     int i;
00041 
00042     dbg_return_if (mon == NULL, -1);
00043     
00044     for(i = 0; i < 12; ++i)
00045         if(strcasecmp(months[i], mon) == 0)
00046             return i;
00047 
00048     return -1;
00049 }
00050 
00063 int u_asctime_to_tt(const char *str, time_t *tp)
00064 {
00065     enum { BUFSZ = 64 };
00066     char wday[BUFSZ], mon[BUFSZ];
00067     unsigned int day, year, hour, min, sec;
00068     struct tm tm;
00069     int i;
00070 
00071     dbg_return_if (str == NULL, ~0);
00072     dbg_return_if (tp == NULL, ~0);
00073     dbg_return_if (strlen(str) >= BUFSZ, ~0);
00074 
00075     dbg_err_if((i = sscanf(str, "%s %s %u %u:%u:%u %u", wday, 
00076         mon, &day, &hour, &min, &sec, &year)) != 7);
00077 
00078     memset(&tm, 0, sizeof(struct tm));
00079 
00080     /* time */
00081     tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00082 
00083     /* date */
00084     tm.tm_mday = day; 
00085     tm.tm_mon = month_idx(mon);
00086     tm.tm_year = year - 1900;
00087 
00088     dbg_err_if(tm.tm_mon < 0);
00089 
00090     *tp = timegm(&tm);
00091     
00092     return 0;
00093 err:
00094     return ~0;
00095 }
00096 
00109 int u_rfc850_to_tt(const char *str, time_t *tp)
00110 {
00111     enum { BUFSZ = 64 };
00112     char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00113     unsigned int day, year, hour, min, sec;
00114     struct tm tm;
00115     int i;
00116     char c;
00117 
00118     dbg_return_if (str == NULL, ~0);
00119     dbg_return_if (tp == NULL, ~0);
00120     dbg_return_if (strlen(str) >= BUFSZ, ~0);
00121 
00122     dbg_err_if((i = sscanf(str, "%[^,], %u%c%[^-]%c%u %u:%u:%u %s", wday, 
00123         &day, &c, mon, &c, &year, &hour, &min, &sec, tzone)) != 10);
00124 
00125     memset(&tm, 0, sizeof(struct tm));
00126 
00127     /* time */
00128     tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00129 
00130     /* date */
00131     tm.tm_mday = day; 
00132     tm.tm_mon = month_idx(mon);
00133     tm.tm_year = year - 1900;
00134 
00135     dbg_err_if(tm.tm_mon < 0);
00136 
00137 #ifdef HAVE_TMZONE
00138     /* time zone */
00139     tm.tm_zone = tzone;
00140 #endif
00141 
00142     *tp = timegm(&tm);
00143 
00144     return 0;
00145 err:
00146     return ~0;
00147 }
00148 
00161 int u_rfc822_to_tt(const char *str, time_t *tp)
00162 {
00163     enum { BUFSZ = 64 };
00164     char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00165     unsigned int day, year, hour, min, sec;
00166     struct tm tm;
00167 
00168     dbg_return_if (str == NULL, ~0);
00169     dbg_return_if (tp == NULL, ~0);
00170     dbg_return_if (strlen(str) >= BUFSZ, ~0);
00171 
00172     dbg_err_if(sscanf(str, "%[^,], %u %s %u %u:%u:%u %s", wday, 
00173         &day, mon, &year, &hour, &min, &sec, tzone) != 8);
00174 
00175     memset(&tm, 0, sizeof(struct tm));
00176 
00177     /* time */
00178     tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00179 
00180     /* date */
00181     tm.tm_mday = day; 
00182     tm.tm_mon = month_idx(mon);
00183     tm.tm_year = year - 1900; 
00184 
00185     dbg_err_if(tm.tm_mon < 0);
00186 
00187 #ifdef HAVE_TMZONE
00188     /* time zone */
00189     tm.tm_zone = tzone;
00190 #endif
00191 
00192     *tp = timegm(&tm);
00193 
00194     return 0;
00195 err:
00196     return ~0;
00197 }
00198 
00211 int u_httpdate_to_tt(const char *str, time_t *tp)
00212 {
00213     dbg_return_if (str == NULL, ~0);
00214     dbg_return_if (tp == NULL, ~0);
00215     dbg_return_if (strlen(str) < 4, ~0);
00216 
00217     if(str[3] == ',')
00218         return u_rfc822_to_tt(str, tp);
00219     else if(str[3] == ' ')
00220         return u_asctime_to_tt(str, tp);
00221 
00222     return u_rfc850_to_tt(str, tp);
00223 }
00224 
00239 int u_tt_to_rfc822(char dst[RFC822_DATE_BUFSZ], time_t ts)
00240 {
00241     char buf[RFC822_DATE_BUFSZ];
00242     struct tm tm;
00243 
00244     dbg_return_if (dst == NULL, ~0);
00245 
00246 #ifdef OS_WIN
00247     memcpy(&tm, gmtime(&ts), sizeof(tm));
00248 #else
00249     dbg_err_if(gmtime_r(&ts, &tm) == NULL);
00250 #endif
00251 
00252     dbg_err_if(tm.tm_wday > 6 || tm.tm_wday < 0);
00253     dbg_err_if(tm.tm_mon > 11 || tm.tm_mon < 0);
00254 
00255     dbg_err_if(u_snprintf(buf, sizeof buf, 
00256                 "%s, %02u %s %02u %02u:%02u:%02u GMT",
00257                 days3[tm.tm_wday], 
00258                 tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900, 
00259                 tm.tm_hour, tm.tm_min, tm.tm_sec));
00260 
00261     /* copy out */
00262     u_strlcpy(dst, buf, RFC822_DATE_BUFSZ);
00263 
00264     return 0;
00265 err:
00266     return ~0;
00267 }
00268 

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved