xref: /titanic_51/usr/src/cmd/acct/lib/pnpsplit.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.7	*/
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * pnpsplit splits interval into prime & nonprime portions
35*7c478bd9Sstevel@tonic-gate  * ONLY ROUTINE THAT KNOWS ABOUT HOLIDAYS AND DEFN OF PRIME/NONPRIME
36*7c478bd9Sstevel@tonic-gate  */
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #include <stdio.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
41*7c478bd9Sstevel@tonic-gate #include "acctdef.h"
42*7c478bd9Sstevel@tonic-gate #include <time.h>
43*7c478bd9Sstevel@tonic-gate #include <ctype.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate /* validate that hours and minutes of prime/non-prime read in
46*7c478bd9Sstevel@tonic-gate  * from holidays file fall within proper boundaries.
47*7c478bd9Sstevel@tonic-gate  * Time is expected in the form and range of 0000-2359.
48*7c478bd9Sstevel@tonic-gate  */
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate static int	thisyear = 1970;	/* this is changed by holidays file */
51*7c478bd9Sstevel@tonic-gate static int	holidays[NHOLIDAYS];	/* holidays file day-of-year table */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate static int day_tab[2][13] = {
54*7c478bd9Sstevel@tonic-gate 	{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
55*7c478bd9Sstevel@tonic-gate 	{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
56*7c478bd9Sstevel@tonic-gate };
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate  *	prime(0) and nonprime(1) times during a day
60*7c478bd9Sstevel@tonic-gate  *	for BTL, prime time is 9AM to 5PM
61*7c478bd9Sstevel@tonic-gate  */
62*7c478bd9Sstevel@tonic-gate static struct hours {
63*7c478bd9Sstevel@tonic-gate 	int	h_sec;		/* normally always zero */
64*7c478bd9Sstevel@tonic-gate 	int	h_min;		/* initialized from holidays file (time%100) */
65*7c478bd9Sstevel@tonic-gate 	int	h_hour;		/* initialized from holidays file (time/100) */
66*7c478bd9Sstevel@tonic-gate 	long	h_type;		/* prime/nonprime of previous period */
67*7c478bd9Sstevel@tonic-gate } h[4];
68*7c478bd9Sstevel@tonic-gate int	daysend[] = {60, 59, 23};	/* the sec, min, hr of the day's end */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate struct tm *localtime();
71*7c478bd9Sstevel@tonic-gate long	tmsecs();
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /*
74*7c478bd9Sstevel@tonic-gate  * split interval of length etime, starting at start into prime/nonprime
75*7c478bd9Sstevel@tonic-gate  * values, return as result
76*7c478bd9Sstevel@tonic-gate  * input values in seconds
77*7c478bd9Sstevel@tonic-gate  */
78*7c478bd9Sstevel@tonic-gate pnpsplit(start, etime, result)
79*7c478bd9Sstevel@tonic-gate long start, result[2];
80*7c478bd9Sstevel@tonic-gate ulong_t etime;
81*7c478bd9Sstevel@tonic-gate {
82*7c478bd9Sstevel@tonic-gate 	struct tm cur, end;
83*7c478bd9Sstevel@tonic-gate 	time_t tcur, tend;
84*7c478bd9Sstevel@tonic-gate 	long tmp;
85*7c478bd9Sstevel@tonic-gate 	register sameday;
86*7c478bd9Sstevel@tonic-gate 	register struct hours *hp;
87*7c478bd9Sstevel@tonic-gate 	char *memcpy();
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	/* once holidays file is read, this is zero */
90*7c478bd9Sstevel@tonic-gate 	if (thisyear && (checkhol() == 0)) {
91*7c478bd9Sstevel@tonic-gate 		return(0);
92*7c478bd9Sstevel@tonic-gate 	}
93*7c478bd9Sstevel@tonic-gate 	tcur = start;
94*7c478bd9Sstevel@tonic-gate 	tend = start+etime;
95*7c478bd9Sstevel@tonic-gate 	memcpy(&end, localtime(&tend), sizeof(end));
96*7c478bd9Sstevel@tonic-gate 	result[PRIME] = 0;
97*7c478bd9Sstevel@tonic-gate 	result[NONPRIME] = 0;
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	while (tcur < tend) {	/* one iteration per day or part thereof */
100*7c478bd9Sstevel@tonic-gate 		memcpy(&cur, localtime(&tcur), sizeof(cur));
101*7c478bd9Sstevel@tonic-gate 		sameday = cur.tm_yday == end.tm_yday;
102*7c478bd9Sstevel@tonic-gate 		if (ssh(&cur)) {	/* ssh:only NONPRIME */
103*7c478bd9Sstevel@tonic-gate 			if (sameday) {
104*7c478bd9Sstevel@tonic-gate 				result[NONPRIME] += tend-tcur;
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate 				break;
107*7c478bd9Sstevel@tonic-gate 			} else {
108*7c478bd9Sstevel@tonic-gate 				tmp = tmsecs(&cur, daysend);
109*7c478bd9Sstevel@tonic-gate 				result[NONPRIME] += tmp;
110*7c478bd9Sstevel@tonic-gate 				tcur += tmp;
111*7c478bd9Sstevel@tonic-gate 			}
112*7c478bd9Sstevel@tonic-gate 		} else {	/* working day, PRIME or NONPRIME */
113*7c478bd9Sstevel@tonic-gate 			for (hp = h; tmless(hp, &cur); hp++);
114*7c478bd9Sstevel@tonic-gate 			for (; hp->h_sec >= 0; hp++) {
115*7c478bd9Sstevel@tonic-gate 				if (sameday && tmless(&end, hp)) {
116*7c478bd9Sstevel@tonic-gate 			/* WHCC mod, change from = to +=   3/6/86   Paul */
117*7c478bd9Sstevel@tonic-gate 					result[hp->h_type] += tend-tcur;
118*7c478bd9Sstevel@tonic-gate 					tcur = tend;
119*7c478bd9Sstevel@tonic-gate 					break;	/* all done */
120*7c478bd9Sstevel@tonic-gate 				} else {	/* time to next PRIME /NONPRIME change */
121*7c478bd9Sstevel@tonic-gate 					tmp = tmsecs(&cur, hp);
122*7c478bd9Sstevel@tonic-gate 					result[hp->h_type] += tmp;
123*7c478bd9Sstevel@tonic-gate 					tcur += tmp;
124*7c478bd9Sstevel@tonic-gate 					cur.tm_sec = hp->h_sec;
125*7c478bd9Sstevel@tonic-gate 					cur.tm_min = hp->h_min;
126*7c478bd9Sstevel@tonic-gate 					cur.tm_hour = hp->h_hour;
127*7c478bd9Sstevel@tonic-gate 				}
128*7c478bd9Sstevel@tonic-gate 			}
129*7c478bd9Sstevel@tonic-gate 		}
130*7c478bd9Sstevel@tonic-gate 	}
131*7c478bd9Sstevel@tonic-gate 	return(1);
132*7c478bd9Sstevel@tonic-gate }
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate /*
135*7c478bd9Sstevel@tonic-gate  *	Starting day after Christmas, complain if holidays not yet updated.
136*7c478bd9Sstevel@tonic-gate  *	This code is only executed once per program invocation.
137*7c478bd9Sstevel@tonic-gate  */
138*7c478bd9Sstevel@tonic-gate checkhol()
139*7c478bd9Sstevel@tonic-gate {
140*7c478bd9Sstevel@tonic-gate 	register struct tm *tp;
141*7c478bd9Sstevel@tonic-gate 	time_t t;
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	if(inithol() == 0) {
144*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "pnpsplit: holidays table setup failed\n");
145*7c478bd9Sstevel@tonic-gate 		thisyear = 0;
146*7c478bd9Sstevel@tonic-gate 		holidays[0] = -1;
147*7c478bd9Sstevel@tonic-gate 		return(0);
148*7c478bd9Sstevel@tonic-gate 	}
149*7c478bd9Sstevel@tonic-gate 	time(&t);
150*7c478bd9Sstevel@tonic-gate 	tp = localtime(&t);
151*7c478bd9Sstevel@tonic-gate 	tp->tm_year += 1900;
152*7c478bd9Sstevel@tonic-gate 	if ((tp->tm_year == thisyear && tp->tm_yday > 359)
153*7c478bd9Sstevel@tonic-gate 		|| tp->tm_year > thisyear)
154*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
155*7c478bd9Sstevel@tonic-gate 			"***UPDATE %s WITH NEW HOLIDAYS***\n", HOLFILE);
156*7c478bd9Sstevel@tonic-gate 	thisyear = 0;	/* checkhol() will not be called again */
157*7c478bd9Sstevel@tonic-gate 	return(1);
158*7c478bd9Sstevel@tonic-gate }
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate /*
161*7c478bd9Sstevel@tonic-gate  * ssh returns 1 if Sat, Sun, or Holiday
162*7c478bd9Sstevel@tonic-gate  */
163*7c478bd9Sstevel@tonic-gate ssh(ltp)
164*7c478bd9Sstevel@tonic-gate register struct tm *ltp;
165*7c478bd9Sstevel@tonic-gate {
166*7c478bd9Sstevel@tonic-gate 	register i;
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	if (ltp->tm_wday == 0 || ltp->tm_wday == 6)
169*7c478bd9Sstevel@tonic-gate 		return(1);
170*7c478bd9Sstevel@tonic-gate 	for (i = 0; holidays[i] >= 0; i++)
171*7c478bd9Sstevel@tonic-gate 		if (ltp->tm_yday == holidays[i])
172*7c478bd9Sstevel@tonic-gate 			return(1);
173*7c478bd9Sstevel@tonic-gate 	return(0);
174*7c478bd9Sstevel@tonic-gate }
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate /*
177*7c478bd9Sstevel@tonic-gate  * inithol - read from an ascii file and initialize the "thisyear"
178*7c478bd9Sstevel@tonic-gate  * variable, the times that prime and non-prime start, and the
179*7c478bd9Sstevel@tonic-gate  * holidays array.
180*7c478bd9Sstevel@tonic-gate  */
181*7c478bd9Sstevel@tonic-gate inithol()
182*7c478bd9Sstevel@tonic-gate {
183*7c478bd9Sstevel@tonic-gate 	FILE		*fopen(), *holptr;
184*7c478bd9Sstevel@tonic-gate 	char		*fgets(), holbuf[128];
185*7c478bd9Sstevel@tonic-gate 	register int	line = 0,
186*7c478bd9Sstevel@tonic-gate 			holindx = 0,
187*7c478bd9Sstevel@tonic-gate 			errflag = 0;
188*7c478bd9Sstevel@tonic-gate 	int		pstart, npstart;
189*7c478bd9Sstevel@tonic-gate 	int		doy;	/* day of the year */
190*7c478bd9Sstevel@tonic-gate 	int 		month, day;
191*7c478bd9Sstevel@tonic-gate 	char		*c;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 	if((holptr=fopen(HOLFILE, "r")) == NULL) {
194*7c478bd9Sstevel@tonic-gate 		perror(HOLFILE);
195*7c478bd9Sstevel@tonic-gate 		fclose(holptr);
196*7c478bd9Sstevel@tonic-gate 		return(0);
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 	while(fgets(holbuf, sizeof(holbuf), holptr) != NULL) {
199*7c478bd9Sstevel@tonic-gate 		/* skip over blank lines and comments */
200*7c478bd9Sstevel@tonic-gate 		if (holbuf[0] == '*')
201*7c478bd9Sstevel@tonic-gate 			continue;
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 		for (c = holbuf; isspace(*c); c++)
204*7c478bd9Sstevel@tonic-gate 			/* is a space */;
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 		if (*c == '\0')
207*7c478bd9Sstevel@tonic-gate 			continue;
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 		else if(++line == 1) {	/* format: year p-start np-start */
210*7c478bd9Sstevel@tonic-gate 			if(sscanf(holbuf, "%4d %4d %4d",
211*7c478bd9Sstevel@tonic-gate 				&thisyear, &pstart, &npstart) != 3) {
212*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
213*7c478bd9Sstevel@tonic-gate 					"%s: bad {yr ptime nptime} conversion\n",
214*7c478bd9Sstevel@tonic-gate 					HOLFILE);
215*7c478bd9Sstevel@tonic-gate 				errflag++;
216*7c478bd9Sstevel@tonic-gate 				break;
217*7c478bd9Sstevel@tonic-gate 			}
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 			/* validate year */
220*7c478bd9Sstevel@tonic-gate 			if(thisyear < 1970 || thisyear > 2037) {
221*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "pnpsplit: invalid year: %d\n",
222*7c478bd9Sstevel@tonic-gate 					thisyear);
223*7c478bd9Sstevel@tonic-gate 				errflag++;
224*7c478bd9Sstevel@tonic-gate 				break;
225*7c478bd9Sstevel@tonic-gate 			}
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 			/* validate prime/nonprime hours */
228*7c478bd9Sstevel@tonic-gate 			if((! okay(pstart)) || (! okay(npstart))) {
229*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
230*7c478bd9Sstevel@tonic-gate 					"pnpsplit: invalid p/np hours\n");
231*7c478bd9Sstevel@tonic-gate 				errflag++;
232*7c478bd9Sstevel@tonic-gate 				break;
233*7c478bd9Sstevel@tonic-gate 			}
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 			/* Set up start of prime time; 2400 == 0000 */
236*7c478bd9Sstevel@tonic-gate 			h[0].h_sec = 0;
237*7c478bd9Sstevel@tonic-gate 			h[0].h_min = pstart%100;
238*7c478bd9Sstevel@tonic-gate 			h[0].h_hour = (pstart/100==24) ? 0 : pstart/100;
239*7c478bd9Sstevel@tonic-gate 			h[0].h_type = NONPRIME;
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 			/* Set up start of non-prime time; 2400 == 0000 */
242*7c478bd9Sstevel@tonic-gate 			h[1].h_sec = 0;
243*7c478bd9Sstevel@tonic-gate 			h[1].h_min = npstart%100;
244*7c478bd9Sstevel@tonic-gate 			h[1].h_hour = (npstart/100==24) ? 0 : npstart/100;
245*7c478bd9Sstevel@tonic-gate 			h[1].h_type = PRIME ;
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate 			/* This is the end of the day */
248*7c478bd9Sstevel@tonic-gate 			h[2].h_sec = 60;
249*7c478bd9Sstevel@tonic-gate 			h[2].h_min = 59;
250*7c478bd9Sstevel@tonic-gate 			h[2].h_hour = 23;
251*7c478bd9Sstevel@tonic-gate 			h[2].h_type = NONPRIME;
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 			/* The end of the array */
254*7c478bd9Sstevel@tonic-gate 			h[3].h_sec = -1;
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 			continue;
257*7c478bd9Sstevel@tonic-gate 		}
258*7c478bd9Sstevel@tonic-gate 		else if(holindx >= NHOLIDAYS) {
259*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "pnpsplit: too many holidays, ");
260*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "recompile with larger NHOLIDAYS\n");
261*7c478bd9Sstevel@tonic-gate 			errflag++;
262*7c478bd9Sstevel@tonic-gate 			break;
263*7c478bd9Sstevel@tonic-gate 		}
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 		/* Fill up holidays array from holidays file */
266*7c478bd9Sstevel@tonic-gate 		sscanf(holbuf, "%d/%d	%*s %*s	%*[^\n]\n", &month, &day);
267*7c478bd9Sstevel@tonic-gate 		if (month < 0 || month > 12) {
268*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "pnpsplit: invalid month %d\n", month);
269*7c478bd9Sstevel@tonic-gate 			errflag++;
270*7c478bd9Sstevel@tonic-gate 			break;
271*7c478bd9Sstevel@tonic-gate 		}
272*7c478bd9Sstevel@tonic-gate 		if (day < 0 || day > 31) {
273*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "pnpsplit: invalid day %d\n", day);
274*7c478bd9Sstevel@tonic-gate 			errflag++;
275*7c478bd9Sstevel@tonic-gate 			break;
276*7c478bd9Sstevel@tonic-gate 		}
277*7c478bd9Sstevel@tonic-gate 		doy = day_of_year(thisyear, month, day);
278*7c478bd9Sstevel@tonic-gate 		holidays[holindx++] = (doy - 1);
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate 	fclose(holptr);
281*7c478bd9Sstevel@tonic-gate 	if(!errflag && holindx < NHOLIDAYS) {
282*7c478bd9Sstevel@tonic-gate 		holidays[holindx] = -1;
283*7c478bd9Sstevel@tonic-gate 		return(1);
284*7c478bd9Sstevel@tonic-gate 	}
285*7c478bd9Sstevel@tonic-gate 	else
286*7c478bd9Sstevel@tonic-gate 		return(0);
287*7c478bd9Sstevel@tonic-gate }
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate /*
290*7c478bd9Sstevel@tonic-gate  *	tmsecs returns number of seconds from t1 to t2,
291*7c478bd9Sstevel@tonic-gate  *	times expressed in localtime format.
292*7c478bd9Sstevel@tonic-gate  *	assumed that t1 <= t2, and are in same day.
293*7c478bd9Sstevel@tonic-gate  */
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate long
296*7c478bd9Sstevel@tonic-gate tmsecs(t1, t2)
297*7c478bd9Sstevel@tonic-gate register struct tm *t1, *t2;
298*7c478bd9Sstevel@tonic-gate {
299*7c478bd9Sstevel@tonic-gate 	return((t2->tm_sec - t1->tm_sec) +
300*7c478bd9Sstevel@tonic-gate 		60*(t2->tm_min - t1->tm_min) +
301*7c478bd9Sstevel@tonic-gate 		3600L*(t2->tm_hour - t1->tm_hour));
302*7c478bd9Sstevel@tonic-gate }
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate /*
305*7c478bd9Sstevel@tonic-gate  *	return 1 if t1 earlier than t2 (times in localtime format)
306*7c478bd9Sstevel@tonic-gate  *	assumed that t1 and t2 are in same day
307*7c478bd9Sstevel@tonic-gate  */
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate tmless(t1, t2)
310*7c478bd9Sstevel@tonic-gate register struct tm *t1, *t2;
311*7c478bd9Sstevel@tonic-gate {
312*7c478bd9Sstevel@tonic-gate 	if (t1->tm_hour != t2->tm_hour)
313*7c478bd9Sstevel@tonic-gate 		return(t1->tm_hour < t2->tm_hour);
314*7c478bd9Sstevel@tonic-gate 	if (t1->tm_min != t2->tm_min)
315*7c478bd9Sstevel@tonic-gate 		return(t1->tm_min < t2->tm_min);
316*7c478bd9Sstevel@tonic-gate 	return(t1->tm_sec < t2->tm_sec);
317*7c478bd9Sstevel@tonic-gate }
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate /* set day of year from month and day */
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate day_of_year(year, month, day)
322*7c478bd9Sstevel@tonic-gate {
323*7c478bd9Sstevel@tonic-gate 	int i, leap;
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	leap = year%4 == 0 && year%100 || year%400 == 0;
326*7c478bd9Sstevel@tonic-gate 	for (i = 1; i < month; i++)
327*7c478bd9Sstevel@tonic-gate 		day += day_tab[leap][i];
328*7c478bd9Sstevel@tonic-gate 	return(day);
329*7c478bd9Sstevel@tonic-gate }
330