1 /*
2 * Copyright 2001-2004 Brandon Long
3 * All Rights Reserved.
4 *
5 * ClearSilver Templating System
6 *
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
9 *
10 */
11
12 #include "cs_config.h"
13
14 #include <time.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <stdlib.h>
19 #include "util/neo_misc.h"
20 #include "util/neo_err.h"
21 #include "util/neo_hdf.h"
22 #include "util/neo_date.h"
23 #include "cgi.h"
24 #include "date.h"
25
26 /*
27 * prefix.sec
28 * prefix.min
29 * prefix.hour - 12 hour
30 * prefix.am - 1 if AM
31 * prefix.24hour - 24 hour
32 * prefix.mday
33 * prefix.mon - numeric month
34 * prefix.year - full year (ie, 4 digits)
35 * prefix.2yr - year (2 digits)
36 * prefix.wday - day of the week
37 * prefix.tzoffset - hhmm from UTC
38 *
39 */
40
export_date_tm(HDF * data,const char * prefix,struct tm * ttm)41 NEOERR *export_date_tm (HDF *data, const char *prefix, struct tm *ttm)
42 {
43 NEOERR *err;
44 HDF *obj;
45 int hour, am = 1;
46 char buf[256];
47 int tzoffset_seconds = 0;
48 int tzoffset = 0;
49 char tzsign = '+';
50
51 obj = hdf_get_obj (data, prefix);
52 if (obj == NULL)
53 {
54 err = hdf_set_value (data, prefix, "");
55 if (err) return nerr_pass(err);
56 obj = hdf_get_obj (data, prefix);
57 }
58
59 snprintf (buf, sizeof(buf), "%02d", ttm->tm_sec);
60 err = hdf_set_value (obj, "sec", buf);
61 if (err) return nerr_pass(err);
62 snprintf (buf, sizeof(buf), "%02d", ttm->tm_min);
63 err = hdf_set_value (obj, "min", buf);
64 if (err) return nerr_pass(err);
65 snprintf (buf, sizeof(buf), "%02d", ttm->tm_hour);
66 err = hdf_set_value (obj, "24hour", buf);
67 if (err) return nerr_pass(err);
68 hour = ttm->tm_hour;
69 if (hour == 0)
70 {
71 hour = 12;
72 }
73 else if (hour == 12)
74 {
75 am = 0;
76 }
77 else if (hour > 12)
78 {
79 am = 0;
80 hour -= 12;
81 }
82 err = hdf_set_int_value (obj, "hour", hour);
83 if (err) return nerr_pass(err);
84 err = hdf_set_int_value (obj, "am", am);
85 if (err) return nerr_pass(err);
86 err = hdf_set_int_value (obj, "mday", ttm->tm_mday);
87 if (err) return nerr_pass(err);
88 err = hdf_set_int_value (obj, "mon", ttm->tm_mon + 1);
89 if (err) return nerr_pass(err);
90 err = hdf_set_int_value (obj, "year", ttm->tm_year + 1900);
91 if (err) return nerr_pass(err);
92 snprintf(buf, sizeof(buf), "%02d", ttm->tm_year % 100);
93 err = hdf_set_value (obj, "2yr", buf);
94 if (err) return nerr_pass(err);
95 err = hdf_set_int_value (obj, "wday", ttm->tm_wday);
96 if (err) return nerr_pass(err);
97 // neo_tz_offset() returns offset from GMT in seconds
98 tzoffset_seconds = neo_tz_offset(ttm);
99 tzoffset = tzoffset_seconds / 60;
100 if (tzoffset < 0)
101 {
102 tzoffset *= -1;
103 tzsign = '-';
104 }
105 snprintf(buf, sizeof(buf), "%c%02d%02d", tzsign, tzoffset / 60, tzoffset % 60);
106 err = hdf_set_value (obj, "tzoffset", buf);
107 if (err) return nerr_pass(err);
108
109 return STATUS_OK;
110 }
111
export_date_time_t(HDF * data,const char * prefix,const char * timezone,time_t tt)112 NEOERR *export_date_time_t (HDF *data, const char *prefix, const char *timezone,
113 time_t tt)
114 {
115 struct tm ttm;
116
117 neo_time_expand (tt, timezone, &ttm);
118 return nerr_pass (export_date_tm (data, prefix, &ttm));
119 }
120
121 /* from httpd util.c : made infamous with Roy owes Rob beer. */
122 static char *months[] = {
123 "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
124 };
125
find_month(char * mon)126 int find_month(char *mon) {
127 register int x;
128
129 for(x=0;x<12;x++)
130 if(!strcmp(months[x],mon))
131 return x;
132 return -1;
133 }
134
later_than(struct tm * lms,char * ims)135 int later_than(struct tm *lms, char *ims) {
136 char *ip;
137 char mname[256];
138 int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, x;
139
140 /* Whatever format we're looking at, it will start
141 * with weekday. */
142 /* Skip to first space. */
143 if(!(ip = strchr(ims,' ')))
144 return 0;
145 else
146 while(isspace(*ip))
147 ++ip;
148
149 if(isalpha(*ip)) {
150 /* ctime */
151 sscanf(ip,"%25s %d %d:%d:%d %d",mname,&day,&hour,&min,&sec,&year);
152 }
153 else if(ip[2] == '-') {
154 /* RFC 850 (normal HTTP) */
155 char t[256];
156 sscanf(ip,"%s %d:%d:%d",t,&hour,&min,&sec);
157 t[2] = '\0';
158 day = atoi(t);
159 t[6] = '\0';
160 strcpy(mname,&t[3]);
161 x = atoi(&t[7]);
162 /* Prevent
163 * wraparound
164 * from
165 * ambiguity
166 * */
167 if(x < 70)
168 x += 100;
169 year = 1900 + x;
170 }
171 else {
172 /* RFC 822 */
173 sscanf(ip,"%d %s %d %d:%d:%d",&day,mname,&year,&hour,&min,&sec);
174 }
175 month = find_month(mname);
176
177 if((x = (1900+lms->tm_year) - year))
178 return x < 0;
179 if((x = lms->tm_mon - month))
180 return x < 0;
181 if((x = lms->tm_mday - day))
182 return x < 0;
183 if((x = lms->tm_hour - hour))
184 return x < 0;
185 if((x = lms->tm_min - min))
186 return x < 0;
187 if((x = lms->tm_sec - sec))
188 return x < 0;
189
190 return 1;
191 }
192
193