92aea24fd3bfd9ac123ebef3778fb40f0ee5508b
[oweals/cde.git] / cde / lib / tt / mini_isam / isam_impl.h
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
24 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
25 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
26 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
27 /*%%  $TOG: isam_impl.h /main/4 1998/03/16 14:41:21 mgreess $                                                    */
28 /* @(#)isam_impl.h      1.11 93/09/07 */
29
30 /*
31  * Copyright (c) 1988 by Sun Microsystems, Inc.
32  */
33
34 /*
35  * isam_impl.h
36  *
37  * Description:
38  *      NetISAM implementation specific definitions
39  *
40  */
41
42 #ifndef _ISAM_IMPL_H
43 #define _ISAM_IMPL_H
44
45 #include <assert.h> 
46 #include <stdio.h>
47 #include <fcntl.h>
48 #include <setjmp.h>
49 #include <string.h>
50 #include <errno.h>
51 #include <sys/types.h>
52 #include <sys/param.h>
53 #include <sys/time.h>
54 /* AIX does not define FD_SETSIZE in sys/types.h. */
55 #if !defined(FD_SETSIZE)
56 #include <sys/select.h>
57 #endif
58
59 /*
60  * #include sys/types.h is to get u_long, u_short, dev_t
61  *
62  * #include sys/param.h is to get MAXHOSTNAMELEN
63  */
64
65 #include "isam.h"
66
67 /*
68  * Static is used in definitions of local functions. It is defined to 
69  * "static" normally, but to an empty string when compiled for profiling
70  * purposes (-p or -pg options to the cc compiler). If a function is
71  * defined as static, then the profiling tools account the time spent in
72  * this function to the physically previous global function which is
73  * incorrect and makes the output of the profiler tools useless.
74  */
75 #if defined(PROF) || defined(GPROF)
76 #define Static  
77 #else
78 #define Static static
79 #endif
80
81 extern int isdupl;
82
83 typedef long Recno;                          /* record numbers */
84 typedef long Blkno;                          /* block numbers */
85 typedef long Time;                           /* standard UNIX time */
86 typedef int  Isfd;                           /* ISAM file descriptor */
87
88 typedef int  Bool;
89 #ifndef FALSE
90 #define FALSE   0
91 #define TRUE    1
92 #endif
93
94 #define ISOPENMODE      0xff                 /* Mask to get ISINPUT/ISOUTPUT */
95                                              /* or ISINOUT */
96 #define ISLOCKMODE      0xff00               /* Mask to get lock mode */
97 #define ISREADMODE      0xff                 /* Mask to get ISFIRST, etc. */
98
99 #define ISLENMODE       0x10000              /* Mask to get FIX/VAR length */
100
101 #define ISPAGESIZE      1024                 /* page size */
102
103 #define N_CNTL_PAGES    2                    /* 
104                                               * Number of control pages 
105                                               * at the beg. of .rec file 
106                                               */
107 #define ISCNTLSIZE      (ISPAGESIZE * N_CNTL_PAGES)
108
109
110 #define ISMAGIC         "NetISAM"            /* 'magic number' in ISAM files */
111
112 #ifndef ISVERSION
113 #define ISVERSION       "Unknown"
114 #endif
115
116 #define MAXFCB_UNIXFD   30                   /* Maximum number of UNIX fd
117                                               * used by the FCB module
118                                               */
119
120 #define ISLEAFSLACK     10                   /* Default slack in leaves */
121
122 /* Default RPC timeout values */
123 #define ISRPCS_TO_DEF   60                   /* secs for short oper. */
124 #define ISRPCL_TO_DEF  (120 * 60)            /* secs for long oper. */
125 #define ISTCP_TO_DEF   (3 * 60)              /* secs to reconnect TCP/IP */
126 #define ISRPC_POLL_TO_DEF 30                 /* interval to hear from polled client */
127 #define ISTCP_RETRY_SLEEP 5                  /* time between tries to
128                                               * establish a connection 
129                                               */
130
131 /* 
132  * The X/OPEN ISAM internal data representations.
133  * The #define statements are used to declare type lengths and offsets
134  * in structures in order for the definitions to be compiler independent.
135  */
136
137 #define TIMETYPE        LONGTYPE             /* standard UNIX time */
138 #define TIMESIZE        LONGSIZE        
139
140 #define BLKNOTYPE       LONGTYPE             /* block (page) numbers */
141 #define BLKNOSIZE       LONGSIZE
142
143 #define RECNOTYPE       LONGTYPE             /* record numbers */
144 #define RECNOSIZE       LONGSIZE
145
146 /* 
147  * SHORTTYPE is a safeguard - if the X/OPEN ISAM changes INTTYPE to 4 bytes 
148  * all the internals of NetISAM will work. The only change will be
149  * re-defining SHORTTYPE.       
150  */
151
152 #define SHORTTYPE       INTTYPE              
153 #define SHORTSIZE       INTSIZE
154
155 /* The following defines are used in isstart() */
156 #define WHOLEKEY        0
157 #define USE_PHYS_ORDER(keydesc)  (keydesc->k_nparts == 0)
158
159 /* Structure for storing and passing variable length byte array data */
160 typedef struct bytearray {
161     u_short     length;
162     char        *data;
163 } Bytearray;
164
165 extern Bytearray _bytearr_getempty(), _bytearr_dup(), _bytearr_new();
166 extern void _bytearr_free();
167
168
169 /* Client identification - used to identify owners of locks */
170 /*
171    #define IPADDRLEN    4
172 */
173
174 /* Definitions related to ISAM file descriptor (isfd.c file) */
175 #define MAXISFD         FD_SETSIZE
176 #define NOISFD          (-1)                 /* Not a valid file descriptor */
177
178 extern struct fab *_isfd_find();
179 extern void _isfd_delete();
180 extern Isfd _isfd_insert();
181
182 /* Definitions related to File access block (isfab.c file */
183
184 /* File open mode */
185 enum openmode  { OM_INPUT = 0, OM_OUTPUT = 1, OM_INOUT = 2, OM_BADMODE = 3};
186 enum lockmode  { LM_FAST = 0, LM_EXCL = 1, LM_AUTOMATIC = 2, LM_MANUAL = 3, LM_BADMODE = 4}; 
187
188 /* isread() read modes */
189 enum readmode { RM_FIRST = 0, RM_LAST = 1, RM_NEXT = 2, RM_PREV = 3, 
190                     RM_CURR = 4, RM_EQUAL = 5, RM_GREAT = 6, RM_GTEQ = 7,
191                     RM_LESS = 8, RM_LTEQ = 9, RM_BADMODE = 10 };
192
193 /* lock flag is passed to Access Method module for every record oriented op. */
194 /* Bit position in the lock flag: */
195
196 enum openmode _getopenmode();
197 enum readmode _getreadmode();
198
199 /* Error code structure */
200 struct errcode {
201     int         iserrno;
202     char        isstat [4];
203 };
204
205 typedef struct fab {
206     Isfd                isfd;                /* ISAM file descriptor */
207     enum openmode       openmode;            /* File access mode */
208     enum lockmode       lockmode;            /* File lock mode */
209     Bool                locked;              /* TRUE if file is locked */
210     Bool                varlength;           /* TRUE if variable length records
211                                               * supported by this ISAM file */
212     int                 minreclen;           /* Minimum record length */
213     int                 maxreclen;           /* Maximum record length */
214     char                *isamhost;           /* IP host name */
215     char                *isfname;            /* ISAM file local pathname */
216     Bytearray           isfhandle;           /* ISAM file handle */
217     Bytearray           curpos;              /* Current record position */
218     struct errcode      errcode;             /* Error codes structure */
219 } Fab;
220
221 /* values for filemode */
222 #define LOCAL_FILE      0
223 #define REMOTE_FILE     1
224 #define NFS_FILE        2                    /* File is remote, but is
225                                               * accessed via NFS
226                                               */
227
228 #define FAB_ISFDSET(fab, isfd) (fab->isfd = isfd)
229
230 extern Fab *_fab_new();
231 void _fab_destroy();
232
233 /* ISAM file identification for locking purposes. */
234 typedef struct lckfid {
235     dev_t               diskid;              /* Disk device id */
236     ino_t               inode;               /* .rec file inode number */
237 } Lckfid; 
238
239 /* File Control Block */
240 typedef struct fcb {
241     char                *isfname;            /* ISAM file name */
242     int                 blocksize;           /* Block size */
243     Bool                rdonly;              /* file is read-only */
244     Lckfid              lckfid;              /* File id for locking */
245     int                 datfd;               /* UNIX file descr. of .rec file */
246     int                 indfd;               /* UNIX file descr. of .ind file */
247     int                 varfd;               /* UNIX file descr. of .var file */
248     Blkno               datsize;             /* dat file size in blocks */
249     Blkno               indsize;             /* ind file size in blocks */
250     Blkno               varsize;             /* var file size in blocks */
251     Bool                varflag;             /* TRUE if variable length*/
252     long                nrecords;            /* Number of records */
253     int                 minreclen;           /* Minimum record length */
254     int                 maxreclen;           /* Maximum record length */
255     Recno               lastrecno;           /* Last recno in use */
256     Recno               freerecno;           /* Pointer to first free record */
257     int                 lastkeyid;           /* Last key identifier used */
258     int                 changestamp1;        /* Stamp 1 of last change */
259     int                 changestamp2;        /* Stamp 2 of last change */
260     Blkno               indfreelist;         /* Head of freepage list of .ind */
261
262     int                 nkeys;               /* Number of keys */
263     struct keydesc2     *keys;               /* Key descriptors */
264     long                varend;              /* Offset of the last byte */
265                                              /* in .var file */
266     int                 lockfd;        /* lock file fd for locking .rec for 5.0 */
267 } Fcb;
268
269 #define FCB_NOPRIMARY_KEY(fcb) ((fcb)->keys[0].k2_nparts == 0)
270
271 /* Current Record Position (interpreted only by Access Method) */
272 enum crpflag { CRP_UNDEF = 0, CRP_ON = 1, CRP_AFTER = 2, CRP_BEFORE = 3,
273                CRP_BEFOREANY = 4, CRP_AFTERANY = 5};
274 typedef struct crp {
275     int                 keyid;               /* Key index */
276     enum crpflag        flag;                /* ON/BEFORE/AFTER/UNDEF */
277     Recno               recno;               /* Record number */
278     int                 matchkeylen;         /* match so many bytes of key */
279     char                key[1];              /* Index position */
280 } Crp;
281
282 #define PHYS_ORDER   (-1)                    /* value for keyid when physical
283                                               order is used*/
284
285 /* 
286  * keydesc2 is the 'internal copy'of keydesc. 
287  * keydesc2 contains all information needed by internally by NetISAM,
288  * whereas keydesc conforms to the X/OPEN ISAM. 
289  */
290
291 #define NPARTS2 (NPARTS+2)                   /* duplid and recno */
292 #define DUPSMASK   001                       /* Mask to get ISDUPS/ISNODUPS */
293 #define ISPRIMKEY       040                  /* this is primary key */
294 #define ALLOWS_DUPS2(pkdesc2) (((pkdesc2)->k2_flags & DUPSMASK) == ISDUPS)
295 #define ALLOWS_DUPS(pkdesc) (((pkdesc)->k_flags & DUPSMASK) == ISDUPS)
296
297 /* serial number of duplicate keys */
298 #define DUPIDTYPE       LONGTYPE
299 #define DUPIDSIZE       LONGSIZE
300
301 #define KEY_RECNO_OFF   0
302 #define KEY_DUPS_OFF    RECNOSIZE
303
304 #define stdupser(n, b) stlong((long)(n), (b))
305 #define lddupser(b)  ((int)ldlong(b))
306
307 struct keypart2 {
308     u_short     kp2_start;                   /* starting byte of key part */
309     short       kp2_leng;                    /* length in bytes */
310     short       kp2_type;                    /* type of key part */
311     u_short     kp2_offset;                  /* offset in key buffer */
312 };
313
314 typedef struct keydesc2 {
315     short       k2_flags;                    /* flags */
316     short       k2_nparts;                   /* number of parts in key */
317     short       k2_len;                      /* length of the whole key */
318     Blkno       k2_rootnode;                 /* pointer to root node */
319     int         k2_keyid;                    /* Key identifier */
320     struct keypart2 k2_part[NPARTS2];        /* each part */
321 } Keydesc2;
322
323 typedef unsigned long rel_addr;
324 /* Double linked list element */
325 struct dlink {
326     rel_addr     dln_forward;                /* Forward link */
327     rel_addr     dln_backward;               /* Backward link */
328 };
329
330 /* Disk buffer management definitions */
331
332 /* cache buffer header */
333 typedef struct bufhdr {
334     Fcb         *isb_fcb;                    /* Pointer to FCB */
335     int         isb_unixfd;                  /* UNIX file descriptor */
336     Blkno       isb_blkno;                   /* block number */
337     struct dlink isb_hash;                   /* hashed list*/
338     struct dlink isb_aclist;                 /* available or changed list */
339     struct dlink isb_flist;                  /* list of fixed blocks */
340     char        *isb_buf_w;                  /* malloc() buffer with dirty data */
341     char        *isb_buf_r;                  /* points to mapped segment */
342     char        *isb_buffer;                 /* set to isb_buf_r or isb_buf_w */
343     char        isb_flags;                   /* flags - defs. see below */
344     struct bufhdr *isb_oldcopy;              /* pointer to old copy */
345 } Bufhdr;
346
347 /* mapped segment header */
348 typedef struct maphdr {
349     Fcb         *m_fcb;                      /* Pointer to FCB */
350     int         m_unixfd;                    /* UNIX file descriptor */
351     char        *m_addr;                     /* Pointer to beginning of seg. */
352     int         m_segm_num;                  /* Segment number in the file */
353     unsigned long m_stamp;                   /* Assigned when touched */
354 } Maphdr;
355
356
357 /* values of isb_flags */
358 #define ISB_NODATA      00                   /* block has no data */
359 #define ISB_READ        01                   /* page has valid data */
360 #define ISB_CHANGE      02                   /* page must be flushed */
361 #define ISB_RFIXED      04                   /* block is fixed for read*/
362 #define ISB_WFIXED     010                   /* block is fixed for write*/
363 #define ISB_OLDCOPY    020                   /* block is old copy */
364
365 /* mode values to is__cache_fix() */
366 #define ISFIXREAD       1                    /* fix for read */
367 #define ISFIXWRITE      2                    /* fix for update */
368 #define ISFIXNOREAD     3                    /* fix for update, don't read */
369
370
371 /* 
372  * Macro to get pointer to structure if pointer to some element is known 
373  */
374 #define GETBASE(p,s,e) ((struct s *) ((char *)(p) - (int)&((struct s *)0)->e))
375
376 /* In memory sorting object */
377 typedef struct issort {
378     int         ist_reclength;               /* record length in bytes */
379     int         ist_allocrecs;               /* memory allocated for so */
380                                              /* many records */
381     int         ist_nrecs;                   /* number of records inserted */
382     int         ist_currec;                  /* current position */
383     int         (*ist_compf) ();             /* comparison function */
384     char        *ist_array;                  /* array of records */
385 } Issort;
386
387
388 /* btree is object used for processing B-tree operations */
389
390 #define ISMAXBTRLEVEL   12                   /* Maximum level of B-tree */
391
392 typedef struct btree {
393     Fcb         *fcb;
394     Keydesc2    *keydesc2;
395     int         depth;                       /* depth of the B-tree */
396     Bufhdr      *bufhdr[ISMAXBTRLEVEL];      /* fixed blocks buf. headers */
397     int         curpos[ISMAXBTRLEVEL];       /* current position on block */
398 } Btree;
399
400 /* Lock manager related definitions. */
401 /* Entry in lock table */
402
403 /* Number of buckets for hashing by clientid. Must be a power of 2*/
404 #ifndef HASHPROCSIZE
405 #define HASHPROCSIZE    64
406 #endif
407
408 /* 
409  * Number of buckets for hashing by record number and fileid.
410  * Must be a power of 2 
411  */
412 #ifndef HASHENTSIZE
413 #define HASHENTSIZE     1024
414 #endif
415
416 /* Pseudo record numbers used by file locking. */
417 #define AVAIL_RECNO     (0L)                 /* Entry is available */
418 #define ALLFILE_RECNO   (-1L)                /* Entire file lock */
419 #define OPENFILE_RECNO  (-2L)                /* Used by isopen() */
420
421 /* Lock table file header */
422 struct lockfilehdr {
423     int                 size;                /* size of LOCKTABLEFILE 
424                                               * set to 0 forces reinitialization
425                                               * at next lock request.
426                                               */
427     int                 prochdsn;            /* Number of lists hashed by 
428                                               * clientid */
429     int                 enthdsn;             /* Number of list hashed by
430                                               * record number */
431     int                 lockentriesn;        /* total number of lock entries */
432     struct dlink        avail;               /* Double linked list of 
433                                               * available lock entries */
434 };
435
436 /* Exported filesystem options structure and constants*/
437  
438 #define RW_CLIENTS_SIZE 1     /* Not currently needed */
439 #define UID_SIZE 10           /* Big enough to hold a Unix UID */
440 #define ROOT_OPT_SIZE 240     /* List of hosts for which root access
441                                  is allowed -- can be quite long */
442 #define SHARE_BUFFER_SIZE 400
443  
444 struct export_opts {
445   int read_write; /* 0 => read-only, 1 => read/write */
446   char rw_clients[1]; /* Not interesting, len=1 to save space */
447   char export_dir[1]; /* ditto here */
448   char anon[UID_SIZE];
449   char root[ROOT_OPT_SIZE];
450   int secure; /* RPC authentication flag: 0 => AUTH_UNIX, 1 => AUTH_DES */
451 };
452
453
454 extern Fcb *_isfcb_create();
455 extern Fcb *_isfcb_open();
456 extern void _isfcb_remove();
457 extern void _isfcb_close();
458 extern void _isfcb_setreclength();
459 extern void _isfcb_setprimkey();
460 extern int _isfcb_cntlpg_w();
461
462
463 #define DAT_SUFFIX      ".rec"
464 #define IND_SUFFIX      ".ind"
465 #define VAR_SUFFIX      ".var"
466 #define LOCK_SUFFIX     ".lock"         /* yh: lock file for .rec to solve mmap in 5.0 */
467
468 /* Values of deleted flag for fixed length records */
469 #define FL_RECDELETED   0
470 #define FL_RECEXISTS    1
471
472 /* Special values of tail pointer for variable length records */
473 #define VL_RECDELETED   ((long ) -1L)
474 #define VL_RECNOTAIL    ((long ) -2L)
475
476
477 extern long lseek();
478
479 extern char *_ismalloc(), *_isrealloc(), *_isallocstring();
480 extern void _isfree(), _isfreestring();
481 extern void _isfatal_error(), _setiserrno2(), _seterr_errcode();
482 extern void _makedat_isfname();
483 extern void _makeind_isfname();
484 extern void _makevar_isfname();
485 extern void _amseterrcode();
486
487 extern void _isseekpg(), _isreadpg(), _iswritepg();
488
489 extern Bufhdr *_isdisk_fix(), *_isdisk_refix();
490 extern void _isdisk_commit(), _isdisk_sync(), _isdisk_inval(), 
491     _isdisk_commit1(), _isdisk_unfix();
492 extern void _isdisk_rollback();
493 extern void _cp_tofile(), _cp_fromfile();
494 Blkno  _extend_file();
495
496 extern void _isdln_base_insert(), _isdln_base_remove(), _isdln_base_append(), 
497     _isdln_base_makeempty();
498 extern struct dlink *_isdln_base_prev(), *_isdln_base_next(), *_isdln_base_first();
499
500 extern void _mngfcb_insert(), _mngfcb_delete();
501 extern Fcb *_mngfcb_find();
502 extern Bytearray *_mngfcb_victim();
503 extern char *_getisfname();
504 extern Bytearray _makeisfhandle();
505
506 extern Bytearray _makeisfhandle();
507 extern Fcb *_openfcb();
508
509 extern Time _amtime_set(), _amtime_get();
510
511 extern void _islock_closefile(), _islock_unlockfile();
512
513 extern Keydesc2 *_isfcb_findkey(), *_isfcb_indfindkey();
514 extern void stkey(), ldkey();
515
516 extern Issort *_issort_create();
517 extern char *_issort_read();
518 extern void _issort_destroy(), _issort_insert(), _issort_sort(), 
519     _issort_rewind();
520
521 extern void _iskeycmp_set();
522 extern int _iskeycmp();
523
524 extern char *_isbsearch();
525
526 extern void _iskey_extract();
527 extern Blkno _isindfreel_alloc();
528 extern void _isindfreel_free();
529 extern long _fl_getpos();
530
531 extern Btree *_isbtree_create();
532 extern void _isbtree_destroy(), _isbtree_search(), _isbtree_insert(),
533     _isbtree_remove();
534 extern char *_isbtree_current(), *_isbtree_next();
535
536 extern void _iskey_fillmin(), _iskey_fillmax();
537
538 extern Bufhdr *_allockpage();
539
540 extern void _del1key();
541 extern int _add1key(), _change1key();
542 extern void _delkeys();
543 extern char *_ismap_getaddr();
544 extern void _ismap_endop(), _ismap_unmapfcb();
545
546 extern void _isam_entryhook(), _isam_exithook();
547
548 #define stshort(n,p) stint((n), (p))
549 #define ldshort(p) ldint(p)
550
551 #define strecno(n,p) stlong((long)(n), (p))
552 #define ldrecno(p) ((Recno)ldlong(p))
553
554 #define stblkno(n,p) stlong((long)(n), (p))
555 #define ldblkno(p) ((Blkno)ldlong(p))
556
557 extern int _flrec_read(), _flrec_write(), _flrec_rewrite(), _flrec_delete(),
558     _flrec_wrrec();
559 extern int _vlrec_read(), _vlrec_write(), _vlrec_rewrite(), _vlrec_delete(),
560     _vlrec_wrrec();
561
562 /*------------ UNIX file formats ---------------------------------------------*/
563
564 #define ISCNTLPGOFF     ((Blkno) 0)          /* offset of Control Page */
565
566 /* internal key descriptor */
567
568 #define KP2_START_OFF   0                    /* see struct keypart2 */
569 #define KP2_LENGTH_OFF  SHORTSIZE
570 #define KP2_TYPE_OFF    (2*SHORTSIZE)
571 #define KP2_OFFSET_OFF  (3*SHORTSIZE)
572 #define KP2_LEN         (4*SHORTSIZE)
573
574 #define K2_FLAGS_OFF    0                    /* see struct keydesc2 */
575 #define K2_NPARTS_OFF   SHORTSIZE       
576 #define K2_LEN_OFF      (2*SHORTSIZE)
577 #define K2_ROOT_OFF     (3*SHORTSIZE)
578 #define K2_KEYID_OFF    (3*SHORTSIZE+BLKNOSIZE)
579 #define K2_KEYPART_OFF  (3*SHORTSIZE+2*BLKNOSIZE)
580 #define K2_LEN          (3*SHORTSIZE+2*BLKNOSIZE+ NPARTS2*KP2_LEN)
581
582 #define NULL_BLKNO      0L
583 #define NULL_RECNO      0L
584 #define PAGE1_BLKNO     0                    /* Block number of control page */
585 /*------------------------- Control Page  layout -----------------------------*/
586
587 /* Magic number (must be equal to "NetISAM") */
588 #define CP_MAGIC_OFF    0
589 #define CP_MAGIC_LEN    8
590
591 /* Version stamp */
592 #define CP_VERSION_OFF (CP_MAGIC_OFF+CP_MAGIC_LEN)
593 #define CP_VERSION_LEN 8
594
595 /* Application stamp */
596 #define CP_APPLMAGIC_OFF (CP_VERSION_OFF+ CP_VERSION_LEN)
597 #define CP_APPLMAGIC_LEN ISAPPLMAGICLEN
598
599 /* Block size */
600 #define CP_BLOCKSIZE_OFF (CP_APPLMAGIC_OFF+CP_APPLMAGIC_LEN)
601 #define CP_BLOCKSIZE_LEN SHORTSIZE
602
603 /* file size in blocks */
604 #define CP_DATSIZE_OFF  (CP_BLOCKSIZE_OFF+CP_BLOCKSIZE_LEN)     
605 #define CP_DATSIZE_LEN  BLKNOSIZE
606
607 /* file size in blocks */
608 #define CP_INDSIZE_OFF  (CP_DATSIZE_OFF+CP_DATSIZE_LEN) 
609 #define CP_INDSIZE_LEN  BLKNOSIZE
610
611 /* file size in blocks */
612 #define CP_VARSIZE_OFF  (CP_INDSIZE_OFF+CP_INDSIZE_LEN)
613 #define CP_VARSIZE_LEN  BLKNOSIZE
614
615 /* 0/1 flag telling whether file supports variable length records. */
616 #define CP_VARFLAG_OFF  (CP_VARSIZE_OFF+CP_VARSIZE_LEN)
617 #define CP_VARFLAG_LEN  SHORTSIZE
618
619 /* number of record in the file */
620 #define CP_NRECORDS_OFF (CP_VARFLAG_OFF+CP_VARFLAG_LEN)
621 #define CP_NRECORDS_LEN LONGSIZE
622
623 /*  minimum record length */
624 #define CP_MINRECLEN_OFF (CP_NRECORDS_OFF+CP_NRECORDS_LEN)
625 #define CP_MINRECLEN_LEN  SHORTSIZE
626
627 /*  maximum record length */
628 #define CP_MAXRECLEN_OFF (CP_MINRECLEN_OFF+CP_MINRECLEN_LEN)
629 #define CP_MAXRECLEN_LEN  SHORTSIZE
630
631 /* 
632  * Left 0 and not used in NetISAM 1.0.
633  * Will be set at restructuring to some optimal value x 
634  * (minreclen <= x <= maxreclen).
635  * Record with length will be stored in .rec file only. 
636  * In NetISAM 1.0  x == minreclen.
637  */
638 /*  split record record length */
639 #define CP_SPLITRECLEN_OFF (CP_MAXRECLEN_OFF+CP_MAXRECLEN_LEN)
640 #define CP_SPLITRECLEN_LEN  SHORTSIZE
641
642 /* Recno of last record */
643 #define CP_LASTRECNO_OFF  (CP_SPLITRECLEN_OFF+CP_SPLITRECLEN_LEN)
644 #define CP_LASTRECNO_LEN  RECNOSIZE
645
646 /* Head of deleted records list */
647 #define CP_FREERECNO_OFF  (CP_LASTRECNO_OFF+CP_LASTRECNO_LEN)
648 #define CP_FREERECNO_LEN  RECNOSIZE
649
650 /* 0/1 flag telling whether file has a primary key */
651 #define CP_HASPRIMKEY_OFF (CP_FREERECNO_OFF+CP_FREERECNO_LEN)
652 #define CP_HASPRIMKEY_LEN SHORTSIZE
653
654 /* Last key indentifier. */
655 #define CP_LASTKEYID_OFF (CP_HASPRIMKEY_OFF+CP_HASPRIMKEY_LEN)
656 #define CP_LASTKEYID_LEN  LONGSIZE      
657
658 /* Stamp 1 of last change */
659 #define CP_CHANGESTAMP1_OFF (CP_LASTKEYID_OFF+CP_LASTKEYID_LEN)
660 #define CP_CHANGESTAMP1_LEN  LONGSIZE   
661
662 /* Stamp 2 of last change */
663 #define CP_CHANGESTAMP2_OFF (CP_CHANGESTAMP1_OFF+CP_CHANGESTAMP1_LEN)
664 #define CP_CHANGESTAMP2_LEN  LONGSIZE   
665
666 /* .ind file free list */
667 #define CP_INDFREELIST_OFF (CP_CHANGESTAMP2_OFF+CP_CHANGESTAMP2_LEN)
668 #define CP_INDFREELIST_LEN  BLKNOSIZE
669
670 /* number of keys */
671 #define CP_NKEYS_OFF    (CP_INDFREELIST_OFF+CP_INDFREELIST_LEN)
672 #define CP_NKEYS_LEN    SHORTSIZE
673
674 /* use 4 bytes of reserved space */
675 #define CP_VAREND_OFF   (CP_NKEYS_OFF+CP_NKEYS_LEN)
676 #define CP_VAREND_LEN   LONGSIZE
677
678 /* use 4 bytes of reserved space for time stamp*/
679 #define CP_UNIQUE_OFF   (CP_VAREND_OFF+CP_VAREND_LEN)
680 #define CP_UNIQUE_LEN   LONGSIZE
681
682 /* reserve some space for future */
683 #define CP_RESERVE_OFF  (CP_UNIQUE_OFF+CP_UNIQUE_LEN)
684 #define CP_RESERVE_LEN   120                 /* 128 was reserved originally */
685
686 /* table of key descriptors */
687 #define CP_KEYS_OFF     (CP_RESERVE_OFF+CP_RESERVE_LEN)
688
689 #define MAXNKEYS2 ((ISCNTLSIZE - CP_KEYS_OFF) / K2_LEN)
690 #define MAXNKEYS        17
691
692 #if (MAXNKEYS2 < MAXNKEYS)
693 Cause a compiler error here. There is not enought space in the control
694 page to hold MAXNKEYS.
695 #endif
696
697 /*------ page type indicator values -------------*/
698 #define PT_INDEX        1                    /* B-tree page */
699 #define PT_FREELIST     2                    /* free list */
700
701 /*-------------- B-Tree page layout -----------------------------------*/
702 /* page type */
703 #define BT_TYPE_OFF     0
704 #define BT_TYPE_LEN     SHORTSIZE
705
706 /* level (leaves have level 0) */
707 #define BT_LEVEL_OFF    (BT_TYPE_OFF+BT_TYPE_LEN)
708 #define BT_LEVEL_LEN    SHORTSIZE
709
710 /* page capacity */
711 #define BT_CAPAC_OFF    (BT_LEVEL_OFF+BT_LEVEL_LEN)
712 #define BT_CAPAC_LEN    SHORTSIZE
713
714 /* current number of keys */
715 #define BT_NKEYS_OFF    (BT_CAPAC_OFF+BT_CAPAC_LEN)
716 #define BT_NKEYS_LEN    SHORTSIZE
717
718 /* array of key entries */
719 #define BT_KEYS_OFF     (BT_NKEYS_OFF+BT_NKEYS_LEN)
720
721 /* down pointers are stored at the end of the page */
722
723 /*----------- Free List Page Layout --------------------------------------*/
724 /* page type */
725 #define FL_TYPE_OFF     0
726 #define FL_TYPE_LEN     SHORTSIZE
727
728 /* pointer to next block in the list */
729 #define FL_NEXT_OFF     (FL_TYPE_OFF + FL_TYPE_LEN)
730 #define FL_NEXT_LEN     BLKNOSIZE
731
732 /* number of free page pointers */
733 #define FL_NPOINTERS_OFF  (FL_NEXT_OFF + FL_NEXT_LEN)
734 #define FL_NPOINTERS_LEN  SHORTSIZE
735
736 /* free page pointers table */
737 #define FL_POINTERS_OFF   (FL_NPOINTERS_OFF + FL_NPOINTERS_LEN)
738
739 /* maximum number of pointers that can be stored in a page */
740 #define FL_MAXNPOINTERS ((ISPAGESIZE - FL_POINTERS_OFF) / BLKNOSIZE)
741
742 #define FREELIST_NOPAGE ((Blkno) -1)
743
744 /* .var file related defines */
745 #define VR_FRAMELEN_OFF  0
746 #define VR_TAILLEN_OFF   2
747
748
749 /* maximum and minimum values are in B-tree seaches */
750 #if LONG_BIT == 64
751 #define ISMAXLONG   { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
752 #define ISMINLONG   { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
753 #else
754 #define ISMAXLONG       { 0x7f, 0xff, 0xff, 0xff }
755 #define ISMINLONG       { 0x80, 0x00, 0x00, 0x00 }
756 #endif
757
758 #define ISMAXSHORT      { 0x7f, 0xff }
759 #define ISMINSHORT      { 0x80, 0x00 }
760
761 #define ISMINCHAR       ('\0')
762 #define ISMAXCHAR       ('\377')
763
764 #define ISMINBIN        ('\0')
765 #define ISMAXBIN        ('\377')
766
767 /* double and float are declared using IEEE bit paterns */
768
769 #define ISMAXDOUBLE      { 0x7f, 0xf0, 0, /* rest is 0 */ }
770 #define ISMINDOUBLE      { 0xff, 0xf0, 0, /* rest is 0 */ }
771
772 #define ISMAXFLOAT       { 0x7f, 0x80, 0, /* rest is 0 */ }
773 #define ISMINFLOAT       { 0xff, 0x80, 0, /* rest is 0 */ }
774
775
776 /* Hide these from user till we return error code */
777 extern char     isstat3;
778 extern char     isstat4;
779
780 #define OP_BUILD                0
781 #define OP_OPEN                 1
782
783 #endif
784