#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="mininterval";

static char const var_delay[]="$DELAY";
static char const var_file[]="$MININTERVAL_FILE";
static char const var_min[]="$MININTERVAL";

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 min;
    unsigned int len;

    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);

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

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

      if (delay<min) delay=min;

      {
        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