xref: /freebsd/contrib/ntp/util/lsf-times.c (revision f5f40dd63bc7acbb5312b26ac1ea1103c12352a6)
1*f5f40dd6SCy Schubert #include "config.h"
2*f5f40dd6SCy Schubert #include "ntp_calendar.h"
3*f5f40dd6SCy Schubert 
4*f5f40dd6SCy Schubert #include <stdlib.h>
5*f5f40dd6SCy Schubert #include <errno.h>
6*f5f40dd6SCy Schubert 
7*f5f40dd6SCy Schubert #include "ntp_types.h"
8*f5f40dd6SCy Schubert #include "ntp_fp.h"
9*f5f40dd6SCy Schubert #include "vint64ops.h"
10*f5f40dd6SCy Schubert 
11*f5f40dd6SCy Schubert /*
12*f5f40dd6SCy Schubert  * If we're called with 1 arg, it's a u_long timestamp.
13*f5f40dd6SCy Schubert  * If we're called with 3 args, we're expecting YYYY MM DD,
14*f5f40dd6SCy Schubert  *   and MM must be 6 or 12, and DD must be 28,
15*f5f40dd6SCy Schubert  * If we're called with 2 args, we're expecting YYYY MM, and
16*f5f40dd6SCy Schubert  *   MM mst be 6 or 12, and we assume DD is 28.
17*f5f40dd6SCy Schubert  */
18*f5f40dd6SCy Schubert 
19*f5f40dd6SCy Schubert char *progname;
20*f5f40dd6SCy Schubert static const char *MONTHS[] =
21*f5f40dd6SCy Schubert                 { "January", "February", "March", "April", "May", "June",
22*f5f40dd6SCy Schubert 		  "July", "August", "September", "October", "November",
23*f5f40dd6SCy Schubert 		  "December" };
24*f5f40dd6SCy Schubert 
25*f5f40dd6SCy Schubert void usage(void);
26*f5f40dd6SCy Schubert 
27*f5f40dd6SCy Schubert void
28*f5f40dd6SCy Schubert usage(void)
29*f5f40dd6SCy Schubert {
30*f5f40dd6SCy Schubert 	printf("Usage:\n");
31*f5f40dd6SCy Schubert 	printf(" %s nnnnnn\n", progname);
32*f5f40dd6SCy Schubert 	printf(" %s YYYY [6|12]\n", progname);
33*f5f40dd6SCy Schubert 	printf(" %s YYYY [6|12] 28\n", progname);
34*f5f40dd6SCy Schubert 
35*f5f40dd6SCy Schubert 	return;
36*f5f40dd6SCy Schubert }
37*f5f40dd6SCy Schubert 
38*f5f40dd6SCy Schubert 
39*f5f40dd6SCy Schubert int
40*f5f40dd6SCy Schubert main(
41*f5f40dd6SCy Schubert 	int	argc,		/* command line options */
42*f5f40dd6SCy Schubert 	char	**argv		/* poiniter to list of tokens */
43*f5f40dd6SCy Schubert 	)
44*f5f40dd6SCy Schubert {
45*f5f40dd6SCy Schubert 	int err = 0;
46*f5f40dd6SCy Schubert 	vint64 expires;
47*f5f40dd6SCy Schubert 	unsigned int year = 0;
48*f5f40dd6SCy Schubert 	unsigned int mon = 0;
49*f5f40dd6SCy Schubert 	unsigned int dom = 0;
50*f5f40dd6SCy Schubert 	int scount;
51*f5f40dd6SCy Schubert 	char *ep;
52*f5f40dd6SCy Schubert 	struct calendar cal = {0};
53*f5f40dd6SCy Schubert 
54*f5f40dd6SCy Schubert 	progname = argv[0];
55*f5f40dd6SCy Schubert 
56*f5f40dd6SCy Schubert 	switch(argc) {
57*f5f40dd6SCy Schubert 	 case 2:	/* 1 arg, must be a string of digits */
58*f5f40dd6SCy Schubert 		expires = strtouv64(argv[1], &ep, 10);
59*f5f40dd6SCy Schubert 
60*f5f40dd6SCy Schubert 		if (0 == *ep) {
61*f5f40dd6SCy Schubert 			ntpcal_ntp64_to_date(&cal, &expires);
62*f5f40dd6SCy Schubert 
63*f5f40dd6SCy Schubert 			printf("%02u %s %04u %02u:%02u:%02u\n"
64*f5f40dd6SCy Schubert 				, cal.monthday
65*f5f40dd6SCy Schubert 				, MONTHS[cal.month - 1]
66*f5f40dd6SCy Schubert 				, cal.year
67*f5f40dd6SCy Schubert 				, cal.hour
68*f5f40dd6SCy Schubert 				, cal.minute
69*f5f40dd6SCy Schubert 				, cal.second
70*f5f40dd6SCy Schubert 				);
71*f5f40dd6SCy Schubert 
72*f5f40dd6SCy Schubert 			exit(0);
73*f5f40dd6SCy Schubert 		} else {
74*f5f40dd6SCy Schubert 			printf("1 arg, but not a string of digits: <%s>\n",
75*f5f40dd6SCy Schubert 				argv[1]);
76*f5f40dd6SCy Schubert 			err = 1;
77*f5f40dd6SCy Schubert 		}
78*f5f40dd6SCy Schubert 		break;
79*f5f40dd6SCy Schubert 		;;
80*f5f40dd6SCy Schubert 	 case 3:	/* 2 args, must be YY MM, where MM is 6 or 12 */
81*f5f40dd6SCy Schubert 		dom = 28;
82*f5f40dd6SCy Schubert 		scount = sscanf(argv[1], "%u", &year);
83*f5f40dd6SCy Schubert 		if (1 == scount) {
84*f5f40dd6SCy Schubert 			// printf("2 args: year %u\n", year);
85*f5f40dd6SCy Schubert 		} else {
86*f5f40dd6SCy Schubert 			printf("2 args, but #1 is not a string of digits: <%s>\n", argv[1]);
87*f5f40dd6SCy Schubert 			err = 1;
88*f5f40dd6SCy Schubert 		}
89*f5f40dd6SCy Schubert 
90*f5f40dd6SCy Schubert 		scount = sscanf(argv[2], "%u", &mon);
91*f5f40dd6SCy Schubert 		if (1 == scount) {
92*f5f40dd6SCy Schubert 			if (6 == mon || 12 == mon) {
93*f5f40dd6SCy Schubert 				// printf("2 args: month %u\n", mon);
94*f5f40dd6SCy Schubert 			} else {
95*f5f40dd6SCy Schubert 				printf("2 arg, but #2 is not 6 or 12: <%d>\n", mon);
96*f5f40dd6SCy Schubert 				err = 1;
97*f5f40dd6SCy Schubert 			}
98*f5f40dd6SCy Schubert 		} else {
99*f5f40dd6SCy Schubert 			printf("2 arg, but #2 is not a string of digits: <%s>\n", argv[2]);
100*f5f40dd6SCy Schubert 			err = 1;
101*f5f40dd6SCy Schubert 		}
102*f5f40dd6SCy Schubert 
103*f5f40dd6SCy Schubert 		break;
104*f5f40dd6SCy Schubert 		;;
105*f5f40dd6SCy Schubert 	 case 4:	/* 3 args, YY MM DD, where MM is 6 or 12, DD is 28 */
106*f5f40dd6SCy Schubert 		scount = sscanf(argv[1], "%u", &year);
107*f5f40dd6SCy Schubert 		if (1 == scount) {
108*f5f40dd6SCy Schubert 			// printf("3 args: year %u\n", year);
109*f5f40dd6SCy Schubert 		} else {
110*f5f40dd6SCy Schubert 			printf("3 args, but #1 is not a string of digits: <%s>\n", argv[1]);
111*f5f40dd6SCy Schubert 			err = 1;
112*f5f40dd6SCy Schubert 		}
113*f5f40dd6SCy Schubert 
114*f5f40dd6SCy Schubert 		scount = sscanf(argv[2], "%u", &mon);
115*f5f40dd6SCy Schubert 		if (1 == scount) {
116*f5f40dd6SCy Schubert 			if (6 == mon || 12 == mon) {
117*f5f40dd6SCy Schubert 				// printf("3 args: month %u\n", mon);
118*f5f40dd6SCy Schubert 			} else {
119*f5f40dd6SCy Schubert 				printf("3 arg, but #2 is not 6 or 12: <%d>\n", mon);
120*f5f40dd6SCy Schubert 				err = 1;
121*f5f40dd6SCy Schubert 			}
122*f5f40dd6SCy Schubert 		} else {
123*f5f40dd6SCy Schubert 			printf("3 arg, but #2 is not a string of digits: <%s>\n", argv[2]);
124*f5f40dd6SCy Schubert 			err = 1;
125*f5f40dd6SCy Schubert 		}
126*f5f40dd6SCy Schubert 
127*f5f40dd6SCy Schubert 		scount = sscanf(argv[3], "%u", &dom);
128*f5f40dd6SCy Schubert 		if (1 == scount) {
129*f5f40dd6SCy Schubert 			if (28 == dom) {
130*f5f40dd6SCy Schubert 				// printf("3 args: dom %u\n", dom);
131*f5f40dd6SCy Schubert 			} else {
132*f5f40dd6SCy Schubert 				printf("3 arg, but #3 is not 28: <%d>\n", dom);
133*f5f40dd6SCy Schubert 				err = 1;
134*f5f40dd6SCy Schubert 			}
135*f5f40dd6SCy Schubert 		} else {
136*f5f40dd6SCy Schubert 			printf("3 arg, but #3 is not a string of digits: <%s>\n", argv[2]);
137*f5f40dd6SCy Schubert 			err = 1;
138*f5f40dd6SCy Schubert 		}
139*f5f40dd6SCy Schubert 
140*f5f40dd6SCy Schubert 		break;
141*f5f40dd6SCy Schubert 		;;
142*f5f40dd6SCy Schubert 	 default:
143*f5f40dd6SCy Schubert 		err = 1;
144*f5f40dd6SCy Schubert 		break;
145*f5f40dd6SCy Schubert 		;;
146*f5f40dd6SCy Schubert 	}
147*f5f40dd6SCy Schubert 
148*f5f40dd6SCy Schubert 	if (err) {
149*f5f40dd6SCy Schubert 		usage();
150*f5f40dd6SCy Schubert 		exit(err);
151*f5f40dd6SCy Schubert 	}
152*f5f40dd6SCy Schubert 
153*f5f40dd6SCy Schubert 	cal.year = year;
154*f5f40dd6SCy Schubert 	cal.month = mon;
155*f5f40dd6SCy Schubert 	cal.monthday = dom;
156*f5f40dd6SCy Schubert 	cal.hour = 0;
157*f5f40dd6SCy Schubert 	cal.minute = 0;
158*f5f40dd6SCy Schubert 	cal.second = 0;
159*f5f40dd6SCy Schubert 
160*f5f40dd6SCy Schubert 	printf("%u ", ntpcal_date_to_ntp(&cal));
161*f5f40dd6SCy Schubert 
162*f5f40dd6SCy Schubert 	printf("%02d %s %04d "
163*f5f40dd6SCy Schubert 		, cal.monthday
164*f5f40dd6SCy Schubert 		, MONTHS[cal.month - 1]
165*f5f40dd6SCy Schubert 		, cal.year
166*f5f40dd6SCy Schubert 		);
167*f5f40dd6SCy Schubert 	printf("\n");
168*f5f40dd6SCy Schubert 
169*f5f40dd6SCy Schubert 	exit(err);
170*f5f40dd6SCy Schubert }
171*f5f40dd6SCy Schubert 
172*f5f40dd6SCy Schubert #if 0
173*f5f40dd6SCy Schubert 
174*f5f40dd6SCy Schubert 
175*f5f40dd6SCy Schubert void
176*f5f40dd6SCy Schubert test_DateGivenMonthDay(void) {
177*f5f40dd6SCy Schubert 	// 2010-06-24 12:50:00
178*f5f40dd6SCy Schubert 	struct calendar input = {2010, 0, 6, 24, 12, 50, 0};
179*f5f40dd6SCy Schubert 
180*f5f40dd6SCy Schubert 	u_long expected = 3486372600UL; // This is the timestamp above.
181*f5f40dd6SCy Schubert 
182*f5f40dd6SCy Schubert 	TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
183*f5f40dd6SCy Schubert }
184*f5f40dd6SCy Schubert 
185*f5f40dd6SCy Schubert void
186*f5f40dd6SCy Schubert test_DateGivenYearDay(void) {
187*f5f40dd6SCy Schubert 	// 2010-06-24 12:50:00
188*f5f40dd6SCy Schubert 	// This is the 175th day of 2010.
189*f5f40dd6SCy Schubert 	struct calendar input = {2010, 175, 0, 0, 12, 50, 0};
190*f5f40dd6SCy Schubert 
191*f5f40dd6SCy Schubert 	u_long expected = 3486372600UL; // This is the timestamp above.
192*f5f40dd6SCy Schubert 
193*f5f40dd6SCy Schubert 	TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
194*f5f40dd6SCy Schubert }
195*f5f40dd6SCy Schubert 
196*f5f40dd6SCy Schubert void
197*f5f40dd6SCy Schubert test_DateLeapYear(void) {
198*f5f40dd6SCy Schubert 	// 2012-06-24 12:00:00
199*f5f40dd6SCy Schubert 	// This is the 176th day of 2012 (since 2012 is a leap year).
200*f5f40dd6SCy Schubert 	struct calendar inputYd = {2012, 176, 0, 0, 12, 00, 00};
201*f5f40dd6SCy Schubert 	struct calendar inputMd = {2012, 0, 6, 24, 12, 00, 00};
202*f5f40dd6SCy Schubert 
203*f5f40dd6SCy Schubert 	u_long expected = 3549528000UL;
204*f5f40dd6SCy Schubert 
205*f5f40dd6SCy Schubert 	TEST_ASSERT_EQUAL_UINT(expected, caltontp(&inputYd));
206*f5f40dd6SCy Schubert 	TEST_ASSERT_EQUAL_UINT(expected, caltontp(&inputMd));
207*f5f40dd6SCy Schubert }
208*f5f40dd6SCy Schubert 
209*f5f40dd6SCy Schubert void
210*f5f40dd6SCy Schubert test_WraparoundDateIn2036(void) {
211*f5f40dd6SCy Schubert 	// 2036-02-07 06:28:16
212*f5f40dd6SCy Schubert 	// This is (one) wrapping boundary where we go from ULONG_MAX to 0.
213*f5f40dd6SCy Schubert 	struct calendar input = {2036, 0, 2, 7, 6, 28, 16};
214*f5f40dd6SCy Schubert 
215*f5f40dd6SCy Schubert 	u_long expected = 0UL;
216*f5f40dd6SCy Schubert 
217*f5f40dd6SCy Schubert 	TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
218*f5f40dd6SCy Schubert }
219*f5f40dd6SCy Schubert 
220*f5f40dd6SCy Schubert #endif
221