Imported queue-fix-1.4 default tip
authortomas@localhost
Thu, 01 Nov 2007 14:46:11 +0100
changeset 0 c045670f36e9
Imported queue-fix-1.4
CHANGES
Makefile
README
TARGETS
alloc.c
alloc.h
alloc_re.c
byte.h
byte_chr.c
byte_copy.c
byte_cr.c
byte_diff.c
byte_rchr.c
byte_zero.c
conf-cc
conf-ld
direntry.h
direntry.h1
direntry.h2
error.c
error.h
error_str.c
error_temp.c
fifo.c
fifo.h
find-systype.sh
fmt.h
fmt_str.c
fmt_strn.c
fmt_uint.c
fmt_uint0.c
fmt_ulong.c
gen_alloc.h
gen_allocdefs.h
getln.c
getln.h
getln2.c
make-compile.sh
make-load.sh
make-makelib.sh
open.h
open_append.c
open_excl.c
open_read.c
open_trunc.c
open_write.c
queue-fix.c
readwrite.h
scan.h
scan_8long.c
scan_ulong.c
str.h
str_chr.c
str_cpy.c
str_diff.c
str_diffn.c
str_len.c
str_rchr.c
str_start.c
stralloc.h
stralloc_arts.c
stralloc_cat.c
stralloc_catb.c
stralloc_cats.c
stralloc_copy.c
stralloc_eady.c
stralloc_opyb.c
stralloc_opys.c
stralloc_pend.c
subfd.h
subfderr.c
subfdin.c
subfdins.c
subfdout.c
subfdouts.c
substdi.c
substdio.c
substdio.h
substdio_copy.c
substdo.c
trycpp.c
trydrent.c
trymkffo.c
warn-auto.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGES	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,24 @@
+1.4 (19990314)
+===
+Checks for the existence of clashing filenames before it tries
+to rename a file.  This will resolve cyclic inode filenames.
+Thanks Harald Hanche-Olsen.
+
+1.3 (19981011)
+===
+Checks for stray files in todo,intd,info,local,remote, and bounce.
+-N command-line option to see all actions before they are done.
+Updated README.
+
+1.2 (19980602)
+===
+Improperly handled todo, intd, and bounce
+
+1.1 (19980529)
+===
+Did not rehash files into the correct split directory.
+Interactive mode did not ask before renaming files.
+
+1.0 (19980516)
+===
+First release.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,368 @@
+# Don't edit Makefile! Use conf-* for configuration.
+
+SHELL=/bin/sh
+
+default: it
+
+
+############### Begin compile-time work
+
+clean: \
+TARGETS
+	rm -f `cat TARGETS`
+
+load: \
+make-load warn-auto.sh systype
+	( cat warn-auto.sh; ./make-load "`cat systype`" ) > load
+	chmod 755 load
+
+make-load: \
+make-load.sh auto-ccld.sh
+	cat auto-ccld.sh make-load.sh > make-load
+	chmod 755 make-load
+
+make-makelib: \
+make-makelib.sh auto-ccld.sh
+	cat auto-ccld.sh make-makelib.sh > make-makelib
+	chmod 755 make-makelib
+
+makelib: \
+make-makelib warn-auto.sh systype
+	( cat warn-auto.sh; ./make-makelib "`cat systype`" ) > \
+	makelib
+	chmod 755 makelib
+
+auto-ccld.sh: \
+conf-cc conf-ld warn-auto.sh
+	( cat warn-auto.sh; \
+	echo CC=\'`head -1 conf-cc`\'; \
+	echo LD=\'`head -1 conf-ld`\' \
+	) > auto-ccld.sh
+
+make-compile: \
+make-compile.sh auto-ccld.sh
+	cat auto-ccld.sh make-compile.sh > make-compile
+	chmod 755 make-compile
+
+direntry.h: \
+compile trydrent.c direntry.h1 direntry.h2
+	( ./compile trydrent.c >/dev/null 2>&1 \
+	&& cat direntry.h2 || cat direntry.h1 ) > direntry.h
+	rm -f trydrent.o
+
+compile: \
+make-compile warn-auto.sh systype
+	( cat warn-auto.sh; ./make-compile "`cat systype`" ) > \
+	compile
+	chmod 755 compile
+
+find-systype: \
+find-systype.sh auto-ccld.sh
+	cat auto-ccld.sh find-systype.sh > find-systype
+	chmod 755 find-systype
+
+hasmkffo.h: \
+trymkffo.c compile load
+	( ( ./compile trymkffo.c && ./load trymkffo ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASMKFIFO 1 || exit 0 ) > hasmkffo.h
+	rm -f trymkffo.o trymkffo
+
+systype: \
+find-systype trycpp.c
+	./find-systype > systype
+
+############### Begin alloc
+
+alloc.a: \
+makelib alloc.o alloc_re.o
+	./makelib alloc.a alloc.o alloc_re.o
+
+alloc.o: \
+compile alloc.c alloc.h error.h
+	./compile alloc.c
+
+alloc_re.o: \
+compile alloc_re.c alloc.h byte.h
+	./compile alloc_re.c
+
+############### Begin str
+
+byte_chr.o: \
+compile byte_chr.c byte.h
+	./compile byte_chr.c
+
+byte_copy.o: \
+compile byte_copy.c byte.h
+	./compile byte_copy.c
+
+byte_cr.o: \
+compile byte_cr.c byte.h
+	./compile byte_cr.c
+
+byte_diff.o: \
+compile byte_diff.c byte.h
+	./compile byte_diff.c
+
+byte_rchr.o: \
+compile byte_rchr.c byte.h
+	./compile byte_rchr.c
+
+byte_zero.o: \
+compile byte_zero.c byte.h
+	./compile byte_zero.c
+
+str_chr.o: \
+compile str_chr.c str.h
+	./compile str_chr.c
+
+str_cpy.o: \
+compile str_cpy.c str.h
+	./compile str_cpy.c
+
+str_diff.o: \
+compile str_diff.c str.h
+	./compile str_diff.c
+
+str_diffn.o: \
+compile str_diffn.c str.h
+	./compile str_diffn.c
+
+str_len.o: \
+compile str_len.c str.h
+	./compile str_len.c
+
+str_rchr.o: \
+compile str_rchr.c str.h
+	./compile str_rchr.c
+
+str_start.o: \
+compile str_start.c str.h
+	./compile str_start.c
+
+str.a: \
+makelib str_len.o str_diff.o str_diffn.o str_cpy.o str_chr.o \
+str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o \
+byte_cr.o byte_zero.o
+	./makelib str.a str_len.o str_diff.o str_diffn.o str_cpy.o \
+	str_chr.o str_rchr.o str_start.o byte_chr.o byte_rchr.o \
+	byte_diff.o byte_copy.o byte_cr.o byte_zero.o
+
+############### Begin error
+
+error.a: \
+makelib error.o error_str.o error_temp.o
+	./makelib error.a error.o error_str.o error_temp.o
+
+error.o: \
+compile error.c error.h
+	./compile error.c
+
+error_str.o: \
+compile error_str.c error.h
+	./compile error_str.c
+
+error_temp.o: \
+compile error_temp.c error.h
+	./compile error_temp.c
+
+############### Begin fifo
+
+fifo.o: \
+compile fifo.c hasmkffo.h fifo.h
+	./compile fifo.c
+
+############### Begin fs
+
+fmt_str.o: \
+compile fmt_str.c fmt.h
+	./compile fmt_str.c
+
+fmt_strn.o: \
+compile fmt_strn.c fmt.h
+	./compile fmt_strn.c
+
+fmt_uint.o: \
+compile fmt_uint.c fmt.h
+	./compile fmt_uint.c
+
+fmt_uint0.o: \
+compile fmt_uint0.c fmt.h
+	./compile fmt_uint0.c
+
+fmt_ulong.o: \
+compile fmt_ulong.c fmt.h
+	./compile fmt_ulong.c
+
+fmtqfn.o: \
+compile fmtqfn.c fmtqfn.h fmt.h auto_split.h
+	./compile fmtqfn.c
+
+scan_8long.o: \
+compile scan_8long.c scan.h
+	./compile scan_8long.c
+
+scan_ulong.o: \
+compile scan_ulong.c scan.h
+	./compile scan_ulong.c
+
+fs.a: \
+makelib fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o fmt_ulong.o \
+scan_ulong.o scan_8long.o
+	./makelib fs.a fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o \
+	fmt_ulong.o scan_ulong.o scan_8long.o
+
+############### Begin getln
+
+getln.a: \
+makelib getln.o getln2.o
+	./makelib getln.a getln.o getln2.o
+
+getln.o: \
+compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h
+	./compile getln.c
+
+getln2.o: \
+compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h
+	./compile getln2.c
+
+it: \
+queue-fix
+
+############### Begin open
+
+open.a: \
+makelib open_append.o open_excl.o open_read.o open_trunc.o \
+open_write.o
+	./makelib open.a open_append.o open_excl.o open_read.o \
+	open_trunc.o open_write.o
+
+open_append.o: \
+compile open_append.c open.h
+	./compile open_append.c
+
+open_excl.o: \
+compile open_excl.c open.h
+	./compile open_excl.c
+
+open_read.o: \
+compile open_read.c open.h
+	./compile open_read.c
+
+open_trunc.o: \
+compile open_trunc.c open.h
+	./compile open_trunc.c
+
+open_write.o: \
+compile open_write.c open.h
+	./compile open_write.c
+
+############### Begin stralloc
+
+stralloc.a: \
+makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \
+stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \
+stralloc_catb.o stralloc_arts.o
+	./makelib stralloc.a stralloc_eady.o stralloc_pend.o \
+	stralloc_copy.o stralloc_opys.o stralloc_opyb.o \
+	stralloc_cat.o stralloc_cats.o stralloc_catb.o \
+	stralloc_arts.o
+
+stralloc_arts.o: \
+compile stralloc_arts.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_arts.c
+
+stralloc_cat.o: \
+compile stralloc_cat.c byte.h stralloc.h gen_alloc.h
+	./compile stralloc_cat.c
+
+stralloc_catb.o: \
+compile stralloc_catb.c stralloc.h gen_alloc.h byte.h
+	./compile stralloc_catb.c
+
+stralloc_cats.o: \
+compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_cats.c
+
+stralloc_copy.o: \
+compile stralloc_copy.c byte.h stralloc.h gen_alloc.h
+	./compile stralloc_copy.c
+
+stralloc_eady.o: \
+compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+	./compile stralloc_eady.c
+
+stralloc_opyb.o: \
+compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h
+	./compile stralloc_opyb.c
+
+stralloc_opys.o: \
+compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_opys.c
+
+stralloc_pend.o: \
+compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+	./compile stralloc_pend.c
+
+############### Begin substdio
+
+subfderr.o: \
+compile subfderr.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfderr.c
+
+subfdin.o: \
+compile subfdin.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdin.c
+
+subfdins.o: \
+compile subfdins.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdins.c
+
+subfdout.o: \
+compile subfdout.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdout.c
+
+subfdouts.o: \
+compile subfdouts.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdouts.c
+
+subgetopt.o: \
+compile subgetopt.c subgetopt.h
+	./compile subgetopt.c
+
+substdi.o: \
+compile substdi.c substdio.h byte.h error.h
+	./compile substdi.c
+
+substdio.a: \
+makelib substdio.o substdi.o substdo.o subfderr.o subfdout.o \
+subfdouts.o subfdin.o subfdins.o substdio_copy.o
+	./makelib substdio.a substdio.o substdi.o substdo.o \
+	subfderr.o subfdout.o subfdouts.o subfdin.o subfdins.o \
+	substdio_copy.o
+
+substdio.o: \
+compile substdio.c substdio.h
+	./compile substdio.c
+
+substdio_copy.o: \
+compile substdio_copy.c substdio.h
+	./compile substdio_copy.c
+
+substdo.o: \
+compile substdo.c substdio.h str.h byte.h error.h
+	./compile substdo.c
+
+############### Begin queue-fix
+
+queue-fix: \
+load queue-fix.o fifo.o fs.a stralloc.a getln.a open.a error.a \
+substdio.a alloc.a str.a
+	./load queue-fix fifo.o fs.a stralloc.a getln.a open.a error.a \
+	substdio.a alloc.a str.a
+
+queue-fix.o: \
+compile queue-fix.c direntry.h hasmkffo.h
+	./compile queue-fix.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,105 @@
+queue-fix 1.4
+19990314
+Copyright 1999
+Eric Huss
+e-huss@netmeridian.com
+
+This is a small utility for checking and repairing the qmail queue
+structure.  It will fix uid/gid settings and permissions.  It will
+rename the message files to match their inodes.  It will even create
+directories and files that don't exist that should be there (you can
+even create a queue from scratch).  It will also print warnings for
+any files it finds that should not exist.
+
+Compiling:
+1) Extract the tar file.
+2) Edit conf-cc and conf-ld for your compiler.
+3) If you changed conf-split when you compiled qmail, edit queue-fix.c
+and change SPLIT_NUM to this value.
+4) Type make.
+
+This will produce the "queue-fix" executable.
+
+How to use:
+	queue-fix [-i | -N] queue_directory
+
+Use the -i option to go into interactive mode.  In interactive mode,
+it will prompt for confirmation before it begins a task.
+Alternatively, you may use the -N option to go into test mode.
+In test mode, queue-fix will print to standard output all the actions
+queue-fix would normally do, but does not actually call them.
+queue_directory is the location of the queue to fix.
+
+For your safety, you should always make a backup of your queue before
+running queue-fix.
+
+Examples:
+
+1) Moving your queue.
+     a) Shut down qmail-send.  Wait for exiting to show up in the log.
+        Shut down qmail-smptd:
+             - if inetd, comment out of /etc/inetd.conf and send inetd
+               a HUP.
+             - if supervise, use svc -d to bring it down
+        Shut down any processes which may run qmail-queue.  This includes,
+        but is not limited to qmqpd, pop, imapd, etc.
+     b) Choose the location for the new home of your queue.  In this
+        example:  originally in /var/qmail/queue
+                  moving to /other/qmail/queue
+     c) cd /var/qmail
+     d) mv queue /other/qmail
+     e) queue-fix -i /other/qmail/queue
+     f) Run queue-fix again just to make sure it worked.  If it prints
+        anything other than finished, then something is seriously
+        wrong.
+     g) Either make a link to the new queue location, or recompile
+        qmail with the new queue location.
+     h) Restart qmail and test it.
+
+2) Reconstructing the file system.
+     a) Shut down qmail-send.  Wait for exiting to show up in the log.
+        Shut down qmail-smptd:
+             - if inetd, comment out of /etc/inetd.conf and send inetd
+               a HUP.
+             - if supervise, use svc -d to bring it down
+        Shut down any processes which may run qmail-queue.  This includes,
+        but is not limited to qmqpd, pop, imapd, etc.
+     b) Do whatever file system changes that you need to do.
+     c) queue-fix -i /var/qmail/queue
+     d) Run queue-fix again just to make sure it worked.  If it prints
+        anything other than finished, then something is seriously
+        wrong.
+     e) Restart qmail and test it.
+
+Extra Safety:
+
+You must ensure that no other program modifies the queue while queue-fix
+is running.  If you are unsure whether or not something will try to use
+the queue, type:
+
+     chmod 0 /var/qmail/bin/qmail-queue
+
+before running queue-fix.  This will assume that MUA's and other applications
+that inject mail will recognize the failure to run qmail-queue.
+Once you are done, type:
+
+     chmod 4711 /var/qmail/bin/qmail-queue
+
+to get it going again.
+
+Known faults:
+
+- The error messages are not very descriptive of the problem.
+- Responding "no" during interactive mode results in a confusing
+  error message.
+- queue-fix checks for special files to exist in the queue, but does
+  not check their type (for example, a regular file existing where
+  there should be a named pipe).
+
+Epilogue:
+
+If you have problems, please let me know.  I make no guarantees about
+the quality of this program.
+
+This utility as an experiment uses the libraries written by D. J.
+Bernstein.  Thanks!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TARGETS	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,70 @@
+alloc.o
+alloc_re.o
+byte_chr.o
+byte_copy.o
+byte_cr.o
+byte_diff.o
+byte_rchr.o
+byte_zero.o
+error.o
+error_str.o
+error_temp.o
+fifo.o
+fmt_str.o
+fmt_strn.o
+fmt_uint.o
+fmt_uint0.o
+fmt_ulong.o
+getln.o
+getln2.o
+open_append.o
+open_excl.o
+open_read.o
+open_trunc.o
+open_write.o
+queue-fix.o
+scan_8long.o
+scan_ulong.o
+str_chr.o
+str_cpy.o
+str_diff.o
+str_diffn.o
+str_len.o
+str_rchr.o
+str_start.o
+stralloc_arts.o
+stralloc_cat.o
+stralloc_catb.o
+stralloc_cats.o
+stralloc_copy.o
+stralloc_eady.o
+stralloc_opyb.o
+stralloc_opys.o
+stralloc_pend.o
+subfderr.o
+subfdin.o
+subfdins.o
+subfdout.o
+subfdouts.o
+substdi.o
+substdio.o
+substdio_copy.o
+substdo.o
+alloc.a
+error.a
+fs.a
+getln.a
+open.a
+str.a
+stralloc.a
+substdio.a
+auto-ccld.sh
+find-systype
+systype
+load
+compile
+make-compile
+make-makelib
+make-load
+direntry.h
+hasmkffo.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alloc.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,32 @@
+#include "alloc.h"
+#include "error.h"
+extern char *malloc();
+extern void free();
+
+#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
+#define SPACE 4096 /* must be multiple of ALIGNMENT */
+
+typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
+static aligned realspace[SPACE / ALIGNMENT];
+#define space ((char *) realspace)
+static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
+
+/*@null@*//*@out@*/char *alloc(n)
+unsigned int n;
+{
+  char *x;
+  n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
+  if (n <= avail) { avail -= n; return space + avail; }
+  x = malloc(n);
+  if (!x) errno = error_nomem;
+  return x;
+}
+
+void alloc_free(x)
+char *x;
+{
+  if (x >= space)
+    if (x < space + SPACE)
+      return; /* XXX: assuming that pointers are flat */
+  free(x);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alloc.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,8 @@
+#ifndef ALLOC_H
+#define ALLOC_H
+
+extern /*@null@*//*@out@*/char *alloc();
+extern void alloc_free();
+extern int alloc_re();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alloc_re.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,17 @@
+#include "alloc.h"
+#include "byte.h"
+
+int alloc_re(x,m,n)
+char **x;
+unsigned int m;
+unsigned int n;
+{
+  char *y;
+ 
+  y = alloc(n);
+  if (!y) return 0;
+  byte_copy(y,m,*x);
+  alloc_free(*x);
+  *x = y;
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,13 @@
+#ifndef BYTE_H
+#define BYTE_H
+
+extern unsigned int byte_chr();
+extern unsigned int byte_rchr();
+extern void byte_copy();
+extern void byte_copyr();
+extern int byte_diff();
+extern void byte_zero();
+
+#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_chr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,20 @@
+#include "byte.h"
+
+unsigned int byte_chr(s,n,c)
+char *s;
+register unsigned int n;
+int c;
+{
+  register char ch;
+  register char *t;
+
+  ch = c;
+  t = s;
+  for (;;) {
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+  }
+  return t - s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_copy.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,14 @@
+#include "byte.h"
+
+void byte_copy(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+  for (;;) {
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_cr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,16 @@
+#include "byte.h"
+
+void byte_copyr(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+  to += n;
+  from += n;
+  for (;;) {
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_diff.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,16 @@
+#include "byte.h"
+
+int byte_diff(s,n,t)
+register char *s;
+register unsigned int n;
+register char *t;
+{
+  for (;;) {
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+  }
+  return ((int)(unsigned int)(unsigned char) *s)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_rchr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,23 @@
+#include "byte.h"
+
+unsigned int byte_rchr(s,n,c)
+char *s;
+register unsigned int n;
+int c;
+{
+  register char ch;
+  register char *t;
+  register char *u;
+
+  ch = c;
+  t = s;
+  u = 0;
+  for (;;) {
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+  }
+  if (!u) u = t;
+  return u - s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/byte_zero.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,13 @@
+#include "byte.h"
+
+void byte_zero(s,n)
+char *s;
+register unsigned int n;
+{
+  for (;;) {
+    if (!n) break; *s++ = 0; --n;
+    if (!n) break; *s++ = 0; --n;
+    if (!n) break; *s++ = 0; --n;
+    if (!n) break; *s++ = 0; --n;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/conf-cc	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,3 @@
+gcc -O2
+
+This will be used to compile .c files.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/conf-ld	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,3 @@
+gcc -s
+
+This will be used to link .o files into an executable.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/direntry.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,8 @@
+#ifndef DIRENTRY_H
+#define DIRENTRY_H
+
+#include <sys/types.h>
+#include <dirent.h>
+#define direntry struct dirent
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/direntry.h1	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,8 @@
+#ifndef DIRENTRY_H
+#define DIRENTRY_H
+
+#include <sys/types.h>
+#include <sys/dir.h>
+#define direntry struct direct
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/direntry.h2	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,8 @@
+#ifndef DIRENTRY_H
+#define DIRENTRY_H
+
+#include <sys/types.h>
+#include <dirent.h>
+#define direntry struct dirent
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,95 @@
+#include <errno.h>
+#include "error.h"
+
+/* warning: as coverage improves here, should update error_{str,temp} */
+
+int error_intr =
+#ifdef EINTR
+EINTR;
+#else
+-1;
+#endif
+
+int error_nomem =
+#ifdef ENOMEM
+ENOMEM;
+#else
+-2;
+#endif
+
+int error_noent = 
+#ifdef ENOENT
+ENOENT;
+#else
+-3;
+#endif
+
+int error_txtbsy =
+#ifdef ETXTBSY
+ETXTBSY;
+#else
+-4;
+#endif
+
+int error_io =
+#ifdef EIO
+EIO;
+#else
+-5;
+#endif
+
+int error_exist =
+#ifdef EEXIST
+EEXIST;
+#else
+-6;
+#endif
+
+int error_timeout =
+#ifdef ETIMEDOUT
+ETIMEDOUT;
+#else
+-7;
+#endif
+
+int error_inprogress =
+#ifdef EINPROGRESS
+EINPROGRESS;
+#else
+-8;
+#endif
+
+int error_wouldblock =
+#ifdef EWOULDBLOCK
+EWOULDBLOCK;
+#else
+-9;
+#endif
+
+int error_again =
+#ifdef EAGAIN
+EAGAIN;
+#else
+-10;
+#endif
+
+int error_pipe =
+#ifdef EPIPE
+EPIPE;
+#else
+-11;
+#endif
+
+int error_perm =
+#ifdef EPERM
+EPERM;
+#else
+-12;
+#endif
+
+int error_acces =
+#ifdef EACCES
+EACCES;
+#else
+-13;
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,23 @@
+#ifndef ERROR_H
+#define ERROR_H
+
+extern int errno;
+
+extern int error_intr;
+extern int error_nomem;
+extern int error_noent;
+extern int error_txtbsy;
+extern int error_io;
+extern int error_exist;
+extern int error_timeout;
+extern int error_inprogress;
+extern int error_wouldblock;
+extern int error_again;
+extern int error_pipe;
+extern int error_perm;
+extern int error_acces;
+
+extern char *error_str();
+extern int error_temp();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error_str.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,276 @@
+#include <errno.h>
+#include "error.h"
+
+#define X(e,s) if (i == e) return s;
+
+char *error_str(i)
+int i;
+{
+  X(0,"no error")
+  X(error_intr,"interrupted system call")
+  X(error_nomem,"out of memory")
+  X(error_noent,"file does not exist")
+  X(error_txtbsy,"text busy")
+  X(error_io,"input/output error")
+  X(error_exist,"file already exists")
+  X(error_timeout,"timed out")
+  X(error_inprogress,"operation in progress")
+  X(error_again,"temporary failure")
+  X(error_wouldblock,"input/output would block")
+  X(error_pipe,"broken pipe")
+  X(error_perm,"permission denied")
+  X(error_acces,"access denied")
+#ifdef ESRCH
+  X(ESRCH,"no such process")
+#endif
+#ifdef ENXIO
+  X(ENXIO,"device not configured")
+#endif
+#ifdef E2BIG
+  X(E2BIG,"argument list too long")
+#endif
+#ifdef ENOEXEC
+  X(ENOEXEC,"exec format error")
+#endif
+#ifdef EBADF
+  X(EBADF,"file descriptor not open")
+#endif
+#ifdef ECHILD
+  X(ECHILD,"no child processes")
+#endif
+#ifdef EDEADLK
+  X(EDEADLK,"operation would cause deadlock")
+#endif
+#ifdef EFAULT
+  X(EFAULT,"bad address")
+#endif
+#ifdef ENOTBLK
+  X(ENOTBLK,"not a block device")
+#endif
+#ifdef EBUSY
+  X(EBUSY,"device busy")
+#endif
+#ifdef EXDEV
+  X(EXDEV,"cross-device link")
+#endif
+#ifdef ENODEV
+  X(ENODEV,"device does not support operation")
+#endif
+#ifdef ENOTDIR
+  X(ENOTDIR,"not a directory")
+#endif
+#ifdef EISDIR
+  X(EISDIR,"is a directory")
+#endif
+#ifdef EINVAL
+  X(EINVAL,"invalid argument")
+#endif
+#ifdef ENFILE
+  X(ENFILE,"system cannot open more files")
+#endif
+#ifdef EMFILE
+  X(EMFILE,"process cannot open more files")
+#endif
+#ifdef ENOTTY
+  X(ENOTTY,"not a tty")
+#endif
+#ifdef EFBIG
+  X(EFBIG,"file too big")
+#endif
+#ifdef ENOSPC
+  X(ENOSPC,"out of disk space")
+#endif
+#ifdef ESPIPE
+  X(ESPIPE,"unseekable descriptor")
+#endif
+#ifdef EROFS
+  X(EROFS,"read-only file system")
+#endif
+#ifdef EMLINK
+  X(EMLINK,"too many links")
+#endif
+#ifdef EDOM
+  X(EDOM,"input out of range")
+#endif
+#ifdef ERANGE
+  X(ERANGE,"output out of range")
+#endif
+#ifdef EALREADY
+  X(EALREADY,"operation already in progress")
+#endif
+#ifdef ENOTSOCK
+  X(ENOTSOCK,"not a socket")
+#endif
+#ifdef EDESTADDRREQ
+  X(EDESTADDRREQ,"destination address required")
+#endif
+#ifdef EMSGSIZE
+  X(EMSGSIZE,"message too long")
+#endif
+#ifdef EPROTOTYPE
+  X(EPROTOTYPE,"incorrect protocol type")
+#endif
+#ifdef ENOPROTOOPT
+  X(ENOPROTOOPT,"protocol not available")
+#endif
+#ifdef EPROTONOSUPPORT
+  X(EPROTONOSUPPORT,"protocol not supported")
+#endif
+#ifdef ESOCKTNOSUPPORT
+  X(ESOCKTNOSUPPORT,"socket type not supported")
+#endif
+#ifdef EOPNOTSUPP
+  X(EOPNOTSUPP,"operation not supported")
+#endif
+#ifdef EPFNOSUPPORT
+  X(EPFNOSUPPORT,"protocol family not supported")
+#endif
+#ifdef EAFNOSUPPORT
+  X(EAFNOSUPPORT,"address family not supported")
+#endif
+#ifdef EADDRINUSE
+  X(EADDRINUSE,"address already used")
+#endif
+#ifdef EADDRNOTAVAIL
+  X(EADDRNOTAVAIL,"address not available")
+#endif
+#ifdef ENETDOWN
+  X(ENETDOWN,"network down")
+#endif
+#ifdef ENETUNREACH
+  X(ENETUNREACH,"network unreachable")
+#endif
+#ifdef ENETRESET
+  X(ENETRESET,"network reset")
+#endif
+#ifdef ECONNABORTED
+  X(ECONNABORTED,"connection aborted")
+#endif
+#ifdef ECONNRESET
+  X(ECONNRESET,"connection reset")
+#endif
+#ifdef ENOBUFS
+  X(ENOBUFS,"out of buffer space")
+#endif
+#ifdef EISCONN
+  X(EISCONN,"already connected")
+#endif
+#ifdef ENOTCONN
+  X(ENOTCONN,"not connected")
+#endif
+#ifdef ESHUTDOWN
+  X(ESHUTDOWN,"socket shut down")
+#endif
+#ifdef ETOOMANYREFS
+  X(ETOOMANYREFS,"too many references")
+#endif
+#ifdef ECONNREFUSED
+  X(ECONNREFUSED,"connection refused")
+#endif
+#ifdef ELOOP
+  X(ELOOP,"symbolic link loop")
+#endif
+#ifdef ENAMETOOLONG
+  X(ENAMETOOLONG,"file name too long")
+#endif
+#ifdef EHOSTDOWN
+  X(EHOSTDOWN,"host down")
+#endif
+#ifdef EHOSTUNREACH
+  X(EHOSTUNREACH,"host unreachable")
+#endif
+#ifdef ENOTEMPTY
+  X(ENOTEMPTY,"directory not empty")
+#endif
+#ifdef EPROCLIM
+  X(EPROCLIM,"too many processes")
+#endif
+#ifdef EUSERS
+  X(EUSERS,"too many users")
+#endif
+#ifdef EDQUOT
+  X(EDQUOT,"disk quota exceeded")
+#endif
+#ifdef ESTALE
+  X(ESTALE,"stale NFS file handle")
+#endif
+#ifdef EREMOTE
+  X(EREMOTE,"too many levels of remote in path")
+#endif
+#ifdef EBADRPC
+  X(EBADRPC,"RPC structure is bad")
+#endif
+#ifdef ERPCMISMATCH
+  X(ERPCMISMATCH,"RPC version mismatch")
+#endif
+#ifdef EPROGUNAVAIL
+  X(EPROGUNAVAIL,"RPC program unavailable")
+#endif
+#ifdef EPROGMISMATCH
+  X(EPROGMISMATCH,"program version mismatch")
+#endif
+#ifdef EPROCUNAVAIL
+  X(EPROCUNAVAIL,"bad procedure for program")
+#endif
+#ifdef ENOLCK
+  X(ENOLCK,"no locks available")
+#endif
+#ifdef ENOSYS
+  X(ENOSYS,"system call not available")
+#endif
+#ifdef EFTYPE
+  X(EFTYPE,"bad file type")
+#endif
+#ifdef EAUTH
+  X(EAUTH,"authentication error")
+#endif
+#ifdef ENEEDAUTH
+  X(ENEEDAUTH,"not authenticated")
+#endif
+#ifdef ENOSTR
+  X(ENOSTR,"not a stream device")
+#endif
+#ifdef ETIME
+  X(ETIME,"timer expired")
+#endif
+#ifdef ENOSR
+  X(ENOSR,"out of stream resources")
+#endif
+#ifdef ENOMSG
+  X(ENOMSG,"no message of desired type")
+#endif
+#ifdef EBADMSG
+  X(EBADMSG,"bad message type")
+#endif
+#ifdef EIDRM
+  X(EIDRM,"identifier removed")
+#endif
+#ifdef ENONET
+  X(ENONET,"machine not on network")
+#endif
+#ifdef ERREMOTE
+  X(ERREMOTE,"object not local")
+#endif
+#ifdef ENOLINK
+  X(ENOLINK,"link severed")
+#endif
+#ifdef EADV
+  X(EADV,"advertise error")
+#endif
+#ifdef ESRMNT
+  X(ESRMNT,"srmount error")
+#endif
+#ifdef ECOMM
+  X(ECOMM,"communication error")
+#endif
+#ifdef EPROTO
+  X(EPROTO,"protocol error")
+#endif
+#ifdef EMULTIHOP
+  X(EMULTIHOP,"multihop attempted")
+#endif
+#ifdef EREMCHG
+  X(EREMCHG,"remote address changed")
+#endif
+  return "unknown error";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error_temp.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,80 @@
+#include <errno.h>
+#include "error.h"
+
+#define X(n) if (e == n) return 1;
+
+int error_temp(e)
+int e;
+{
+  X(error_intr)
+  X(error_nomem)
+  X(error_txtbsy)
+  X(error_io)
+  X(error_timeout)
+  X(error_wouldblock)
+  X(error_again)
+#ifdef EDEADLK
+  X(EDEADLK)
+#endif
+#ifdef EBUSY
+  X(EBUSY)
+#endif
+#ifdef ENFILE
+  X(ENFILE)
+#endif
+#ifdef EMFILE
+  X(EMFILE)
+#endif
+#ifdef EFBIG
+  X(EFBIG)
+#endif
+#ifdef ENOSPC
+  X(ENOSPC)
+#endif
+#ifdef ENETDOWN
+  X(ENETDOWN)
+#endif
+#ifdef ENETUNREACH
+  X(ENETUNREACH)
+#endif
+#ifdef ENETRESET
+  X(ENETRESET)
+#endif
+#ifdef ECONNABORTED
+  X(ECONNABORTED)
+#endif
+#ifdef ECONNRESET
+  X(ECONNRESET)
+#endif
+#ifdef ENOBUFS
+  X(ENOBUFS)
+#endif
+#ifdef ETOOMANYREFS
+  X(ETOOMANYREFS)
+#endif
+#ifdef ECONNREFUSED
+  X(ECONNREFUSED)
+#endif
+#ifdef EHOSTDOWN
+  X(EHOSTDOWN)
+#endif
+#ifdef EHOSTUNREACH
+  X(EHOSTUNREACH)
+#endif
+#ifdef EPROCLIM
+  X(EPROCLIM)
+#endif
+#ifdef EUSERS
+  X(EUSERS)
+#endif
+#ifdef EDQUOT
+  X(EDQUOT)
+#endif
+#ifdef ESTALE
+  X(ESTALE)
+#endif
+#ifdef ENOLCK
+  X(ENOLCK)
+#endif
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fifo.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,10 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "hasmkffo.h"
+#include "fifo.h"
+
+#ifdef HASMKFIFO
+int fifo_make(fn,mode) char *fn; int mode; { return mkfifo(fn,mode); }
+#else
+int fifo_make(fn,mode) char *fn; int mode; { return mknod(fn,S_IFIFO | mode,0); }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fifo.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#ifndef FIFO_H
+#define FIFO_H
+
+extern int fifo_make();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/find-systype.sh	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,144 @@
+# oper-:arch-:syst-:chip-:kern-
+# oper = operating system type; e.g., sunos-4.1.4
+# arch = machine language; e.g., sparc
+# syst = which binaries can run; e.g., sun4
+# chip = chip model; e.g., micro-2-80
+# kern = kernel version; e.g., sun4m
+# dependence: arch --- chip
+#                 \        \
+#          oper --- syst --- kern
+# so, for example, syst is interpreted in light of oper, but chip is not.
+# anyway, no slashes, no extra colons, no uppercase letters.
+# the point of the extra -'s is to ease parsing: can add hierarchies later.
+# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium,
+# and i386-486 (486s do have more instructions, you know) as well as i386.
+# the idea here is to include ALL useful available information.
+
+exec 2>/dev/null
+sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`"
+if [ x"$sys" != x ]
+then
+  unamer="`uname -r | tr /: ..`"
+  unamem="`uname -m | tr /: ..`"
+  unamev="`uname -v | tr /: ..`"
+
+  case "$sys" in
+  bsd.os)
+    # in bsd 4.4, uname -v does not have useful info.
+    # in bsd 4.4, uname -m is arch, not chip.
+    oper="$sys-$unamer"
+    arch="$unamem"
+    syst=""
+    chip="`sysctl -n hw.model`"
+    kern=""
+    ;;
+  freebsd)
+    # see above about bsd 4.4
+    oper="$sys-$unamer"
+    arch="$unamem"
+    syst=""
+    chip="`sysctl -n hw.model`" # hopefully
+    kern=""
+    ;;
+  netbsd)
+    # see above about bsd 4.4
+    oper="$sys-$unamer"
+    arch="$unamem"
+    syst=""
+    chip="`sysctl -n hw.model`" # hopefully
+    kern=""
+    ;;
+  linux)
+    # as in bsd 4.4, uname -v does not have useful info.
+    oper="$sys-$unamer"
+    syst=""
+    chip="$unamem"
+    kern=""
+    case "$chip" in
+    i386|i486|i586|i686)
+      arch="i386"
+      ;;
+    alpha)
+      arch="alpha"
+      ;;
+    esac
+    ;;
+  aix)
+    # naturally IBM has to get uname -r and uname -v backwards. dorks.
+    oper="$sys-$unamev-$unamer"
+    arch="`arch | tr /: ..`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  sunos)
+    oper="$sys-$unamer-$unamev"
+    arch="`(uname -p || mach) | tr /: ..`"
+    syst="`arch | tr /: ..`"
+    chip="$unamem" # this is wrong; is there any way to get the real info?
+    kern="`arch -k | tr /: ..`"
+    ;;
+  unix_sv)
+    oper="$sys-$unamer-$unamev"
+    arch="`uname -m`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  *)
+    oper="$sys-$unamer-$unamev"
+    arch="`arch | tr /: ..`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  esac
+else
+  $CC -c trycpp.c
+  $LD -o trycpp trycpp.o
+  case `./trycpp` in
+  nextstep)
+    oper="nextstep-`hostinfo | sed -n 's/^[ 	]*NeXT Mach \([^:]*\):.*$/\1/p'`"
+    arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`"
+    syst=""
+    chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`"
+    kern=""
+    ;;
+  *)
+    oper="unknown"
+    arch=""
+    syst=""
+    chip=""
+    kern=""
+    ;;
+  esac
+  rm -f trycpp.o trycpp
+fi
+
+case "$chip" in
+80486)
+  # let's try to be consistent here. (BSD/OS)
+  chip=i486
+  ;;
+i486DX)
+  # respect the hyphen hierarchy. (FreeBSD)
+  chip=i486-dx
+  ;;
+i486.DX2)
+  # respect the hyphen hierarchy. (FreeBSD)
+  chip=i486-dx2
+  ;;
+Intel.586)
+  # no, you nitwits, there is no such chip. (NeXTStep)
+  chip=pentium
+  ;;
+i586)
+  # no, you nitwits, there is no such chip. (Linux)
+  chip=pentium
+  ;;
+i686)
+  # STOP SAYING THAT! (Linux)
+  chip=ppro
+esac
+
+echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,25 @@
+#ifndef FMT_H
+#define FMT_H
+
+#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
+#define FMT_LEN ((char *) 0) /* convenient abbreviation */
+
+extern unsigned int fmt_uint();
+extern unsigned int fmt_uint0();
+extern unsigned int fmt_xint();
+extern unsigned int fmt_nbbint();
+extern unsigned int fmt_ushort();
+extern unsigned int fmt_xshort();
+extern unsigned int fmt_nbbshort();
+extern unsigned int fmt_ulong();
+extern unsigned int fmt_xlong();
+extern unsigned int fmt_nbblong();
+
+extern unsigned int fmt_plusminus();
+extern unsigned int fmt_minus();
+extern unsigned int fmt_0x();
+
+extern unsigned int fmt_str();
+extern unsigned int fmt_strn();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt_str.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,12 @@
+#include "fmt.h"
+
+unsigned int fmt_str(s,t)
+register char *s; register char *t;
+{
+  register unsigned int len;
+  char ch;
+  len = 0;
+  if (s) { while (ch = t[len]) s[len++] = ch; }
+  else while (t[len]) len++;
+  return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt_strn.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,12 @@
+#include "fmt.h"
+
+unsigned int fmt_strn(s,t,n)
+register char *s; register char *t; register unsigned int n;
+{
+  register unsigned int len;
+  char ch;
+  len = 0;
+  if (s) { while (n-- && (ch = t[len])) s[len++] = ch; }
+  else while (n-- && t[len]) len++;
+  return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt_uint.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include "fmt.h"
+
+unsigned int fmt_uint(s,u) register char *s; register unsigned int u;
+{
+  register unsigned long l; l = u; return fmt_ulong(s,l);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt_uint0.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,10 @@
+#include "fmt.h"
+
+unsigned int fmt_uint0(s,u,n) char *s; unsigned int u; unsigned int n;
+{
+  unsigned int len;
+  len = fmt_uint(FMT_LEN,u);
+  while (len < n) { if (s) *s++ = '0'; ++len; }
+  if (s) fmt_uint(s,u);
+  return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fmt_ulong.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,13 @@
+#include "fmt.h"
+
+unsigned int fmt_ulong(s,u) register char *s; register unsigned long u;
+{
+  register unsigned int len; register unsigned long q;
+  len = 1; q = u;
+  while (q > 9) { ++len; q /= 10; }
+  if (s) {
+    s += len;
+    do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
+  }
+  return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen_alloc.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#ifndef GEN_ALLOC_H
+#define GEN_ALLOC_H
+
+#define GEN_ALLOC_typedef(ta,type,field,len,a) \
+  typedef struct ta { type *field; unsigned int len; unsigned int a; } ta;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen_allocdefs.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,34 @@
+#ifndef GEN_ALLOC_DEFS_H
+#define GEN_ALLOC_DEFS_H
+
+#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \
+int ta_ready(x,n) register ta *x; register unsigned int n; \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \
+int ta_rplus(x,n) register ta *x; register unsigned int n; \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; n += x->len; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \
+int ta_append(x,i) register ta *x; register type *i; \
+{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getln.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,20 @@
+#include "substdio.h"
+#include "byte.h"
+#include "stralloc.h"
+#include "getln.h"
+
+int getln(ss,sa,match,sep)
+register substdio *ss;
+register stralloc *sa;
+int *match;
+int sep;
+{
+  char *cont;
+  unsigned int clen;
+
+  if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1;
+  if (!clen) { *match = 0; return 0; }
+  if (!stralloc_catb(sa,cont,clen)) return -1;
+  *match = 1;
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getln.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#ifndef GETLN_H
+#define GETLN_H
+
+extern int getln();
+extern int getln2();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getln2.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,31 @@
+#include "substdio.h"
+#include "stralloc.h"
+#include "byte.h"
+#include "getln.h"
+
+int getln2(ss,sa,cont,clen,sep)
+register substdio *ss;
+register stralloc *sa;
+/*@out@*/char **cont;
+/*@out@*/unsigned int *clen;
+int sep;
+{
+  register char *x;
+  register unsigned int i;
+  int n;
+ 
+  if (!stralloc_ready(sa,0)) return -1;
+  sa->len = 0;
+ 
+  for (;;) {
+    n = substdio_feed(ss);
+    if (n < 0) return -1;
+    if (n == 0) { *clen = 0; return 0; }
+    x = substdio_PEEK(ss);
+    i = byte_chr(x,n,sep);
+    if (i < n) { substdio_SEEK(ss,*clen = i + 1); *cont = x; return 0; }
+    if (!stralloc_readyplus(sa,n)) return -1;
+    i = sa->len;
+    sa->len = i + substdio_get(ss,sa->s + i,n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make-compile.sh	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,1 @@
+echo exec "$CC" -c '${1+"$@"}'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make-load.sh	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,2 @@
+echo 'main="$1"; shift'
+echo exec "$LD" '-o "$main" "$main".o ${1+"$@"}'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make-makelib.sh	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,16 @@
+echo 'main="$1"; shift'
+echo 'rm -f "$main"'
+echo 'ar cr "$main" ${1+"$@"}'
+
+case "$1" in
+sunos-5.*) ;;
+unix_sv*) ;;
+irix64-*) ;;
+irix-*) ;;
+dgux-*) ;;
+hp-ux-*) ;;
+sco*) ;;
+*)
+  echo 'ranlib "$main"'
+  ;;
+esac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,10 @@
+#ifndef OPEN_H
+#define OPEN_H
+
+extern int open_read();
+extern int open_excl();
+extern int open_append();
+extern int open_trunc();
+extern int open_write();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open_append.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_append(fn) char *fn;
+{ return open(fn,O_WRONLY | O_NDELAY | O_APPEND | O_CREAT,0600); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open_excl.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_excl(fn) char *fn;
+{ return open(fn,O_WRONLY | O_EXCL | O_CREAT,0644); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open_read.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_read(fn) char *fn;
+{ return open(fn,O_RDONLY | O_NDELAY); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open_trunc.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_trunc(fn) char *fn;
+{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open_write.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_write(fn) char *fn;
+{ return open(fn,O_WRONLY | O_NDELAY); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/queue-fix.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,757 @@
+/*
+  queue-fix 1.4
+  by Eric Huss
+  e-huss@netmeridian.com
+
+  reconstructs qmail's queue
+*/
+#include <stdio.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+#include "stralloc.h"
+#include "direntry.h"
+#include "fmt.h"
+#include "error.h"
+#include "subfd.h"
+#include "getln.h"
+#include "str.h"
+#include "open.h"
+#include "fifo.h"
+#include "scan.h"
+
+/*change this to your qmail's conf-split value*/
+#define SPLIT_NUM 23
+
+stralloc queue_dir     = {0}; /*the root queue dir with trailing slash*/
+stralloc check_dir     = {0}; /*the current directory being checked*/
+stralloc temp_filename = {0}; /*temporary used for checking individuals*/
+stralloc temp_dirname  = {0}; /*temporary used for checking individuals*/
+stralloc old_name      = {0}; /*used in rename*/
+stralloc new_name      = {0}; /*used in rename*/
+stralloc mess_dir      = {0}; /*used for renaming in mess dir*/
+stralloc query         = {0}; /*used in interactive query function*/
+
+char name_num[FMT_ULONG];
+int flag_interactive=0;
+int flag_doit=1;
+int flag_dircreate=0;
+int flag_filecreate=0;
+int flag_permfix=0;
+int flag_namefix=0;
+int flag_unlink=0;
+
+int qmailq_uid;
+int qmails_uid;
+int qmailr_uid;
+int qmail_gid;
+
+void die_make(char * name)
+{
+printf("Failed to make %s\n"
+       "\nExiting...\n\n",name);
+exit(1);
+}
+
+void die_user(char * user)
+{
+printf("Failed to determine the uid of %s\n"
+       "\nExiting...\n\n",user);
+exit(1);
+}
+
+void die_group(char * group)
+{
+printf("Failed to determine the gid of %s\n"
+       "\nExiting...\n\n",group);
+exit(1);
+}
+
+void die_args()
+{
+printf("Invalid arguments.\n"
+       "queue-fix [-i | -N] queue_dir\n"
+       "\nExiting...\n\n");
+exit(1);
+}
+
+void die_check()
+{
+printf("Failed while checking directory structure.\n"
+       "Make sure the given queue exists and you have permission to access it.\n"
+       "\nExiting...\n\n");
+exit(1);
+}
+
+void die_recon()
+{
+printf("Failed to reconstruct queue.\n"
+       "Make sure the queue exists and you have permission to modify it.\n"
+       "\nExiting...\n\n");
+exit(1);
+}
+
+void die_nomem()
+{
+printf("Hmm..  Out of memory\n"
+       "\nExiting...\n\n");
+exit(1);
+}
+
+void die_rerun()
+{
+printf(".tmp files exist in the queue.\n"
+	   "queue-fix may have abnormally terminated in a previous run.\n"
+	   "The queue must be manually cleaned of the .tmp files.\n"
+	   "\nExiting...\n\n");
+exit(1);
+}
+
+/*returns 1==yes, 0==no*/
+int confirm()
+{
+int match;
+
+	if(getln(subfdinsmall,&query,&match,'\n')) return 0;
+	if(!match) return 0;
+	if(query.s[0]=='y' || query.s[0]=='Y' || query.s[0]=='\n') return 1;
+	return 0;
+}
+
+/*gid may be -1 on files for "unknown*/
+int check_item(char * name,int uid,int gid,int perm,char type,int size)
+{
+struct stat st;
+int fd;
+
+	/*check for existence and proper credentials*/
+	switch(type) {
+	case 'd': /*directory*/
+		if(stat(name,&st)) {
+			if(errno!=error_noent) return -1;
+			if(!flag_dircreate && flag_interactive) {
+				printf("It looks like some directories don't exist, should I create them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_dircreate = 1;
+			}
+			/*create it*/
+			printf("Creating directory [%s]\n",name);
+			if(flag_doit)	if(mkdir(name,perm)) die_make(name);
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+			return 0;
+		}
+		/*check the values*/
+		if(st.st_uid!=uid || st.st_gid!=gid) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+		}
+		if((st.st_mode & 07777) != perm) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+		}
+		return 0;
+	case 'f': /*regular file*/
+		if(stat(name,&st)) return -1;
+		/*check the values*/
+		if(st.st_uid!=uid || (st.st_gid!=gid && gid!=-1)) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+		}
+		if((st.st_mode & 07777) != perm) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+		}
+		return 0;
+	case 'z': /*regular file with a size*/
+		if(stat(name,&st)) {
+			if(errno!=error_noent) return -1;
+			if(!flag_filecreate && flag_interactive) {
+				printf("It looks like some files don't exist, should I create them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_filecreate = 1;
+			}
+			/*create it*/
+			printf("Creating [%s] with size [%u]\n",name,size);
+			if(flag_doit) {
+				fd = open_trunc(name);
+				if(fd==-1) die_make(name);
+				while(size--) {
+					if(write(fd,"",1)!=1) die_make(name);
+				}
+				close(fd);
+			}
+
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+			return 0;
+		}
+		/*check the values*/
+		if(st.st_uid!=uid || (st.st_gid!=gid && gid!=-1)) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+		}
+		if((st.st_mode & 07777) != perm) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+		}
+		if(st.st_size!=size) {
+			printf("%s is not the right size.  I will not fix it, please investigate.\n",name);
+		}
+		return 0;
+	case 'p': /*a named pipe*/
+		if(stat(name,&st)) {
+			if(errno!=error_noent) return -1;
+			if(!flag_filecreate && flag_interactive) {
+				printf("It looks like some files don't exist, should I create them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_filecreate = 1;
+			}
+			/*create it*/
+			printf("Creating fifo [%s]\n",name);
+			if(flag_doit)	if(fifo_make(name,perm)) die_make(name);
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+			return 0;
+		}
+		/*check the values*/
+		if(st.st_uid!=uid || (st.st_gid!=gid && gid!=-1)) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing ownership of [%s] to uid %u gid %u\n",name,uid,gid);
+			if(flag_doit)	if(chown(name,uid,gid)) die_make(name);
+		}
+		if((st.st_mode & 07777) != perm) {
+			if(!flag_permfix && flag_interactive) {
+				printf("It looks like some permissions are wrong, should I fix them? (Y/n)\n");
+				if(!confirm()) return -1;
+				flag_permfix = 1;
+			}
+			/*fix it*/
+			printf("Changing permissions of [%s] to [%o]\n",name,perm);
+			if(flag_doit)	if(chmod(name,perm)) die_make(name);
+		}
+		return 0;
+	} /*end switch*/
+
+	return 0;
+}
+
+int check_files(char * directory, int uid, int gid, int perm)
+{
+DIR * dir;
+direntry * d;
+
+	dir = opendir(directory);
+	if(!dir) return -1;
+	while((d = readdir(dir))) {
+		if(d->d_name[0]=='.') continue;
+		if(!stralloc_copys(&temp_filename,directory)) die_nomem();
+		if(!stralloc_append(&temp_filename,"/")) die_nomem();
+		if(!stralloc_cats(&temp_filename,d->d_name)) die_nomem();
+		if(!stralloc_0(&temp_filename)) die_nomem();
+		if(check_item(temp_filename.s,uid,gid,perm,'f',0))  { closedir(dir); return -1; }
+	}
+	closedir(dir);
+	return 0;
+}
+
+void warn_files(char * directory)
+{
+DIR * dir;
+direntry * d;
+int found = 0;
+
+	dir = opendir(directory);
+	if(!dir) return;
+
+	while((d = readdir(dir))) {
+		if(d->d_name[0]=='.') continue;
+		found = 1;
+		break;
+	}
+
+	closedir(dir);
+
+	if(found) {
+		printf("Found files in %s that shouldn't be there.\n"
+		       "I will not remove them. You should consider checking it out.\n\n",directory);
+	}
+}
+
+int check_splits(char * directory, int dir_uid, int dir_gid, int dir_perm,
+				 int file_gid, int file_perm)
+{
+DIR * dir;
+direntry * d;
+int i;
+
+	for(i=0;i<SPLIT_NUM;i++) {
+		name_num[fmt_ulong(name_num,i)]=0;
+		if(!stralloc_copys(&temp_dirname,directory)) die_nomem();
+		if(!stralloc_append(&temp_dirname,"/")) die_nomem();
+		if(!stralloc_cats(&temp_dirname,name_num)) die_nomem();
+		if(!stralloc_0(&temp_dirname)) die_nomem();
+		/*check the split dir*/
+		if(check_item(temp_dirname.s,dir_uid,dir_gid,dir_perm,'d',0)) return -1;
+		/*check its contents*/
+		dir = opendir(temp_dirname.s);
+		if(!dir) return -1;
+		while((d = readdir(dir))) {
+			if(d->d_name[0]=='.') continue;
+			if(!stralloc_copy(&temp_filename,&temp_dirname)) die_nomem();
+			temp_filename.len--;		/*remove NUL*/
+			if(!stralloc_append(&temp_filename,"/")) die_nomem();
+			if(!stralloc_cats(&temp_filename,d->d_name)) die_nomem();
+			if(!stralloc_0(&temp_filename)) die_nomem();
+			if(check_item(temp_filename.s,dir_uid,file_gid,file_perm,'f',0)) { closedir(dir); return -1; }
+		}
+		closedir(dir);
+	} /*end for*/
+	return 0;
+}
+
+int rename_mess(char * dir, char * part, char * new_part, char * old_filename, char * new_filename)
+{
+struct stat st;
+
+	if(flag_interactive && !flag_namefix) {
+		printf("It looks like some files need to be renamed, should I rename them? (Y/n)\n");
+		if(!confirm()) return -1;
+		flag_namefix = 1;
+	}
+	/*prepare the old filename*/
+	if(!stralloc_copy(&old_name,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&old_name,dir)) die_nomem();
+	if(!stralloc_cats(&old_name,part)) die_nomem();
+	if(!stralloc_append(&old_name,"/")) die_nomem();
+	if(!stralloc_cats(&old_name,old_filename)) die_nomem();
+	if(!stralloc_0(&old_name)) die_nomem();
+
+	/*prepare the new filename*/
+	if(!stralloc_copy(&new_name,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&new_name,dir)) die_nomem();
+	if(!stralloc_cats(&new_name,new_part)) die_nomem();
+	if(!stralloc_append(&new_name,"/")) die_nomem();
+	if(!stralloc_cats(&new_name,new_filename)) die_nomem();
+	if(!stralloc_0(&new_name)) die_nomem();
+
+	/*check if destination exists*/
+	if(stat(new_name.s,&st)==0) {
+		/*it exists*/
+		new_name.len--;			/*remove NUL*/
+		/*append an extension to prevent name clash*/
+		if(!stralloc_cats(&new_name,".tmp")) die_nomem();
+		if(!stralloc_0(&new_name)) die_nomem();
+		/*do a double check for collision*/
+		if(stat(new_name.s,&st)==0) die_rerun();
+	}
+
+	printf("Renaming [%s] to [%s]\n",old_name.s,new_name.s);
+	if(flag_doit) {
+		if(rename(old_name.s,new_name.s)) {
+			if(errno!=error_noent) {
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+int fix_part(char * part,int part_num)
+{
+DIR * dir;
+direntry * d;
+struct stat st;
+char inode[FMT_ULONG];
+char new_part[FMT_ULONG];
+int old_inode;
+int correct_part_num;
+
+	if(!stralloc_copy(&mess_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&mess_dir,"mess/")) die_nomem();
+	if(!stralloc_cats(&mess_dir,part)) die_nomem();
+	if(!stralloc_0(&mess_dir)) die_nomem();
+
+	dir = opendir(mess_dir.s);
+	if(!dir) return -1;
+
+	while((d = readdir(dir))) {
+		if(d->d_name[0]=='.') continue;
+		/*check from mess*/
+		if(!stralloc_copy(&temp_filename,&mess_dir)) die_nomem();
+		temp_filename.len--;			/*remove NUL*/
+		if(!stralloc_append(&temp_filename,"/")) die_nomem();
+		if(!stralloc_cats(&temp_filename,d->d_name)) die_nomem();
+		if(!stralloc_0(&temp_filename)) die_nomem();
+		if(stat(temp_filename.s,&st)) { closedir(dir); return -1; }
+
+		/*check that filename==inode number*/
+		/*check that inode%auto_split==part_num*/
+		scan_ulong(d->d_name,&old_inode);
+		correct_part_num = st.st_ino % SPLIT_NUM;
+		if(st.st_ino != old_inode ||
+			part_num!=correct_part_num) {
+			/*rename*/
+			inode[fmt_ulong(inode,st.st_ino)]=0;
+			new_part[fmt_ulong(new_part,correct_part_num)]=0;
+			if(rename_mess("mess/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; }
+			if(rename_mess("info/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; }
+			if(rename_mess("local/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; }
+			if(rename_mess("remote/",part,new_part,d->d_name,inode)) { closedir(dir); return -1; }
+
+			if(rename_mess("intd","","",d->d_name,inode)) { closedir(dir); return -1; }
+			if(rename_mess("todo","","",d->d_name,inode)) { closedir(dir); return -1; }
+			if(rename_mess("bounce","","",d->d_name,inode)) { closedir(dir); return -1; }
+		}
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+int clean_tmp(char * directory, char * part)
+{
+DIR * dir;
+direntry * d;
+struct stat st;
+int length;
+
+	if(!stralloc_copy(&mess_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&mess_dir,directory)) die_nomem();
+	if(!stralloc_cats(&mess_dir,part)) die_nomem();
+	if(!stralloc_0(&mess_dir)) die_nomem();
+
+	dir = opendir(mess_dir.s);
+	if(!dir) return -1;
+
+	while((d = readdir(dir))) {
+		if(d->d_name[0]=='.') continue;
+
+		/*check for tmp extension*/
+		length = str_len(d->d_name);
+		if(length>4) {
+			if(str_equal(d->d_name+length-4,".tmp")) {
+				/*remove the extension*/
+				if(!stralloc_copys(&temp_filename,d->d_name)) die_nomem();
+				temp_filename.len-=4;
+				if(!stralloc_0(&temp_filename)) die_nomem();
+
+				if(rename_mess(directory,part,part,d->d_name,temp_filename.s)) { closedir(dir); return -1; }
+			}
+		}
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+int fix_names()
+{
+int i;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"mess")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+
+	/*make the filenames match their inode*/
+	for(i=0;i<SPLIT_NUM;i++) {
+		name_num[fmt_ulong(name_num,i)]=0;
+		if(fix_part(name_num,i)) return -1;
+	}
+
+	/*clean up any tmp files*/
+	for(i=0;i<SPLIT_NUM;i++) {
+		name_num[fmt_ulong(name_num,i)]=0;
+		if(clean_tmp("mess/",name_num)) return -1;
+		if(clean_tmp("info/",name_num)) return -1;
+		if(clean_tmp("local/",name_num)) return -1;
+		if(clean_tmp("remote/",name_num)) return -1;
+	}
+	if(clean_tmp("intd","")) return -1;
+	if(clean_tmp("todo","")) return -1;
+	if(clean_tmp("bounce","")) return -1;
+
+	return 0;
+}
+
+int check_dirs()
+{
+	/*check root existence*/
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0750,'d',0)) return -1;
+
+	/*check the big 4*/
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"info")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0700,'d',0)) return -1;
+	if(check_splits(check_dir.s,qmails_uid,qmail_gid,0700,qmail_gid,0600)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"mess")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0750,'d',0)) return -1;
+	if(check_splits(check_dir.s,qmailq_uid,qmail_gid,0750,-1,0644)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"remote")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0700,'d',0)) return -1;
+	if(check_splits(check_dir.s,qmails_uid,qmail_gid,0700,qmail_gid,0600)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"local")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0700,'d',0)) return -1;
+	if(check_splits(check_dir.s,qmails_uid,qmail_gid,0700,qmail_gid,0600)) return -1;
+
+	/*check the others*/
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"todo")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0750,'d',0)) return -1;
+	if(check_files(check_dir.s,qmailq_uid,-1,0644)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"intd")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0700,'d',0)) return -1;
+	if(check_files(check_dir.s,qmailq_uid,-1,0644)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"bounce")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0700,'d',0)) return -1;
+	if(check_files(check_dir.s,qmails_uid,qmail_gid,0600)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"pid")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0700,'d',0)) return -1;
+	warn_files(check_dir.s);
+
+	/*lock has special files that must exist*/
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"lock")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailq_uid,qmail_gid,0750,'d',0)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"lock/sendmutex")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0600,'z',0)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"lock/tcpto")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmailr_uid,qmail_gid,0644,'z',1024)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+	if(!stralloc_cats(&check_dir,"lock/trigger")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_item(check_dir.s,qmails_uid,qmail_gid,0622,'p',0)) return -1;
+
+	return 0;
+}
+
+int check_strays(char * directory)
+{
+DIR * dir;
+direntry * d;
+struct stat st;
+int inode;
+int part;
+char new_part[FMT_ULONG];
+
+	dir = opendir(directory);
+	if(!dir) return -1;
+
+	while((d = readdir(dir))) {
+		if(d->d_name[0]=='.') continue;
+
+		scan_ulong(d->d_name,&inode);
+		part = inode % SPLIT_NUM;
+		new_part[fmt_ulong(new_part,part)]=0;
+
+		/*check for corresponding entry in mess dir*/
+		if(!stralloc_copy(&mess_dir,&queue_dir)) die_nomem();
+		if(!stralloc_cats(&mess_dir,"mess/")) die_nomem();
+		if(!stralloc_cats(&mess_dir,new_part)) die_nomem();
+		if(!stralloc_append(&mess_dir,"/")) die_nomem();
+		if(!stralloc_cats(&mess_dir,d->d_name)) die_nomem();
+		if(!stralloc_0(&mess_dir)) die_nomem();
+
+		if(stat(mess_dir.s,&st)) {
+			/*failed to find in mess*/
+			if(flag_interactive && !flag_unlink) {
+				printf("There are some stray files in %s\n",directory);
+				printf("Should I remove them? (Y/n)\n");
+				if(!confirm()) {
+					closedir(dir);
+					return -1;
+				}
+				flag_unlink = 1;
+			}
+			if(!stralloc_copys(&temp_filename,directory)) die_nomem();
+			if(!stralloc_append(&temp_filename,"/")) die_nomem();
+			if(!stralloc_cats(&temp_filename,d->d_name)) die_nomem();
+			if(!stralloc_0(&temp_filename)) die_nomem();
+
+			printf("Unlinking [%s]\n",temp_filename.s);
+			if(flag_doit)	if(unlink(temp_filename.s)==-1) { closedir(dir); return -1; }
+		}
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+int check_stray_parts()
+{
+int i;
+
+	for(i=0;i<SPLIT_NUM;i++) {
+		name_num[fmt_ulong(name_num,i)]=0;
+		if(!stralloc_copy(&temp_dirname,&check_dir)) die_nomem();
+		if(!stralloc_append(&temp_dirname,"/")) die_nomem();
+		if(!stralloc_cats(&temp_dirname,name_num)) die_nomem();
+		if(!stralloc_0(&temp_dirname)) die_nomem();
+		/*check this dir for strays*/
+		if(check_strays(temp_dirname.s)) return -1;
+	}
+	return 0;
+}
+
+int find_strays()
+{
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"info")) die_nomem();
+	if(check_stray_parts()) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"local")) die_nomem();
+	if(check_stray_parts()) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"remote")) die_nomem();
+	if(check_stray_parts()) return -1;
+
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"todo")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_strays(check_dir.s)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"intd")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_strays(check_dir.s)) return -1;
+
+	if(!stralloc_copy(&check_dir,&queue_dir)) die_nomem();
+ 	if(!stralloc_cats(&check_dir,"bounce")) die_nomem();
+	if(!stralloc_0(&check_dir)) die_nomem();
+	if(check_strays(check_dir.s)) return -1;
+
+	return 0;
+}
+
+int main(int argc, char ** argv)
+{
+struct passwd * pw;
+struct group * gr;
+
+	if(argc<2 || !argv[1] || !argv[1][0]) {
+		die_args();
+	}
+
+	if(str_diff(argv[1],"-i")==0) {
+		flag_interactive = 1;
+		argv++;
+		if(!argv[1] || !argv[1][0]) die_args();
+	} else if(str_diff(argv[1],"-N")==0) {
+		printf("Running in test mode, no changes will be made.\n");
+		flag_doit = 0;
+		argv++;
+		if(!argv[1] || !argv[1][0]) die_args();
+	}
+
+	if(!stralloc_copys(&queue_dir,argv[1])) die_nomem();
+	if(queue_dir.s[queue_dir.len-1]!='/') {
+		if(!stralloc_append(&queue_dir,"/")) die_nomem();
+	}
+
+	/*prepare the uid and gid*/
+	pw = getpwnam("qmailq");
+	if(!pw) die_user("qmailq");
+	qmailq_uid = pw->pw_uid;
+
+	pw = getpwnam("qmails");
+	if(!pw) die_user("qmails");
+	qmails_uid = pw->pw_uid;
+
+	pw = getpwnam("qmailr");
+	if(!pw) die_user("qmailr");
+	qmailr_uid = pw->pw_uid;
+
+	gr = getgrnam("qmail");
+	if(!gr) die_group("qmail");
+	qmail_gid = gr->gr_gid;
+
+	/*check that all the proper directories exist with proper credentials*/
+	if(check_dirs()) die_check();
+	/*rename inode filenames*/
+	if(fix_names()) die_check();
+	/*check for stray files*/
+	if(find_strays()) die_check();
+
+	printf("queue-fix finished...\n");
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/readwrite.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#ifndef READWRITE_H
+#define READWRITE_H
+
+extern int read();
+extern int write();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scan.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,27 @@
+#ifndef SCAN_H
+#define SCAN_H
+
+extern unsigned int scan_uint();
+extern unsigned int scan_xint();
+extern unsigned int scan_nbbint();
+extern unsigned int scan_ushort();
+extern unsigned int scan_xshort();
+extern unsigned int scan_nbbshort();
+extern unsigned int scan_ulong();
+extern unsigned int scan_xlong();
+extern unsigned int scan_nbblong();
+
+extern unsigned int scan_plusminus();
+extern unsigned int scan_0x();
+
+extern unsigned int scan_whitenskip();
+extern unsigned int scan_nonwhitenskip();
+extern unsigned int scan_charsetnskip();
+extern unsigned int scan_noncharsetnskip();
+
+extern unsigned int scan_strncmp();
+extern unsigned int scan_memcmp();
+
+extern unsigned int scan_long();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scan_8long.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,11 @@
+#include "scan.h"
+
+unsigned int scan_8long(s,u) register char *s; register unsigned long *u;
+{
+  register unsigned int pos; register unsigned long result;
+  register unsigned long c;
+  pos = 0; result = 0;
+  while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 8)
+    { result = result * 8 + c; ++pos; }
+  *u = result; return pos;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scan_ulong.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,11 @@
+#include "scan.h"
+
+unsigned int scan_ulong(s,u) register char *s; register unsigned long *u;
+{
+  register unsigned int pos; register unsigned long result;
+  register unsigned long c;
+  pos = 0; result = 0;
+  while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10)
+    { result = result * 10 + c; ++pos; }
+  *u = result; return pos;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,14 @@
+#ifndef STR_H
+#define STR_H
+
+extern unsigned int str_copy();
+extern int str_diff();
+extern int str_diffn();
+extern unsigned int str_len();
+extern unsigned int str_chr();
+extern unsigned int str_rchr();
+extern int str_start();
+
+#define str_equal(s,t) (!str_diff((s),(t)))
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_chr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,19 @@
+#include "str.h"
+
+unsigned int str_chr(s,c)
+register char *s;
+int c;
+{
+  register char ch;
+  register char *t;
+
+  ch = c;
+  t = s;
+  for (;;) {
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+  }
+  return t - s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_cpy.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,16 @@
+#include "str.h"
+
+unsigned int str_copy(s,t)
+register char *s;
+register char *t;
+{
+  register int len;
+
+  len = 0;
+  for (;;) {
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_diff.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,17 @@
+#include "str.h"
+
+int str_diff(s,t)
+register char *s;
+register char *t;
+{
+  register char x;
+
+  for (;;) {
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+  }
+  return ((int)(unsigned int)(unsigned char) x)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_diffn.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,18 @@
+#include "str.h"
+
+int str_diffn(s,t,len)
+register char *s;
+register char *t;
+unsigned int len;
+{
+  register char x;
+
+  for (;;) {
+    if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+  }
+  return ((int)(unsigned int)(unsigned char) x)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_len.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,15 @@
+#include "str.h"
+
+unsigned int str_len(s)
+register char *s;
+{
+  register char *t;
+
+  t = s;
+  for (;;) {
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_rchr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,22 @@
+#include "str.h"
+
+unsigned int str_rchr(s,c)
+register char *s;
+int c;
+{
+  register char ch;
+  register char *t;
+  register char *u;
+
+  ch = c;
+  t = s;
+  u = 0;
+  for (;;) {
+    if (!*t) break; if (*t == ch) u = t; ++t;
+    if (!*t) break; if (*t == ch) u = t; ++t;
+    if (!*t) break; if (*t == ch) u = t; ++t;
+    if (!*t) break; if (*t == ch) u = t; ++t;
+  }
+  if (!u) u = t;
+  return u - s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/str_start.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,15 @@
+#include "str.h"
+
+int str_start(s,t)
+register char *s;
+register char *t;
+{
+  register char x;
+
+  for (;;) {
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,21 @@
+#ifndef STRALLOC_H
+#define STRALLOC_H
+
+#include "gen_alloc.h"
+
+GEN_ALLOC_typedef(stralloc,char,s,len,a)
+
+extern int stralloc_ready();
+extern int stralloc_readyplus();
+extern int stralloc_copy();
+extern int stralloc_cat();
+extern int stralloc_copys();
+extern int stralloc_cats();
+extern int stralloc_copyb();
+extern int stralloc_catb();
+extern int stralloc_append(); /* beware: this takes a pointer to 1 char */
+extern int stralloc_starts();
+
+#define stralloc_0(sa) stralloc_append(sa,"")
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_arts.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,12 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_starts(sa,s)
+stralloc *sa;
+char *s;
+{
+  int len;
+  len = str_len(s);
+  return (sa->len >= len) && byte_equal(s,len,sa->s);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_cat.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,9 @@
+#include "byte.h"
+#include "stralloc.h"
+
+int stralloc_cat(sato,safrom)
+stralloc *sato;
+stralloc *safrom;
+{
+  return stralloc_catb(sato,safrom->s,safrom->len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_catb.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,15 @@
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_catb(sa,s,n)
+stralloc *sa;
+char *s;
+unsigned int n;
+{
+  if (!sa->s) return stralloc_copyb(sa,s,n);
+  if (!stralloc_readyplus(sa,n + 1)) return 0;
+  byte_copy(sa->s + sa->len,n,s);
+  sa->len += n;
+  sa->s[sa->len] = 'Z'; /* ``offensive programming'' */
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_cats.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,10 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_cats(sa,s)
+stralloc *sa;
+char *s;
+{
+  return stralloc_catb(sa,s,str_len(s));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_copy.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,9 @@
+#include "byte.h"
+#include "stralloc.h"
+
+int stralloc_copy(sato,safrom)
+stralloc *sato;
+stralloc *safrom;
+{
+  return stralloc_copyb(sato,safrom->s,safrom->len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_eady.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,6 @@
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready)
+GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_opyb.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,14 @@
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_copyb(sa,s,n)
+stralloc *sa;
+char *s;
+unsigned int n;
+{
+  if (!stralloc_ready(sa,n + 1)) return 0;
+  byte_copy(sa->s,n,s);
+  sa->len = n;
+  sa->s[n] = 'Z'; /* ``offensive programming'' */
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_opys.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,10 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_copys(sa,s)
+stralloc *sa;
+char *s;
+{
+  return stralloc_copyb(sa,s,str_len(s));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stralloc_pend.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,5 @@
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfd.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,15 @@
+#ifndef SUBFD_H
+#define SUBFD_H
+
+#include "substdio.h"
+
+extern substdio *subfdin;
+extern substdio *subfdinsmall;
+extern substdio *subfdout;
+extern substdio *subfdoutsmall;
+extern substdio *subfderr;
+
+extern int subfd_read();
+extern int subfd_readsmall();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfderr.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+char subfd_errbuf[256];
+static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256);
+substdio *subfderr = &it;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfdin.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,13 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+int subfd_read(fd,buf,len) int fd; char *buf; int len;
+{
+  if (substdio_flush(subfdout) == -1) return -1;
+  return read(fd,buf,len);
+}
+
+char subfd_inbuf[SUBSTDIO_INSIZE];
+static substdio it = SUBSTDIO_FDBUF(subfd_read,0,subfd_inbuf,SUBSTDIO_INSIZE);
+substdio *subfdin = &it;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfdins.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,13 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+int subfd_readsmall(fd,buf,len) int fd; char *buf; int len;
+{
+  if (substdio_flush(subfdoutsmall) == -1) return -1;
+  return read(fd,buf,len);
+}
+
+char subfd_inbufsmall[256];
+static substdio it = SUBSTDIO_FDBUF(subfd_readsmall,0,subfd_inbufsmall,256);
+substdio *subfdinsmall = &it;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfdout.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+char subfd_outbuf[SUBSTDIO_OUTSIZE];
+static substdio it = SUBSTDIO_FDBUF(write,1,subfd_outbuf,SUBSTDIO_OUTSIZE);
+substdio *subfdout = &it;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subfdouts.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+char subfd_outbufsmall[256];
+static substdio it = SUBSTDIO_FDBUF(write,1,subfd_outbufsmall,256);
+substdio *subfdoutsmall = &it;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/substdi.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,91 @@
+#include "substdio.h"
+#include "byte.h"
+#include "error.h"
+
+static int oneread(op,fd,buf,len)
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  register int r;
+
+  for (;;) {
+    r = op(fd,buf,len);
+    if (r == -1) if (errno == error_intr) continue;
+    return r;
+  }
+}
+
+static int getthis(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+  register int q;
+ 
+  r = s->p;
+  q = r - len;
+  if (q > 0) { r = len; s->p = q; } else s->p = 0;
+  byte_copy(buf,r,s->x + s->n);
+  s->n += r;
+  return r;
+}
+
+int substdio_feed(s)
+register substdio *s;
+{
+  register int r;
+  register int q;
+
+  if (s->p) return s->p;
+  q = s->n;
+  r = oneread(s->op,s->fd,s->x,q);
+  if (r <= 0) return r;
+  s->p = r;
+  q -= r;
+  s->n = q;
+  if (q > 0) /* damn, gotta shift */ byte_copyr(s->x + q,r,s->x);
+  return r;
+}
+
+int substdio_bget(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  r = s->n; if (r <= len) return oneread(s->op,s->fd,buf,r);
+  r = substdio_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+int substdio_get(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  if (s->n <= len) return oneread(s->op,s->fd,buf,len);
+  r = substdio_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+char *substdio_peek(s)
+register substdio *s;
+{
+  return s->x + s->n;
+}
+
+void substdio_seek(s,len)
+register substdio *s;
+register int len;
+{
+  s->n += len;
+  s->p -= len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/substdio.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,15 @@
+#include "substdio.h"
+
+void substdio_fdbuf(s,op,fd,buf,len)
+register substdio *s;
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  s->x = buf;
+  s->fd = fd;
+  s->op = op;
+  s->p = 0;
+  s->n = len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/substdio.h	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,47 @@
+#ifndef SUBSTDIO_H
+#define SUBSTDIO_H
+
+typedef struct substdio {
+  char *x;
+  int p;
+  int n;
+  int fd;
+  int (*op)();
+} substdio;
+
+#define SUBSTDIO_FDBUF(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
+
+extern void substdio_fdbuf();
+
+extern int substdio_flush();
+extern int substdio_put();
+extern int substdio_bput();
+extern int substdio_putflush();
+extern int substdio_puts();
+extern int substdio_bputs();
+extern int substdio_putsflush();
+
+extern int substdio_get();
+extern int substdio_bget();
+extern int substdio_feed();
+
+extern char *substdio_peek();
+extern void substdio_seek();
+
+#define substdio_fileno(s) ((s)->fd)
+
+#define SUBSTDIO_INSIZE 8192
+#define SUBSTDIO_OUTSIZE 8192
+
+#define substdio_PEEK(s) ( (s)->x + (s)->n )
+#define substdio_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
+
+#define substdio_BPUTC(s,c) \
+  ( ((s)->n != (s)->p) \
+    ? ( (s)->x[(s)->p++] = (c), 0 ) \
+    : substdio_bput((s),&(c),1) \
+  )
+
+extern int substdio_copy();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/substdio_copy.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,18 @@
+#include "substdio.h"
+
+int substdio_copy(ssout,ssin)
+register substdio *ssout;
+register substdio *ssin;
+{
+  register int n;
+  register char *x;
+
+  for (;;) {
+    n = substdio_feed(ssin);
+    if (n < 0) return -2;
+    if (!n) return 0;
+    x = substdio_PEEK(ssin);
+    if (substdio_put(ssout,x,n) == -1) return -3;
+    substdio_SEEK(ssin,n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/substdo.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,108 @@
+#include "substdio.h"
+#include "str.h"
+#include "byte.h"
+#include "error.h"
+
+static int allwrite(op,fd,buf,len)
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  register int w;
+
+  while (len) {
+    w = op(fd,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      return -1; /* note that some data may have been written */
+    }
+    if (w == 0) ; /* luser's fault */
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+int substdio_flush(s)
+register substdio *s;
+{
+  register int p;
+ 
+  p = s->p;
+  if (!p) return 0;
+  s->p = 0;
+  return allwrite(s->op,s->fd,s->x,p);
+}
+
+int substdio_bput(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int n;
+ 
+  while (len > (n = s->n - s->p)) {
+    byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
+    if (substdio_flush(s) == -1) return -1;
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int substdio_put(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int n;
+ 
+  n = s->n;
+  if (len > n - s->p) {
+    if (substdio_flush(s) == -1) return -1;
+    /* now s->p == 0 */
+    if (n < SUBSTDIO_OUTSIZE) n = SUBSTDIO_OUTSIZE;
+    while (len > s->n) {
+      if (n > len) n = len;
+      if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
+      buf += n;
+      len -= n;
+    }
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int substdio_putflush(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  if (substdio_flush(s) == -1) return -1;
+  return allwrite(s->op,s->fd,buf,len);
+}
+
+int substdio_bputs(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_bput(s,buf,str_len(buf));
+}
+
+int substdio_puts(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_put(s,buf,str_len(buf));
+}
+
+int substdio_putsflush(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_putflush(s,buf,str_len(buf));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trycpp.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+void main()
+{
+#ifdef NeXT
+  printf("nextstep\n"); exit(0);
+#endif
+  printf("unknown\n"); exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trydrent.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,8 @@
+#include <sys/types.h>
+#include <dirent.h>
+
+void foo()
+{
+  DIR *dir;
+  struct dirent *d;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trymkffo.c	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,7 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+void main()
+{
+  mkfifo("temp-trymkffo",0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/warn-auto.sh	Thu Nov 01 14:46:11 2007 +0100
@@ -0,0 +1,2 @@
+#!/bin/sh
+# WARNING: This file was auto-generated. Do not edit!