1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#include "buffer.h"
#include "stralloc.h"
#include "exit.h"
#include "readwrite.h"
#include "open.h"
#include "scan.h"
#include "fmt.h"
#include "getln.h"
#include "qmail.h"
#define TAI64NLEN 24
/** @file tai64nfrac
@brief Read a TAI64N external format timestamp from stdin and
write fractional seconds since epoch (TAI, not UTC) to stdout.
Return the characters after the timestamp.
*/
char outbuf[BUFFER_SMALL];
buffer bo = BUFFER_INIT(write,1,outbuf,sizeof(outbuf));
static void outs(char *s)
{
if (buffer_puts(&bo,s) == -1) _exit(1);
if (buffer_flush(&bo) == -1) _exit(1);
}
static void outi(int i)
{
char num[FMT_ULONG];
if (buffer_put(&bo,num,fmt_ulong(num,(unsigned long) i)) == -1) _exit(1);
if (buffer_flush(&bo) == -1) _exit(1);
}
char inbuf[BUFSIZE_LINE];
buffer bi = BUFFER_INIT(read,0,inbuf,sizeof(inbuf));
int main(void)
{
int c;
int i;
int match;
unsigned long u;
unsigned long seconds;
unsigned long nanoseconds;
stralloc line = {0};
/* Read from stdin */
buffer_init(&bi,read,0,inbuf,sizeof(inbuf));
for (;;) {
if (getln(&bi,&line,&match,'\n') != 0) _exit(1);
if (!match) break;
if (!stralloc_0(&line)) _exit(1);
seconds = 0;
nanoseconds = 0;
if (line.s[0] == '@') { /* tai64 timestamp */
for (i = 1; i <= TAI64NLEN; i++) {
c = (int)line.s[i];
u = c - '0';
if (u >= 10) {
u = c - 'a';
if (u >= 6) break;
u += 10;
}
seconds <<= 4;
seconds += nanoseconds >> 28;
nanoseconds &= 0xfffffff;
nanoseconds <<= 4;
nanoseconds += u;
}
seconds -= 4611686018427387914ULL;
seconds = seconds > 0 ? seconds : 0;
outi(seconds); outs("."); outi(nanoseconds); outs(line.s + i); outs("\n");
} else {
outs("tai64nfrac: fatal: Wrong TAI64N input format."); outs("\n");
_exit(1);
}
}
_exit(0);
}
|