date.c (2043B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h> /* errno */
- #include <locale.h> /* setlocale() */
- #include <stdio.h> /* BUFSIZ, perror(), puts() */
- #include <stdlib.h> /* exit(), strtol() */
- #include <time.h> /* time, localtime, tm, strftime */
- #include <unistd.h> /* getopt(), optarg, optind */
- int
- custom_datetime(time_t *now, char *optarg)
- {
- if(optarg[0] == '@')
- {
- optarg++;
- errno = 0;
- *now = (time_t)strtol(optarg, NULL, 10);
- if(errno != 0)
- {
- perror("strtol");
- return 0;
- }
- return 1;
- }
- return 0;
- }
- void
- usage()
- {
- fprintf(stderr, "date [-u][-d datetime] [+format]\n");
- }
- int
- main(int argc, char *argv[])
- {
- char outstr[BUFSIZ];
- struct tm *tm;
- time_t now;
- char *format = "%c";
- int uflag = 0;
- int c;
- setlocale(LC_ALL, "");
- now = time(NULL);
- if(now == (time_t)-1)
- {
- perror("time");
- exit(EXIT_FAILURE);
- }
- while((c = getopt(argc, argv, ":d:u")) != -1)
- {
- switch(c)
- {
- case 'd': /* Custom datetime */
- if(!custom_datetime(&now, optarg))
- {
- return 1;
- }
- break;
- case 'u': /* UTC timezone */
- uflag++;
- break;
- case ':':
- fprintf(stderr, "Error: Missing operand for option: '-%c'\n", optopt);
- usage();
- return 1;
- case '?':
- fprintf(stderr, "Error: Unrecognised option: '-%c'\n", optopt);
- usage();
- return 1;
- }
- }
- if(uflag)
- {
- tm = gmtime(&now);
- if(tm == NULL)
- {
- perror("gmtime");
- exit(EXIT_FAILURE);
- }
- }
- else
- {
- tm = localtime(&now);
- if(tm == NULL)
- {
- perror("localtime");
- exit(EXIT_FAILURE);
- }
- }
- argc -= optind;
- argv += optind;
- (void)argc;
- if(*argv && **argv == '+') format = *argv + 1;
- errno = 0;
- if(strftime(outstr, sizeof(outstr), format, tm) == 0 && errno != 0)
- {
- perror("strftime");
- exit(EXIT_FAILURE);
- }
- if(puts(outstr) < 0)
- {
- perror("puts");
- exit(EXIT_FAILURE);
- }
- return 0;
- }