"Fossies" - the Fresh Open Source Software Archive

Member "date.c" (16 Jun 2017, 5553 Bytes) of package /linux/misc/tzcode2018i.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "date.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2017b_vs_2017c.

    1 /* Display or set the current time and date.  */
    2 
    3 /* Copyright 1985, 1987, 1988 The Regents of the University of California.
    4    All rights reserved.
    5 
    6    Redistribution and use in source and binary forms, with or without
    7    modification, are permitted provided that the following conditions
    8    are met:
    9    1. Redistributions of source code must retain the above copyright
   10       notice, this list of conditions and the following disclaimer.
   11    2. Redistributions in binary form must reproduce the above copyright
   12       notice, this list of conditions and the following disclaimer in the
   13       documentation and/or other materials provided with the distribution.
   14    3. Neither the name of the University nor the names of its contributors
   15       may be used to endorse or promote products derived from this software
   16       without specific prior written permission.
   17 
   18    THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
   19    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21    ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   22    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28    SUCH DAMAGE.  */
   29 
   30 #include "private.h"
   31 #include <locale.h>
   32 #include <stdio.h>
   33 
   34 /*
   35 ** The two things date knows about time are. . .
   36 */
   37 
   38 #ifndef TM_YEAR_BASE
   39 #define TM_YEAR_BASE    1900
   40 #endif /* !defined TM_YEAR_BASE */
   41 
   42 #ifndef SECSPERMIN
   43 #define SECSPERMIN  60
   44 #endif /* !defined SECSPERMIN */
   45 
   46 #if !HAVE_POSIX_DECLS
   47 extern char *       optarg;
   48 extern int      optind;
   49 #endif
   50 
   51 static int      retval = EXIT_SUCCESS;
   52 
   53 static void     display(const char *, time_t);
   54 static void     dogmt(void);
   55 static void     errensure(void);
   56 static void     timeout(FILE *, const char *, const struct tm *);
   57 static _Noreturn void   usage(void);
   58 
   59 int
   60 main(const int argc, char *argv[])
   61 {
   62     register const char *   format;
   63     register const char *   cp;
   64     register int        ch;
   65     register bool       rflag = false;
   66     time_t          t;
   67     intmax_t        secs;
   68     char *          endarg;
   69 
   70 #ifdef LC_ALL
   71     setlocale(LC_ALL, "");
   72 #endif /* defined(LC_ALL) */
   73 #if HAVE_GETTEXT
   74 #ifdef TZ_DOMAINDIR
   75     bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
   76 #endif /* defined(TEXTDOMAINDIR) */
   77     textdomain(TZ_DOMAIN);
   78 #endif /* HAVE_GETTEXT */
   79     t = time(NULL);
   80     format = NULL;
   81     while ((ch = getopt(argc, argv, "ucr:")) != EOF && ch != -1) {
   82         switch (ch) {
   83         default:
   84             usage();
   85         case 'u':       /* do it in UT */
   86         case 'c':
   87             dogmt();
   88             break;
   89         case 'r':       /* seconds since 1970 */
   90             if (rflag) {
   91                 fprintf(stderr,
   92                     _("date: error: multiple -r's used"));
   93                 usage();
   94             }
   95             rflag = true;
   96             errno = 0;
   97             secs = strtoimax (optarg, &endarg, 0);
   98             if (*endarg || optarg == endarg)
   99                 errno = EINVAL;
  100             else if (! (TIME_T_MIN <= secs && secs <= TIME_T_MAX))
  101                 errno = ERANGE;
  102             if (errno) {
  103                 perror(optarg);
  104                 errensure();
  105                 exit(retval);
  106             }
  107             t = secs;
  108             break;
  109         }
  110     }
  111     while (optind < argc) {
  112         cp = argv[optind++];
  113         if (*cp == '+')
  114             if (format == NULL)
  115                 format = cp + 1;
  116             else {
  117                 fprintf(stderr,
  118 _("date: error: multiple formats in command line\n"));
  119                 usage();
  120             }
  121         else {
  122           fprintf(stderr, _("date: unknown operand: %s\n"), cp);
  123           usage();
  124         }
  125     }
  126 
  127     display(format, t);
  128     return retval;
  129 }
  130 
  131 static void
  132 dogmt(void)
  133 {
  134     static char **  fakeenv;
  135 
  136     if (fakeenv == NULL) {
  137         register int    from;
  138         register int    to;
  139         register int    n;
  140         static char tzegmt0[] = "TZ=GMT0";
  141 
  142         for (n = 0;  environ[n] != NULL;  ++n)
  143             continue;
  144         fakeenv = malloc((n + 2) * sizeof *fakeenv);
  145         if (fakeenv == NULL) {
  146             perror(_("Memory exhausted"));
  147             errensure();
  148             exit(retval);
  149         }
  150         to = 0;
  151         fakeenv[to++] = tzegmt0;
  152         for (from = 1; environ[from] != NULL; ++from)
  153             if (strncmp(environ[from], "TZ=", 3) != 0)
  154                 fakeenv[to++] = environ[from];
  155         fakeenv[to] = NULL;
  156         environ = fakeenv;
  157     }
  158 }
  159 
  160 static void
  161 errensure(void)
  162 {
  163     if (retval == EXIT_SUCCESS)
  164         retval = EXIT_FAILURE;
  165 }
  166 
  167 static void
  168 usage(void)
  169 {
  170     fprintf(stderr,
  171                _("date: usage: date [-u] [-c] [-r seconds]"
  172              " [+format]\n"));
  173     errensure();
  174     exit(retval);
  175 }
  176 
  177 static void
  178 display(char const *format, time_t now)
  179 {
  180     struct tm *tmp;
  181 
  182     tmp = localtime(&now);
  183     if (!tmp) {
  184         fprintf(stderr,
  185             _("date: error: time out of range\n"));
  186         errensure();
  187         return;
  188     }
  189     timeout(stdout, format ? format : "%+", tmp);
  190     putchar('\n');
  191     fflush(stdout);
  192     fflush(stderr);
  193     if (ferror(stdout) || ferror(stderr)) {
  194         fprintf(stderr,
  195             _("date: error: couldn't write results\n"));
  196         errensure();
  197     }
  198 }
  199 
  200 #define INCR    1024
  201 
  202 static void
  203 timeout(FILE *fp, char const *format, struct tm const *tmp)
  204 {
  205     char *  cp;
  206     size_t  result;
  207     size_t  size;
  208     struct tm tm;
  209 
  210     if (*format == '\0')
  211         return;
  212     if (!tmp) {
  213         fprintf(stderr, _("date: error: time out of range\n"));
  214         errensure();
  215         return;
  216     }
  217     tm = *tmp;
  218     tmp = &tm;
  219     size = INCR;
  220     cp = malloc(size);
  221     for ( ; ; ) {
  222         if (cp == NULL) {
  223             fprintf(stderr,
  224                 _("date: error: can't get memory\n"));
  225             errensure();
  226             exit(retval);
  227         }
  228         cp[0] = '\1';
  229         result = strftime(cp, size, format, tmp);
  230         if (result != 0 || cp[0] == '\0')
  231             break;
  232         size += INCR;
  233         cp = realloc(cp, size);
  234     }
  235     fwrite(cp, 1, result, fp);
  236     free(cp);
  237 }