Index: /trunk/Ohana/src/opihi/include/convert.h
===================================================================
--- /trunk/Ohana/src/opihi/include/convert.h	(revision 4601)
+++ /trunk/Ohana/src/opihi/include/convert.h	(revision 4602)
@@ -26,4 +26,6 @@
 int           dms_format            PROTO((char *line, double value));
 int           hh_hm                 PROTO((double hh, int *hr, double *mn));
+int           day_to_sec            PROTO((char *string, time_t *second));
+int           hms_to_sec            PROTO((char *string, time_t *second));
 
 char         *meade_deg_to_str      PROTO((double deg));
Index: /trunk/Ohana/src/opihi/include/scheduler.h
===================================================================
--- /trunk/Ohana/src/opihi/include/scheduler.h	(revision 4601)
+++ /trunk/Ohana/src/opihi/include/scheduler.h	(revision 4602)
@@ -26,4 +26,6 @@
 } ControllerStat;
 
+enum {RANGE_ABS, RANGE_DAY, RANGE_WEEK};
+
 /* socket / pipe communication buffer */
 typedef struct {
@@ -34,4 +36,11 @@
   int   Nbuffer;
 } IOBuffer;
+
+typedef struct {
+  time_t start;
+  time_t stop;
+  char type;
+  char keep;
+} TimeRange;
 
 /* a task is a description of the wrapping of a job */
@@ -78,11 +87,4 @@
 // keep: FALSE: do not perform action within this time period
   
