From: =?utf-8?b?0L3QsNCx?= <nabijaczleweli@nabijaczleweli.xyz>
Date: Fri, 22 Aug 2025 00:20:34 +0200
Subject: Properly prototype the code (Closes: #1097837). This includes
 de1999ifying it a lot and fixing some bugs (like an off-by-10 at least) and
 removing a reimplementation of like half-of libc

The horrors: https://101010.pl/@nabijaczleweli/115068484641732979
---
 alloc.3         |  62 -------------
 alloc.c         |  31 -------
 alloc.h         |   8 --
 alloc_re.c      |  17 ----
 buffer.h        |  50 -----------
 byte.h          |  10 +--
 byte_copy.c     |  14 ---
 byte_cr.c       |  16 ----
 byte_diff.c     |  16 ----
 byte_zero.c     |  13 ---
 error.c         | 102 ---------------------
 error.h         |  24 -----
 error_str.c     | 273 --------------------------------------------------------
 fmt.h           |  26 ------
 fmt_uint64.c    |  14 ---
 gen_alloc.h     |   7 --
 gen_allocdefs.h |  34 -------
 hostname.c      |   2 +-
 meson.build     |  12 ---
 readwrite.h     |   3 +-
 safecat.c       |  24 +++--
 sig.c           |  12 +--
 sig.h           |   5 +-
 stat_dir.c      |   7 +-
 str.h           |  14 ---
 str_diffn.c     |  18 ----
 str_len.c       |  14 ---
 stralloc.3      |   4 +-
 stralloc.h      |  33 +++----
 stralloc_cat.c  |   4 +-
 stralloc_catb.c |   5 +-
 stralloc_cats.c |   9 +-
 stralloc_copy.c |   4 +-
 stralloc_eady.c |  22 ++++-
 stralloc_opyb.c |   5 +-
 stralloc_opys.c |   9 +-
 stralloc_pend.c |   9 +-
 strerr.h        |  73 ++-------------
 strerr_die.c    |  34 +++----
 strerr_sys.c    |  10 +--
 subfd.h         |   6 --
 subfderr.c      |   2 +-
 subfdouts.c     |   2 +-
 substdi.c       |  69 +-------------
 substdio.c      |   7 +-
 substdio.h      |  31 ++-----
 substdio_copy.c |   4 +-
 substdo.c       |  61 +++----------
 tai.h           |  22 -----
 taia.h          |  31 -------
 taia_fmtfrac.c  |  33 -------
 taia_now.c      |  15 ----
 taia_tai.c      |   8 --
 tempfile.c      |  37 +++-----
 writefile.c     |  14 ++-
 55 files changed, 146 insertions(+), 1245 deletions(-)
 delete mode 100644 alloc.3
 delete mode 100644 alloc.c
 delete mode 100644 alloc.h
 delete mode 100644 alloc_re.c
 delete mode 100644 buffer.h
 delete mode 100644 byte_copy.c
 delete mode 100644 byte_cr.c
 delete mode 100644 byte_diff.c
 delete mode 100644 byte_zero.c
 delete mode 100644 error.c
 delete mode 100644 error.h
 delete mode 100644 error_str.c
 delete mode 100644 fmt.h
 delete mode 100644 fmt_uint64.c
 delete mode 100644 gen_alloc.h
 delete mode 100644 gen_allocdefs.h
 delete mode 100644 str.h
 delete mode 100644 str_diffn.c
 delete mode 100644 str_len.c
 delete mode 100644 tai.h
 delete mode 100644 taia.h
 delete mode 100644 taia_fmtfrac.c
 delete mode 100644 taia_now.c
 delete mode 100644 taia_tai.c

diff --git a/alloc.3 b/alloc.3
deleted file mode 100644
index 58b4432..0000000
--- a/alloc.3
+++ /dev/null
@@ -1,62 +0,0 @@
-.TH alloc 3
-.SH NAME
-alloc \- allocate memory
-.SH SYNTAX
-.B #include <alloc.h>
-
-char *\fBalloc\fP(\fInew\fR);
-
-void \fBalloc_free\fP(\fIx\fR);
-
-void \fBalloc_re\fP(&\fIx\fR,\fIold\fR,\fInew\fR);
-
-char *\fIx\fR;
-.br
-unsigned int \fIold\fR;
-.br
-unsigned int \fInew\fR;
-.SH DESCRIPTION
-.B alloc
-allocates enough space from the heap for
-.I new
-bytes of data,
-adequately aligned for any data type.
-.I new
-may be 0.
-.B alloc
-returns a pointer to the space.
-If space is not available,
-.B alloc
-returns 0,
-setting
-.B errno
-appropriately.
-
-.B alloc_free
-returns space to the heap.
-
-.B alloc_re
-expands the space allocated to
-.I x
-from
-.I old
-bytes to
-.I new
-bytes.
-It allocates new space,
-copies
-.I old
-bytes from the old space to the new space,
-returns the old space to the heap,
-and changes
-.I x
-to point to the new space.
-It then returns 1.
-If space is not available,
-.B alloc_re
-returns 0,
-leaving the old space alone.
-.SH "SEE ALSO"
-sbrk(2),
-malloc(3),
-error(3)
diff --git a/alloc.c b/alloc.c
deleted file mode 100644
index 48a109b..0000000
--- a/alloc.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "alloc.h"
-#include "error.h"
-#include <stdlib.h>
-
-#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);
-}
diff --git a/alloc.h b/alloc.h
deleted file mode 100644
index 1b1d893..0000000
--- a/alloc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef ALLOC_H
-#define ALLOC_H
-
-extern /*@null@*//*@out@*/char *alloc();
-extern void alloc_free();
-extern int alloc_re();
-
-#endif
diff --git a/alloc_re.c b/alloc_re.c
deleted file mode 100644
index feb8b49..0000000
--- a/alloc_re.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#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;
-}
diff --git a/buffer.h b/buffer.h
deleted file mode 100644
index df59c52..0000000
--- a/buffer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef BUFFER_H
-#define BUFFER_H
-
-typedef struct buffer {
-  char *x;
-  unsigned int p;
-  unsigned int n;
-  int fd;
-  int (*op)();
-} buffer;
-
-#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
-#define BUFFER_INSIZE 8192
-#define BUFFER_OUTSIZE 8192
-
-extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int);
-
-extern int buffer_flush(buffer *);
-extern int buffer_put(buffer *,char *,unsigned int);
-extern int buffer_putalign(buffer *,char *,unsigned int);
-extern int buffer_putflush(buffer *,char *,unsigned int);
-extern int buffer_puts(buffer *,char *);
-extern int buffer_putsalign(buffer *,char *);
-extern int buffer_putsflush(buffer *,char *);
-
-#define buffer_PUTC(s,c) \
-  ( ((s)->n != (s)->p) \
-    ? ( (s)->x[(s)->p++] = (c), 0 ) \
-    : buffer_put((s),&(c),1) \
-  )
-
-extern int buffer_get(buffer *,char *,unsigned int);
-extern int buffer_bget(buffer *,char *,unsigned int);
-extern int buffer_feed(buffer *);
-
-extern char *buffer_peek(buffer *);
-extern void buffer_seek(buffer *,unsigned int);
-
-#define buffer_PEEK(s) ( (s)->x + (s)->n )
-#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
-
-extern int buffer_copy(buffer *,buffer *);
-
-extern buffer *buffer_0;
-extern buffer *buffer_0small;
-extern buffer *buffer_1;
-extern buffer *buffer_1small;
-extern buffer *buffer_2;
-
-#endif
diff --git a/byte.h b/byte.h
index de06c69..8df08fa 100644
--- a/byte.h
+++ b/byte.h
@@ -1,13 +1,9 @@
 #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();
