This source file includes following definitions.
- log_time_period
- main
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/crm.h>
12 #include <crm/common/iso8601.h>
13 #include <crm/common/util.h>
14 #include <unistd.h>
15
16 char command = 0;
17
18 static pcmk__cli_option_t long_options[] = {
19
20 {
21 "help", no_argument, NULL, '?',
22 "\tThis text", pcmk__option_default
23 },
24 {
25 "version", no_argument, NULL, '$',
26 "\tVersion information", pcmk__option_default
27 },
28 {
29 "verbose", no_argument, NULL, 'V',
30 "\tIncrease debug output", pcmk__option_default
31 },
32 {
33 "-spacer-", no_argument, NULL, '-',
34 "\nCommands:", pcmk__option_default
35 },
36 {
37 "now", no_argument, NULL, 'n',
38 "\tDisplay the current date/time", pcmk__option_default
39 },
40 {
41 "date", required_argument, NULL, 'd',
42 "Parse an ISO 8601 date/time (for example, "
43 "'2019-09-24 00:30:00 +01:00' or '2019-040')",
44 pcmk__option_default
45 },
46 {
47 "period", required_argument, NULL, 'p',
48 "Parse an ISO 8601 period (interval) with start time (for example, "
49 "'2005-040/2005-043')",
50 pcmk__option_default
51 },
52 {
53 "duration", required_argument, NULL, 'D',
54 "Parse an ISO 8601 duration (for example, 'P1M')", pcmk__option_default
55 },
56 {
57 "expected", required_argument, NULL, 'E',
58 "Exit with error status if result does not match this text. "
59 "Requires: -n or -d",
60 pcmk__option_default
61 },
62 {
63 "-spacer-", no_argument, NULL, '-',
64 "\nOutput Modifiers:", pcmk__option_default
65 },
66 {
67 "seconds", no_argument, NULL, 's',
68 "\tShow result as a seconds since 0000-001 00:00:00Z",
69 pcmk__option_default
70 },
71 {
72 "epoch", no_argument, NULL, 'S',
73 "\tShow result as a seconds since EPOCH (1970-001 00:00:00Z)",
74 pcmk__option_default
75 },
76 {
77 "local", no_argument, NULL, 'L',
78 "\tShow result as a 'local' date/time", pcmk__option_default
79 },
80 {
81 "ordinal", no_argument, NULL, 'O',
82 "\tShow result as an 'ordinal' date/time", pcmk__option_default
83 },
84 {
85 "week", no_argument, NULL, 'W',
86 "\tShow result as an 'calendar week' date/time", pcmk__option_default
87 },
88 {
89 "-spacer-", no_argument, NULL, '-',
90 "\nFor more information on the ISO 8601 standard, see "
91 "https://en.wikipedia.org/wiki/ISO_8601",
92 pcmk__option_default
93 },
94 { 0, 0, 0, 0 }
95 };
96
97 static void
98 log_time_period(int log_level, crm_time_period_t * dtp, int flags)
99 {
100 char *start = crm_time_as_string(dtp->start, flags);
101 char *end = crm_time_as_string(dtp->end, flags);
102
103 CRM_ASSERT(start != NULL && end != NULL);
104 do_crm_log(log_level, "Period: %s to %s", start, end);
105 free(start);
106 free(end);
107 }
108
109 int
110 main(int argc, char **argv)
111 {
112 crm_exit_t exit_code = CRM_EX_OK;
113 int argerr = 0;
114 int flag;
115 int index = 0;
116 int print_options = 0;
117 crm_time_t *duration = NULL;
118 crm_time_t *date_time = NULL;
119
120 const char *period_s = NULL;
121 const char *duration_s = NULL;
122 const char *date_time_s = NULL;
123 const char *expected_s = NULL;
124
125 pcmk__cli_init_logging("iso8601", 0);
126 pcmk__set_cli_options(NULL, "<command> [options] ", long_options,
127 "display and parse ISO 8601 dates and times");
128
129 if (argc < 2) {
130 argerr++;
131 }
132
133 while (1) {
134 flag = pcmk__next_cli_option(argc, argv, &index, NULL);
135 if (flag == -1)
136 break;
137
138 switch (flag) {
139 case 'V':
140 crm_bump_log_level(argc, argv);
141 break;
142 case '?':
143 case '$':
144 pcmk__cli_help(flag, CRM_EX_OK);
145 break;
146 case 'n':
147 date_time_s = "now";
148 break;
149 case 'd':
150 date_time_s = optarg;
151 break;
152 case 'p':
153 period_s = optarg;
154 break;
155 case 'D':
156 duration_s = optarg;
157 break;
158 case 'E':
159 expected_s = optarg;
160 break;
161 case 'S':
162 print_options |= crm_time_epoch;
163 break;
164 case 's':
165 print_options |= crm_time_seconds;
166 break;
167 case 'W':
168 print_options |= crm_time_weeks;
169 break;
170 case 'O':
171 print_options |= crm_time_ordinal;
172 break;
173 case 'L':
174 print_options |= crm_time_log_with_timezone;
175 break;
176 break;
177 }
178 }
179
180 if (pcmk__str_eq("now", date_time_s, pcmk__str_casei)) {
181 date_time = crm_time_new(NULL);
182
183 if (date_time == NULL) {
184 fprintf(stderr, "Internal error: couldn't determine 'now'!\n");
185 crm_exit(CRM_EX_SOFTWARE);
186 }
187 crm_time_log(LOG_TRACE, "Current date/time", date_time,
188 crm_time_ordinal | crm_time_log_date | crm_time_log_timeofday);
189 crm_time_log(LOG_STDOUT, "Current date/time", date_time,
190 print_options | crm_time_log_date | crm_time_log_timeofday);
191
192 } else if (date_time_s) {
193 date_time = crm_time_new(date_time_s);
194
195 if (date_time == NULL) {
196 fprintf(stderr, "Invalid date/time specified: %s\n", date_time_s);
197 crm_exit(CRM_EX_INVALID_PARAM);
198 }
199 crm_time_log(LOG_TRACE, "Date", date_time,
200 crm_time_ordinal | crm_time_log_date | crm_time_log_timeofday);
201 crm_time_log(LOG_STDOUT, "Date", date_time,
202 print_options | crm_time_log_date | crm_time_log_timeofday);
203 }
204
205 if (duration_s) {
206 duration = crm_time_parse_duration(duration_s);
207
208 if (duration == NULL) {
209 fprintf(stderr, "Invalid duration specified: %s\n", duration_s);
210 crm_exit(CRM_EX_INVALID_PARAM);
211 }
212 crm_time_log(LOG_TRACE, "Duration", duration, crm_time_log_duration);
213 crm_time_log(LOG_STDOUT, "Duration", duration,
214 print_options | crm_time_log_duration);
215 }
216
217 if (period_s) {
218 crm_time_period_t *period = crm_time_parse_period(period_s);
219
220 if (period == NULL) {
221 fprintf(stderr, "Invalid interval specified: %s\n", period_s);
222 crm_exit(CRM_EX_INVALID_PARAM);
223 }
224 log_time_period(LOG_TRACE, period,
225 print_options | crm_time_log_date | crm_time_log_timeofday);
226 log_time_period(LOG_STDOUT, period,
227 print_options | crm_time_log_date | crm_time_log_timeofday);
228 crm_time_free_period(period);
229 }
230
231 if (date_time && duration) {
232 crm_time_t *later = crm_time_add(date_time, duration);
233
234 if (later == NULL) {
235 fprintf(stderr, "Unable to calculate ending time of %s plus %s",
236 date_time_s, duration_s);
237 crm_exit(CRM_EX_SOFTWARE);
238 }
239 crm_time_log(LOG_TRACE, "Duration ends at", later,
240 crm_time_ordinal | crm_time_log_date | crm_time_log_timeofday);
241 crm_time_log(LOG_STDOUT, "Duration ends at", later,
242 print_options | crm_time_log_date | crm_time_log_timeofday |
243 crm_time_log_with_timezone);
244 if (expected_s) {
245 char *dt_s = crm_time_as_string(later,
246 print_options | crm_time_log_date |
247 crm_time_log_timeofday);
248 if (!pcmk__str_eq(expected_s, dt_s, pcmk__str_casei)) {
249 exit_code = CRM_EX_ERROR;
250 }
251 free(dt_s);
252 }
253 crm_time_free(later);
254
255 } else if (date_time && expected_s) {
256 char *dt_s = crm_time_as_string(date_time,
257 print_options | crm_time_log_date | crm_time_log_timeofday);
258
259 if (!pcmk__str_eq(expected_s, dt_s, pcmk__str_casei)) {
260 exit_code = CRM_EX_ERROR;
261 }
262 free(dt_s);
263 }
264
265 crm_time_free(date_time);
266 crm_time_free(duration);
267 crm_exit(exit_code);
268 }