Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * This routine converts time as follows.
3
 * The epoch is 0000 Jan 1 1970 GMT.
4
 * The argument time is in seconds since then.
5
 * The localtime(t) entry returns a pointer to an array
6
 * containing
7
 *
8
 *	seconds (0-59)
9
 *	minutes (0-59)
10
 *	hours (0-23)
11
 *	day of month (1-31)
12
 *	month (0-11)
13
 *	year-1970
14
 *	weekday (0-6, Sun is 0)
15
 *	day of the year
16
 *	daylight savings flag
17
 *
18
 * The routine gets the daylight savings time from the environment.
19
 *
20
 * asctime(tvec))
21
 * where tvec is produced by localtime
22
 * returns a ptr to a character string
23
 * that has the ascii time in the form
24
 *
25
 *	                            \\
26
 *	Thu Jan 01 00:00:00 1970n0
27
 *	01234567890123456789012345
28
 *	0	  1	    2
29
 *
30
 * ctime(t) just calls localtime, then asctime.
31
 */
32
 
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <fcntl.h>
36
#include <time.h>
37
#include <unistd.h>
38
#include <string.h>
39
 
40
static	char	dmsize[12] =
41
{
42
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
43
};
44
 
45
/*
46
 * The following table is used for 1974 and 1975 and
47
 * gives the day number of the first day after the Sunday of the
48
 * change.
49
 */
50
 
51
static	int	dysize(int);
52
static	void	ct_numb(char*, int);
53
static	void	readtimezone(void);
54
static	int	rd_name(char**, char*);
55
static	int	rd_long(char**, long*);
56
 
57
#define	TZSIZE	150
58
 
59
static
60
struct
61
{
62
	char	stname[4];
63
	char	dlname[4];
64
	long	stdiff;
65
	long	dldiff;
66
	long	dlpairs[TZSIZE];
67
} timezone;
68
 
69
char*
70
ctime(const time_t *t)
71
{
72
	return asctime(localtime(t));
73
}
74
 
75
struct tm*
76
gmtime_r(const time_t *timp, struct tm *result)
77
{
78
	int d0, d1;
79
	long hms, day;
80
	time_t tim;
81
 
82
	tim = *timp;
83
	/*
84
	 * break initial number into days
85
	 */
86
	hms = tim % 86400L;
87
	day = tim / 86400L;
88
	if(hms < 0) {
89
		hms += 86400L;
90
		day -= 1;
91
	}
92
 
93
	/*
94
	 * generate hours:minutes:seconds
95
	 */
96
	result->tm_sec = hms % 60;
97
	d1 = hms / 60;
98
	result->tm_min = d1 % 60;
99
	d1 /= 60;
100
	result->tm_hour = d1;
101
 
102
	/*
103
	 * day is the day number.
104
	 * generate day of the week.
105
	 * The addend is 4 mod 7 (1/1/1970 was Thursday)
106
	 */
107
 
108
	result->tm_wday = (day + 7340036L) % 7;
109
 
110
	/*
111
	 * year number
112
	 */
113
	if(day >= 0)
114
		for(d1 = 70; day >= dysize(d1); d1++)
115
			day -= dysize(d1);
116
	else
117
		for (d1 = 70; day < 0; d1--)
118
			day += dysize(d1-1);
119
	result->tm_year = d1;
120
	result->tm_yday = d0 = day;
121
 
122
	/*
123
	 * generate month
124
	 */
125
 
126
	if(dysize(d1) == 366)
127
		dmsize[1] = 29;
128
	for(d1 = 0; d0 >= dmsize[d1]; d1++)
129
		d0 -= dmsize[d1];
130
	dmsize[1] = 28;
131
	result->tm_mday = d0 + 1;
132
	result->tm_mon = d1;
133
	result->tm_isdst = 0;
134
	return result;
135
}
136
 
137
struct tm*
138
gmtime(const time_t *timp)
139
{
140
	static struct tm xtime;
141
 
142
	return gmtime_r(timp, &xtime);
143
}
144
 
145
struct tm*
146
localtime_r(const time_t *timp, struct tm *result)
147
{
148
	struct tm *ct;
149
	time_t t, tim;
150
	long *p;
151
	int dlflag;
152
 
153
	tim = *timp;
154
	if(timezone.stname[0] == 0)
155
		readtimezone();
156
	t = tim + timezone.stdiff;
157
	dlflag = 0;
158
	for(p = timezone.dlpairs; *p; p += 2)
159
		if(t >= p[0])
160
		if(t < p[1]) {
161
			t = tim + timezone.dldiff;
162
			dlflag++;
163
			break;
164
		}
165
	ct = gmtime_r(&t, result);
166
	ct->tm_isdst = dlflag;
167
	return ct;
168
}
169
 