+#include <string.h>
 
-#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
+#define byte_copy(to, n, from) memcpy(to, from, n)
+#define byte_copyr(to, n, from) memmove(to, from, n)
 
 #endif
diff --git a/byte_copy.c b/byte_copy.c
deleted file mode 100644
index eaad11b..0000000
--- a/byte_copy.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#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;
-  }
-}
diff --git a/byte_cr.c b/byte_cr.c
deleted file mode 100644
index 3e7a1d5..0000000
--- a/byte_cr.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#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;
-  }
-}
diff --git a/byte_diff.c b/byte_diff.c
deleted file mode 100644
index cdbd760..0000000
--- a/byte_diff.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#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);
-}
diff --git a/byte_zero.c b/byte_zero.c
deleted file mode 100644
index 92009ba..0000000
--- a/byte_zero.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#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;
-  }
-}
diff --git a/error.c b/error.c
deleted file mode 100644
index c3babc1..0000000
--- a/error.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#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
-
-int error_nodevice =
-#ifdef ENXIO
-ENXIO;
-#else
--14;
-#endif
diff --git a/error.h b/error.h
deleted file mode 100644
index fdb9f23..0000000
--- a/error.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef ERROR_H
-#define ERROR_H
-
-#include <errno.h>
-
-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 int error_nodevice;
-
-extern char *error_str(int);
-extern int error_temp(int);
-
-#endif
diff --git a/error_str.c b/error_str.c
deleted file mode 100644
index 59954d6..0000000
--- a/error_str.c
+++ /dev/null
@@ -1,273 +0,0 @@
-#include <errno.h>
-#include "error.h"
-
-#define X(e,s) if (i == e) return s;
-
-char *error_str(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")
-  X(error_nodevice,"device not configured")
-#ifdef ESRCH
-  X(ESRCH,"no such process")
-#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";
-}
diff --git a/fmt.h b/fmt.h
deleted file mode 100644
index 5d6b1b4..0000000
--- a/fmt.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#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_uint64();
-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
diff --git a/fmt_uint64.c b/fmt_uint64.c
deleted file mode 100644
index 707ebbd..0000000
--- a/fmt_uint64.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "fmt.h"
-#include <stdint.h>
-
-unsigned int fmt_uint64(s,u) register char *s; register uint64_t u;
-{
-  register unsigned int len; register uint64_t 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;
-}
diff --git a/gen_alloc.h b/gen_alloc.h
deleted file mode 100644
index b94a956..0000000
--- a/gen_alloc.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
diff --git a/gen_allocdefs.h b/gen_allocdefs.h
deleted file mode 100644
index 783a9b1..0000000
--- a/gen_allocdefs.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#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
diff --git a/hostname.c b/hostname.c
index aa92918..d945331 100644
--- a/hostname.c
+++ b/hostname.c
@@ -8,6 +8,6 @@ void get_hostname(char *hostnam, size_t len) {
   if(gethostname(hostnam, len) == 0) return;
 
   /* Fatal error if we can't read the hostname. */
-  strerr_die1sys(111, "safecat: fatal: can't determine hostname: ");
+  strerr_die_sys(111, "safecat: fatal: ","can't determine hostname: ");
 }
 /* ****************************************************************** */