-typedef struct {
-  e_time start;
-  e_time stop;
-  char type;
-  char keep;
-} TimeRange;
-
 typedef struct {
   int JobID;				/* internal ID for job */
@@ -141,4 +143,5 @@
 int CheckTasks ();
 int CheckSystem ();
+int CheckTimeRanges (TimeRange *ranges, int Nranges);
 int GetJobOutput (char *channel, int pid, IOBuffer *buffer, int Nbytes);
 int CheckControllerJob (Job *job);
Index: /trunk/Ohana/src/opihi/lib.data/convert.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/convert.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/lib.data/convert.c	(revision 4602)
@@ -1,3 +1,8 @@
 # include "convert.h"
+# define _XOPEN_SOURCE /* glibc2 needs this */
+# include <time.h>
+
+char *strptime(const char *s, const char *format, struct tm *tm);
+
   
 int hh_hms (double hh, int *hr, int *mn, double *sc) {
@@ -160,4 +165,51 @@
 
   return (status);
+}
+
+/***** convert 00:00:00 or 00:00 to 0 - 86400 ****/
+int hms_to_sec (char *string, time_t *second) {
+  
+  char *p;
+  struct tm time;
+
+  p = strptime (string, "%H:%M:%S", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%H:%M", &time);
+  if (p != NULL) goto valid;
+
+  return (FALSE);
+    
+valid:
+  if (*p) return (FALSE);
+  *second = time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
+  return (TRUE);
+}
+
+/***** convert Mon[@00:00:00] or 00:00 to 0 - 86400*7 ****/
+int day_to_sec (char *string, time_t *second) {
+  
+  char *p;
+  struct tm time;
+
+  bzero (&time, sizeof(time));
+  p = strptime (string, "%A@%H:%M:%S", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A@%H:%M", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A@%H", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A", &time);
+  if (p != NULL) goto valid;
+
+  return (FALSE);
+
+valid:
+  if (*p) return (FALSE);
+  *second = time.tm_wday*86400 + time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
+  return (TRUE);
 }
 
Index: /trunk/Ohana/src/opihi/pantasks/CheckJobs.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/CheckJobs.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/CheckJobs.c	(revision 4602)
@@ -14,5 +14,5 @@
     /* check for timeout - only local jobs timeout here */
     if ((job[0].mode == JOB_LOCAL) && (GetTaskTimer(job[0].start) >= job[0].task[0].timeout_period)) {
-      fprintf (stderr, "timeout on %s\n", job[0].task[0].name);
+      if (VerboseMode()) fprintf (stderr, "timeout on %s\n", job[0].task[0].name);
       /* run task[0].timeout macro, if it exists */
       if (job[0].task[0].timeout != NULL) {
@@ -30,9 +30,9 @@
     switch (status) {
       case JOB_PENDING:
-	fprintf (stderr, "job %s (%d) pending\n", job[0].task[0].name, job[0].JobID);
+	if (VerboseMode()) fprintf (stderr, "job %s (%d) pending\n", job[0].task[0].name, job[0].JobID);
 	break;
 
       case JOB_BUSY:
-	fprintf (stderr, "job %s (%d) busy\n", job[0].task[0].name, job[0].JobID);
+	if (VerboseMode()) fprintf (stderr, "job %s (%d) busy\n", job[0].task[0].name, job[0].JobID);
 	break;
 
@@ -41,5 +41,5 @@
 	/* set the stdout and stderr variables with job.stdout, job.stderr */
 	/* XXX this will break on 0 values in output streams */
-	fprintf (stderr, "job %s (%d) crash\n", job[0].task[0].name, job[0].JobID);
+	if (VerboseMode()) fprintf (stderr, "job %s (%d) crash\n", job[0].task[0].name, job[0].JobID);
 	set_str_variable ("stdout", job[0].stdout.buffer);
 	set_str_variable ("stderr", job[0].stderr.buffer);
@@ -52,5 +52,5 @@
 
       case JOB_EXIT:
-	fprintf (stderr, "job %s (%d) exit\n", job[0].task[0].name, job[0].JobID);
+	if (VerboseMode()) fprintf (stderr, "job %s (%d) exit\n", job[0].task[0].name, job[0].JobID);
 	set_str_variable ("stdout", job[0].stdout.buffer);
 	set_str_variable ("stderr", job[0].stderr.buffer);
@@ -69,5 +69,5 @@
 
       default:
-	fprintf (stderr, "unknown exit status: %d\n", status);
+	if (VerboseMode()) fprintf (stderr, "unknown exit status: %d\n", status);
 	/** do something more useful here ?? **/
 	break;
Index: /trunk/Ohana/src/opihi/pantasks/CheckTasks.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/CheckTasks.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/CheckTasks.c	(revision 4602)
@@ -15,6 +15,8 @@
     if (GetTaskTimer(task[0].last) < task[0].exec_period) continue;
 
+    /* need to check if the current time is within valid/invalid periods */
+    if (!CheckTimeRanges (task[0].ranges, task[0].Nranges)) continue;
+
     SetCurrentTask (task[0].name);
-    fprintf (stderr, "trying task %s\n", task[0].name);
 
     /* ready to run? : run task.exec macro */
@@ -35,4 +37,5 @@
     /* reset timer on task (don't do this if Create/Submit fails)*/
     gettimeofday (&task[0].last, (void *) NULL);
+    task[0].Njobs ++;
   }
   return (TRUE);
Index: /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c	(revision 4602)
+++ /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c	(revision 4602)
@@ -0,0 +1,35 @@
+# include "scheduler.h"
+
+int CheckTimeRanges (TimeRange *ranges, int Nranges) {
+
+  int i, intime, valid;
+  time_t daytime, weektime, abstime;
+  struct timeval now;
+  struct tm Now;
+
+  gettimeofday (&now, NULL);
+  gmtime_r (&now.tv_sec, &Now);
+  daytime = Now.tm_sec + Now.tm_min*60 + Now.tm_hour*3600;
+  weektime = Now.tm_sec + Now.tm_min*60 + Now.tm_hour*3600 + Now.tm_wday*86400;
+  abstime = now.tv_sec;
+
+  valid = TRUE;
+  for (i = 0; (i < Nranges) && valid; i++) {
+    switch (ranges[i].type) {
+      case RANGE_ABS:
+	intime = (abstime >= ranges[i].start) && (abstime <= ranges[i].stop);
+	valid = ranges[i].keep ? intime : !intime;
+	break;
+      case RANGE_DAY:
+	intime = (daytime >= ranges[i].start) && (daytime <= ranges[i].stop);
+	valid = ranges[i].keep ? intime : !intime;
+	break;
+      case RANGE_WEEK:
+	intime = (weektime >= ranges[i].start) && (weektime <= ranges[i].stop);
+	valid = ranges[i].keep ? intime : !intime;
+	break;
+    }
+    if (!valid) return (FALSE);
+  }
+  return (valid);
+}  
Index: /trunk/Ohana/src/opihi/pantasks/ControllerOps.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/ControllerOps.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/ControllerOps.c	(revision 4602)
@@ -339,4 +339,6 @@
   int Nread;
 
+  if (!status) return (TRUE);
+
   /* read stdout buffer */
   Nread = ReadtoIOBuffer (&stdout_buffer, stdout_cntl);
Index: /trunk/Ohana/src/opihi/pantasks/LocalJob.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/LocalJob.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/LocalJob.c	(revision 4602)
@@ -15,5 +15,5 @@
   pid = fork ();
   if (!pid) { /* must be child process */
-    fprintf (stderr, "starting local job\n");
+    if (VerboseMode()) fprintf (stderr, "starting local job\n");
 
     /* close the other ends of the pipes */
Index: /trunk/Ohana/src/opihi/pantasks/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/Makefile	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/Makefile	(revision 4602)
@@ -31,4 +31,5 @@
 $(SDIR)/CheckSystem.$(ARCH).o \
 $(SDIR)/CheckTasks.$(ARCH).o \
+$(SDIR)/CheckTimeRanges.$(ARCH).o \
 $(SDIR)/ControllerOps.$(ARCH).o \
 $(SDIR)/LocalJob.$(ARCH).o \
@@ -44,4 +45,5 @@
 $(SDIR)/kill.$(ARCH).o \
 $(SDIR)/delete.$(ARCH).o \
+$(SDIR)/verbose.$(ARCH).o \
 $(SDIR)/controller.$(ARCH).o \
 $(SDIR)/controller_host.$(ARCH).o \
@@ -53,4 +55,5 @@
 $(SDIR)/task_host.$(ARCH).o \
 $(SDIR)/task_macros.$(ARCH).o \
+$(SDIR)/task_trange.$(ARCH).o \
 $(SDIR)/task_periods.$(ARCH).o
 
Index: /trunk/Ohana/src/opihi/pantasks/TaskOps.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/TaskOps.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/TaskOps.c	(revision 4602)
@@ -37,8 +37,14 @@
 void ListTasks () {
 
-  int i;
+  int i, valid;
 
   for (i = 0; i < Ntasks; i++) {
-    fprintf (stderr, "%-15s %20s\n", tasks[i].name, tasks[i].argv[0]);
+    valid = CheckTimeRanges (tasks[i].ranges, tasks[i].Nranges);
+    if (valid) {
+      fprintf (stderr, "+ ");
+    } else {
+      fprintf (stderr, "- ");
+    }
+    fprintf (stderr, "%-15s %4d %20s\n", tasks[i].name, tasks[i].Njobs, tasks[i].argv[0]);
   }
   return;
@@ -126,6 +132,10 @@
   tasks[Ntasks].timeout_period = 1.0;
 
+  tasks[Ntasks].Nranges = 0;
+  ALLOCATE (tasks[Ntasks].ranges, TimeRange, 1);
+
   /* init task timer (is reset by 'run') */  
   gettimeofday (&tasks[Ntasks].last, (void *) NULL);
+  tasks[Ntasks].Njobs = 0;
 
   Ntasks ++;
Index: /trunk/Ohana/src/opihi/pantasks/init.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/init.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/init.c	(revision 4602)
@@ -4,4 +4,5 @@
 int task	    PROTO((int, char **));
 int task_host	    PROTO((int, char **));
+int task_trange	    PROTO((int, char **));
 int task_macros	    PROTO((int, char **));
 int task_command    PROTO((int, char **));
@@ -12,4 +13,5 @@
 int kill_job        PROTO((int, char **));
 int delete_job      PROTO((int, char **));
+int verbose         PROTO((int, char **));
 
 static Command cmds[] = {  
@@ -17,4 +19,5 @@
   {"task",       task,         "define a schedulable task"},
   {"host",       task_host,    "define host machine for a task"},
+  {"trange",     task_trange,  "define valid/invalid time periods for a task"},
   {"task.exit",  task_macros,  "define exit macros for a task"},
   {"task.exec",  task_macros,  "define pre-exec macro for a task"},
@@ -26,4 +29,5 @@
   {"kill",       kill_job,     "kill job"},
   {"delete",     delete_job,   "delete job"},
+  {"verbose",    verbose,      "set/toggle verbose mode"},
 }; 
 
Index: /trunk/Ohana/src/opihi/pantasks/status.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/status.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/status.c	(revision 4602)
@@ -3,4 +3,9 @@
 int status_sys (int argc, char **argv) {
 
+  if (rl_event_hook == NULL) {
+    fprintf (stderr, "scheduler is stopped\n");
+  } else {
+    fprintf (stderr, "scheduler is running\n");
+  }
   ListTasks ();
   ListJobs ();
Index: /trunk/Ohana/src/opihi/pantasks/task.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/task.c	(revision 4601)
+++ /trunk/Ohana/src/opihi/pantasks/task.c	(revision 4602)
@@ -2,5 +2,5 @@
 # define prompt "> "
 
-enum {TASK_NONE, TASK_EMPTY, TASK_COMMENT, TASK_END, TASK_HOST, TASK_COMMAND, TASK_PERIODS, TASK_EXIT, TASK_EXEC};
+enum {TASK_NONE, TASK_EMPTY, TASK_COMMENT, TASK_NMAX, TASK_TRANGE, TASK_END, TASK_HOST, TASK_COMMAND, TASK_PERIODS, TASK_EXIT, TASK_EXEC};
 
 int task (int argc, char **argv) {
@@ -68,8 +68,12 @@
 
       case TASK_END:
+	/* I need to add in a test here to see if all task elements 
+	   have been defined.  delete the task if not */
 	free (input);
 	return (TRUE);
 	break;
 
+      case TASK_TRANGE:
+      case TASK_NMAX:
       case TASK_HOST:
       case TASK_EXIT:
@@ -104,4 +108,6 @@
   if (!strcasecmp (command, "END"))       hash = TASK_END;
   if (!strcasecmp (command, "HOST"))      hash = TASK_HOST;
+  if (!strcasecmp (command, "NMAX"))      hash = TASK_NMAX;
+  if (!strcasecmp (command, "TRANGE"))    hash = TASK_TRANGE;
   if (!strcasecmp (command, "COMMAND"))   hash = TASK_COMMAND;
   if (!strcasecmp (command, "PERIODS"))   hash = TASK_PERIODS;
Index: /trunk/Ohana/src/opihi/pantasks/task_trange.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/task_trange.c	(revision 4602)
+++ /trunk/Ohana/src/opihi/pantasks/task_trange.c	(revision 4602)
@@ -0,0 +1,71 @@
+# include "scheduler.h"
+
+int task_trange (int argc, char **argv) {
+
+  int N, RequiredHost;
+  Task *task;
+  TimeRange range;
+  char *taskname;
+
+  /* add a -reset option? 
+  if (N = get_argument (argc, argv, "-reset")) {
+    remove_argument (N, &argc, argv);
+  } */
+
+
+  /* keep = true means the time range defines a valid time range
+     keep = false means the time range defines an invalid range */
+  range.keep = TRUE;
+  if (N = get_argument (argc, argv, "-exclude")) {
+    remove_argument (N, &argc, argv);
+    range.keep = FALSE;
+  }
+
+  if (argc != 3) goto usage;
+
+  taskname = GetCurrentTask ();
+  if (taskname == NULL) {
+    fprintf (stderr, "ERROR: not defining or running a task\n");
+    return (FALSE);
+  }
+  task = FindTask (taskname);
+  if (task == NULL) {
+    fprintf (stderr, "ERROR: current task not found??\n");
+    return (FALSE);
+  }
+
+  /* test for Mon[@HH:MM:SS] - both must match */
+  if (day_to_sec (argv[1], &range.start)) {
+    if (!day_to_sec (argv[2], &range.stop)) goto usage;
+    range.type = RANGE_WEEK;
+    goto valid;
+  }
+
+  /* test for HH:MM:SS */
+  if (hms_to_sec (argv[1], &range.start)) {
+    if (!hms_to_sec (argv[2], &range.stop)) goto usage;
+    range.type = RANGE_DAY;
+    goto valid;
+  }
+
+  /* this test does not fail sufficiently robustly for invalid inputs */
+  /* test for YYYY/MM/DD - both must match */
+  if (str_to_time (argv[1], &range.start)) {
+    if (!str_to_time (argv[2], &range.stop)) goto usage;
+    range.type = RANGE_ABS;
+    goto valid;
+  }
+  goto usage;
+
+valid:
+  N = task[0].Nranges;
+  task[0].Nranges ++;
+  REALLOCATE (task[0].ranges, TimeRange, task[0].Nranges);
+  
+  task[0].ranges[N] = range;
+  return (TRUE);
+
+usage:
+  fprintf (stderr, "USAGE: trange start end\n");
+  return (FALSE);
+}
Index: /trunk/Ohana/src/opihi/pantasks/verbose.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/verbose.c	(revision 4602)
+++ /trunk/Ohana/src/opihi/pantasks/verbose.c	(revision 4602)
@@ -0,0 +1,37 @@
+# include "scheduler.h"
+
+static int VERBOSE = FALSE;
+
+int verbose (int argc, char **argv) {
+
+  if (argc == 1) {
+    if (VERBOSE) {
+      fprintf (stderr, "verbose mode ON\n");
+    } else {
+      fprintf (stderr, "verbose mode OFF\n");
+    }
+    return (TRUE);
+  }
+
+  if (argc == 2) {
+    if (!strcasecmp (argv[1], "ON")) {
+      VERBOSE = TRUE;
+      return (TRUE);
+    }
+    if (!strcasecmp (argv[1], "OFF")) {
+      VERBOSE = FALSE;
+      return (TRUE);
+    }
+    if (!strcasecmp (argv[1], "TOGGLE")) {
+      VERBOSE = ~VERBOSE;
+      return (TRUE);
+    }
+  }
+
+  fprintf (stderr, "USAGE: verbose (on/off/toggle)\n");
+  return (FALSE);
+}
+
+int VerboseMode () {
+  return (VERBOSE);
+}
Index: /trunk/Ohana/src/opihi/scripts/sched.pro
===================================================================
--- /trunk/Ohana/src/opihi/scripts/sched.pro	(revision 4601)
+++ /trunk/Ohana/src/opihi/scripts/sched.pro	(revision 4602)
@@ -3,14 +3,16 @@
 
 task test
-  command sched.test 
+  command date 
   periods -poll 1.0
-  periods -exec 2.0
-  periods -timeout 8.0
-  # host local
-  host localhost
+  periods -exec 5.0
+  periods -timeout 10.0
+  trange 07:09 07:10
+  trange -exclude 07:09:30 07:09:45
+  host local
+  # host localhost
   # local is default 
 
   task.exec
-    echo "starting job sched.test"
+    # echo "starting job sched.test"
   end
 
