1 /*
2    Copyright (c) 1991-1999 Thomas T. Wetmore IV
3 
4    Permission is hereby granted, free of charge, to any person
5    obtaining a copy of this software and associated documentation
6    files (the "Software"), to deal in the Software without
7    restriction, including without limitation the rights to use, copy,
8    modify, merge, publish, distribute, sublicense, and/or sell copies
9    of the Software, and to permit persons to whom the Software is
10    furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be
13    included in all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22    SOFTWARE.
23 */
24 /* modified 05 Jan 2000 by Paul B. McBride (pmcbride@tiac.net) */
25 /*=============================================================
26  * btree.h -- BTREE database header
27  * Copyright(c) 1991-94 by T.T. Wetmore IV; all rights reserved
28  * pre-SourceForge version information:
29  *   2.3.4 - 24 Jun 93    2.3.5 - 19 Aug 93
30  *   3.0.0 - 04 Oct 94
31  *===========================================================*/
32 
33 #ifndef _BTREE_H
34 #define _BTREE_H
35 
36 #include "standard.h"
37 
38 #define BUFLEN 4096
39 /* see comment at declaration of INDEX below for explanation */
40 #define NOENTS ((BUFLEN-12)/12)
41 /* see comment at declaration of BLOCK below for explanation */
42 #define NORECS ((BUFLEN-12)/16)
43 
44 /*
45 All records in a LifeLines btree are indexed on 8 character keys
46 Note that this must be the same as MAXKEYWIDTH in gedcom.h
47 */
48 #define RKEYLEN 8
49 typedef struct {
50 	char r_rkey[RKEYLEN];
51 }  RKEY; /*record key*/
52 
53 
54 typedef INT FKEY; /*file key*/
55 
56 typedef char *RAWRECORD;
57 
58 typedef struct {
59 	FKEY k_mkey;  /* current master key*/
60 	FKEY k_fkey;  /* current file key*/
61 	/* ostat: -2=immutable, -1=writer, 0=closed, 1+=reader count */
62 	INT k_ostat;
63 } KEYFILE1;
64 
65 /*
66 Additional data added to keyfile by Perry in winter of 2000-2001
67 in order to trap attempt to open a non-keyfile, or an incorrect
68 version, or a database from a differing byte alignment. KEYFILE2
69 occurs directly after KEYFILE1, and the program will silently
70 add it to any database that does not yet have it.
71 */
72 typedef struct {
73 	char name[18]; /* KF_NAME */
74 	INT magic;     /* KF_MAGIC */ /* byte alignment check */
75 	INT version;   /* KF_VER */
76 } KEYFILE2;
77 
78 #define KF2_NAME "LifeLines Keyfile"
79 #define KF2_MAGIC 0x12345678
80 #define KF2_VER 1
81 
82 /*==============================================
83  * INDEX -- Data structure for BTREE index files
84  *  The constant NOENTS above depends on this exact contents:
85  * 12=4+2+4+2=sizeof(FKEY)+sizeof(SHORT)+sizeof(FKEY)+sizeof(SHORT)
86  * 12=8+4=sizeof(RKEY)+sizeof(FKEY)
87  *============================================*/
88 typedef struct {
89 	FKEY  ix_self;		/*fkey of index*/
90 	SHORT ix_type;           /*block/file type*/
91 	FKEY  ix_parent;         /*parent file's fkey*/
92 	SHORT ix_nkeys;          /*num of keys in index*/
93 	RKEY  ix_rkeys[NOENTS];  /*rkeys in index*/
94 	FKEY  ix_fkeys[NOENTS];  /*fkeys in index*/
95 } *INDEX, INDEXSTRUCT;
96 /*=======================================
97  * BTREE -- Internal BTREE data structure
98  *=====================================*/
99 typedef struct {
100 	STRING  b_basedir;   /* btree base directory */
101 	INDEX   b_master;    /* master index block */
102 	FKEY    b_nkey;      /* next index key */
103 	FILE   *b_kfp;       /* keyfile file pointer */
104 	KEYFILE1 b_kfile;    /* keyfile contents */
105 	INT     b_ncache;    /* number of indices in cache */
106 	INDEX  *b_cache;     /* index cache */
107 	BOOLEAN b_write;     /* database writeable? */
108 	BOOLEAN b_immut;     /* database immutable? */
109 } *BTREE, BTREESTRUCT;
110 #define bbasedir(b) ((b)->b_basedir)
111 #define bmaster(b)  ((b)->b_master)
112 /* #define bnkey(b)    ((b)->b_nkey) */ /* UNUSED */
113 #define bkfp(b)     ((b)->b_kfp)
114 #define bkfile(b)   ((b)->b_kfile)
115 #define bncache(b)  ((b)->b_ncache)
116 #define bcache(b)   ((b)->b_cache)
117 #define bwrite(b)   ((b)->b_write)
118 #define bimmut(b)   ((b)->b_immut)
119 
120 /*======================================================
121  * BLOCK -- Data structure for BTREE record file headers
122  *  The constant NORECS above depends on this exact contents:
123  * 12=4+2+4+2=sizeof(FKEY)+sizeof(SHORT)+sizeof(FKEY)+sizeof(SHORT)
124  * 16=8+4+4=sizeof(RKEY)+sizeof(INT)+sizeof(INT)
125  *====================================================*/
126 typedef struct {
127 	FKEY   ix_self;             /*fkey of this block*/
128 	SHORT  ix_type;		/*block/file type*/
129 	FKEY   ix_parent;           /*parent file's fkey*/
130 	SHORT  ix_nkeys;            /*num of keys in block*/
131 	RKEY   ix_rkeys[NORECS];    /*rkeys in block/file*/
132 	INT    ix_offs[NORECS];     /*offsets for data in file*/
133 	INT    ix_lens[NORECS];     /*lengths for data in file*/
134 } *BLOCK, BLOCKSTRUCT;
135 
136 /*============================================
137  * Macros for selecting INDEX and BLOCK fields
138  *==========================================*/
139 #define ixself(p)    ((p)->ix_self)
140 #define ixtype(p)    ((p)->ix_type)
141 #define ixparent(p)  ((p)->ix_parent)
142 #define nkeys(p)   ((p)->ix_nkeys)
143 #define rkeys(p,i) ((p)->ix_rkeys[i])
144 #define fkeys(p,i) ((p)->ix_fkeys[i])
145 #define offs(p,i)  ((p)->ix_offs[i])
146 #define lens(p,i)  ((p)->ix_lens[i])
147 
148 /*============================================
149  * Traversal function pointer typedefs
150  *==========================================*/
151 typedef BOOLEAN(*TRAV_INDEX_FUNC)(BTREE, INDEX, void*);
152 typedef BOOLEAN(*TRAV_BLOCK_FUNC)(BTREE, BLOCK, void*);
153 
154 typedef BOOLEAN(*TRAV_RECORD_FUNC_BYKEY)(RKEY, STRING, INT, void*);
155 #define TRAV_RECORD_FUNC_BYKEY_ARGS(a,b,c,d) RKEY a, STRING b, INT c, void* d
156 
157 /*====================================
158  * BTREE library function declarations
159  *==================================*/
160 
161 /* file.c */
162 BOOLEAN addfile(BTREE, RKEY, STRING file);
163 BOOLEAN addtextfile(BTREE, RKEY, CNSTRING file, TRANSLFNC);
164 RECORD_STATUS write_record_to_file(BTREE btree, RKEY rkey, STRING file);
165 RECORD_STATUS write_record_to_textfile(BTREE btree, RKEY rkey, STRING file, TRANSLFNC);
166 
167 /* opnbtree.c */
168 BOOLEAN closebtree(BTREE);
169 void describe_dberror(INT dberr, STRING buffer, INT buflen);
170 BTREE bt_openbtree(STRING dir, BOOLEAN cflag, INT writ, BOOLEAN immut, INT *lldberr);
171 BOOLEAN validate_keyfile2(KEYFILE2 * kfile2, INT *lldberr);
172 
173 /* index.c */
174 void get_index_file(STRING path, BTREE btr, FKEY ikey);
175 INDEX readindex(BTREE btr, FKEY ikey, BOOLEAN robust);
176 
177 /* names.c */
178 
179 /* btrec.c */
180 BOOLEAN bt_addrecord(BTREE, RKEY, RAWRECORD, INT);
181 RAWRECORD bt_getrecord(BTREE, const RKEY *, INT*);
182 BOOLEAN isrecord(BTREE, RKEY);
183 INT cmpkeys(const RKEY * rk1, const RKEY * rk2);
184 
185 /* traverse.c */
186 BOOLEAN traverse_index_blocks(BTREE, INDEX, void *, TRAV_INDEX_FUNC ifunc, TRAV_BLOCK_FUNC dfunc);
187 void traverse_db_rec_rkeys(BTREE, RKEY lo, RKEY hi, TRAV_RECORD_FUNC_BYKEY func, void *param);
188 
189 /* utils.c */
190 STRING rkey2str(RKEY);
191 RKEY   str2rkey(CNSTRING);
192 STRING fkey2path(FKEY);
193 
194 
195 enum {
196   BTERR_NODB=8            /* no db directory */
197 , BTERR_DBBLOCKEDBYFILE   /* db directory is file, not directory */
198 , BTERR_DBCREATEFAILED    /* failed to create db directory */
199 , BTERR_DBACCESS          /* access error to db directory */
200 , BTERR_NOKEY             /* no keyfile */
201 , BTERR_KFILE             /*problem with the key file*/
202 , BTERR_KFILE_ALTERDB     /*problem with the key file trying to alter a db*/
203 , BTERR_INDEX             /*problem with an index file*/
204 , BTERR_MASTER_INDEX      /*problem with master index file*/
205 , BTERR_BLOCK             /*problem with a data block file*/
206 , BTERR_LNGDIR            /*base directory name too long*/
207 , BTERR_WRITER            /*can't open database because writer has it & -w was specified*/
208 , BTERR_LOCKED            /* error because db was locked */
209 , BTERR_UNLOCKED          /* error because db was unlocked */
210 , BTERR_ILLEGKF           /* illegal keyfile */
211 , BTERR_ALIGNKF           /* wrong alignment key file */
212 , BTERR_VERKF             /* wrong version key file */
213 , BTERR_EXISTS            /* previous database found (create was specified) */
214 , BTERR_READERS           /* db locked by readers (string in custom string) */
215 , BTERR_BADPROPS          /* new db properties invalid */
216 
217 };
218 
219 
220 #define BTINDEXTYPE 1
221 #define BTBLOCKTYPE 2
222 
223 #define BTFLGCRT (1<<0)
224 
225 #endif
226