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