4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
31 * pnpsplit splits interval into prime & nonprime portions
32 * ONLY ROUTINE THAT KNOWS ABOUT HOLIDAYS AND DEFN OF PRIME/NONPRIME
36 #include <sys/types.h>
37 #include <sys/param.h>
43 * validate that hours and minutes of prime/non-prime read in
44 * from holidays file fall within proper boundaries.
45 * Time is expected in the form and range of 0000-2400.
48 static int thisyear
= 1970; /* this is changed by holidays file */
49 static int holidays
[NHOLIDAYS
]; /* holidays file day-of-year table */
52 static int day_tab
[2][13] = {
53 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
54 {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
58 * prime(0) and nonprime(1) times during a day
59 * for BTL, prime time is 9AM to 5PM
62 int h_sec
; /* normally always zero */
63 int h_min
; /* initialized from holidays file (time%100) */
64 int h_hour
; /* initialized from holidays file (time/100) */
65 long h_type
; /* prime/nonprime of previous period */
67 int daysend
[] = {0, 60, 23}; /* the sec, min, hr of the day's end */
69 struct tm
*localtime();
73 * split interval of length etime, starting at start into prime/nonprime
74 * values, return as result
75 * input values in seconds
78 pnpsplit(start
, etime
, result
)
79 long start
, result
[2];
86 register struct hours
*hp
;
89 /* once holidays file is read, this is zero */
90 if(thisyear
&& (checkhol() == 0)) {
95 memcpy(&end
, localtime(&tend
), sizeof(end
));
99 while ( tcur
< tend
) { /* one iteration per day or part thereof */
100 memcpy(&cur
, localtime(&tcur
), sizeof(cur
));
101 sameday
= cur
.tm_yday
== end
.tm_yday
;
102 if (ssh(&cur
)) { /* ssh:only NONPRIME */
104 result
[NONPRIME
] += tend
-tcur
;
108 tmp
= tmsecs(&cur
, daysend
);
109 result
[NONPRIME
] += tmp
;
112 } else { /* working day, PRIME or NONPRIME */
113 for (hp
= h
; tmless(hp
, &cur
); hp
++);
114 for (; hp
->h_sec
>= 0; hp
++) {
115 if (sameday
&& tmless(&end
, hp
)) {
116 /* WHCC mod, change from = to += 3/6/86 Paul */
117 result
[hp
->h_type
] += tend
-tcur
;
119 break; /* all done */
120 } else { /* time to next PRIME /NONPRIME change */
121 tmp
= tmsecs(&cur
, hp
);
122 result
[hp
->h_type
] += tmp
;
124 cur
.tm_sec
= hp
->h_sec
;
125 cur
.tm_min
= hp
->h_min
;
126 cur
.tm_hour
= hp
->h_hour
;
135 * Starting day after Christmas, complain if holidays not yet updated.
136 * This code is only executed once per program invocation.
141 register struct tm
*tp
;
145 fprintf(stderr
, "pnpsplit: holidays table setup failed\n");
153 if ((tp
->tm_year
== thisyear
&& tp
->tm_yday
> 359)
154 || tp
->tm_year
> thisyear
)
156 "***UPDATE %s WITH NEW HOLIDAYS***\n", HOLFILE
);
157 thisyear
= 0; /* checkhol() will not be called again */
162 * ssh returns 1 if Sat, Sun, or Holiday
166 register struct tm
*ltp
;
170 if (ltp
->tm_wday
== 0 || ltp
->tm_wday
== 6)
172 for (i
= 0; holidays
[i
] >= 0; i
++)
173 if (ltp
->tm_yday
== holidays
[i
])
179 * inithol - read from an ascii file and initialize the "thisyear"
180 * variable, the times that prime and non-prime start, and the
186 FILE *fopen(), *holptr
;
187 char *fgets(), holbuf
[128];
188 register int line
= 0,
192 int doy
; /* day of the year */
196 if((holptr
=fopen(HOLFILE
, "r")) == NULL
) {
201 while(fgets(holbuf
, sizeof(holbuf
), holptr
) != NULL
) {
202 /* skip over blank lines and comments */
203 if (holbuf
[0] == '*')
206 for (c
= holbuf
; isspace(*c
); c
++)
212 else if(++line
== 1) { /* format: year p-start np-start */
213 if(sscanf(holbuf
, "%4d %4d %4d",
214 &thisyear
, &pstart
, &npstart
) != 3) {
216 "%s: bad {yr ptime nptime} conversion\n",
223 if(thisyear
< 1970 || thisyear
> 2037) {
224 fprintf(stderr
, "pnpsplit: invalid year: %d\n",
230 /* validate prime/nonprime hours */
231 if((! okay(pstart
)) || (! okay(npstart
))) {
233 "pnpsplit: invalid p/np hours\n");
238 /* Set up start of prime time; 2400 == 0000 */
240 h
[0].h_min
= pstart
%100;
241 h
[0].h_hour
= (pstart
/100==24) ? 0 : pstart
/100;
242 h
[0].h_type
= NONPRIME
;
244 /* Set up start of non-prime time; 2400 == 2360 */
245 if ((npstart
/100) == 24) {
251 h
[1].h_min
= npstart
% 100;
252 h
[1].h_hour
= npstart
/ 100;
257 /* This is the end of the day */
261 h
[2].h_type
= NONPRIME
;
263 /* The end of the array */
268 else if(holindx
>= NHOLIDAYS
) {
269 fprintf(stderr
, "pnpsplit: too many holidays, ");
270 fprintf(stderr
, "recompile with larger NHOLIDAYS\n");
275 /* Fill up holidays array from holidays file */
276 sscanf(holbuf
, "%d/%d %*s %*s %*[^\n]\n", &month
, &day
);
277 if (month
< 0 || month
> 12) {
278 fprintf(stderr
, "pnpsplit: invalid month %d\n", month
);
282 if (day
< 0 || day
> 31) {
283 fprintf(stderr
, "pnpsplit: invalid day %d\n", day
);
287 doy
= day_of_year(thisyear
, month
, day
);
288 holidays
[holindx
++] = (doy
- 1);
291 if(!errflag
&& holindx
< NHOLIDAYS
) {
292 holidays
[holindx
] = -1;
300 * tmsecs returns number of seconds from t1 to t2,
301 * times expressed in localtime format.
302 * assumed that t1 <= t2, and are in same day.
307 register struct tm
*t1
, *t2
;
309 return((t2
->tm_sec
- t1
->tm_sec
) +
310 60*(t2
->tm_min
- t1
->tm_min
) +
311 3600L*(t2
->tm_hour
- t1
->tm_hour
));
315 * return 1 if t1 earlier than t2 (times in localtime format)
316 * assumed that t1 and t2 are in same day
321 register struct tm
*t1
, *t2
;
323 if (t1
->tm_hour
!= t2
->tm_hour
)
324 return(t1
->tm_hour
< t2
->tm_hour
);
325 if (t1
->tm_min
!= t2
->tm_min
)
326 return(t1
->tm_min
< t2
->tm_min
);
327 return(t1
->tm_sec
< t2
->tm_sec
);
330 /* set day of year from month and day */
333 day_of_year(year
, month
, day
)
337 leap
= year
%4 == 0 && year
%100 || year
%400 == 0;
338 for (i
= 1; i
< month
; i
++)
339 day
+= day_tab
[leap
][i
];