diff --new-file -u orig/Makefile ./Makefile
--- orig/Makefile	Mon Mar  6 00:21:09 2000
+++ ./Makefile	Fri Dec 29 09:26:23 2000
@@ -254,6 +254,15 @@
 compile lock_exnb.c hasflock.h lock.h
 	./compile lock_exnb.c
 
+logselect.o: \
+compile logselect.c byte.h open.h error.h direntry.h stralloc.h \
+gen_alloc.h openreadclose.h stralloc.h strerr.h pathexec.h sorted.h
+	./compile logselect.c
+
+logselect: \
+load logselect.o sorted.o unix.a byte.a time.a
+	./load logselect sorted.o unix.a byte.a time.a
+
 makelib: \
 warn-auto.sh systype
 	( cat warn-auto.sh; \
@@ -336,7 +345,8 @@
 
 prog: \
 svscan supervise svc svok svstat fghack multilog tai64n tai64nlocal \
-softlimit setuidgid envuidgid envdir setlock rts matchtest
+sortedtest \
+softlimit setuidgid envuidgid envdir setlock rts matchtest logselect
 
 prot.o: \
 compile prot.c hasshsgr.h prot.h
@@ -407,6 +417,18 @@
 compile softlimit.c pathexec.h sgetopt.h subgetopt.h strerr.h scan.h \
 str.h
 	./compile softlimit.c
+
+sorted.o: \
+compile sorted.c str.h
+	./compile sorted.c
+
+sortedtest: \
+load sortedtest.o sorted.o unix.a byte.a
+	./load sortedtest sorted.o unix.a byte.a 
+
+sortedtest.o: \
+compile sortedtest.c sorted.h buffer.h stralloc.h
+	./compile sortedtest.c
 
 str_chr.o: \
 compile str_chr.c str.h
diff --new-file -u orig/hier.c ./hier.c
--- orig/hier.c	Mon Mar  6 00:21:09 2000
+++ ./hier.c	Fri Jun 30 09:55:35 2000
@@ -12,6 +12,7 @@
   c(auto_home,"bin","svok",-1,-1,0755);
   c(auto_home,"bin","svstat",-1,-1,0755);
   c(auto_home,"bin","fghack",-1,-1,0755);
+  c(auto_home,"bin","logselect",-1,-1,0755);
   c(auto_home,"bin","multilog",-1,-1,0755);
   c(auto_home,"bin","tai64n",-1,-1,0755);
   c(auto_home,"bin","tai64nlocal",-1,-1,0755);
diff --new-file -u orig/logselect.c ./logselect.c
--- orig/logselect.c	Wed Dec 31 19:00:00 1969
+++ ./logselect.c	Fri Dec 29 09:24:11 2000
@@ -0,0 +1,207 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "byte.h"
+#include "open.h"
+#include "error.h"
+#include "direntry.h"
+#include "stralloc.h"
+#include "readwrite.h"
+#include "buffer.h"
+#include "sorted.h"
+#include "strerr.h"
+#include "pathexec.h"
+#include "taia.h"
+#include "timestamp.h"
+
+#define FATAL "logselect: fatal: "
+
+void die_usage(void)
+{
+  strerr_die1x(111,"logselect: usage: logselect dir start stop");
+}
+void die_dot(void)
+{
+  strerr_die2x(111,FATAL,"dir must not have '/' in it.");
+}
+void die_nofile(void)
+{
+  strerr_die2x(111,FATAL,"a timestamp file does not exist.");
+}
+void nomem(void)
+{
+  strerr_die2x(111,FATAL,"out of memory");
+}
+
+char inbuf[BUFFER_INSIZE];
+buffer ssin;
+
+int get(char *ch)
+{
+  int r;
+
+  r = buffer_GETC(&ssin,ch);
+  if (r == 1) return 1;
+  if (r == 0) return 0;
+  _exit(111);
+}
+
+static stralloc sa;
+static char starttime[TIMESTAMP];
+static char stoptime[TIMESTAMP];
+
+void out(char *buf,int len)
+{
+  if (buffer_put(buffer_1,buf,len) == -1)
+    _exit(111);
+    
+}
+
+do_file(char *dirname,char *fn)
+{
+  int fd;
+  char ch;
+  char tai64[25+1];
+  int i;
+  int r;
+
+  fd = open_read(fn);
+  if (fd == -1)
+    strerr_die6sys(111,FATAL,"unable to read ",dirname,"/",fn,": ");
+  buffer_init(&ssin,read,fd,inbuf,sizeof inbuf);
+
+  for (;;) {
+    r=get(&ch);
+    if (!r) break;
+    if (ch == '@') {
+      i = 0;
+      tai64[i++] = ch;
+      for(;;) {
+	r=get(&ch);
+	if (!r) break;
+	if (ch == '\n') break;
+        if (i >= 25) break;
+        tai64[i++] = ch;
+      }
+      if (i == 25) {
+	tai64[25] = '\0';
+	if (str_diff(tai64, starttime) < 0 || str_diff(tai64, stoptime) >= 0) {
+	  while(ch != '\n') {
+	    r=get(&ch);
+	    if (!r) break;
+	  }
+	  if (!r) break;
+	  continue;
+	}
+      }
+      out(tai64,i);
+    }
+    if (!r) break;
+    for (;;) {
+      out(&ch,1);
+      if (ch == '\n') break;
+      r=get(&ch);
+      if (!r) break;
+    }
+    if (!r) break;
+  }
+
+  close(fd);
+}
+
+static char hex[16] = "0123456789abcdef";
+
+void fmt_timestamp(struct taia *t, char s[TIMESTAMP])
+{
+  char nowpack[TAIA_PACK];
+  int i;
+
+  taia_pack(nowpack,t);
+
+  s[0] = '@';
+  for (i = 0;i < 12;++i) {
+    s[i * 2 + 1] = hex[(nowpack[i] >> 4) & 15];
+    s[i * 2 + 2] = hex[nowpack[i] & 15];
+  }
+}
+
+
+main(int argc,char **argv)
+{
+  char *dirname;
+  char *fn;
+  struct stat st;
+  struct taia t;
+  DIR *dir;
+  direntry *d;
+  int i, j;
+  sorted sl = {0};
+
+  if (!*argv++) die_usage();
+
+  if (!*argv) die_usage();
+  dirname = *argv++;
+  for(i=0; dirname[i]; i++)
+    if (dirname[i] == '/') die_dot();
+
+  if (*argv) fn= *argv++;
+  if (stat(fn, &st) == -1) die_nofile();
+  tai_unix(&t.sec,st.st_mtime);
+  t.nano = 0;
+  t.atto = 0;
+  fmt_timestamp(&t,starttime);
+
+  if (*argv) fn = *argv++;
+  if (stat(fn, &st) == -1) die_nofile();
+  tai_unix(&t.sec,st.st_mtime);
+  t.nano = 0;
+  t.atto = 0;
+  fmt_timestamp(&t,stoptime);
+
+  if (*argv) die_usage();
+
+  if (chdir(dirname) == -1)
+    strerr_die4sys(111,FATAL,"unable to switch to directory ",dirname,": ");
+
+  dir = opendir(".");
+  if (!dir)
+    strerr_die4sys(111,FATAL,"unable to read directory ",dirname,": ");
+  for (;;) {
+    errno = 0;
+    d = readdir(dir);
+    if (!d) {
+      if (errno)
+        strerr_die4sys(111,FATAL,"unable to read directory ",dirname,": ");
+      break;
+    }
+    if (d->d_name[0] == '@') {
+      if (!stralloc_copys(&sa, d->d_name)) nomem();
+      if (!stralloc_0(&sa)) nomem();
+      if (!sorted_insert(&sl, &sa)) nomem();
+    }
+  }
+  closedir(dir);
+
+  if (!stralloc_copys(&sa, "current")) nomem();
+  if (!stralloc_0(&sa)) nomem();
+  if (!sorted_insert(&sl, &sa)) nomem();
+
+  i = sl.len - 1;
+  for(;;) {
+    if (str_diff(sl.p[i].s, starttime) < 0) {
+      i++;
+      break;
+    }
+    if (i == 0) break;
+    i--;
+  }
+
+  for(;;) {
+    do_file(dirname, sl.p[i].s);
+    if (str_diff(sl.p[i].s, stoptime) > 0)
+      break;
+    i++;
+    if (i >= sl.len)
+      strerr_die2sys(100,FATAL,"examined too many files.");
+  }
+  buffer_flush(buffer_1);
+}
diff --new-file -u orig/sorted.c ./sorted.c
--- orig/sorted.c	Wed Dec 31 19:00:00 1969
+++ ./sorted.c	Tue Jun 27 18:10:49 2000
@@ -0,0 +1,37 @@
+#include "stralloc.h"
+#include "alloc.h"
+#include "gen_allocdefs.h"
+#include "sorted.h"
+
+GEN_ALLOC_readyplus(sorted,stralloc,p,len,a,i,n,x,100,sorted_readyplus)
+
+int sorted_insert(sl,sa)
+sorted *sl;
+stralloc *sa;
+{
+  int i;
+  int j;
+  int eq;
+  int len;
+  stralloc newsa;
+
+  if (!sorted_readyplus(sl,1)) return 0;
+  j = sl->len++;
+  newsa = sl->p[j];
+  while (j) {
+    i = (j - 1);
+    len = sa->len;
+    if (sl->p[i].len < len) len = sl->p[i].len;
+    eq = byte_diff(sl->p[i].s, len, sa->s);
+    if (eq < 0) break;
+    if (eq == 0)
+      if (sl->p[i].len < sa->len)
+	break;
+    sl->p[j] = sl->p[i];
+    j = i;
+  }
+  sl->p[j] = newsa;
+  stralloc_copyb(&sl->p[j],sa->s,sa->len);
+  return 1;
+}
+
diff --new-file -u orig/sorted.h ./sorted.h
--- orig/sorted.h	Wed Dec 31 19:00:00 1969
+++ ./sorted.h	Tue Jun 27 17:30:34 2000
@@ -0,0 +1,11 @@
+#ifndef SORTED_H
+#define SORTED_H
+
+#include "gen_alloc.h"
+#include "stralloc.h"
+
+GEN_ALLOC_typedef(sorted,stralloc,p,len,a)
+
+extern int sorted_insert();
+
+#endif
diff --new-file -u orig/sortedtest.c ./sortedtest.c
--- orig/sortedtest.c	Wed Dec 31 19:00:00 1969
+++ ./sortedtest.c	Tue Jun 27 17:48:40 2000
@@ -0,0 +1,26 @@
+#include "sorted.h"
+#include "buffer.h"
+#include "stralloc.h"
+
+static stralloc sa;
+
+main(int argc,char **argv)
+{
+  sorted sl = {0};
+  int i;
+
+  while (argv[1]) {
+    if (!stralloc_copys(&sa, argv[1])) _exit(2);
+    if (!sorted_insert(&sl, &sa)) _exit(3);
+    argv++;
+  }
+  i = 0;
+  while (i < sl.len) {
+    buffer_put(buffer_1,sl.p[i].s,sl.p[i].len);
+    buffer_puts(buffer_1," ");
+    i++;
+  }
+  buffer_puts(buffer_1,"\n");
+  buffer_flush(buffer_1);
+  _exit(0);
+}
diff --new-file -u orig/sortedtest.sh ./sortedtest.sh
--- orig/sortedtest.sh	Wed Dec 31 19:00:00 1969
+++ ./sortedtest.sh	Tue Jun 27 18:13:24 2000
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+./sortedtest a b c
+./sortedtest a c b
+./sortedtest b c a
+./sortedtest b a c
+./sortedtest c a b
+./sortedtest c b a
+./sortedtest a b b
+./sortedtest a bb b
+./sortedtest a b bb
+./sortedtest a bb ba
+./sortedtest a bb bc
+./sortedtest a ba bb
+./sortedtest a bc bb
+