diff --git a/meson.build b/meson.build
index 7588980..bc3dc01 100644
--- a/meson.build
+++ b/meson.build
@@ -12,19 +12,10 @@ configure_file(configuration: config,
 	input: 'hassgact.h.in', output: 'hassgact.h')
 
 executable('safecat',
-	'alloc.c',
-	'alloc_re.c',
-	'byte_copy.c',
-	'byte_cr.c',
-	'error.c',
-	'error_str.c',
-	'fmt_uint64.c',
 	'hostname.c',
 	'safecat.c',
 	'sig.c',
 	'stat_dir.c',
-	'str_diffn.c',
-	'str_len.c',
 	'stralloc_cat.c',
 	'stralloc_catb.c',
 	'stralloc_cats.c',
@@ -40,9 +31,6 @@ executable('safecat',
 	'substdio.c',
 	'substdo.c',
 	'substdio_copy.c',
-	'taia_fmtfrac.c',
-	'taia_now.c',
-	'taia_tai.c',
 	'tempfile.c',
 	'writefile.c',
 	install: true)
diff --git a/readwrite.h b/readwrite.h
index 2a64968..89c20d7 100644
--- a/readwrite.h
+++ b/readwrite.h
@@ -1,7 +1,6 @@
 #ifndef READWRITE_H
 #define READWRITE_H
 
-extern int read();
-extern int write();
+extern int false_write(int fd, char *buf, int len);
 
 #endif
diff --git a/safecat.c b/safecat.c
index 962e1af..cb3c8f4 100644
--- a/safecat.c
+++ b/safecat.c
@@ -1,7 +1,7 @@
 /* Copyright (c) 2000, Len Budney. See COPYING for details. */
 
 /* safecat.c -- write stdin to a directory using the maildir algorithm.
- * 
+ *
  * Safecat implements the maildir algorithm of Professor DJ Bernstein,
  * which is also used by his mail agent Qmail.  This program can be
  * used to deliver data to a qmail maildir from a shell script,
@@ -9,7 +9,6 @@
  * directory).
  */
 
-#include "alloc.h"
 #include "sig.h"
 #include "stat_dir.h"
 #include "stralloc.h"
@@ -32,8 +31,7 @@
 #endif
 
 /* Function prototypes. */
-static
-void die_nomem() { strerr_die2x(111,"safecat: fatal: ","out of memory"); }
+void die_nomem() { strerr_die_x(111,"safecat: fatal: ","out of memory"); }
 stralloc tmppath = {0};
 
 /* ****************************************************************** */
@@ -49,7 +47,7 @@ int main(int argc, char *argv[]) {
 
   /* Check that we were called with the correct number of arguments. */
   if(argc != 3) {
-    strerr_die2x(100, "safecat: usage: ","safecat <tempdir> <destdir>");
+    strerr_die_x(100, "safecat: usage: ","safecat <tempdir> <destdir>");
   }
 
   /* Scan the command line arguments, to get the temp directory
@@ -58,7 +56,7 @@ int main(int argc, char *argv[]) {
   destdir = argv[2];
 
   /* Declare a handler for SIGALRM so we can time out. */
-  set_handler(SIGALRM, alarm_handler);
+  set_alarm_handler();
 
   /* Step 1:  Check that the supplied directories are OK. */
   stat_dir(tempdir);
@@ -69,22 +67,22 @@ int main(int argc, char *argv[]) {
     /* Get the temporary filename to use now for dumping data. */
     mk_tempfile(&outfile);
     if (!stralloc_cats(&outpath,tempdir)) die_nomem();
-    if (!stralloc_append(&outpath, "/")) die_nomem();
+    if (!stralloc_append(&outpath, '/')) die_nomem();
     if (!stralloc_cat(&outpath,&outfile)) die_nomem();
     if(stat(outpath.s,&filestat) == -1 && errno == ENOENT) {
       if (!stralloc_cats(&dstpath, destdir)) die_nomem();
-      if (!stralloc_append(&dstpath, "/")) die_nomem();
+      if (!stralloc_append(&dstpath, '/')) die_nomem();
       if (!stralloc_cat(&dstpath,&outfile)) die_nomem();
 
       if (!stralloc_cats(&tmppath, tempdir)) die_nomem();
-      if (!stralloc_append(&tmppath, "/")) die_nomem();
+      if (!stralloc_append(&tmppath, '/')) die_nomem();
       if (!stralloc_cat(&tmppath,&outfile)) die_nomem();
       break;
     }
 
     /* Try up to 5 times, every 2 seconds. */
     if(count == 5) {
-      strerr_die2x(111, "safecat: fatal: ","could not stat temporary file");
+      strerr_die_x(111, "safecat: fatal: ","could not stat temporary file");
     }
 
     /* Wait 2 seconds, and try again. */
@@ -97,7 +95,7 @@ int main(int argc, char *argv[]) {
   alarm(86400);
   outfd = open(tmppath.s,O_WRONLY | O_EXCL | O_CREAT | O_LARGEFILE,0666);
   if(outfd == -1) {
-    strerr_die2sys(111,"safecat: fatal: ","couldn't create output file: ");
+    strerr_die_sys(111,"safecat: fatal: ","couldn't create output file: ");
   }
 
   /* Step 5:  Copy stdin to the temp file. */
@@ -106,13 +104,13 @@ int main(int argc, char *argv[]) {
   /* Close the file, checking the return value. */
   if(fsync(outfd) == -1 || close(outfd) == -1) {
     unlink(tmppath.s);
-    strerr_die2sys(111,"safecat: fatal: ","can't fsync/close output file: ");
+    strerr_die_sys(111,"safecat: fatal: ","can't fsync/close output file: ");
   }
 
   /* Step 6:  Link the temp file to its final destination. */
   if(link(tmppath.s,dstpath.s) == -1) {
     unlink(tmppath.s);
-    strerr_die2sys(111,"safecat: fatal: ","can't link output file: ");
+    strerr_die_sys(111,"safecat: fatal: ","can't link output file: ");
   }
   /* We've succeeded!  Now, no matter what, we return "success" */
 
diff --git a/sig.c b/sig.c
index 87f062b..c27d07e 100644
--- a/sig.c
+++ b/sig.c
@@ -8,21 +8,21 @@
 
 /* ****************************************************************** */
 extern stralloc tmppath;
-void alarm_handler(int sig) {
+static void alarm_handler(int sig) {
   unlink(tmppath.s);
-  strerr_die2x(111,"safecat: fatal: ","Timer has expired; giving up");
+  strerr_die_x(111,"safecat: fatal: ","Timer has expired; giving up");
 }
 /* ****************************************************************** */
 
 
-/* ****************************************************************** 
+/* ******************************************************************
    This function was pretty much lifted from Qmail code.  Thanks to
-   Professor Bernstein. 
+   Professor Bernstein.
    ****************************************************************** */
-void set_handler(int sig, void (*h)()) {
+void set_alarm_handler(void) {
 #ifdef HASSIGACTION
   struct sigaction sa;
-  sa.sa_handler = h;
+  sa.sa_handler = alarm_handler;
   sa.sa_flags = 0;
   sigemptyset(&sa.sa_mask);
   sigaction(sig,&sa,(struct sigaction *) 0);
diff --git a/sig.h b/sig.h
index e84adb7..f771ae7 100644
--- a/sig.h
+++ b/sig.h
@@ -1,5 +1,4 @@
 /* Copyright (c) 2000, Len Budney. See COPYING for details. */
 
-/* Signal handler for SIGALRM and signal handler setter. */
-void set_handler(int sig, void (*f)());
-void alarm_handler(int sig);
+/* Set signal handler for SIGALRM. */
+void set_alarm_handler(void);
diff --git a/stat_dir.c b/stat_dir.c
index 27f0212..dbffd93 100644
--- a/stat_dir.c
+++ b/stat_dir.c
@@ -10,14 +10,13 @@ void stat_dir(char *dirname) {
   struct stat filestat;
 
   if(stat(dirname,&filestat) != 0) {
-    strerr_die2sys(111,"safecat: fatal: ","could not stat directory: ");
+    strerr_die_sys(111,"safecat: fatal: ","could not stat directory: ");
   }
   if( !S_ISDIR(filestat.st_mode) ) {
-    strerr_die2x(111, "safecat: fatal: ","not a directory");
+    strerr_die_x(111, "safecat: fatal: ","not a directory");
   }
   if((filestat.st_mode & S_IWUSR) != S_IWUSR) {
-    strerr_die2x(111, "safecat: fatal: ","directory not writable");
+    strerr_die_x(111, "safecat: fatal: ","directory not writable");
   }
-  filestat.st_mode = 0;
 }
 /* ****************************************************************** */
diff --git a/str.h b/str.h
deleted file mode 100644
index ab4aedd..0000000
--- a/str.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef STR_H
-#define STR_H
-
-extern unsigned int str_copy(char *,char *);
-extern int str_diff(char *,char *);
-extern int str_diffn(char *,char *,unsigned int);
-extern unsigned int str_len(char *);
-extern unsigned int str_chr(char *,int);
-extern unsigned int str_rchr(char *,int);
-extern int str_start(char *,char *);
-
-#define str_equal(s,t) (!str_diff((s),(t)))
-
-#endif
diff --git a/str_diffn.c b/str_diffn.c
deleted file mode 100644
index 89142f1..0000000
--- a/str_diffn.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#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);
-}
diff --git a/str_len.c b/str_len.c
deleted file mode 100644
index 5bd3f62..0000000
--- a/str_len.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "str.h"
-
-unsigned int str_len(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;
-  }
-}
diff --git a/stralloc.3 b/stralloc.3
index 3123521..25dde56 100644
--- a/stralloc.3
+++ b/stralloc.3
@@ -20,7 +20,7 @@ .SH SYNTAX
 .br
 int \fBstralloc_catb\fP(&\fIsa\fR,\fIbuf\fR,\fIlen\fR);
 
-int \fBstralloc_append\fP(&\fIsa\fR,\fIbuf\fR);
+int \fBstralloc_append\fP(&\fIsa\fR,\fIc\fR);
 .br
 int \fBstralloc_0\fP(&\fIsa\fR);
 
@@ -125,7 +125,7 @@ .SH DESCRIPTION
 
 .B stralloc_append
 adds a single character,
-.IR *buf ,
+.IR c ,
 to
 .IR sa ,
 allocating space if necessary.
diff --git a/stralloc.h b/stralloc.h
index 2feb7d0..7c50472 100644
--- a/stralloc.h
+++ b/stralloc.h
@@ -1,29 +1,18 @@
 #ifndef STRALLOC_H
 #define STRALLOC_H
 
-#include "gen_alloc.h"
+typedef struct stralloc { char *s; unsigned int len; unsigned int a; } stralloc;
 
-GEN_ALLOC_typedef(stralloc,char,s,len,a)
+extern int stralloc_ready(stralloc *x, unsigned int n);
+extern int stralloc_readyplus(stralloc *x, unsigned int n);
+extern int stralloc_copy(stralloc *sato, stralloc *safrom);
+extern int stralloc_copyb(stralloc *sa, char *s, unsigned int n);
+extern int stralloc_catb(stralloc *sa, char *s, unsigned int n);
+extern int stralloc_cat(stralloc *sato, stralloc *safrom);
+extern int stralloc_copys(stralloc *sa, char *s);
+extern int stralloc_cats(stralloc *sa, char *s);
+extern int stralloc_append(stralloc *x, char i);
 
-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,"")
-
-extern int stralloc_catulong0();
-extern int stralloc_catlong0();
-
-#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
-#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(unsigned long) (i),(n)))
-#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(long) (i),(n)))
-#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(long) (i),0))
+#define stralloc_0(sa) stralloc_append(sa,'\0')
 
 #endif
diff --git a/stralloc_cat.c b/stralloc_cat.c
index efbb112..ca95b9b 100644
--- a/stralloc_cat.c
+++ b/stralloc_cat.c
@@ -1,9 +1,7 @@
 #include "byte.h"
 #include "stralloc.h"
 
-int stralloc_cat(sato,safrom)
-stralloc *sato;
-stralloc *safrom;
+int stralloc_cat(stralloc *sato, stralloc *safrom)
 {
   return stralloc_catb(sato,safrom->s,safrom->len);
 }
diff --git a/stralloc_catb.c b/stralloc_catb.c
index 67dbcc0..d9161d4 100644
--- a/stralloc_catb.c
+++ b/stralloc_catb.c
@@ -1,10 +1,7 @@
 #include "stralloc.h"
 #include "byte.h"
 
-int stralloc_catb(sa,s,n)
-stralloc *sa;
-char *s;
-unsigned int n;
+int stralloc_catb(stralloc *sa, char *s, unsigned int n)
 {
   if (!sa->s) return stralloc_copyb(sa,s,n);
   if (!stralloc_readyplus(sa,n + 1)) return 0;
diff --git a/stralloc_cats.c b/stralloc_cats.c
index d300286..1e3a147 100644
--- a/stralloc_cats.c
+++ b/stralloc_cats.c
@@ -1,10 +1,7 @@
-#include "byte.h"
-#include "str.h"
 #include "stralloc.h"
+#include <string.h>
 
-int stralloc_cats(sa,s)
-stralloc *sa;
-char *s;
+int stralloc_cats(stralloc *sa, char *s)
 {
-  return stralloc_catb(sa,s,str_len(s));
+  return stralloc_catb(sa,s,strlen(s));
 }
diff --git a/stralloc_copy.c b/stralloc_copy.c
index 652aed6..f5d6200 100644
--- a/stralloc_copy.c
+++ b/stralloc_copy.c
@@ -1,9 +1,7 @@
 #include "byte.h"
 #include "stralloc.h"
 
-int stralloc_copy(sato,safrom)
-stralloc *sato;
-stralloc *safrom;
+int stralloc_copy(stralloc *sato, stralloc *safrom)
 {
   return stralloc_copyb(sato,safrom->s,safrom->len);
 }
diff --git a/stralloc_eady.c b/stralloc_eady.c
index 3a31f4b..53a02ff 100644
--- a/stralloc_eady.c
+++ b/stralloc_eady.c
@@ -1,6 +1,20 @@
-#include "alloc.h"
 #include "stralloc.h"
-#include "gen_allocdefs.h"
+#include <stdlib.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)
+int stralloc_ready(stralloc *x, unsigned int n)
+{ register unsigned int i;
+  if (x->s) {
+    i = x->a;
+    if (n > i) {
+      x->a = 30 + n + (n >> 3);
+      char * new = realloc(x->s,x->a);
+      if(!new) { x->a = i; return 0; }
+      x->s = new; }
+    return 1; }
+  x->len = 0;
+  return !!(x->s = malloc(x->a = n)); }
+
+int stralloc_readyplus(stralloc *x, unsigned int n) {
+  if (x->a) n += x->len;
+  return stralloc_ready(x, n);
+}
diff --git a/stralloc_opyb.c b/stralloc_opyb.c
index ac258b3..04bf72e 100644
--- a/stralloc_opyb.c
+++ b/stralloc_opyb.c
@@ -1,10 +1,7 @@
 #include "stralloc.h"
 #include "byte.h"
 
-int stralloc_copyb(sa,s,n)
-stralloc *sa;
-char *s;
-unsigned int n;
+int stralloc_copyb(stralloc *sa, char *s, unsigned int n)
 {
   if (!stralloc_ready(sa,n + 1)) return 0;
   byte_copy(sa->s,n,s);
diff --git a/stralloc_opys.c b/stralloc_opys.c
index fdd7807..654f6b4 100644
--- a/stralloc_opys.c
+++ b/stralloc_opys.c
@@ -1,10 +1,7 @@
-#include "byte.h"
-#include "str.h"
 #include "stralloc.h"
+#include <string.h>
 
-int stralloc_copys(sa,s)
-stralloc *sa;
-char *s;
+int stralloc_copys(stralloc *sa, char *s)
 {
-  return stralloc_copyb(sa,s,str_len(s));
+  return stralloc_copyb(sa,s,strlen(s));
 }
diff --git a/stralloc_pend.c b/stralloc_pend.c
index a3443b8..712d3b3 100644
--- a/stralloc_pend.c
+++ b/stralloc_pend.c
@@ -1,5 +1,8 @@
-#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)
+extern int stralloc_append(stralloc *x, char i)
+{
+	if (!stralloc_readyplus(x,1)) return 0;
+	x->s[x->len++] = i;
+	return 1;
+}
diff --git a/strerr.h b/strerr.h
index d18e833..0a99447 100644
--- a/strerr.h
+++ b/strerr.h
@@ -1,80 +1,23 @@
 #ifndef STRERR_H
 #define STRERR_H
 
+#include <unistd.h>
+
 struct strerr
  {
-  struct strerr *who;
   char *x;
-  char *y;
-  char *z;
  }
 ;
 
 extern struct strerr strerr_sys;
-extern void strerr_sysinit();
-
-extern char *strerr();
-extern void strerr_warn();
-extern void strerr_die();
-
-#define STRERR(r,se,a) \
-{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; }
-
-#define STRERR_SYS(r,se,a) \
-{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; }
-#define STRERR_SYS3(r,se,a,b,c) \
-{ se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; }
-
-#define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \
-strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se))
-#define strerr_warn5(x1,x2,x3,x4,x5,se) \
-strerr_warn((x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se))
-#define strerr_warn4(x1,x2,x3,x4,se) \
-strerr_warn((x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_warn3(x1,x2,x3,se) \
-strerr_warn((x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_warn2(x1,x2,se) \
-strerr_warn((x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_warn1(x1,se) \
-strerr_warn((x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
+extern void strerr_sysinit(void);
 
-#define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se))
-#define strerr_die5(e,x1,x2,x3,x4,x5,se) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se))
-#define strerr_die4(e,x1,x2,x3,x4,se) \
-strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_die3(e,x1,x2,x3,se) \
-strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_die2(e,x1,x2,se) \
-strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
-#define strerr_die1(e,x1,se) \
-strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se))
+extern void strerr_die(int e, struct strerr *se, ...);
 
-#define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys)
-#define strerr_die5sys(e,x1,x2,x3,x4,x5) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,&strerr_sys)
-#define strerr_die4sys(e,x1,x2,x3,x4) \
-strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,&strerr_sys)
-#define strerr_die3sys(e,x1,x2,x3) \
-strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,&strerr_sys)
-#define strerr_die2sys(e,x1,x2) \
-strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys)
-#define strerr_die1sys(e,x1) \
-strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys)
+#define strerr_die_sys(e,...) \
+strerr_die((e),&strerr_sys,__VA_ARGS__,(char *) 0)
 
-#define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) 0)
-#define strerr_die5x(e,x1,x2,x3,x4,x5) \
-strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) 0)
-#define strerr_die4x(e,x1,x2,x3,x4) \
-strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) 0)
-#define strerr_die3x(e,x1,x2,x3) \
-strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0)
-#define strerr_die2x(e,x1,x2) \
-strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0)
-#define strerr_die1x(e,x1) \
-strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0)
+#define strerr_die_x(e,...) \
+strerr_die((e),NULL,__VA_ARGS__,(char *) 0)
 
 #endif
