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