#include "prjlibs-include/standards.h"
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <limits.h>

#include "skalibs/include/stddjb.h"
#include "prjlibs-include/constants.h"
#include "runwhen.h"

char const* PROG="maxinterval";

static char const var_delay[]="$DELAY";
static char const var_file[]="$MAXINTERVAL_FILE";
static char const var_max[]="$MAXINTERVAL";

int main(int argc, char** argv) {
  struct stat statbuf;
  char const* x;

  if (argc<2)
    strerr_die3x(111, usage, PROG, " program [arg ...]");

  x=env_get(var_file+1);
  if (x==null)
    strerr_die4x(111, PROG, ": ", var_file, err_notset);

  if (stat(x, &statbuf)!=0) {
    if (errno!=ENOENT)
      strerr_die5sys(errstat, PROG, err_unable, err_stat, x, ": ");
  } else {
    time_t const now=time(null);
    unsigned long delay;
    unsigned long max;

    {
      unsigned int len;

      x=env_get(var_max+1);
      if (x==null)
        strerr_die4x(111, PROG, ": ", var_max, err_notset);
      len=scan_ulong(x, &max);
      if (len==0 || x[len]!='\0')
        strerr_die4x(111, PROG, ": ", var_max, err_malformed);

      x=env_get(var_delay+1);
      if (x!=null) {
        len=scan_ulong(x, &delay);
        if (len==0 || x[len]!='\0')
          strerr_die4x(111, PROG, ": ", var_delay, err_malformed);
      }
    }

    if (statbuf.st_mtime<=now) {
      unsigned long const since=now-statbuf.st_mtime;
      if (since>=max) max=0;
      else max-=since;
    } else max+=(unsigned long)(statbuf.st_mtime-now);

    if (x==null || delay>max) delay=max;

    {
      char delaybuf[(sizeof delay*CHAR_BIT+2)/3+1];
      delaybuf[fmt_ulong(delaybuf, delay)]='\0';
      if (pathexec_env(var_delay+1, delaybuf)==0)
        strerr_die5sys(111, PROG, err_unable, err_setvar, var_delay, ": ");
    }
  }

  ++argv;
  pathexec((char const**)argv);
  strerr_die5sys(errstat, PROG, err_unable, err_exec, argv[0], ": ");
}


syntax highlighted by Code2HTML, v. 0.9.1