logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git

date.c (2043B)


  1. // Collection of Unix tools, comparable to coreutils
  2. // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
  4. #define _POSIX_C_SOURCE 200809L
  5. #include <errno.h> /* errno */
  6. #include <locale.h> /* setlocale() */
  7. #include <stdio.h> /* BUFSIZ, perror(), puts() */
  8. #include <stdlib.h> /* exit(), strtol() */
  9. #include <time.h> /* time, localtime, tm, strftime */
  10. #include <unistd.h> /* getopt(), optarg, optind */
  11. int
  12. custom_datetime(time_t *now, char *optarg)
  13. {
  14. if(optarg[0] == '@')
  15. {
  16. optarg++;
  17. errno = 0;
  18. *now = (time_t)strtol(optarg, NULL, 10);
  19. if(errno != 0)
  20. {
  21. perror("strtol");
  22. return 0;
  23. }
  24. return 1;
  25. }
  26. return 0;
  27. }
  28. void
  29. usage()
  30. {
  31. fprintf(stderr, "date [-u][-d datetime] [+format]\n");
  32. }
  33. int
  34. main(int argc, char *argv[])
  35. {
  36. char outstr[BUFSIZ];
  37. struct tm *tm;
  38. time_t now;
  39. char *format = "%c";
  40. int uflag = 0;
  41. int c;
  42. setlocale(LC_ALL, "");
  43. now = time(NULL);
  44. if(now == (time_t)-1)
  45. {
  46. perror("time");
  47. exit(EXIT_FAILURE);
  48. }
  49. while((c = getopt(argc, argv, ":d:u")) != -1)
  50. {
  51. switch(c)
  52. {
  53. case 'd': /* Custom datetime */
  54. if(!custom_datetime(&now, optarg))
  55. {
  56. return 1;
  57. }
  58. break;
  59. case 'u': /* UTC timezone */
  60. uflag++;
  61. break;
  62. case ':':
  63. fprintf(stderr, "Error: Missing operand for option: '-%c'\n", optopt);
  64. usage();
  65. return 1;
  66. case '?':
  67. fprintf(stderr, "Error: Unrecognised option: '-%c'\n", optopt);
  68. usage();
  69. return 1;
  70. }
  71. }
  72. if(uflag)
  73. {
  74. tm = gmtime(&now);
  75. if(tm == NULL)
  76. {
  77. perror("gmtime");
  78. exit(EXIT_FAILURE);
  79. }
  80. }
  81. else
  82. {
  83. tm = localtime(&now);
  84. if(tm == NULL)
  85. {
  86. perror("localtime");
  87. exit(EXIT_FAILURE);
  88. }
  89. }
  90. argc -= optind;
  91. argv += optind;
  92. (void)argc;
  93. if(*argv && **argv == '+') format = *argv + 1;
  94. errno = 0;
  95. if(strftime(outstr, sizeof(outstr), format, tm) == 0 && errno != 0)
  96. {
  97. perror("strftime");
  98. exit(EXIT_FAILURE);
  99. }
  100. if(puts(outstr) < 0)
  101. {
  102. perror("puts");
  103. exit(EXIT_FAILURE);
  104. }
  105. return 0;
  106. }