--- a
+++ b/tools/msgcat.h
@@ -0,0 +1,178 @@
+/* -*-c++-*- */
+
+#ifndef __msgcath
+
+
+/***********************************************************
+Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that Alfalfa's name not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+If you make any modifications, bugfixes or other changes to this software
+we'd appreciate it if you could send a copy to us so we can keep things
+up-to-date.  Many thanks.
+				Kee Hinckley
+				Alfalfa Software, Inc.
+				267 Allston St., #3
+				Cambridge, MA 02139  USA
+				nazgul@alfalfa.com
+    
+******************************************************************/
+
+
+#include <sys/types.h>
+
+/*
+ * On disk data structures
+ */
+
+/* Edit History
+
+02/25/91   2 nazgul	Byte order flags, upped the version number
+11/03/90   1 hamilton	Alphalpha->Alfalfa & OmegaMail->Poste
+08/13/90   1 schulert	move from ua to omu
+*/
+
+/* For or'd constants */
+#define MCMakeId(s,m)		(unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \
+						 | (unsigned short)m )
+#define MCSetId(id)		(unsigned int) ( id >> (sizeof(short) * 8) )
+#define MCMsgId(id)		(unsigned int) ( (id << (sizeof(short) * 8)) \
+						>> (sizeof(short) * 8) )
+#undef S
+#undef UI
+#undef UL
+
+#define MCMagicLen	8
+#define MCMagic		"*nazgul*"
+#define MCLastMsg	0
+#define MCLastSet	0
+
+#define MCMajorVer	1
+#define MCMinorVer	0
+
+/*
+ * Critical note here.  Sets and Messages *MUST* be stored in ascending
+ * order.  There are stored that way (by specification) in the original
+ * data file, however in the process of merging in new stuff you might
+ * mix that up.  Don't!  The catget stuff does a binary search and will
+ * totally lose it if these aren't in order (not contiguous mind you, just
+ * in order.  If this turns out to be a major problem this could be enhanced
+ * by adding a 'sorted' flag to the db, and sorting msgs and sets at load
+ * time if things aren't sorted, but I'd like not to have to do that.
+ */
+
+/*
+ * I have tried here to define data structures which can be used
+ * while the catalog is on disk, and at runtime.
+ * This is rather dangerous of course, but I think it can be done without
+ * overly increasing the memory usage, and it makes loading and storing
+ * somewhat simpler and less prone to accidents.  I have also tried to
+ * define on disk data structures which can be updated in place, so that
+ * with a very large catalog (e.g. all system errors) you don't have to
+ * load everything in memory in order to add or update one set.  With
+ * this in mind there are "invalid" flags which allow items to be
+ * invalidated and thus not loaded at runtime.  Note however that although
+ * I pay attention to these when I load the DB, I do not currently use
+ * them in gencat (it just reads everything into memory), so there is
+ * no guarantee that this will all work.
+ */
+
+/* These should be publicly available */
+
+#define MCLoadBySet	0	/* Load entire sets as they are used */
+#define MCLoadAll	1	/* Load entire DB on catopen */
+
+extern char	*MCAppPath;	/* Additional search path for strings (appended) */
+
+/*
+ * MCOffsetT - Union to handle both disk and runtime pointers
+ */
+typedef union {
+    off_t	off;
+    char	*str;
+    void	*ptr;
+    struct _MCMsgT	*msg;
+    struct _MCSetT	*set;
+} MCOffsetT;
+
+/*
+ * MCMsgT - Message structure (disk and runtime)
+ */
+typedef struct _MCMsgT {
+    long	msgId;		/* Id of this message */
+    MCOffsetT	msg;		/* Relative offset on disk or pointer in memory */
+    long	invalid;	/* Valid on disk, loaded in memory */
+} MCMsgT;
+
+/*
+ * MCSetT - Set structure (disk and runtime)
+ */
+typedef struct _MCSetT {
+    long	setId;		/* Id of this set */
+    off_t	nextSet;	/* Offset of next set on disk */
+    union {
+	off_t	firstMsg;	/* Offset to first Msg (while on disk) */
+	MCMsgT	*msgs;		/* Pointer to array of msgs (in mem, loaded) */
+    } u;
+    MCOffsetT	data;		/* Offset to data, or pointer to data */
+    long	dataLen;	/* Length of data area on disk */
+    long	numMsgs;	/* Number of messages */
+    long	invalid;	/* Valid on disk, loaded in memory */
+} MCSetT;
+
+/*
+ * MCCatT - Runtime catalog pointer
+ */
+typedef struct {
+    long	loadType;	/* How to load the messages (see MSLoadType) */
+#ifdef HAVE_MMAP
+  union {
+#endif
+    int		fd;		/* File descriptor of catalog (if load-on-demand) */
+#ifdef HAVE_MMAP
+    caddr_t	addr;		/* Mmaped() address */
+  } u;
+    off_t	size;		/* File size */
+#endif
+    long	numSets;	/* Number of sets */
+    MCSetT	*sets;		/* Pointer to the sets */
+    off_t	firstSet;	/* Offset of first set on disk */
+} MCCatT;
+
+/*
+ * MCHeaderT - Disk file header
+ */
+typedef struct {
+    char	magic[MCMagicLen];	/* Magic cookie "*nazgul*" */
+    long	majorVer;		/* ++ on incompatible changes */
+    long	minorVer;		/* ++ on compatible changes */
+    long	flags;			/* Informational flags */
+    long	numSets;		/* Number of valid Sets */
+    off_t	firstSet;		/* Offset of first set on disk */
+} MCHeaderT;
+
+/* Some flags */
+#define MC68KByteOrder	0x01
+#define MCn86ByteOrder	0x02
+
+
+
+
+#endif