/* date - print or set the system date and time                                 This is the date utility
   Copyright (C) 1989-2018 Free Software Foundation, Inc.                       
                                                                                
   This program is free software: you can redistribute it and/or modify         
   it under the terms of the GNU General Public License as published by         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.       
                                                                                
   David MacKenzie <djm@gnu.ai.mit.edu> */                                      The GNUv3 license
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <getopt.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
#if HAVE_LANGINFO_CODESET                                                       Line 23
# include <langinfo.h>                                                          ...!includes auto-comment...
#endif                                                                          Line 25
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "argmatch.h"                                                           ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "parse-datetime.h"                                                     ...!includes auto-comment...
#include "posixtm.h"                                                            ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "stat-time.h"                                                          ...!includes auto-comment...
#include "fprintftime.h"                                                        ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "date"                                                     Line 38
                                                                                
#define AUTHORS proper_name ("David MacKenzie")                                 Line 40
                                                                                
static bool show_date (const char *, struct timespec, timezone_t);              Line 42
                                                                                
enum Time_spec                                                                  Line 44
{                                                                               
  /* Display only the date.  */                                                 
  TIME_SPEC_DATE,                                                               Line 47
  /* Display date, hours, minutes, and seconds.  */                             
  TIME_SPEC_SECONDS,                                                            Line 49
  /* Similar, but display nanoseconds. */                                       
  TIME_SPEC_NS,                                                                 Line 51
                                                                                
  /* Put these last, since they aren't valid for --rfc-3339.  */                
                                                                                
  /* Display date and hour.  */                                                 
  TIME_SPEC_HOURS,                                                              Line 56
  /* Display date, hours, and minutes.  */                                      
  TIME_SPEC_MINUTES                                                             Line 58
};                                                                              
                                                                                
static char const *const time_spec_string[] =                                   Line 61
{                                                                               
  /* Put "hours" and "minutes" first, since they aren't valid for               
     --rfc-3339.  */                                                            
  "hours", "minutes",                                                           Line 65
  "date", "seconds", "ns", NULL                                                 Line 66
};                                                                              
static enum Time_spec const time_spec[] =                                       Line 68
{                                                                               
  TIME_SPEC_HOURS, TIME_SPEC_MINUTES,                                           Line 70
  TIME_SPEC_DATE, TIME_SPEC_SECONDS, TIME_SPEC_NS                               Line 71
};                                                                              Block 3
ARGMATCH_VERIFY (time_spec_string, time_spec);                                  Line 73
                                                                                
/* A format suitable for Internet RFCs 5322, 2822, and 822.  */                 
static char const rfc_email_format[] = "%a, %d %b %Y %H:%M:%S %z";              Line 76
                                                                                
/* For long options that have no equivalent short option, use a                 
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */      
enum                                                                            Line 80
{                                                                               
  RFC_3339_OPTION = CHAR_MAX + 1,                                               Line 82
  DEBUG_DATE_PARSING                                                            Line 83
};                                                                              Block 4
                                                                                
static char const short_options[] = "d:f:I::r:Rs:u";                            Line 86
                                                                                
static struct option const long_options[] =                                     Line 88
{                                                                               
  {"date", required_argument, NULL, 'd'},                                       Line 90
  {"debug", no_argument, NULL, DEBUG_DATE_PARSING},                             Line 91
  {"file", required_argument, NULL, 'f'},                                       Line 92
  {"iso-8601", optional_argument, NULL, 'I'},                                   Line 93
  {"reference", required_argument, NULL, 'r'},                                  Line 94
  {"rfc-email", no_argument, NULL, 'R'},                                        Line 95
  {"rfc-822", no_argument, NULL, 'R'},                                          Line 96
  {"rfc-2822", no_argument, NULL, 'R'},                                         Line 97
  {"rfc-3339", required_argument, NULL, RFC_3339_OPTION},                       Line 98
  {"set", required_argument, NULL, 's'},                                        Line 99
  {"uct", no_argument, NULL, 'u'},                                              Line 100
  {"utc", no_argument, NULL, 'u'},                                              Line 101
  {"universal", no_argument, NULL, 'u'},                                        Line 102
  {GETOPT_HELP_OPTION_DECL},                                                    Line 103
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 104
  {NULL, 0, NULL, 0}                                                            Line 105
};                                                                              Block 5
                                                                                
/* flags for parse_datetime2 */                                                 
static unsigned int parse_datetime_flags;                                       Line 109
                                                                                