diff --git a/strerr_die.c b/strerr_die.c
index f070229..69d74f9 100644
--- a/strerr_die.c
+++ b/strerr_die.c
@@ -1,37 +1,25 @@
 #include "substdio.h"
 #include "subfd.h"
 #include "strerr.h"
+#include <stdarg.h>
 #include <unistd.h>
 
-void strerr_warn(x1,x2,x3,x4,x5,x6,se)
-char *x1; char *x2; char *x3; char *x4; char *x5; char *x6;
-struct strerr *se;
+void strerr_die(int e, struct strerr *se, ...)
 {
   strerr_sysinit();
- 
-  if (x1) substdio_puts(subfderr,x1);
-  if (x2) substdio_puts(subfderr,x2);
-  if (x3) substdio_puts(subfderr,x3);
-  if (x4) substdio_puts(subfderr,x4);
-  if (x5) substdio_puts(subfderr,x5);
-  if (x6) substdio_puts(subfderr,x6);
- 
-  while(se) {
+
+  va_list ap;
+  va_start(ap, se);
+  for(char *s; (s = va_arg(ap, char *)); ) {
+    substdio_puts(subfderr,s);
+  }
+
+  if(se) {
     if (se->x) substdio_puts(subfderr,se->x);
-    if (se->y) substdio_puts(subfderr,se->y);
-    if (se->z) substdio_puts(subfderr,se->z);
-    se = se->who;
   }
- 
+
   substdio_puts(subfderr,"\n");
   substdio_flush(subfderr);
-}
 
-void strerr_die(e,x1,x2,x3,x4,x5,x6,se)
-int e;
-char *x1; char *x2; char *x3; char *x4; char *x5; char *x6;
-struct strerr *se;
-{
-  strerr_warn(x1,x2,x3,x4,x5,x6,se);
   _exit(e);
 }
diff --git a/strerr_sys.c b/strerr_sys.c
index 198198b..0dedc07 100644
--- a/strerr_sys.c
+++ b/strerr_sys.c
@@ -1,12 +1,10 @@
-#include "error.h"
 #include "strerr.h"
+#include <string.h>
+#include <errno.h>
 
 struct strerr strerr_sys;
 
-void strerr_sysinit()
+void strerr_sysinit(void)
 {
-  strerr_sys.who = 0;
-  strerr_sys.x = error_str(errno);
-  strerr_sys.y = "";
-  strerr_sys.z = "";
+  strerr_sys.x = strerror(errno);
 }
diff --git a/subfd.h b/subfd.h
index bcb2e1e..a560889 100644
--- a/subfd.h
+++ b/subfd.h
@@ -3,13 +3,7 @@
 
 #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
diff --git a/subfderr.c b/subfderr.c
index 011ab0f..8c5c537 100644
--- a/subfderr.c
+++ b/subfderr.c
@@ -3,5 +3,5 @@
 #include "subfd.h"
 
 char subfd_errbuf[256];
-static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256);
+static substdio it = SUBSTDIO_FDBUF(false_write,2,subfd_errbuf,256);
 substdio *subfderr = &it;