170
struct tm*
171
localtime(const time_t *timp)
172
{
173
	static struct tm xtime;
174
 
175
	return localtime_r(timp, &xtime);
176
}
177
 
178
char*
179
asctime_r(const struct tm *t, char *buf)
180
{
181
	char *ncp;
182
 
183
	strcpy(buf, "Thu Jan 01 00:00:00 1970\n");
184
	ncp = &"SunMonTueWedThuFriSat"[t->tm_wday*3];
185
	buf[0] = *ncp++;
186
	buf[1] = *ncp++;
187
	buf[2] = *ncp;
188
	ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->tm_mon*3];
189
	buf[4] = *ncp++;
190
	buf[5] = *ncp++;
191
	buf[6] = *ncp;
192
	ct_numb(buf+8, t->tm_mday);
193
	ct_numb(buf+11, t->tm_hour+100);
194
	ct_numb(buf+14, t->tm_min+100);
195
	ct_numb(buf+17, t->tm_sec+100);
196
	if(t->tm_year >= 100) {
197
		buf[20] = '2';
198
		buf[21] = '0';
199
	}
200
	ct_numb(buf+22, t->tm_year+100);
201
	return buf;
202
}
203
 
204
char*
205
asctime(const struct tm *t)
206
{
207
	static char cbuf[30];
208
 
209
	return asctime_r(t, cbuf);
210
}
211
 
212
static
213
dysize(int y)
214
{
215
	if((y%4) == 0)
216
		return 366;
217
	return 365;
218
}
219
 
220
static
221
void
222
ct_numb(char *cp, int n)
223
{
224
	cp[0] = ' ';
225
	if(n >= 10)
226
		cp[0] = (n/10)%10 + '0';
227
	cp[1] = n%10 + '0';
228
}
229
 
230
static
231
void
232
readtimezone(void)
233
{
234
	char buf[TZSIZE*11+30], *p;
235
	int i;
236
 
237
	memset(buf, 0, sizeof(buf));
238
	i = open("/env/timezone", 0);
239
	if(i < 0)
240
		goto error;
241
	if(read(i, buf, sizeof(buf)) >= sizeof(buf))
242
		goto error;
243
	close(i);
244
	p = buf;
245
	if(rd_name(&p, timezone.stname))
246
		goto error;
247
	if(rd_long(&p, &timezone.stdiff))
248
		goto error;
249
	if(rd_name(&p, timezone.dlname))
250
		goto error;
251
	if(rd_long(&p, &timezone.dldiff))
252
		goto error;
253
	for(i=0; i<TZSIZE; i++) {
254
		if(rd_long(&p, &timezone.dlpairs[i]))
255
			goto error;
256
		if(timezone.dlpairs[i] == 0)
257
			return;
258
	}
259
 
260
error:
261
	timezone.stdiff = 0;
262
	strcpy(timezone.stname, "GMT");
263
	timezone.dlpairs[0] = 0;
264
}
265
 
266
static
267
rd_name(char **f, char *p)
268
{
269
	int c, i;
270
 
271
	for(;;) {
272
		c = *(*f)++;
273
		if(c != ' ' && c != '\n')
274
			break;
275
	}
276
	for(i=0; i<3; i++) {
277
		if(c == ' ' || c == '\n')
278
			return 1;
279
		*p++ = c;
280
		c = *(*f)++;
281
	}
282
	if(c != ' ' && c != '\n')
283
		return 1;
284
	*p = 0;
285
	return 0;
286
}
287
 
288
static
289
rd_long(char **f, long *p)
290
{
291
	int c, s;
292
	long l;
293
 
294
	s = 0;
295
	for(;;) {
296
		c = *(*f)++;
297
		if(c == '-') {
298
			s++;
299
			continue;
300
		}
301
		if(c != ' ' && c != '\n')
302
			break;
303
	}
304
	if(c == 0) {
305
		*p = 0;
306
		return 0;
307
	}
308
	l = 0;
309
	for(;;) {
310
		if(c == ' ' || c == '\n')
311
			break;
312
		if(c < '0' || c > '9')
313
			return 1;
314
		l = l*10 + c-'0';
315
		c = *(*f)++;
316
	}
317
	if(s)
318
		l = -l;
319
	*p = l;
320
	return 0;
321
}