blob: f2d36765422f4f6c232c2d1219fab73be23ee7b6 [file] [log] [blame]
Denys Vlasenko16df5e82019-03-26 11:02:31 +01001/* vi: set sw=4 ts=4: */
2/*
Denys Vlasenkof370a662019-03-26 11:12:15 +01003 * Copyright (C) 2019 Denys Vlasenko <vda.linux@googlemail.com>
4 * Licensed under GPLv2, see file LICENSE in this source tree.
Denys Vlasenko16df5e82019-03-26 11:02:31 +01005 */
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"
Denys Vlasenko16df5e82019-03-26 11:02:31 +010020
21int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denys Vlasenkof370a662019-03-26 11:12:15 +010022int ts_main(int argc UNUSED_PARAM, char **argv)
Denys Vlasenko16df5e82019-03-26 11:02:31 +010023{
Denys Vlasenko973698d2019-03-26 11:44:48 +010024 struct timeval base;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010025 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++;
Denys Vlasenko3395e2a2019-03-26 11:41:35 +010044 frac[0] = frac[1];
45 frac[1] = '\0';
Denys Vlasenko16df5e82019-03-26 11:02:31 +010046 }
47
48#define date_buf bb_common_bufsiz1
49 setup_common_bufsiz();
Denys Vlasenko973698d2019-03-26 11:44:48 +010050 gettimeofday(&base, NULL);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010051
52 while ((line = xmalloc_fgets(stdin)) != NULL) {
Denys Vlasenko973698d2019-03-26 11:44:48 +010053 struct timeval ts;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010054 struct tm tm_time;
55
Denys Vlasenko973698d2019-03-26 11:44:48 +010056 gettimeofday(&ts, NULL);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010057 if (opt) {
58 /* -i and/or -s */
Denys Vlasenko973698d2019-03-26 11:44:48 +010059 struct timeval ts1 = ts1;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010060 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);
Denys Vlasenko973698d2019-03-26 11:44:48 +010065 ts.tv_usec -= base.tv_usec;
66 if ((int32_t)(ts.tv_usec) < 0) {
Denys Vlasenko16df5e82019-03-26 11:02:31 +010067 ts.tv_sec--;
Denys Vlasenko973698d2019-03-26 11:44:48 +010068 ts.tv_usec += 1000*1000;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010069 }
70 if (opt & 1) /* -i */
71 base = ts1;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010072 }
Denys Vlasenkofe78c9a2019-03-26 11:51:21 +010073 localtime_r(&ts.tv_sec, &tm_time);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010074 strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time);
75 if (!frac) {
76 printf("%s %s", date_buf, line);
77 } else {
Denys Vlasenko973698d2019-03-26 11:44:48 +010078 printf("%s.%06u %s", date_buf, (unsigned)ts.tv_usec, line);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010079 }
80 free(line);
81 }
82
83 return EXIT_SUCCESS;
84}