summaryrefslogtreecommitdiff
path: root/net-mail/qmailanalog/files/tai64nfrac.c
blob: 28e6cdbb87541503f293506a1aac7631cc2fcadf (plain)
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
/*
   Convert external TAI64N timestamps to fractional seconds since epoch.

   Written by Russ Allbery <rra@stanford.edu>
   This work is in the public domain.

Usage:

tai64nfrac < input > output

Expects the input stream to be a sequence of lines beginning with @, a
timestamp in external TAI64N format, and a space.  Replaces the @ and the
timestamp with fractional seconds since epoch (1970-01-01 00:00:00 UTC).
The input time format is the format written by tai64n and multilog.  The
output time format is expected by qmailanalog. */

#include <stdio.h>

/* Read a TAI64N external format timestamp from stdin and write fractional
   seconds since epoch (TAI, not UTC) to stdout.  Return the character after
   the timestamp. */
int decode(void)
{
    int c;
    unsigned long u;
    unsigned long seconds = 0;
    unsigned long nanoseconds = 0;

    while ((c = getchar()) != EOF) 
    {
	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;
    printf("%lu.%lu ", seconds, nanoseconds);
    return c;
}


int main(void)
{
    int c;
    unsigned long seconds;
    unsigned long nanoseconds;

    while ((c = getchar()) != EOF)
    {
	if (c == '@') c = decode();
	while (c != EOF) 
	{
	    putchar(c);
	    if (c == '\n') break;
	    c = getchar();
	}
    }
}