1 /* $MirOS: contrib/code/jupp/compat.c,v 1.4 2012/06/08 16:48:58 tg Exp $ */
4 * Copyright © 2004, 2005, 2006, 2007, 2011, 2012
5 * Thorsten “mirabilos” Glaser <tg@mirbsd.org>
7 * Provided that these terms and disclaimer and all copyright notices
8 * are retained or reproduced in an accompanying document, permission
9 * is granted to deal in this work without restriction, including un‐
10 * limited rights to use, publicly perform, distribute, sell, modify,
11 * merge, give away, or sublicence.
13 * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
14 * the utmost extent permitted by applicable law, neither express nor
15 * implied; without malicious intent or gross negligence. In no event
16 * may a licensor, author or contributor be held liable for indirect,
17 * direct, other damage, loss, or other issues arising in any way out
18 * of dealing in the work, even if advised of the possibility of such
19 * damage or existence of a defect, except proven that it results out
20 * of said person’s immediate fault when using the work as intended.
22 * Compatibility functions for jupp.
24 * – ctime: based on mirtime from MirBSD libc; not leap second capable
25 * src/kern/include/mirtime.h,v 1.2 2011/11/20 23:40:11 tg Exp
26 * src/kern/c/mirtime.c,v 1.3 2011/11/20 23:40:10 tg Exp
27 * – strlcpy, strlcat: pulled in via "strlfun.inc"
28 * – popen, pclose: pulled in via "popen.inc"
35 #define __RCSID(x) /* nothing, in jupp */
45 #if defined(L_strlcat) || defined(L_strlcpy)
46 #define OUTSIDE_OF_LIBKERN
47 #include "strlfun.inc"
51 #ifdef TIME_WITH_SYS_TIME
52 # include <sys/time.h>
55 # ifdef HAVE_SYS_TIME_H
56 # include <sys/time.h>
66 int tm_sec; /* seconds [0-60] */
67 int tm_min; /* minutes [0-59] */
68 int tm_hour; /* hours [0-23] */
69 int tm_mday; /* day of month [1-31] */
70 int tm_mon; /* month of year - 1 [0-11] */
71 int tm_year; /* year - 1900 */
72 int tm_wday; /* day of week (0 = sunday) */
75 static void joe_timet2tm(joe_tm *, const time_t *);
78 char *ctime(const time_t *);
81 /* 302 / 1000 is log10(2.0) rounded up */
82 #define T_SIGNED(t) (((t)-1) < 0)
83 #define T_MAXLEN(t) ((sizeof(t) * CHAR_BIT - T_SIGNED(t)) * 302 / 1000 + \
84 /* div.trunc. */ 1 + /* minus sign */ T_SIGNED(t))
86 static const char joe_days[7][4] = {
87 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
90 static const char joe_months[12][4] = {
91 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
92 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
96 * Dimensions for the buffer, example formats:
97 * "Sun Jan 1 12:34:56 1234\n"
98 * "Sat Dec 31 12:34:56 12345\n"
99 * <- 24 -----------------> + max.length of a year + NL + NUL
101 static char joe_ctime_buf[24 + T_MAXLEN(time_t) + 2];
104 ctime(const time_t *tp)
109 joe_timet2tm(&tm, tp);
110 year = (int)(tm.tm_year + 1900);
111 joe_snprintf_7(joe_ctime_buf, sizeof(joe_ctime_buf),
112 (year >= -999 && year <= 9999) ?
113 "%s %s %2d %02d:%02d:%02d %04d\n" :
114 "%s %s %2d %02d:%02d:%02d %d\n",
115 joe_days[tm.tm_wday], joe_months[tm.tm_mon],
116 tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, year);
117 return (joe_ctime_buf);
121 joe_timet2tm(joe_tm *tm, const time_t *tp)
128 sec = (int)(y % 86400);
136 /* calculate 400-year cycle (y) and offset in it (day) */
137 day = (int)(y % 146097);
140 /* add bias: 678881 = days between "convenient origin" and MJD 0 */
141 /* convenient origin is Wed(3) 1 March 0(fictional)/-1(real) */
143 /* recalculate offset in cycle (Gregorian Period) */
147 /* days in 400 years are cyclic, they have 20871 weeks */
148 tm->tm_wday = (day + 3) % 7;
150 /* calculate year from period, taking leap years into account */
152 /* a long (Julian) century is at the end of each Gregorian Period */
165 /* March to December, or January/February? */
166 /* a leap year is at the end of each olympiad */
175 /* count days and months from 1st March using fixed-point */
177 mon = (day + 5) / 306;
178 day = (day + 5) % 306;
180 /* adjust for Jan/Feb offset */
188 /* adjust for year 0(fictional) which did not exist */
192 /* fill in the values still missing */
193 tm->tm_sec = sec % 60;
195 tm->tm_min = sec % 60;
196 tm->tm_hour = sec / 60;
197 tm->tm_mday = day + 1;
199 /*XXX truncate, for joe_snprintf doesn't know %lld portably */
200 tm->tm_year = (int)(y - 1900);
202 #endif /* ndef HAVE_CTIME */