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