root/tools/iso8601.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. log_time_period
  2. main

   1 /*
   2  * Copyright 2005-2020 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 #include <crm/crm.h>
  12 #include <crm/common/iso8601.h>
  13 #include <crm/common/util.h>  /* CRM_ASSERT */
  14 #include <unistd.h>
  15 
  16 char command = 0;
  17 
  18 static pcmk__cli_option_t long_options[] = {
  19     // long option, argument type, storage, short option, description, flags
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */