nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }