Upstream qmail 1.01
[qmail] / predate.c
CommitLineData
2117e02e
MW
1#include <sys/types.h>
2#include <time.h>
3#include "datetime.h"
4#include "fork.h"
5#include "wait.h"
6#include "fd.h"
7#include "fmt.h"
8#include "substdio.h"
9#include "subfd.h"
10#include "readwrite.h"
11#include "exit.h"
12
13static char *montab[12] = {
14"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
15};
16
17char num[FMT_ULONG];
18char outbuf[1024];
19
20void main(argc,argv)
21int argc;
22char **argv;
23{
24 time_t now;
25 struct tm *tm;
26 struct datetime dt;
27 datetime_sec utc;
28 datetime_sec local;
29 int minutes;
30 int pi[2];
31 substdio ss;
32 int wstat;
33 int pid;
34
35 sig_pipeignore();
36
37 if (!argv[1]) {
38 substdio_putsflush(subfderr,"predate: usage: predate child\n");
39 _exit(100);
40 }
41
42 if (pipe(pi) == -1) {
43 substdio_putsflush(subfderr,"predate: fatal: unable to create pipe\n");
44 _exit(111);
45 }
46
47 switch(pid = fork()) {
48 case -1:
49 substdio_putsflush(subfderr,"predate: fatal: unable to fork\n");
50 _exit(111);
51 case 0:
52 close(pi[1]);
53 if (fd_move(0,pi[0]) == -1) {
54 substdio_putsflush(subfderr,"predate: fatal: unable to set up fds\n");
55 _exit(111);
56 }
57 sig_pipedefault();
58 execvp(argv[1],argv + 1);
59 substdio_putsflush(subfderr,"predate: fatal: unable to exec\n");
60 _exit(111);
61 }
62 close(pi[0]);
63 substdio_fdbuf(&ss,write,pi[1],outbuf,sizeof(outbuf));
64
65 time(&now);
66
67 tm = gmtime(&now);
68 dt.year = tm->tm_year;
69 dt.mon = tm->tm_mon;
70 dt.mday = tm->tm_mday;
71 dt.hour = tm->tm_hour;
72 dt.min = tm->tm_min;
73 dt.sec = tm->tm_sec;
74 utc = datetime_untai(&dt); /* utc == now, if gmtime ignores leap seconds */
75
76 tm = localtime(&now);
77 dt.year = tm->tm_year;
78 dt.mon = tm->tm_mon;
79 dt.mday = tm->tm_mday;
80 dt.hour = tm->tm_hour;
81 dt.min = tm->tm_min;
82 dt.sec = tm->tm_sec;
83 local = datetime_untai(&dt);
84
85 substdio_puts(&ss,"Date: ");
86 substdio_put(&ss,num,fmt_uint(num,dt.mday));
87 substdio_puts(&ss," ");
88 substdio_puts(&ss,montab[dt.mon]);
89 substdio_puts(&ss," ");
90 substdio_put(&ss,num,fmt_uint(num,dt.year + 1900));
91 substdio_puts(&ss," ");
92 substdio_put(&ss,num,fmt_uint0(num,dt.hour,2));
93 substdio_puts(&ss,":");
94 substdio_put(&ss,num,fmt_uint0(num,dt.min,2));
95 substdio_puts(&ss,":");
96 substdio_put(&ss,num,fmt_uint0(num,dt.sec,2));
97
98 if (local < utc) {
99 minutes = (utc - local + 30) / 60;
100 substdio_puts(&ss," -");
101 substdio_put(&ss,num,fmt_uint0(num,minutes / 60,2));
102 substdio_put(&ss,num,fmt_uint0(num,minutes % 60,2));
103 }
104 else {
105 minutes = (local - utc + 30) / 60;
106 substdio_puts(&ss," +");
107 substdio_put(&ss,num,fmt_uint0(num,minutes / 60,2));
108 substdio_put(&ss,num,fmt_uint0(num,minutes % 60,2));
109 }
110
111 substdio_puts(&ss,"\n");
112 substdio_copy(&ss,subfdin);
113 substdio_flush(&ss);
114 close(pi[1]);
115
116 if (wait_pid(&wstat,pid) == -1) {
117 substdio_putsflush(subfderr,"predate: fatal: wait failed\n");
118 _exit(111);
119 }
120 if (wait_crashed(wstat)) {
121 substdio_putsflush(subfderr,"predate: fatal: child crashed\n");
122 _exit(111);
123 }
124 _exit(wait_exitcode(wstat));
125}