Annotation of embedaddon/libpdel/structs/type/structs_type_time.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (c) 2001-2002 Packet Design, LLC.
4: * All rights reserved.
5: *
6: * Subject to the following obligations and disclaimer of warranty,
7: * use and redistribution of this software, in source or object code
8: * forms, with or without modifications are expressly permitted by
9: * Packet Design; provided, however, that:
10: *
11: * (i) Any and all reproductions of the source or object code
12: * must include the copyright notice above and the following
13: * disclaimer of warranties; and
14: * (ii) No rights are granted, in any manner or form, to use
15: * Packet Design trademarks, including the mark "PACKET DESIGN"
16: * on advertising, endorsements, or otherwise except as such
17: * appears in the above copyright notice or in the software.
18: *
19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
36: * THE POSSIBILITY OF SUCH DAMAGE.
37: *
38: * Author: Archie Cobbs <archie@freebsd.org>
39: */
40:
41: #include <sys/types.h>
42:
43: #include <stdio.h>
44: #include <stdlib.h>
45: #include <stdarg.h>
46: #include <string.h>
47: #include <ctype.h>
48: #include <errno.h>
49: #include <time.h>
50:
51: #include "structs/structs.h"
52: #include "structs/type/array.h"
53: #include "structs/type/int.h"
54: #include "structs/type/time.h"
55: #include "util/typed_mem.h"
56:
57: /*********************************************************************
58: TIME TYPE
59: *********************************************************************/
60:
61: #define FMT_GMT "%a %b %e %T GMT %Y"
62: #define FMT_LOCAL "%a %b %e %T %Y"
63: #define FMT_IS08601 "%Y%m%dT%H:%M:%S"
64:
65: #ifndef _KERNEL
66:
67: static structs_ascify_t structs_time_ascify;
68: static structs_binify_t structs_time_binify;
69:
70: static char *
71: structs_time_ascify(const struct structs_type *type,
72: const char *mtype, const void *data)
73: {
74: const char *fmt = type->args[0].s;
75: const int local = type->args[1].i;
76: const time_t when = *((time_t *)data);
77: struct tm tm;
78: char buf[64];
79:
80: if (local)
81: localtime_r(&when, &tm);
82: else
83: gmtime_r(&when, &tm);
84: strftime(buf, sizeof(buf), fmt, &tm);
85: return (STRDUP(mtype, buf));
86: }
87:
88: static int
89: structs_time_binify(const struct structs_type *type,
90: const char *ascii, void *data, char *ebuf, size_t emax)
91: {
92: const char *fmt = type->args[0].s;
93: const int local = type->args[1].i;
94: struct tm whentm;
95: time_t when;
96:
97: memset(&whentm, 0, sizeof(whentm));
98: while (isspace(*ascii))
99: ascii++;
100: if (strptime(ascii, fmt, &whentm) == NULL) {
101: strlcpy(ebuf, "invalid time", emax);
102: errno = EINVAL;
103: return (-1);
104: }
105: if (local) {
106: whentm.tm_isdst = -1;
107: when = mktime(&whentm);
108: } else
109: when = timegm(&whentm);
110: if (when == (time_t)-1) {
111: errno = EDOM;
112: return (-1);
113: }
114: *((time_t *)data) = when;
115: return (0);
116: }
117: #endif /* !_KERNEL */
118:
119: const struct structs_type structs_type_time_gmt = {
120: sizeof(time_t),
121: "time",
122: STRUCTS_TYPE_PRIMITIVE,
123: structs_region_init,
124: structs_region_copy,
125: structs_region_equal,
126: #ifndef _KERNEL
127: structs_time_ascify,
128: structs_time_binify,
129: #else
130: structs_notsupp_ascify,
131: structs_notsupp_binify,
132: #endif
133: structs_region_encode_netorder,
134: structs_region_decode_netorder,
135: structs_nothing_free,
136: { { (void *)FMT_GMT }, { (void *)0 } }
137: };
138:
139: const struct structs_type structs_type_time_local = {
140: sizeof(time_t),
141: "time",
142: STRUCTS_TYPE_PRIMITIVE,
143: structs_region_init,
144: structs_region_copy,
145: structs_region_equal,
146: #ifndef _KERNEL
147: structs_time_ascify,
148: structs_time_binify,
149: #else
150: structs_notsupp_ascify,
151: structs_notsupp_binify,
152: #endif
153: structs_region_encode_netorder,
154: structs_region_decode_netorder,
155: structs_nothing_free,
156: { { (void *)FMT_LOCAL }, { (void *)1 } }
157: };
158:
159: const struct structs_type structs_type_time_iso8601 = {
160: sizeof(time_t),
161: "time",
162: STRUCTS_TYPE_PRIMITIVE,
163: structs_region_init,
164: structs_region_copy,
165: structs_region_equal,
166: #ifndef _KERNEL
167: structs_time_ascify,
168: structs_time_binify,
169: #else
170: structs_notsupp_ascify,
171: structs_notsupp_binify,
172: #endif
173: structs_region_encode_netorder,
174: structs_region_decode_netorder,
175: structs_nothing_free,
176: { { (void *)FMT_IS08601 }, { (void *)0 } }
177: };
178:
179: /*
180: * Absolute time.
181: *
182: * Use custom ascify/binify routines to work around FreeBSD
183: * bug with '%s' format of strftime().
184: */
185:
186: /* XXX This assumes sizeof(time_t) <= sizeof(long) */
187:
188: static structs_ascify_t structs_time_abs_ascify;
189: static structs_binify_t structs_time_abs_binify;
190:
191: static char *
192: structs_time_abs_ascify(const struct structs_type *type,
193: const char *mtype, const void *data)
194: {
195: const u_long when = (u_long)*((time_t *)data);
196:
197: return (structs_type_ulong.ascify(&structs_type_ulong, mtype, &when));
198: }
199:
200: static int
201: structs_time_abs_binify(const struct structs_type *type,
202: const char *ascii, void *data, char *ebuf, size_t emax)
203: {
204: u_long when;
205:
206: if (structs_type_ulong.binify(&structs_type_ulong,
207: ascii, &when, ebuf, emax) == -1)
208: return (-1);
209: *((time_t *)data) = (time_t)when;
210: return (0);
211: }
212:
213: const struct structs_type structs_type_time_abs = {
214: sizeof(time_t),
215: "time",
216: STRUCTS_TYPE_PRIMITIVE,
217: structs_region_init,
218: structs_region_copy,
219: structs_region_equal,
220: structs_time_abs_ascify,
221: structs_time_abs_binify,
222: structs_region_encode_netorder,
223: structs_region_decode_netorder,
224: structs_nothing_free,
225: };
226:
227: /*
228: * Relative time
229: */
230:
231: static structs_ascify_t structs_reltime_ascify;
232: static structs_binify_t structs_reltime_binify;
233:
234: /* XXX This assumes sizeof(time_t) <= sizeof(long) */
235:
236: static char *
237: structs_reltime_ascify(const struct structs_type *type,
238: const char *mtype, const void *data)
239: {
240: const time_t now = time(NULL);
241: const time_t diff = *((time_t *)data) - now;
242: char buf[32];
243:
244: snprintf(buf, sizeof(buf), "%ld", (u_long)diff);
245: return (STRDUP(mtype, buf));
246: }
247:
248: static int
249: structs_reltime_binify(const struct structs_type *type,
250: const char *ascii, void *data, char *ebuf, size_t emax)
251: {
252: const time_t now = time(NULL);
253: int64_t absolute;
254: int64_t diff;
255:
256: if (structs_type_int64.binify(&structs_type_int64,
257: ascii, &diff, ebuf, emax) == -1)
258: return (-1);
259: absolute = (int64_t)now + diff;
260: if (absolute < (time_t)(int64_t)~0
261: || absolute > ((int64_t)1 << ((sizeof(time_t) * 8) - 1)) - 1) {
262: errno = EDOM;
263: return (-1);
264: }
265: *((time_t *)data) = (time_t)absolute;
266: return (0);
267: }
268:
269: const struct structs_type structs_type_time_rel = {
270: sizeof(time_t),
271: "reltime",
272: STRUCTS_TYPE_PRIMITIVE,
273: structs_region_init,
274: structs_region_copy,
275: structs_region_equal,
276: structs_reltime_ascify,
277: structs_reltime_binify,
278: structs_region_encode_netorder,
279: structs_region_decode_netorder,
280: structs_nothing_free,
281: };
282:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>