randomconfig fixes
[oweals/busybox.git] / miscutils / ts.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Copyright (C) 2019 Denys Vlasenko <vda.linux@googlemail.com>
4  * Licensed under GPLv2, see file LICENSE in this source tree.
5  */
6 //config:config TS
7 //config:       bool "ts (450 bytes)"
8 //config:       default y
9
10 //applet:IF_TS(APPLET(ts, BB_DIR_USR_BIN, BB_SUID_DROP))
11
12 //kbuild:lib-$(CONFIG_TS) += ts.o
13
14 //usage:#define ts_trivial_usage
15 //usage:       "[-is] [STRFTIME]"
16 //usage:#define ts_full_usage ""
17
18 #include "libbb.h"
19 #include "common_bufsiz.h"
20
21 int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
22 int ts_main(int argc UNUSED_PARAM, char **argv)
23 {
24         struct timeval base;
25         unsigned opt;
26         char *frac;
27         char *fmt_dt2str;
28         char *line;
29
30         opt = getopt32(argv, "^" "is" "\0" "?1" /*max one arg*/);
31         if (opt) {
32                 putenv((char*)"TZ=UTC0");
33                 tzset();
34         }
35         /*argc -= optind;*/
36         argv += optind;
37         fmt_dt2str = argv[0] ? argv[0]
38                 : (char*)(opt ? "%b %d %H:%M:%S"+6 : "%b %d %H:%M:%S");
39         frac = is_suffixed_with(fmt_dt2str, "%.S");
40         if (!frac)
41                 frac = is_suffixed_with(fmt_dt2str, "%.s");
42         if (frac) {
43                 frac++;
44                 frac[0] = frac[1];
45                 frac[1] = '\0';
46         }
47
48 #define date_buf bb_common_bufsiz1
49         setup_common_bufsiz();
50         gettimeofday(&base, NULL);
51
52         while ((line = xmalloc_fgets(stdin)) != NULL) {
53                 struct timeval ts;
54                 struct tm tm_time;
55
56                 gettimeofday(&ts, NULL);
57                 if (opt) {
58                         /* -i and/or -s */
59                         struct timeval ts1 = ts1;
60                         if (opt & 1) /* -i */
61                                 ts1 = ts;
62 //printf("%d %d\n", ts.tv_sec, base.tv_sec);
63                         ts.tv_sec -= base.tv_sec;
64 //printf("%d %d\n", ts.tv_sec, base.tv_sec);
65                         ts.tv_usec -= base.tv_usec;
66                         if ((int32_t)(ts.tv_usec) < 0) {
67                                 ts.tv_sec--;
68                                 ts.tv_usec += 1000*1000;
69                         }
70                         if (opt & 1) /* -i */
71                                 base = ts1;
72                 }
73                 localtime_r(&ts.tv_sec, &tm_time);
74                 strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time);
75                 if (!frac) {
76                         printf("%s %s", date_buf, line);
77                 } else {
78                         printf("%s.%06u %s", date_buf, (unsigned)ts.tv_usec, line);
79                 }
80                 free(line);
81         }
82
83         return EXIT_SUCCESS;
84 }