diff --git a/subfdouts.c b/subfdouts.c
index 5be356d..471bba8 100644
--- a/subfdouts.c
+++ b/subfdouts.c
@@ -3,5 +3,5 @@
 #include "subfd.h"
 
 char subfd_outbufsmall[256];
-static substdio it = SUBSTDIO_FDBUF(write,1,subfd_outbufsmall,256);
+static substdio it = SUBSTDIO_FDBUF(false_write,1,subfd_outbufsmall,256);
 substdio *subfdoutsmall = &it;
diff --git a/substdi.c b/substdi.c
index 42407a1..23892af 100644
--- a/substdi.c
+++ b/substdi.c
@@ -1,40 +1,19 @@
 #include "substdio.h"
 #include "byte.h"
-#include "error.h"
+#include <errno.h>
 
-static int oneread(op,fd,buf,len)
-register int (*op)();
-register int fd;
-register char *buf;
-register int len;
+static int oneread(int (*op)(int fd, char *buf, int len), int fd, char *buf, int len)
 {
   register int r;
 
   for (;;) {
     r = op(fd,buf,len);
-    if (r == -1) if (errno == error_intr) continue;
+    if (r == -1) if (errno == EINTR) 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;
+int substdio_feed(substdio *s)
 {
   register int r;
   register int q;
@@ -49,43 +28,3 @@ register substdio *s;
   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;
-}
diff --git a/substdio.c b/substdio.c
index d03dff2..a6160f3 100644
--- a/substdio.c
+++ b/substdio.c
@@ -1,11 +1,6 @@
 #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;
+void substdio_fdbuf(substdio *s, int (*op)(), int fd, char *buf, int len)
 {
   s->x = buf;
   s->fd = fd;
diff --git a/substdio.h b/substdio.h
index c3f7f7d..0fdf4db 100644
--- a/substdio.h
+++ b/substdio.h
@@ -6,42 +6,27 @@ typedef struct substdio {
   int p;
   int n;
   int fd;
-  int (*op)();
+  int (*op)(int fd, char *buf, int len);
 } substdio;
 
 #define SUBSTDIO_FDBUF(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
 
-extern void substdio_fdbuf();
+extern void substdio_fdbuf(substdio *s, int (*op)(int fd, char *buf, int len), int fd, char *buf, int len);
 
-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_flush(substdio *s);
+extern int substdio_put(substdio *s, char *buf, int len);
+extern int substdio_bput(substdio *s, char *buf, int len);
+extern int substdio_puts(substdio *s, char *buf);
 
-extern int substdio_get();
-extern int substdio_bget();
-extern int substdio_feed();
-
-extern char *substdio_peek();
-extern void substdio_seek();
+extern int substdio_feed(substdio *s);
 
 #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();
+extern int substdio_copy(substdio *ssout, substdio *ssin);
 
 #endif
diff --git a/substdio_copy.c b/substdio_copy.c
index 71cf200..5bbfd3f 100644
--- a/substdio_copy.c
+++ b/substdio_copy.c
@@ -1,8 +1,6 @@
 #include "substdio.h"
 
-int substdio_copy(ssout,ssin)
-register substdio *ssout;
-register substdio *ssin;
+int substdio_copy(substdio *ssout, substdio *ssin)
 {
   register int n;
   register char *x;
diff --git a/substdo.c b/substdo.c
index fb616f7..cd75e28 100644
--- a/substdo.c
+++ b/substdo.c
@@ -1,47 +1,38 @@
 #include "substdio.h"
-#include "str.h"
 #include "byte.h"
-#include "error.h"
+#include <string.h>
+#include <errno.h>
 
-static int allwrite(op,fd,buf,len)
-register int (*op)();
-register int fd;
-register char *buf;
-register int len;
+static int allwrite(int (*op)(int fd, char *buf, int len), int fd, char *buf, int len)
 {
   register int w;
 
   while (len) {
     w = op(fd,buf,len);
     if (w == -1) {
-      if (errno == error_intr) continue;
+      if (errno == EINTR) 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;
+int substdio_flush(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;
+int substdio_bput(substdio *s, char *buf, 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;
@@ -52,13 +43,10 @@ register int len;
   return 0;
 }
 
-int substdio_put(s,buf,len)
-register substdio *s;
-register char *buf;
-register int len;
+int substdio_put(substdio *s, char *buf, int len)
 {
   register int n;
- 
+
   n = s->n;
   if (len > n - s->p) {
     if (substdio_flush(s) == -1) return -1;
@@ -77,32 +65,7 @@ register int 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;
+int substdio_puts(substdio *s, char *buf)
 {
-  return substdio_putflush(s,buf,str_len(buf));
+  return substdio_put(s,buf,strlen(buf));
 }
diff --git a/tai.h b/tai.h
deleted file mode 100644
index 6c2fb47..0000000
--- a/tai.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef TAI_H
-#define TAI_H
-
-#include <stdint.h>
-
-struct tai {
-  uint64_t x;
-} ;
-
-extern void tai_now();
-
-#define tai_approx(t) ((double) ((t)->x))
-
-extern void tai_add();
-extern void tai_sub();
-#define tai_less(t,u) ((t)->x < (u)->x)
-
-#define TAI_PACK 8
-extern void tai_pack();
-extern void tai_unpack();
-
-#endif
diff --git a/taia.h b/taia.h
deleted file mode 100644
index 7aa30dc..0000000
--- a/taia.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef TAIA_H
-#define TAIA_H
-
-#include "tai.h"
-
-struct taia {
-  struct tai sec;
-  unsigned long nano; /* 0...999999999 */
-  unsigned long atto; /* 0...999999999 */
-} ;
-
-extern void taia_tai();
-
-extern void taia_now();
-
-extern double taia_approx();
-extern double taia_frac();
-
-extern void taia_add();
-extern void taia_sub();
-extern void taia_half();
-extern int taia_less();
-
-#define TAIA_PACK 16
-extern void taia_pack();
-extern void taia_unpack();
-
-#define TAIA_FMTFRAC 19
-extern unsigned int taia_fmtfrac();
-
-#endif
diff --git a/taia_fmtfrac.c b/taia_fmtfrac.c
deleted file mode 100644
index f02945d..0000000
--- a/taia_fmtfrac.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "taia.h"
-
-unsigned int taia_fmtfrac(s,t)
-char *s;
-struct taia *t;
-{
-  unsigned long x;
-
-  if (s) {
-    x = t->atto;
-    s[17] = '0' + (x % 10); x /= 10;
-    s[16] = '0' + (x % 10); x /= 10;
-    s[15] = '0' + (x % 10); x /= 10;
-    s[14] = '0' + (x % 10); x /= 10;
-    s[13] = '0' + (x % 10); x /= 10;
-    s[12] = '0' + (x % 10); x /= 10;
-    s[11] = '0' + (x % 10); x /= 10;
-    s[10] = '0' + (x % 10); x /= 10;
-    s[9] = '0' + (x % 10);
-    x = t->nano;
-    s[8] = '0' + (x % 10); x /= 10;
-    s[7] = '0' + (x % 10); x /= 10;
-    s[6] = '0' + (x % 10); x /= 10;
-    s[5] = '0' + (x % 10); x /= 10;
-    s[4] = '0' + (x % 10); x /= 10;
-    s[3] = '0' + (x % 10); x /= 10;
-    s[2] = '0' + (x % 10); x /= 10;
-    s[1] = '0' + (x % 10); x /= 10;
-    s[0] = '0' + (x % 10);
-  }
-
-  return 18;
-}
diff --git a/taia_now.c b/taia_now.c
deleted file mode 100644
index a176b93..0000000
--- a/taia_now.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <sys/types.h>
-#include <sys/time.h>
-#include "taia.h"
-
-/* XXX: breaks tai encapsulation */
-
-void taia_now(t)
-struct taia *t;
-{
-  struct timeval now;
-  gettimeofday(&now,(struct timezone *) 0);
-  t->sec.x = 4611686018427387914ULL + (uint64_t) now.tv_sec;
-  t->nano = 1000 * now.tv_usec + 500;
-  t->atto = 0;
-}
diff --git a/taia_tai.c b/taia_tai.c
deleted file mode 100644
index 72d8108..0000000
--- a/taia_tai.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "taia.h"
-
-void taia_tai(ta,t)
-struct taia *ta;
-struct tai *t;
-{
-  *t = ta->sec;
-}
diff --git a/tempfile.c b/tempfile.c
index 659c8fa..5f10ec3 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -3,49 +3,32 @@
 #include "hostname.h"
 #include "stralloc.h"
 #include "strerr.h"
-#include "tai.h"
-#include "taia.h"
-#include "fmt.h"
+#include <time.h>
 #include <unistd.h>
+#include <stdio.h>
 
-static
-void die_nomem() { strerr_die2x(111,"safecat: fatal: ","out of memory"); }
+extern void die_nomem();
 
 /* ****************************************************************** */
 void mk_tempfile(stralloc *tmpf) {
   char host[256];
-  char secbuf[11];
-  char atto[TAIA_FMTFRAC];
-  char pidbuf[6];
-  struct taia now;
-  struct tai sec;
+#define secbuf host
+  struct timespec now;
   unsigned long int pid = (unsigned long)getpid();
 
   /* Get a microsecond timestamp with which to build a filename. */
-  taia_now(&now);
-  taia_tai(&now,&sec);
+  clock_gettime(CLOCK_REALTIME, &now);
 
   /* Record the second timestamp on the string. */
-  secbuf[fmt_uint64(secbuf,(uint64_t) sec.x - 4611686018427387904)] = '\0';
-  if (!stralloc_cats(tmpf, secbuf)) die_nomem();
-  
   /* Append the microsecond timestamp to the string. */
-  if (!stralloc_cats(tmpf, ".M")) die_nomem();
-  taia_fmtfrac(atto,&now);
-  atto[6] = '\0'; /* truncate at microsecond */
-  if (!stralloc_cats(tmpf, atto)) die_nomem();
-
   /* Append the PID to the string. */
-  if (!stralloc_append(tmpf, "P")) die_nomem();
-  pidbuf[fmt_uint64(pidbuf, pid)] = '\0';
-  if (!stralloc_cats(tmpf, pidbuf)) die_nomem();
-  
+  sprintf(secbuf, "%lld.M%06dP%lu", (long long)now.tv_sec, (int)now.tv_nsec / 1000, pid);
+  if (!stralloc_cats(tmpf, secbuf)) die_nomem();
+
   /* Copy the hostname to the buffer. */
-  if (!stralloc_append(tmpf, ".")) die_nomem();
+  if (!stralloc_append(tmpf, '.')) die_nomem();
   get_hostname(host,sizeof(host));
   if (!stralloc_cats(tmpf, host)) die_nomem();
   if (!stralloc_0(tmpf)) die_nomem();
 }
 /* ****************************************************************** */
-
-
diff --git a/writefile.c b/writefile.c
index 2a5f116..4483ff2 100644
--- a/writefile.c
+++ b/writefile.c
@@ -10,6 +10,14 @@
 
 extern stralloc tmppath;
 
+static int false_read(int fd, char *buf, int len) {
+  return read(fd, buf, len);
+}
+
+int false_write(int fd, char *buf, int len) {
+  return write(fd, buf, len);
+}
+
 /* ****************************************************************** */
 void writefile(int fd) {
   char inbuf[512];
@@ -18,8 +26,8 @@ void writefile(int fd) {
   substdio ssout;
 
   /* Prepare substdio buffers for reading and writing. */
-  substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
-  substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf));
+  substdio_fdbuf(&ssin,false_read,0,inbuf,sizeof(inbuf));
+  substdio_fdbuf(&ssout,false_write,fd,outbuf,sizeof(outbuf));
 
   /* Copy stdin to the output file, watching the return values each time. */
   if (substdio_copy(&ssout,&ssin) < 0) goto fail;
@@ -30,6 +38,6 @@ void writefile(int fd) {
 
  fail:
   unlink(tmppath.s);
-  strerr_die2x(111,"safecat: fatal: ","unable to copy standard input");
+  strerr_die_x(111,"safecat: fatal: ","unable to copy standard input");
 }
 /* ****************************************************************** */