#if LOCALTIME_CACHE                                                             Line 111
# define TZSET tzset ()                                                         Line 112
#else                                                                           Line 113
# define TZSET /* empty */                                                      Line 114
#endif                                                                          Line 115
                                                                                
#ifdef _DATE_FMT                                                                Line 117
# define DATE_FMT_LANGINFO() nl_langinfo (_DATE_FMT)                            Line 118
#else                                                                           Line 119
# define DATE_FMT_LANGINFO() ""                                                 Line 120
#endif                                                                          Line 121
                                                                                
void                                                                            Line 123
usage (int status)                                                              Line 124
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 126
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 128
    {                                                                           
      printf (_("\                                                              Line 130
Usage: %s [OPTION]... [+FORMAT]\n\                                              Line 131
  or:  %s [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]\n\                     Line 132
"),                                                                             Line 133
              program_name, program_name);                                      Line 134
      fputs (_("\                                                               Line 135
Display the current time in the given FORMAT, or set the system date.\n\        Line 136
"), stdout);                                                                    Line 137
                                                                                
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 141
  -d, --date=STRING          display time described by STRING, not 'now'\n\     Line 142
"), stdout);                                                                    Line 143
      fputs (_("\                                                               Line 144
      --debug                annotate the parsed date,\n\                       Line 145
                              and warn about questionable usage to stderr\n\    Line 146
"), stdout);                                                                    Line 147
      fputs (_("\                                                               Line 148
  -f, --file=DATEFILE        like --date; once for each line of DATEFILE\n\     Line 149
"), stdout);                                                                    Line 150
      fputs (_("\                                                               Line 151
  -I[FMT], --iso-8601[=FMT]  output date/time in ISO 8601 format.\n\            Line 152
                               FMT='date' for date only (the default),\n\       Line 153
                               'hours', 'minutes', 'seconds', or 'ns'\n\        Line 154
                               for date and time to the indicated precision.\n\ Line 155
                               Example: 2006-08-14T02:34:56-06:00\n\            Line 156
"), stdout);                                                                    Line 157
      fputs (_("\                                                               Line 158
  -R, --rfc-email            output date and time in RFC 5322 format.\n\        Line 159
                               Example: Mon, 14 Aug 2006 02:34:56 -0600\n\      Line 160
"), stdout);                                                                    Line 161
      fputs (_("\                                                               Line 162
      --rfc-3339=FMT         output date/time in RFC 3339 format.\n\            Line 163
                               FMT='date', 'seconds', or 'ns'\n\                Line 164
                               for date and time to the indicated precision.\n\ Line 165
                               Example: 2006-08-14 02:34:56-06:00\n\            Line 166
"), stdout);                                                                    Line 167
      fputs (_("\                                                               Line 168
  -r, --reference=FILE       display the last modification time of FILE\n\      Line 169
"), stdout);                                                                    Line 170
      fputs (_("\                                                               Line 171
  -s, --set=STRING           set time described by STRING\n\                    Line 172
  -u, --utc, --universal     print or set Coordinated Universal Time (UTC)\n\   Line 173
"), stdout);                                                                    Line 174
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 175
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 176
      fputs (_("\                                                               Line 177
\n\                                                                             
FORMAT controls the output.  Interpreted sequences are:\n\                      Line 179
\n\                                                                             
  %%   a literal %\n\                                                           Line 181
  %a   locale's abbreviated weekday name (e.g., Sun)\n\                         Line 182
"), stdout);                                                                    Line 183
      fputs (_("\                                                               Line 184
  %A   locale's full weekday name (e.g., Sunday)\n\                             Line 185
  %b   locale's abbreviated month name (e.g., Jan)\n\                           Line 186
  %B   locale's full month name (e.g., January)\n\                              Line 187
  %c   locale's date and time (e.g., Thu Mar  3 23:05:25 2005)\n\               Line 188
"), stdout);                                                                    Line 189
      fputs (_("\                                                               Line 190
  %C   century; like %Y, except omit last two digits (e.g., 20)\n\              Line 191
  %d   day of month (e.g., 01)\n\                                               Line 192
  %D   date; same as %m/%d/%y\n\                                                Line 193
  %e   day of month, space padded; same as %_d\n\                               Line 194
"), stdout);                                                                    Line 195
      fputs (_("\                                                               Line 196
  %F   full date; same as %Y-%m-%d\n\                                           Line 197
  %g   last two digits of year of ISO week number (see %G)\n\                   Line 198
  %G   year of ISO week number (see %V); normally useful only with %V\n\        Line 199
"), stdout);                                                                    Line 200
      fputs (_("\                                                               Line 201
  %h   same as %b\n\                                                            Line 202
  %H   hour (00..23)\n\                                                         Line 203
  %I   hour (01..12)\n\                                                         Line 204
  %j   day of year (001..366)\n\                                                Line 205
"), stdout);                                                                    Line 206
      fputs (_("\                                                               Line 207
  %k   hour, space padded ( 0..23); same as %_H\n\                              Line 208
  %l   hour, space padded ( 1..12); same as %_I\n\                              Line 209
  %m   month (01..12)\n\                                                        Line 210
  %M   minute (00..59)\n\                                                       Line 211
"), stdout);                                                                    Line 212
      fputs (_("\                                                               Line 213
  %n   a newline\n\                                                             Line 214
  %N   nanoseconds (000000000..999999999)\n\                                    Line 215
  %p   locale's equivalent of either AM or PM; blank if not known\n\            Line 216
  %P   like %p, but lower case\n\                                               Line 217
  %q   quarter of year (1..4)\n\                                                Line 218
  %r   locale's 12-hour clock time (e.g., 11:11:04 PM)\n\                       Line 219
  %R   24-hour hour and minute; same as %H:%M\n\                                Line 220
  %s   seconds since 1970-01-01 00:00:00 UTC\n\                                 Line 221
"), stdout);                                                                    Line 222
      fputs (_("\                                                               Line 223
  %S   second (00..60)\n\                                                       Line 224
  %t   a tab\n\                                                                 Line 225
  %T   time; same as %H:%M:%S\n\                                                Line 226
  %u   day of week (1..7); 1 is Monday\n\                                       Line 227
"), stdout);                                                                    Line 228
      fputs (_("\                                                               Line 229
  %U   week number of year, with Sunday as first day of week (00..53)\n\        Line 230
  %V   ISO week number, with Monday as first day of week (01..53)\n\            Line 231
  %w   day of week (0..6); 0 is Sunday\n\                                       Line 232
  %W   week number of year, with Monday as first day of week (00..53)\n\        Line 233
"), stdout);                                                                    Line 234
      fputs (_("\                                                               Line 235
  %x   locale's date representation (e.g., 12/31/99)\n\                         Line 236
  %X   locale's time representation (e.g., 23:13:48)\n\                         Line 237
  %y   last two digits of year (00..99)\n\                                      Line 238
  %Y   year\n\                                                                  Line 239
"), stdout);                                                                    Line 240
      fputs (_("\                                                               Line 241
  %z   +hhmm numeric time zone (e.g., -0400)\n\                                 Line 242
  %:z  +hh:mm numeric time zone (e.g., -04:00)\n\                               Line 243
  %::z  +hh:mm:ss numeric time zone (e.g., -04:00:00)\n\                        Line 244
  %:::z  numeric time zone with : to necessary precision (e.g., -04, +05:30)\n\ Line 245
  %Z   alphabetic time zone abbreviation (e.g., EDT)\n\                         Line 246
\n\                                                                             
By default, date pads numeric fields with zeroes.\n\                            Line 248
"), stdout);                                                                    Line 249
      fputs (_("\                                                               Line 250
The following optional flags may follow '%':\n\                                 Line 251
\n\                                                                             
  -  (hyphen) do not pad the field\n\                                           Line 253
  _  (underscore) pad with spaces\n\                                            Line 254
  0  (zero) pad with zeros\n\                                                   Line 255
  ^  use upper case if possible\n\                                              Line 256
  #  use opposite case if possible\n\                                           Line 257
"), stdout);                                                                    Line 258
      fputs (_("\                                                               Line 259
\n\                                                                             
After any flags comes an optional field width, as a decimal number;\n\          Line 261
then an optional modifier, which is either\n\                                   Line 262
E to use the locale's alternate representations if available, or\n\             Line 263
O to use the locale's alternate numeric symbols if available.\n\                Line 264
"), stdout);                                                                    Line 265
      fputs (_("\                                                               Line 266
\n\                                                                             
Examples:\n\                                                                    Line 268
Convert seconds since the epoch (1970-01-01 UTC) to a date\n\                   Line 269
  $ date --date='@2147483647'\n\                                                Line 270
\n\                                                                             
Show the time on the west coast of the US (use tzselect(1) to find TZ)\n\       Line 272
  $ TZ='America/Los_Angeles' date\n\                                            Line 273
\n\                                                                             
Show the local time for 9AM next Friday on the west coast of the US\n\          Line 275
  $ date --date='TZ=\"America/Los_Angeles\" 09:00 next Fri'\n\                  Line 276
"), stdout);                                                                    Line 277
      emit_ancillary_info (PROGRAM_NAME);                                       Line 278
    }                                                                           
  exit (status);                                                                Line 280
}                                                                               Block 6
                                                                                
/* Parse each line in INPUT_FILENAME as with --date and display each            
   resulting time and date.  If the file cannot be opened, tell why             
   then exit.  Issue a diagnostic for any lines that cannot be parsed.          
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 288
batch_convert (const char *input_filename, const char *format,                  Line 289
               timezone_t tz, char const *tzstring)                             Line 290
{                                                                               
  bool ok;                                                                      Line 292
  FILE *in_stream;                                                              Line 293
  char *line;                                                                   Line 294
  size_t buflen;                                                                Line 295
  struct timespec when;                                                         Line 296
                                                                                
  if (STREQ (input_filename, "-"))                                              Line 298
    {                                                                           
      input_filename = _("standard input");                                     Line 300
      in_stream = stdin;                                                        Line 301
    }                                                                           
  else                                                                          Line 303
    {                                                                           
      in_stream = fopen (input_filename, "r");                                  Line 305...!syscalls auto-comment...
      if (in_stream == NULL)                                                    Line 306
        {                                                                       
          die (EXIT_FAILURE, errno, "%s", quotef (input_filename));             Line 308
        }                                                                       
    }                                                                           
                                                                                
  line = NULL;                                                                  Line 312
  buflen = 0;                                                                   Line 313
  ok = true;                                                                    Line 314
  while (1)                                                                     Line 315
    {                                                                           
      ssize_t line_length = getline (&line, &buflen, in_stream);                Line 317
      if (line_length < 0)                                                      Line 318
        {                                                                       
          /* FIXME: detect/handle error here.  */                               
          break;                                                                Line 321
        }                                                                       
                                                                                
      if (! parse_datetime2 (&when, line, NULL,                                 Line 324
                             parse_datetime_flags, tz, tzstring))               Line 325
        {                                                                       
          if (line[line_length - 1] == '\n')                                    Line 327
            line[line_length - 1] = '\0';                                       Line 328
          error (0, 0, _("invalid date %s"), quote (line));                     Line 329
          ok = false;                                                           Line 330
        }                                                                       
      else                                                                      Line 332
        {                                                                       
          ok &= show_date (format, when, tz);                                   Line 334
        }                                                                       
    }                                                                           
                                                                                
  if (fclose (in_stream) == EOF)                                                Line 338...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, "%s", quotef (input_filename));                   Line 339
                                                                                
  free (line);                                                                  Line 341
                                                                                
  return ok;                                                                    Line 343
}                                                                               Block 7
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 347
{                                                                               
  int optc;                                                                     Line 349
  const char *datestr = NULL;                                                   Line 350
  const char *set_datestr = NULL;                                               Line 351
  struct timespec when;                                                         Line 352
  bool set_date = false;                                                        Line 353
  char const *format = NULL;                                                    Line 354
  char *batch_file = NULL;                                                      Line 355
  char *reference = NULL;                                                       Line 356
  struct stat refstats;                                                         Line 357
  bool ok;                                                                      Line 358
  int option_specified_date;                                                    Line 359
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))   Line 369
         != -1)                                                                 Line 370
    {                                                                           
      char const *new_format = NULL;                                            Line 372
                                                                                
      switch (optc)                                                             Line 374
        {                                                                       
        case 'd':                                                               Line 376
          datestr = optarg;                                                     Line 377
          break;                                                                Line 378
        case DEBUG_DATE_PARSING:                                                Line 379
          parse_datetime_flags |= PARSE_DATETIME_DEBUG;                         Line 380
          break;                                                                Line 381
        case 'f':                                                               Line 382
          batch_file = optarg;                                                  Line 383
          break;                                                                Line 384
        case RFC_3339_OPTION:                                                   Line 385
          {                                                                     
            static char const rfc_3339_format[][32] =                           Line 387
              {                                                                 
                "%Y-%m-%d",                                                     Line 389
                "%Y-%m-%d %H:%M:%S%:z",                                         Line 390
                "%Y-%m-%d %H:%M:%S.%N%:z"                                       Line 391
              };                                                                
            enum Time_spec i =                                                  Line 393
              XARGMATCH ("--rfc-3339", optarg,                                  Line 394
                         time_spec_string + 2, time_spec + 2);                  Line 395
            new_format = rfc_3339_format[i];                                    Line 396
            break;                                                              Line 397
          }                                                                     
        case 'I':                                                               Line 399
          {                                                                     
            static char const iso_8601_format[][32] =                           Line 401
              {                                                                 
                "%Y-%m-%d",                                                     Line 403
                "%Y-%m-%dT%H:%M:%S%:z",                                         Line 404
                "%Y-%m-%dT%H:%M:%S,%N%:z",                                      Line 405
                "%Y-%m-%dT%H%:z",                                               Line 406
                "%Y-%m-%dT%H:%M%:z"                                             Line 407
              };                                                                
            enum Time_spec i =                                                  Line 409
              (optarg                                                           Line 410
               ? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec)  Line 411
               : TIME_SPEC_DATE);                                               Line 412
            new_format = iso_8601_format[i];                                    Line 413
            break;                                                              Line 414
          }                                                                     
        case 'r':                                                               Line 416
          reference = optarg;                                                   Line 417
          break;                                                                Line 418
        case 'R':                                                               Line 419
          new_format = rfc_email_format;                                        Line 420
          break;                                                                Line 421
        case 's':                                                               Line 422
          set_datestr = optarg;                                                 Line 423
          set_date = true;                                                      Line 424
          break;                                                                Line 425
        case 'u':                                                               Line 426
          /* POSIX says that 'date -u' is equivalent to setting the TZ          
             environment variable, so this option should do nothing other       
             than setting TZ.  */                                               
          if (putenv (bad_cast ("TZ=UTC0")) != 0)                               Line 430
            xalloc_die ();                                                      ...!common auto-comment...
          TZSET;                                                                Line 432
          break;                                                                Line 433
        case_GETOPT_HELP_CHAR;                                                  Line 434
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 435
        default:                                                                Line 436
          usage (EXIT_FAILURE);                                                 Line 437
        }                                                                       
                                                                                
      if (new_format)                                                           Line 440
        {                                                                       
          if (format)                                                           Line 442
            die (EXIT_FAILURE, 0, _("multiple output formats specified"));      Line 443
          format = new_format;                                                  Line 444
        }                                                                       
    }                                                                           
                                                                                
  option_specified_date = ((datestr ? 1 : 0)                                    Line 448
                           + (batch_file ? 1 : 0)                               Line 449
                           + (reference ? 1 : 0));                              Line 450
                                                                                
  if (option_specified_date > 1)                                                Line 452
    {                                                                           
      error (0, 0,                                                              Line 454
        _("the options to specify dates for printing are mutually exclusive")); Line 455
      usage (EXIT_FAILURE);                                                     Line 456
    }                                                                           
                                                                                
  if (set_date && option_specified_date)                                        Line 459
    {                                                                           
      error (0, 0,                                                              Line 461
          _("the options to print and set the time may not be used together")); Line 462
      usage (EXIT_FAILURE);                                                     Line 463
    }                                                                           
                                                                                
  if (optind < argc)                                                            Line 466
    {                                                                           
      if (optind + 1 < argc)                                                    Line 468
        {                                                                       
          error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));        Line 470
          usage (EXIT_FAILURE);                                                 Line 471
        }                                                                       
                                                                                
      if (argv[optind][0] == '+')                                               Line 474
        {                                                                       
          if (format)                                                           Line 476
            die (EXIT_FAILURE, 0, _("multiple output formats specified"));      Line 477
          format = argv[optind++] + 1;                                          Line 478
        }                                                                       
      else if (set_date || option_specified_date)                               Line 480
        {                                                                       
          error (0, 0,                                                          Line 482
                 _("the argument %s lacks a leading '+';\n"                     Line 483
                   "when using an option to specify date(s), any non-option\n"  Line 484
                   "argument must be a format string beginning with '+'"),      Line 485
                 quote (argv[optind]));                                         Line 486
          usage (EXIT_FAILURE);                                                 Line 487
        }                                                                       
    }                                                                           
                                                                                
  if (!format)                                                                  Line 491
    {                                                                           
      format = DATE_FMT_LANGINFO ();                                            Line 493
      if (! *format)                                                            Line 494
        {                                                                       
          /* Do not wrap the following literal format string with _(...).       
             For example, suppose LC_ALL is unset, LC_TIME=POSIX,               
             and LANG="ko_KR".  In that case, POSIX says that LC_TIME           
             determines the format and contents of date and time strings        
             written by date, which means "date" must generate output           
             using the POSIX locale; but adding _() would cause "date"          
             to use a Korean translation of the format.  */                     
          format = "%a %b %e %H:%M:%S %Z %Y";                                   Line 503
        }                                                                       
    }                                                                           
                                                                                
  char const *tzstring = getenv ("TZ");                                         Line 507
  timezone_t tz = tzalloc (tzstring);                                           Line 508
                                                                                
  if (batch_file != NULL)                                                       Line 510
    ok = batch_convert (batch_file, format, tz, tzstring);                      Line 511
  else                                                                          Line 512
    {                                                                           
      bool valid_date = true;                                                   Line 514
      ok = true;                                                                Line 515
                                                                                
      if (!option_specified_date && !set_date)                                  Line 517
        {                                                                       
          if (optind < argc)                                                    Line 519
            {                                                                   
              /* Prepare to set system clock to the specified date/time         
                 given in the POSIX-format.  */                                 
              set_date = true;                                                  Line 523
              datestr = argv[optind];                                           Line 524
              valid_date = posixtime (&when.tv_sec,                             Line 525
                                      datestr,                                  Line 526
                                      (PDS_TRAILING_YEAR                        Line 527
                                       | PDS_CENTURY | PDS_SECONDS));           Line 528
              when.tv_nsec = 0; /* FIXME: posixtime should set this.  */        Line 529
            }                                                                   
          else                                                                  Line 531
            {                                                                   
              /* Prepare to print the current date/time.  */                    
              gettime (&when);                                                  Line 534
            }                                                                   
        }                                                                       
      else                                                                      Line 537
        {                                                                       
          /* (option_specified_date || set_date) */                             
          if (reference != NULL)                                                Line 540
            {                                                                   
              if (stat (reference, &refstats) != 0)                             Line 542...!syscalls auto-comment...
                die (EXIT_FAILURE, errno, "%s", quotef (reference));            Line 543
              when = get_stat_mtime (&refstats);                                Line 544
            }                                                                   
          else                                                                  Line 546
            {                                                                   
              if (set_datestr)                                                  Line 548
                datestr = set_datestr;                                          Line 549
              valid_date = parse_datetime2 (&when, datestr, NULL,               Line 550
                                            parse_datetime_flags,               Line 551
                                            tz, tzstring);                      Line 552
            }                                                                   
        }                                                                       
                                                                                
      if (! valid_date)                                                         Line 556
        die (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));           Line 557
                                                                                
      if (set_date)                                                             Line 559
        {                                                                       
          /* Set the system clock to the specified date, then regardless of     
             the success of that operation, format and print that date.  */     
          if (settime (&when) != 0)                                             Line 563
            {                                                                   
              error (0, errno, _("cannot set date"));                           Line 565
              ok = false;                                                       Line 566
            }                                                                   
        }                                                                       
                                                                                
      ok &= show_date (format, when, tz);                                       Line 570
    }                                                                           
                                                                                
  IF_LINT (tzfree (tz));                                                        Line 573
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 575
}                                                                               Block 8
                                                                                
/* Display the date and/or time in WHEN according to the format specified       
   in FORMAT, followed by a newline.  Return true if successful.  */            
                                                                                
static bool                                                                     Line 581
show_date (const char *format, struct timespec when, timezone_t tz)             Line 582
{                                                                               
  struct tm tm;                                                                 Line 584
                                                                                
  if (localtime_rz (tz, &when.tv_sec, &tm))                                     Line 586
    {                                                                           
      if (format == rfc_email_format)                                           Line 588
        setlocale (LC_TIME, "C");                                               Sets up internationalization (i18n)
      fprintftime (stdout, format, &tm, tz, when.tv_nsec);                      Line 590
      if (format == rfc_email_format)                                           Line 591
        setlocale (LC_TIME, "");                                                Sets up internationalization (i18n)
      fputc ('\n', stdout);                                                     Line 593
      return true;                                                              Line 594
    }                                                                           
  else                                                                          Line 596
    {                                                                           
      char buf[INT_BUFSIZE_BOUND (intmax_t)];                                   Line 598
      error (0, 0, _("time %s is out of range"),                                Line 599
             quote (timetostr (when.tv_sec, buf)));                             Line 600
      return false;                                                             Line 601
    }                                                                           
}                                                                               Block 9