home *** CD-ROM | disk | FTP | other *** search
- /*AUGUST 1991 version 3.1*/
-
- /****************************************************************************
- * *
- * KeyTree Utilities *
- * *
- * Copyright 1991 by Rewse Consultants Limited *
- * *
- * The KeyTree Utilities are issued as shareware. In case you are unaware *
- * of how the shareware system works, it is NOT 'free' software. *
- * No initial charge is made for the software, so that you can try it out *
- * without obligation. However, if you continue to use the software (and in *
- * the case of the KeyTree Utilities, use programs created using them), *
- * then you are required to pay a registration fee. To register your use of *
- * the KeyTree Utilities, we ask you to pay a miserly £30 (UK Pounds), a *
- * mere fraction of the cost that you are saving in time and effort. Please *
- * send your registration fee to : *
- * *
- * Rewse Consultants Limited *
- * 44, Horseshoe Road, Pangbourne, Reading, Berkshire RG8 7JL, UK *
- *****************************************************************************
- * ┌─────────┐ *
- * ┌─────┴───┐ │ (R) *
- * ──│ │o │────────────────── *
- * │ ┌─────┴╨──┐ │ Association of *
- * │ │ │─┘ Shareware *
- * └───│ o │ Professionals *
- * ──────│ ║ │──────────────────── *
- * └────╨────┘ MEMBER *
- ****************************************************************************/
- #include "stdio.h"
- #include "stdarg.h"
- #include "dos.h"
- #include "sys\types.h"
- #include "sys\stat.h"
- #include "fcntl.h"
- #include "ctype.h"
- #include "stdlib.h"
- #include "errno.h"
- #define CREATMODE O_RDWR|O_BINARY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE
- #define RWMODE O_RDWR|O_BINARY
- void __ktseparator()
- { putchar('/'); /* if your compiler supports it, you should replace */
- fflush(stdout); /* putchar with putch. The fflush is necessary with */
- /* Zortech's compiler, otherwise the screen is not */
- /* refreshed until you display a newline. */
- }
- void __ktputch(char a)
- { putchar(a);
- fflush(stdout);
- }
- void __back()
- { printf("\b \b"); /* replace this command with cprintf */
- fflush(stdout);
- }
- /*#define __HELP ; The ktGet commands (..Key,..Str,..Char,..Press)
- recognise when a function key is pressed and will
- suspend their operation to call the routine defined
- here. Initially set to the null ; , you should
- insert the name of your help routine with its
- associated parameters, if any, and move the comment
- delimiters to after the #def. Your help routine
- can find which function key was pressed from the
- global integer ktFKEY. The current cursor position
- will be automatically preserved. This facility is
- particularly useful if you are providing on-line
- help screens.
-
- e.g. #define __HELP helpwin(); */
-
- int ktSCAN,ktERRNO,ktFKEY,ktINDEXED;
- char ktCHAR;
-
- /* On no account should you attempt to alter any of the following data *
- * items in your programs */
-
- typedef struct {int dup,inxct,curinx,inx_entry,access,fd,*keys,minsiz,
- curtyp,maxkey,ixdes,hks;
- long inx_pos,base,recptr,nexrec,fsize,chain[2],BaseEntry,
- start;
- char status,filename[60];
- int del,maxread;
- } _kt_;
- _kt_ **_KT_ = NULL,*KT;
-
- struct { long ix;
- int en,x;} __alter[10];
-
- union { int a[2];
- char b[2*sizeof(int)];} __tmplen;
- long __inx_char, __inx[99], lseek(), cur_ind_pos;
-
- int __inx_size[4] = {30,13,40,99},__filect = 0,__function = 0,
- __FORWARD, cur_ind_fd;
- #define _INDEXED !(KT->status&2)
- #define _DELETED KT->status&'\x80'
- #define _LOCKED KT->status&1
- #define _STATUS KT->status
- #define _MAXKEY KT->maxkey
- #define _PREVCHAIN KT->chain[0]
- #define _NEXTCHAIN KT->chain[1]
- #define _FIRSTINDEX -KT->keys[3*KT->curinx]
- #define _INDEXSIZE __inx_size[KT->curtyp]
- #define _INDEXTYPE(x) KT->keys[3*(x) + 1]
- #define _INDEXPARTS(x) KT->keys[3*(x) + 2]
- #define ESCAPE (ktSCAN == 1)
- #define ENTER (ktSCAN == 28)
- /************************************************************************
- * *
- * Common utilities *
- * *
- ************************************************************************/
-
- int __wrdata(char *ptr,unsigned int len)
- { return(write(KT->fd,ptr,len));
- }
- int __ktData(char *ptr,unsigned int len)
- { return(read(KT->fd,ptr,len));
- }
- int __seekdata(long offs)
- { return(lseek(KT->fd,offs,0));
- }
- void __wrtstatus()
- { __seekdata(KT->recptr);
- __wrdata((char *)&_STATUS,1);
- }
- void __wrt_elem(char *recpt,int y)
- { union {int x[2];
- char xc[4];
- } q;
-
- __wrtstatus();
- q.x[0] = y;
- q.x[1] = 0;
- if (KT->dup) __wrdata((char *)&_PREVCHAIN,KT->dup);
- __wrdata(q.xc,2*sizeof(int)); /*data length*/
- __wrdata(recpt,y);
- q.x[0] += 3*sizeof(int) + KT->dup + 1;
- __wrdata(q.xc,sizeof(int));
- KT->fsize += q.x[0];
- }
- int __FileOpen(int fno)
- { if (fno > 0) { KT = _KT_[--fno];
- if (fno < __filect && KT)
- { ktERRNO = 0;
- return(1);
- }
- }
- ktERRNO = 9;
- return(0);
- }
- int __FileReady(int fno)
- { if (__FileOpen(fno)) { if (KT->recptr <= 0) ktERRNO = 20;
- else { if (_DELETED) ktERRNO = 28;
- else return(1);
- }
- }
- return(0);
- }
- int __oktowrite()
- { if (!KT->access) { ktERRNO = 12;
- return(0);
- }
- return(1);
- }
- int __locked(int fno)
- { if (!__FileReady(fno) || !__oktowrite()) return(1);
- if (_LOCKED) { ktERRNO = 22;
- return(1);
- }
- return(0);
- }
- int __inx_key(char keychar)
- { int z;
- if ((z = (int)keychar) != 0)
- { switch (KT->curtyp)
- { case 0 : if (z == ' ') z = 2;
- else if (isalpha(z)) z = toupper(z) - 62;
- else z = 1;
- break;
- case 2 : if (z == ' ') z = 2;
- else if (isalpha(z)) z = toupper(z) - 52;
- else { z -= 45;
- if (z < 3 || z > 12) z = 1;
- }
- break;
- case 1 : if (z < 47 || z > 57) z = 1;
- else z -= 46;
- break;
- case 3 : if (z < 31 || z > 127) z = 1;
- else z -= 30;
- }
- }
- return(KT->inx_entry = ++z);
- }
- va_list __KTap;
- int __setupkey(char **key,char *recpt)
- { int x,*y,z,L,S,b;
- char *p,*q;
-
- q = *key = malloc(_MAXKEY);
- if (!q) { ktERRNO = 7; return(0);}
- memset(q,0,_MAXKEY);
- y = &KT->keys[KT->ixdes];
- z = 0;
- for (x = _INDEXPARTS(KT->curinx); x > 0; --x)
- { L = *y++;
- S = *y++;
- p = (recpt) ? &recpt[S] : va_arg(__KTap,char *);
- if (!p) return(0);
- strncpy(&q[z],p,L);
- b = strlen(&q[z]);
- if (b < L) z++;
- z += b;
- }
- return(1);
- }
- void __readkey(char **ptr)
- { char *trec;
-
- __seekdata(__inx_char);
- __ktData(&_STATUS,1);
- if (KT->dup) __seekdata(__inx_char + KT->dup + 1);
- __ktData(__tmplen.b,2*sizeof(int));
- trec = malloc(__tmplen.a[0]);
- if (!trec) ktERRNO = 7;
- else { __ktData(trec,__tmplen.a[0]);
- __setupkey(&(*ptr),trec);
- free(trec);
- }
- }
- void __setnamefil(char *ptr1,char *ptr2)
- { strcpy(ptr2,ptr1);
- while (*ptr2 && *ptr2 != '.') ++ptr2;
- if (!*ptr2) strcpy(ptr2,".fil");
- }
- int __read_elem(char *recpt)
- { int x;
- union { int x[2];
- char xc[2*sizeof(int)];
- } q;
- ktINDEXED = _INDEXED;
- if (KT->dup) __ktData((char *)&_PREVCHAIN,KT->dup);
- if (__ktData(q.xc,2*sizeof(int)) > 0)
- if (q.x[0] > 1)
- { KT->nexrec = KT->recptr + q.x[0] + q.x[1] +
- KT->dup + 1 + 3*sizeof(int);
- x = (KT->maxread > 0 && q.x[0] > KT->maxread) ?
- KT->maxread : q.x[0];
- if (__ktData(recpt,x) > 0) return(q.x[0]);
- }
- ktERRNO = 18;
- return(0);
- }
- int __read_indexed(char *recpt)
- { __seekdata(KT->recptr);
- if (__ktData((char *)&_STATUS,1) < 1) { ktERRNO = 18;
- return(0);
- }
- return(__read_elem(recpt));
- }
- void __next_index(int y)
- { int x,z;
-
- KT->curinx = y;
- KT->curtyp = _INDEXTYPE(y);
- _MAXKEY = 0;
- z = 3*KT->inxct;
- for (x = 0; x < y; ++x) z += 2*_INDEXPARTS(x);
- KT->ixdes = z;
- for (x = _INDEXPARTS(y); x > 0; --x)
- { _MAXKEY += KT->keys[z];
- z += 2;
- }
- }
- void __read_inx()
- { if (KT->fd != cur_ind_fd || KT->inx_pos != cur_ind_pos)
- { __seekdata(-KT->inx_pos + 1);
- __ktData((char *)__inx,_INDEXSIZE*sizeof(long));
- cur_ind_fd = KT->fd;
- cur_ind_pos = KT->inx_pos;
- }
- }
- void __wrt_inx()
- { union { char a[2];
- int b; } q;
- __seekdata(-KT->inx_pos);
- q.a[0] = '0' + KT->curinx;
- __wrdata(q.a,1);
- q.b = _INDEXSIZE*sizeof(long);
- __wrdata((char *)__inx,q.b);
- if (KT->fsize == -KT->inx_pos)
- { q.b += 1 + sizeof(int);
- __wrdata(q.a,sizeof(int));
- KT->fsize += q.b;
- }
- cur_ind_fd = KT->fd;
- cur_ind_pos = KT->inx_pos;
- }
- int __lookup(char *keypt)
- { int x,y,z,k;
-
- KT->inx_pos = _FIRSTINDEX;
- y = _MAXKEY;
- for (x = k = 0; x < y; ++x)
- { __read_inx();
- z = __inx_key(keypt[x]);
- if (!__inx[z]) break;
- if ((__inx_char = __inx[z]) > 0) { KT->recptr = __inx_char;
- k = 1;
- break;
- }
- KT->inx_pos = __inx_char;
- }
- y = KT->curinx;
- __alter[y].ix = KT->inx_pos;
- __alter[y].x = x;
- __alter[y].en = z;
- return(k);
- }
- void __recordlookup(char *recpt)
- { char *temk;
- if (__setupkey(&temk,recpt)) { __lookup(temk);
- free(temk);
- }
- }
- int __keysmatch(char *new,char *old)
- { int x,y,z;
- char a,b;
-
- for (x = 0; x < _MAXKEY; ++x)
- { a = *new++;
- b = *old++;
- if (a != b) { z = KT->inx_entry;
- /* preserve inx_entry */
- y = __inx_key(a) - __inx_key(b);
- KT->inx_entry = z;
- if (y) return(y);
- }
- }
- return(0);
- }
- int __Exists(char *keypt)
- { int z;
- char *temk;
-
- if (__lookup(keypt)) { __readkey(&temk);
- z = __keysmatch(keypt,temk);
- free(temk);
- if (!z) return(__tmplen.a[0]);
- }
- return(0);
- }
- void __update_index(char *recpt,int s)
- { int x,y,k,i;
- long q,*inxp,L;
- char *oldk,*newk;
-
- L = KT->recptr;
- KT->inx_pos = (s) ? _FIRSTINDEX : __alter[KT->curinx].ix;
- if (!__setupkey(&newk,recpt)) return;
- __read_inx();
- if (s) { for (y = 0;; ++y)
- { x = __inx_key(newk[y]);
- __inx_char = __inx[x];
- if (__inx_char >= 0) break;
- KT->inx_pos = __inx_char;
- __read_inx();
- }
- }
- else { x = __alter[KT->curinx].en;
- y = __alter[KT->curinx].x;
- }
- __inx_char = __inx[x];
- if (__inx_char)
- { __readkey(&oldk);
- q = -KT->fsize;
- for (; ;++y)
- { k = __inx_key(oldk[y]);
- x = __inx_key(newk[y]);
- if (k != x) break;
- __inx[k] = q;
- __wrt_inx();
- i = _INDEXSIZE*sizeof(long);
- memset((char *)__inx,0,i);
- __inx[0] = KT->inx_pos;
- KT->inx_pos = q;
- q -= (i + sizeof(int) + 1);
- }
- __inx[k] = __inx_char;
- free(oldk);
- }
- KT->recptr = L;
- __inx[x] = KT->recptr;
- KT->inx_entry = x;
- __wrt_inx();
- free(newk);
- }
- int __oktoadd(char *recpt,int err)
- { int y,z,k,j;
- long L;
- char *keypt;
-
- z = 1;
- k = KT->curinx;
- L = KT->recptr;
- for (y = 0; y < KT->inxct; ++y)
- { __alter[y].ix = 0;
- __next_index(y);
- if (!__setupkey(&keypt,recpt)) return(0);
- j = __Exists(keypt);
- free(keypt);
- if (j) { ktERRNO = y + err;
- z = 0;
- break;
- }
- }
- KT->recptr = L;
- __next_index(k);
- return(z);
- }
- /************************************************************************
- * *
- * 1 ktCreate - create file and write zero filled base indexes *
- * *
- ************************************************************************/
-
- int ktCreate(char *nameptr,int chaining,int indexcount,int *keyptr)
-
- /* chaining 0 - if no chaining
- 1 - if chaining required
-
- *keyptr ptr to a repeating array of integers
- (2 + 2*indexparts)*indexcount
- key_type 0 - alphabetic inc. space
- 1 - numeric plus space
- 2 - alphanumeric inc. space
- 3 - printable (32 - 127)
- key_length length of key in bytes.
- (if <= 0 : no more sections of key)
- key_start count of bytes preceding key in record
- */
- { int x,y,z,k,n;
- char zz[2];
- _kt_ t;
- union { char a[2]; int b;}q;
-
- ktERRNO = 13; /* validate parameters */
- if (chaining) chaining = 2*sizeof(long);
- if (indexcount > 10 || indexcount <= 0) return(0);
- for (x = y = k = 0; x < indexcount; ++x)
- { if (keyptr[y] < 0 || keyptr[y] > 3) return(0);
- for (;;) { k += 2;
- if (keyptr[++y] <= 0) return(0);
- if (keyptr[++y] < 0) return(0);
- if (keyptr[y + 1] < 0) break;
- }
- y += 2;
- }
- __setnamefil(nameptr,t.filename); /* if no ext. add .fil */
- if ((t.fd = open((char *)(t.filename),RWMODE,0)) >= 0)
- { close(t.fd); ktERRNO = 1; return(0); }
- if ((t.fd = open(t.filename,CREATMODE)) < 0)
- { ktERRNO = (errno == EMFILE) ? 5 : 10; return(0); }
- ktERRNO = 0;
- t.inxct = indexcount;
- t.dup = 19284; /* = 'KT' */
- if (chaining) ++t.dup;
- t.curinx = (k + 3*indexcount)*sizeof(int);
- write(t.fd,(char *)&t,3*sizeof(int));
- t.keys = (int *)malloc(t.curinx);
- if (!t.keys) { ktERRNO = 7; close(t.fd); return(0);}
- n = t.curinx + 3*sizeof(int);
- z = 3*indexcount;
- for (x = y = 0; x < 3*indexcount; ++x)
- { t.keys[x++] = n;
- n += __inx_size[keyptr[y]]*sizeof(long) + 1 + sizeof(int);
- t.keys[x++] = keyptr[y++];
- t.keys[x] = 0;
- for (;;)
- { if (keyptr[y] < 0) break;
- t.keys[x]++;
- t.keys[z++] = keyptr[y++];
- t.keys[z++] = keyptr[y++];
- }
- ++y;
- }
- y = write(t.fd,(char *)t.keys,t.curinx);
- if (y < 1)
- { close(t.fd);
- free((char *)t.keys);
- return(0);
- }
- memset((char *)__inx,0,99*sizeof(long));
- for (x = 0; x < indexcount; ++x)
- { zz[0] = '0' + x;
- write(t.fd,zz,1);
- q.b = __inx_size[t.keys[3*x + 1]]*sizeof(long);
- write(t.fd,(char *)__inx,q.b);
- q.b += 1 + sizeof(int);
- write(t.fd,q.a,sizeof(int));
- }
- close(t.fd);
- free((char *)t.keys);
- return(1);
- }
- /************************************************************************
- * *
- * 2 ktOpen - Open file and read base index *
- * *
- ************************************************************************/
- void __set_min_size()
- { int x,y,*z,q,a;
- z = &KT->keys[3*KT->inxct];
- KT->minsiz = KT->hks = 1;
- for (x = 0; x < KT->inxct; ++x)
- { y = KT->keys[3*x + 2];
- for (a = 1; a <= y; ++a)
- { q = *z;
- z++;
- q += *z;
- if (*z > KT->hks - 1) KT->hks = *z + 1;
- if (KT->minsiz < q) KT->minsiz = q;
- z++;
- }
- }
- }
-
- int ktOpen(char *nameptr,int mode,int indno) /* mode : 0 = read only
- non-0 = read-write
- indno : which index to open */
- { int x,y;
- _kt_ **t;
-
- if (indno < 0) { ktERRNO = 4; return(0); }
- ktERRNO = 0;
- for (y = 0; y < __filect; ++y) if (!_KT_[y]) break;
- if (y == __filect)
- { _KT_ = (_kt_ **)realloc(_KT_,(++__filect)*sizeof(_kt_ *));
- if (!_KT_) { ktERRNO = 7; return(0); }
- }
- KT = _KT_[y] = (_kt_ *)malloc(sizeof(_kt_));
- if (!_KT_[y]) { ktERRNO = 7; return(0); }
- memset((char *)KT,0,sizeof(_kt_));
- __setnamefil(nameptr,KT->filename);
- if ((KT->fd = open((char *)(KT->filename),RWMODE,0)) < 0)
- ktERRNO = (errno == EMFILE) ? 5 :
- ((errno == EACCES) ? 10 : 2);
- else
- { KT->fsize = lseek(KT->fd,0L,2);
- if (KT->fsize <= 0) ktERRNO = 6;
- else { __seekdata(0L);
- __ktData((char *)KT,3*sizeof(int));
- x = KT->dup - 19284;
- if (x && x != 1 && x != 0x100 && x != 0x101) ktERRNO = 3;
- else { KT->dup = x&1;
- if (KT->dup) KT->dup = 2*sizeof(long);
- if (KT->inxct <= indno) ktERRNO = 4;
- else { KT->keys = (int *)malloc(KT->curinx);
- if (!KT->keys) ktERRNO = 7;
- else { if (__ktData((char *)(KT->keys),KT->curinx) > 0)
- { __next_index(indno);
- KT->access = mode;
- KT->start = __inx_size[_INDEXTYPE(KT->inxct-1)]*sizeof(long) +
- KT->keys[3*KT->inxct - 3] + sizeof(int) + 1;
- __set_min_size();
- return(y + 1);
- }
- ktERRNO = 8;
- free((char *)(KT->keys));
- }
- }
- }
- }
- close(KT->fd);
- }
- free((char *)KT);
- _KT_[y] = 0;
- return(0);
- }
- /************************************************************************
- * *
- * 3 ktChangeIndex - change index *
- * *
- ************************************************************************/
-
- int ktChangeIndex(int fno,int indno)
-
- { if (!__FileOpen(fno)) return(0);
- if (indno < 0 || indno >= KT->inxct) { ktERRNO = 4; return(0); }
- if (indno != KT->curinx)
- { __next_index(indno);
- KT->BaseEntry = KT->inx_entry = 0;
- KT->inx_pos = _FIRSTINDEX;
- }
- return(1);
- }
- /************************************************************************
- * *
- * 4 ktFlush - make sure file is written to disk *
- * *
- ************************************************************************/
- int ktFlush(int fno)
-
- { union REGS regs;
-
- if (!__FileOpen(fno)) return(0);
- regs.h.ah = 0x45;
- regs.x.bx = KT->fd;
- int86(0x21,®s,®s);
- if (regs.x.cflag) { close(KT->fd);
- KT->fd = open(KT->filename,RWMODE,0);
- }
- else close(regs.x.ax);
- return(1);
- }
- /************************************************************************
- * *
- * 5 ktClose - close file *
- * *
- ************************************************************************/
-
- int ktClose(int fno)
-
- { if (!__FileOpen(fno)) return(0);
- close(KT->fd);
- free((char *)(KT->keys));
- free((char *)KT);
- _KT_[fno - 1] = NULL;
- return(1);
- }
- /************************************************************************
- * *
- * 7 ktAdd - add a record to a file and update indexes *
- * *
- ************************************************************************/
- void __add_indexes(char *recpt)
- { int k,y;
-
- k = KT->curinx;
- for (y = 0; y < KT->inxct; ++y)
- if (y != k) { __next_index(y);
- __update_index(recpt,0);
- }
- __next_index(k);
- __update_index(recpt,0);
- }
-
- int ktAdd(int fno,void *recpt,int leng)
- { char *areapt;
- int x;
-
- if (leng < 1) ktERRNO = 15;
- else if (__FileOpen(fno))
- { if (__oktowrite())
- { if (leng < KT->minsiz)
- { areapt = (char *)malloc(KT->minsiz);
- memset(areapt,0,KT->minsiz);
- memmove(areapt,(char *)recpt,leng);
- x = (leng > KT->hks) ? leng : KT->hks;
- if (areapt[x-1]) ++x;
- }
- else { areapt = (char *)recpt;
- x = leng;
- }
- if (__oktoadd(areapt,40))
- { KT->recptr = KT->fsize;
- _PREVCHAIN = _NEXTCHAIN = _STATUS = 0;
- __wrt_elem(areapt,x);
- __add_indexes(areapt);
- if (areapt != (char *)recpt) free(areapt);
- return(1);
- }
- if (areapt != (char *)recpt) free(areapt);
- KT->recptr = 0;
- }
- }
- return(0);
- }
- /************************************************************************
- * *
- * 8 ktAddPhys - add a record to file - do not update index *
- * *
- ************************************************************************/
- int ktAddPhys(int fno,void *recpt,int leng)
-
- { if (leng <= 0) ktERRNO = 15;
- else if (__FileOpen(fno))
- if (__oktowrite())
- { _PREVCHAIN = _NEXTCHAIN = 0;
- KT->recptr = KT->fsize;
- _STATUS = 2;
- __wrt_elem((char *)recpt,leng);
- return(1);
- }
- return(0);
- }
- /************************************************************************
- * *
- * 9 ktRead - read a record with a specific key *
- * *
- ************************************************************************/
- int __nn(char *recpt,int b,int errs)
-
- { int a1,qq;
- long y,z,a2,*inxp;
- inxp = __inx;
- a1 = KT->inx_entry;
- a2 = KT->inx_pos;
- KT->del = 0;
- __read_inx();
- for (;;)
- { if (__FORWARD > 0) { ++KT->inx_entry;
- qq = (KT->inx_entry >= _INDEXSIZE ||
- (!b && KT->inx_pos == KT->base &&
- KT->inx_entry != KT->BaseEntry));
- }
- else { --KT->inx_entry;
- qq = (KT->inx_entry <= 0 ||
- (!b && KT->inx_pos == KT->base &&
- KT->inx_entry != KT->BaseEntry));
- }
- if (qq)
- { if (KT->inx_pos >= (long)_FIRSTINDEX ||
- (!b && KT->inx_pos >= KT->base))
- { ktERRNO = errs;
- KT->inx_entry = a1;
- KT->inx_pos = a2;
- return(0);
- }
- y = KT->inx_pos;
- KT->inx_pos = *inxp;
- __read_inx();
- for (KT->inx_entry = 1; y != __inx[KT->inx_entry];)
- ++KT->inx_entry;
- continue;
- }
- if ((z = __inx[KT->inx_entry]) > 0)
- { KT->recptr = z;
- return(__read_indexed(recpt));
- }
- if (z < 0) { KT->inx_pos = z;
- __read_inx();
- KT->inx_entry =
- (__FORWARD > 0) ? 0 : _INDEXSIZE;
- }
- }
- }
-
- int __Find(int fno,char *recpt)
-
- { int x,y;
- char *temk,*oldk;
-
- if (!__FileOpen(fno)) return(0);
-
- ktERRNO = KT->BaseEntry = 0;
- if (!__setupkey(&temk,NULL))
- { if (ktERRNO == 7) return(0);
- if (!__FORWARD) { ktERRNO = 13; free(temk); return(0); }
- }
- if (__lookup(temk))
- { y = __read_indexed(recpt);
- if (!y) { free(temk);
- return(0);
- }
- if (!__setupkey(&oldk,recpt)) { free(temk);
- return(0);
- }
- x = __keysmatch(temk,oldk);
- free(oldk);
- if (!x ||
- (__FORWARD > 0 && x < 0) ||
- (__FORWARD < 0 && x > 0)) { free(temk);
- return(y);
- }
- }
- if (!__FORWARD) { ktERRNO = 17;
- y = 0;
- }
- else y = __nn(recpt,1,(__FORWARD > 0) ? 26 : 27);
- free(temk);
- return(y);
- }
-
- int ktRead(int fno,void *recpt,...)
-
- { int x;
-
- va_start(__KTap,recpt);
- __FORWARD = 0;
- x = __Find(fno,(char *)recpt);
- va_end(__KTap);
- return(x);
- }
- /************************************************************************
- * *
- * 10 ktReadAfter - read record with key >= a specific key, *
- * *
- ************************************************************************/
-
- int ktReadAfter(int fno,void *recpt,...)
-
- { int x;
-
- va_start(__KTap,recpt);
- __FORWARD = 1;
- x = __Find(fno,(char *)recpt);
- va_end(__KTap);
- return(x);
- }
- /************************************************************************
- * *
- * 11 ktReadBefore - read record with key <= a specific key, *
- * *
- ************************************************************************/
-
- int ktReadBefore(int fno,void *recpt,...)
-
- { int x;
-
- va_start(__KTap,recpt);
- __FORWARD = -1;
- x = __Find(fno,(char *)recpt);
- va_end(__KTap);
- return(x);
- }
- /************************************************************************
- * *
- * 12 ktLength - check to see if record with a specific key exists *
- * & return with the record length if it does *
- * set currency to this record but do not read it *
- * *
- ************************************************************************/
-
- int ktLength(int fno,...)
-
- { int x;
- char *temk;
-
- x = __FileOpen(fno);
- if (x) { va_start(__KTap,fno);
- x = __setupkey(&temk,NULL);
- va_end(__KTap);
- if (ktERRNO == 7) return(0);
- if (!x) ktERRNO = 13;
- else { KT->BaseEntry = 0;
- x = __Exists(temk);
- if (!x) ktERRNO = 17;
- }
- free(temk);
- }
- return(x);
- }
- /************************************************************************
- * *
- * 13 ktNext - read next logical record *
- * *
- ************************************************************************/
-
- int __ktNext(int fno,void *recpt,int s)
-
- { if (!__FileOpen(fno)) return(0);
- if (!s) KT->recptr = 0;
- if (KT->recptr <= 0) { KT->inx_pos = _FIRSTINDEX;
- KT->inx_entry = 0;
- }
- else if (KT->del == 2) --KT->inx_entry;
- __FORWARD = 1;
- KT->BaseEntry = 0;
- return(__nn((char *)recpt,1,26));
- }
- int ktNext(int fno,void *recpt)
- { return(__ktNext(fno,recpt,1));
- }
- /************************************************************************
- * *
- * 14 ktPrev - read previous logical record *
- * *
- ************************************************************************/
-
- int __ktPrev(int fno,void *recpt,int s)
-
- { if (!__FileOpen(fno)) return(0);
- if (!s) KT->recptr = 0;
- if (KT->recptr <= 0) { KT->inx_pos = _FIRSTINDEX;
- KT->inx_entry = _INDEXSIZE;
- }
- else if (KT->del == 1) ++KT->inx_entry;
- __FORWARD = KT->BaseEntry = 0;
- return(__nn((char *)recpt,1,27));
- }
- int ktPrev(int fno,void *recpt)
- { return(__ktPrev(fno,recpt,1));
- }
- /************************************************************************
- * *
- * 15 ktDelete - delete last record read *
- * *
- ************************************************************************/
- void __delun(char a)
- { long q,r,s,t, r1[2];
- char b;
- s = r = _PREVCHAIN;
- t = r1[1] = q = _NEXTCHAIN;
- if (a == 2) s = t = KT->recptr;
- b = _STATUS;
- __wrtstatus();
- if (KT->dup)
- { if (!r) { _STATUS = a;
- for (;r1[1];)
- { __seekdata(r1[1]);
- __wrdata((char *)&_STATUS,1);
- __ktData((char *)&r1[0],2*sizeof(long));
- }
- _STATUS = b;
- }
- else { __seekdata(r + 1 + sizeof(long));
- __wrdata((char *)&t,sizeof(long));
- if (q) { __seekdata(++q);
- __wrdata((char *)&s,sizeof(long));
- }
- }
- }
- }
- void __index_zero(int k)
- { long L,Q;
- int x,y,b;
-
- __inx[KT->inx_entry] = 0;
- if (__inx[0])
- { y = b = Q = 0;
- for (x = 1; x < _INDEXSIZE; ++x)
- if (__inx[x]) { if (++y > 1) break;
- Q = __inx[x];
- b = (x < KT->inx_entry) ? 1 : 2;
- }
- if (y < 2 && Q >= 0)
- { for (;y < 2 && __inx[0];)
- { L = KT->inx_pos;
- KT->inx_pos = __inx[0];
- __read_inx();
- for (KT->inx_entry = 1;
- L != __inx[KT->inx_entry];)
- ++KT->inx_entry;
- if (KT->BaseEntry && L == KT->base)
- { KT->base = KT->inx_pos;
- KT->BaseEntry = KT->inx_entry;
- }
- __inx[KT->inx_entry] = Q;
- y = 0;
- for (x = 1; x < _INDEXSIZE; ++x)
- { if (__inx[x]) ++y;
- if (y > 1) break;
- }
- }
- if (k == KT->curinx) KT->del = b;
- }
- }
- __wrt_inx();
- }
- int ktDelete(int fno,void *recpt)
- { int x,k;
- char *temk;
- if (__locked(fno)) return(0);
- _STATUS |= '\x80';
- __delun('\x82');
- if (_INDEXED)
- { k = KT->curinx;
- if (KT->inxct > 1)
- { for (x = 0; x < KT->inxct; ++x)
- if (x != k)
- { __next_index(x);
- __recordlookup((char *)recpt);
- __index_zero(x);
- }
- __next_index(k);
- }
- __recordlookup((char *)recpt);
- __index_zero(k);
- }
- return(1);
- }
- /************************************************************************
- * *
- * 16 ktUndelete - undelete last physicalrecord read *
- * *
- ************************************************************************/
- int ktUndelete(int fno,void *recpt)
-
- { if (__FileOpen(fno))
- { if (__oktowrite())
- { if (KT->recptr <= 0) ktERRNO = 20;
- else { if (_DELETED)
- { if (_INDEXED)
- { if (!__oktoadd((char *)recpt,50)) return(0);
- __add_indexes((char *)recpt);
- }
- _STATUS &= '\x7f';
- __delun(2);
- return(1);
- }
- else ktERRNO = 29;
- }
- }
- }
- return(0);
- }
- /************************************************************************
- * *
- * 17 ktRewrite - rewrite the last record read *
- * *
- ************************************************************************/
- union { int a[2]; char b[4]; } __old_length;
- struct { long ix;
- int en;} __oldix[10];
-
- int __record_moved;
-
- void __alter_index(int y,char *recpt)
- { int x,z;
- __next_index(y);
- KT->inx_pos = __oldix[y].ix;
- KT->inx_entry = __oldix[y].en;
- if (KT->inx_pos)
- { __read_inx();
- if (__alter[y].ix) { KT->inx_entry = __oldix[y].en;
- __index_zero(y);
- __update_index(recpt,1);
- }
- else if (__record_moved)
- { __inx[KT->inx_entry] = KT->recptr;
- __wrt_inx();
- }
- }
- }
- int ktRewrite(int fno,void *recpt,int length)
-
- { int x,y,z,i,j,k,e,f;
- char *oldk,*keypt,*oldrec,*areapt;
-
- long q,r,s,start;
- if (length < 1) { ktERRNO = 15; return(0); }
- if (__locked(fno)) return(0);
- if (length < KT->minsiz && _INDEXED)
- { areapt = (char *)malloc(KT->minsiz);
- memset(areapt,0,KT->minsiz);
- memmove(areapt,(char *)recpt,length);
- if (length < KT->hks) length = KT->hks;
- if (areapt[length-1]) ++length;
- }
- else areapt = (char *)recpt;
- q = KT->recptr;
- r = KT->inx_pos;
- e = KT->inx_entry;
- k = KT->curinx;
- start = q + KT->dup + 1;
- __seekdata(start);
- __ktData(__old_length.b,2*sizeof(int));
- __record_moved = (length > __old_length.a[0] + __old_length.a[1]);
-
- if (_INDEXED)
- { __inx_char = q;
- z = 1;
- f = (__old_length.a[0] > KT->maxkey) ?
- __old_length.a[0] : KT->maxkey + 1;
- oldrec = malloc(f);
- if (!oldrec) { ktERRNO = 7;
- if (areapt != (char *)recpt) free(areapt);
- return(0);
- }
- __ktData(oldrec,__old_length.a[0]);
- for (y = KT->inxct - 1; y >= 0; --y)
- { __next_index(y);
- x = 0;
- if (!__setupkey(&keypt,areapt))
- { z = 0; break;}
- if (!__setupkey(&oldk,oldrec)) { z = 0; break;}
- __oldix[y].ix = __alter[y].ix = 0;
- if (__keysmatch(oldk,keypt)) x = __Exists(keypt);
- if (!x && (__record_moved || __alter[y].ix))
- {
- KT->inx_pos = _FIRSTINDEX;
- for (j = 0; j < _MAXKEY; ++j)
- { __read_inx();
- i = __inx_key(oldk[j]);
- if (!__inx[i]) break;
- if ((__inx_char = __inx[i]) > 0)
- { KT->recptr = __inx_char;
- break;
- }
- KT->inx_pos = __inx_char;
- }
- __oldix[KT->curinx].ix = KT->inx_pos;
- __oldix[KT->curinx].en = i;
- }
- free(oldk);
- free(keypt);
- if (x) { ktERRNO = 30 + y;
- z = 0;
- break;
- }
- }
- __next_index(k);
- free(oldrec);
- KT->recptr = q;
- KT->inx_pos = r;
- KT->inx_entry = e;
- if (!z) { if (areapt != (char *)recpt) free(areapt);
- return(0);
- }
- }
- if (__record_moved)
- { KT->recptr = q;
- _STATUS |= '\x80';
- __wrtstatus();
- s = KT->recptr = KT->fsize;
- _STATUS &= '\x7f';
- __wrt_elem(areapt,length);
- if (KT->dup)
- { if (_PREVCHAIN)
- { __seekdata(_PREVCHAIN + 1 + sizeof(long));
- __wrdata((char *)&s,sizeof(long));
- }
- if (_NEXTCHAIN)
- { __seekdata(_NEXTCHAIN + 1);
- __wrdata((char *)&s,sizeof(long));
- }
- }
- }
- else { if (length != __old_length.a[0])
- { __old_length.a[1] += (__old_length.a[0] - length);
- __old_length.a[0] = length;
- __seekdata(start);
- __wrdata(__old_length.b,2*sizeof(int));
- }
- else __seekdata(start + 2*sizeof(int));
- __wrdata(areapt,length);
- }
- if (_INDEXED) { for (y = 0; y < KT->inxct; ++y)
- if (y != k) __alter_index(y,areapt);
- __alter_index(k,areapt);
- }
- if (areapt != (char *)recpt) free(areapt);
- return(length);
- }
- /************************************************************************
- * *
- * 18 ktGetChar - get character from keyboard *
- * *
- ************************************************************************/
- char __runch = 0,__runsc = 0;
-
- char ktGetChar()
-
- { int d;
- union REGS regs;
-
- if (__runch || __runsc) { ktCHAR = __runch;
- ktSCAN = __runsc;
- __runch = __runsc = 0;
- }
- else for (;;)
- { regs.x.ax = 0;
- int86(0x16,®s,®s);
- ktSCAN = regs.h.ah;
- ktCHAR = regs.h.al;
- if (ktSCAN < 59 || ktSCAN > 68 || __function) break;
- #ifdef __HELP
- regs.x.ax = 0x300;
- regs.x.bx = 0;
- int86(0x10,®s,®s);
- d = regs.x.dx;
- ktFKEY = ktSCAN - 58;
- __function = 1;
- __HELP
- __function = 0;
- regs.x.dx = d;
- regs.x.ax = 0x200;
- regs.x.bx = 0;
- int86(0x10,®s,®s);
- #else
- break;
- #endif
- }
- return(ktCHAR);
- }
- /************************************************************************
- * *
- * 19 ktGetPress - get character from keyboard *
- * but do not remove it from the buffer *
- * *
- ************************************************************************/
-
- char ktGetPress()
-
- { __runch = ktGetChar();
- __runsc = ktSCAN;
- return(__runch);
- }
- /************************************************************************
- * *
- * 20 ktGetStr - get string from keyboard *
- * *
- ************************************************************************/
-
- int ktGetStr(char *dataptr,int maxlen)
-
- { unsigned char a;
- int x;
- if (!maxlen) maxlen = -1;
- for (x = 0;;)
- { a = ktGetChar();
- if (ktSCAN == 1 || a == 13) break;
- if (ktSCAN == 14)
- { if (x > 0) { dataptr[--x] = 0;
- __back();
- }
- }
- else { if (!a) { if (ktSCAN == 75 && x)
- { --x; __ktputch(8); }
- else if (ktSCAN == 77 && x < maxlen)
- { if (!dataptr[x]) dataptr[x] = ' ';
- __ktputch(dataptr[x++]);
- }
- }
- else { if (x >= maxlen) break;
- if (a > 31) { dataptr[x++] = a;
- __ktputch(a);
- }
- }
- }
- }
- dataptr[x] = 0;
- return(x);
- }
- /************************************************************************
- * *
- * 21 ktGetKey - get key from keyboard and read record *
- * *
- ************************************************************************/
- int __found;
- int __get_next_part(int k,char *recpt,char *keypt)
- { int x,y,z,l;
- char a;
- long q;
-
- y = 1;
- l = KT->keys[KT->ixdes + 2*k];
- if (keypt) memset(keypt,0,l);
- for (x = 0; x < l;)
- { a = ktGetChar();
- if (ktSCAN == 14 || (!a && ktSCAN == 75))
- { if (x) { --x;
- if (keypt) keypt[x] = 0;
- __back();
- if (!x) KT->inx_pos = _FIRSTINDEX;
- else { KT->inx_pos = q;
- __read_inx();
- q = __inx[0];
- }
- }
- }
- else { if ESCAPE return(0);
- if ENTER a = 0;
- else { if (a < 32) continue;
- __ktputch(a);
- }
- if (keypt) keypt[x] = a;
- x++;
- __read_inx();
- z = __inx_key(a);
- if ((__inx_char = __inx[z]) > 0)
- { KT->recptr = __inx_char;
- y = __read_indexed(recpt);
- __found = 1;
- break;
- }
- if (!__inx_char) return(((a) ? 0 : -1));
- q = KT->inx_pos;
- KT->inx_pos = __inx_char;
- if (!a) return(1);
- }
- }
- return(y);
- }
- int ktGetKey(int fno,void *recpt,...)
-
- { int y,k;
- char *keypt;
-
- y = __FileOpen(fno);
- va_start(__KTap,recpt);
- for (k = 0; k < _INDEXPARTS(KT->curinx); ++k)
- { keypt = va_arg(__KTap,char *);
- if (!keypt) break;
- keypt[0] = 0;
- }
- va_end(__KTap);
- if (y) { keypt = recpt;
- va_start(__KTap,recpt);
- KT->inx_pos = _FIRSTINDEX;
- KT->recptr = KT->BaseEntry = KT->del = 0;
- for (k = 0; k < _INDEXPARTS(KT->curinx); ++k)
- { __found = 0;
- if (keypt) keypt = va_arg(__KTap,char *);
- y = __get_next_part(k,(char *)recpt,keypt);
- if (__found || y <= 0) break;
- __ktseparator();
- }
- va_end(__KTap);
- }
- return(y);
- }
- /************************************************************************
- * *
- * 22 ktReadAll - get first record whose key matches the mask *
- * *
- ************************************************************************/
-
- int ktReadAll(int fno,void *recpt,...)
-
- { int x,y,z;
- char *tkey,*okey;
-
- if (!__FileOpen(fno)) return(0);
- va_start(__KTap,recpt);
- x = __setupkey(&tkey,NULL);
- va_end(__KTap);
- if (!x && ktERRNO) return(0);
- KT->BaseEntry = 1;
- KT->inx_pos = _FIRSTINDEX;
- KT->base = -1;
- for (y = _MAXKEY; !tkey[y-1] && y;) --y;
- for (x = 0; x < y; ++x)
- { KT->base = KT->inx_pos;
- __read_inx();
- z = __inx_key(tkey[x]);
- if (!__inx[z]) { KT->BaseEntry = 0;
- free(tkey);
- ktERRNO = 17;
- return(0);
- }
- KT->BaseEntry = KT->inx_entry = z;
- __inx_char = __inx[z];
- if (__inx_char > 0)
- { KT->recptr = __inx_char;
- z = __read_indexed((char *)recpt);
- if (z) { __setupkey(&okey,(char *)recpt);
- for (; x < y ; ++x)
- { if (__inx_key(tkey[x]) !=
- __inx_key( okey[x]))
- { KT->BaseEntry = 0;
- z = 0;
- ktERRNO = 17;
- break;
- }
- }
- free(okey);
- }
- free(tkey);
- return(z);
- }
- KT->inx_pos = __inx_char;
- }
- KT->inx_entry = 0;
- __FORWARD = 1;
- free(tkey);
- return(__nn((char *)recpt,0,0));
- }
- /************************************************************************
- * *
- * 23 ktNextAll - get next record whose key matches the mask *
- * which was given in the preceding ktReadAll *
- * *
- ************************************************************************/
- int __FileBase(void *recpt,int fno)
- { if (__FileOpen(fno))
- { if (KT->BaseEntry && KT->base < 0)
- { if (KT->del && (KT->base > KT->inx_pos ||
- KT->inx_entry == KT->BaseEntry))
- { if (__FORWARD)
- { if (KT->del == 2) --KT->inx_entry;
- }
- else { if (KT->del == 1) ++KT->inx_entry;
- }
- }
- return(__nn((char *)recpt,0,0));
- }
- else ktERRNO = ((KT->BaseEntry) ? 0 : 25);
- }
- return(0);
- }
-
- int ktNextAll(int fno,void *recpt)
- { __FORWARD = 1;
- return(__FileBase(recpt,fno));
- }
- /************************************************************************
- * *
- * 24 ktPrevAll - get previous record whose key matches the mask *
- * which was given in the preceding ktReadAll *
- * *
- ************************************************************************/
-
- int ktPrevAll(int fno,void *recpt)
- { __FORWARD = 0;
- return(__FileBase(recpt,fno));
- }
- /************************************************************************
- * *
- * 25 ktAddChain - add new record chained to the current record *
- * *
- ************************************************************************/
-
- int ktAddChain(int fno,void *recpt,int leng)
- { long q,r;
- if (!__FileReady(fno)) return(0);
- if (!KT->dup) { ktERRNO = 23;
- return(0);
- }
- if (!__oktowrite()) return(0);
- if (leng < 1) { ktERRNO = 15; return(0); }
- q = KT->fsize;
- __seekdata(KT->recptr + 1 + sizeof(long));
- __wrdata((char *)&q,sizeof(long));
- r = _NEXTCHAIN;
- if (r) { __seekdata(++r);
- __wrdata((char *)&q,sizeof(long));
- }
- _PREVCHAIN = KT->recptr;
- KT->recptr = q;
- _STATUS = 2;
- __wrt_elem((char *)recpt,leng);
- return(1);
- }
- /************************************************************************
- * *
- * 26 ktNextChain - read next record chained to the current record *
- * *
- ************************************************************************/
- int __NChain(void *recpt,int fno,int n)
- { long q;
- if (__FileOpen(fno))
- { if (!KT->dup) ktERRNO = 23;
- else { if (KT->recptr <= 0) ktERRNO = 20;
- else { if (_DELETED && !KT->chain[0]) ktERRNO = 28;
- else { q = KT->chain[n];
- if (q) { KT->recptr = q;
- __seekdata(q);
- __ktData((char *)&_STATUS,1);
- return(__read_elem((char *)recpt));
- }
- }
- }
- }
- }
- return(0);
- }
-
- int ktNextChain(int fno,void *recpt)
- { return(__NChain(recpt,fno,1));
- }
- /************************************************************************
- * *
- * 27 ktPrevChain - read previous record chained to the current record*
- * *
- ************************************************************************/
-
- int ktPrevChain(int fno,void *recpt)
- { return(__NChain(recpt,fno,0));
- }
- /************************************************************************
- * *
- * 28 ktStart - read first logical record in the file *
- * *
- ************************************************************************/
-
- int ktStart(int fno,void *recpt)
- { return(__ktNext(fno,recpt,0));
- }
- /************************************************************************
- * *
- * 29 ktEnd - read last logical record in the file *
- * *
- ************************************************************************/
-
- int ktEnd(int fno,void *recpt)
- { return(__ktPrev(fno,recpt,0));
- }
- /************************************************************************
- * *
- * 30 ktNextPhys - read next physical record *
- * *
- ************************************************************************/
-
- int __record_status()
- { __seekdata(KT->recptr);
- __ktData((char *)&_STATUS,1);
- ktINDEXED = _INDEXED;
- return (_STATUS < '0' || _STATUS > '9');
- }
- int __ktNextPhys(int fno,void *recpt,int s)
-
- { int y;
- if (!__FileOpen(fno)) return(0);
- if (!s) KT->recptr = 0;
- KT->recptr = (KT->recptr <= 0) ? KT->start : KT->nexrec;
- for (;;)
- { if (KT->recptr >= KT->fsize)
- { ktERRNO = 19; return(0); }
- if (__record_status()) break;
- KT->recptr += 1 + sizeof(int) +
- __inx_size[_INDEXTYPE(_STATUS-'0')]*sizeof(long);
- }
- y = __read_elem((char *)recpt);
- return( ((_DELETED) ? -y : y));
- }
- int ktNextPhys(int fno,void *recpt)
- { return(__ktNextPhys(fno,recpt,1));
- }
- /************************************************************************
- * *
- * 31 ktPrevPhys - read previous physical record *
- * *
- ************************************************************************/
- int __PrevPhys(char *recpt,int fno,int s)
- { int z;
-
- if (!__FileOpen(fno)) return(0);
- if (!s) KT->recptr = 0;
- if (KT->recptr <= 0) KT->recptr = KT->fsize;
- for (;;)
- { if (KT->recptr <= KT->start) { ktERRNO = 21; return(0); }
- __seekdata(KT->recptr - (long)sizeof(int));
- __ktData((char *)&z,sizeof(int));
- KT->recptr -= z;
- if (__record_status()) break;
- }
- z = __read_elem((char *)recpt);
- return( ((_DELETED) ? -z : z));
- }
-
- int ktPrevPhys(int fno,void *recpt)
-
- { return(__PrevPhys((char *)recpt,fno,1));
- }
- /************************************************************************
- * *
- * 32 ktStartPhys - read first physical record in the file *
- * *
- ************************************************************************/
-
- int ktStartPhys(int fno,void *recpt)
- { return(__ktNextPhys(fno,recpt,0));
- }
- /************************************************************************
- * *
- * 33 ktEndPhys - read last physical record in the file *
- * *
- ************************************************************************/
-
- int ktEndPhys(int fno,void *recpt)
- { return(__PrevPhys((char *)recpt,fno,0));
- }
- /************************************************************************
- * *
- * 34 ktLock - lock last record read *
- * *
- ************************************************************************/
- char __FirstChar(int y,int fno)
- { if (!__FileReady(fno)) return(0);
- _STATUS = (_STATUS&254)|y;
- __wrtstatus();
- ktFlush(fno);
- return(1);
- }
-
- int ktLock(int fno)
- { return(__FirstChar(1,fno));
- }
- /************************************************************************
- * *
- * 35 ktUnlock - unlock last record read *
- * *
- ************************************************************************/
-
- int ktUnlock(int fno)
- { return(__FirstChar(0,fno));
- }
- /************************************************************************
- * *
- * 36 ktLocked - returns true if record exists and is locked *
- * *
- ************************************************************************/
-
- int ktLocked(int fno,...)
- { char x[2],*temk;
- int k;
-
- if (__FileOpen(fno)) { va_start(__KTap,fno);
- k = __setupkey(&temk,NULL);
- va_end(__KTap);
- if (!k) ktERRNO = 13;
- else { k = __Exists(temk);
- if (!k) ktERRNO = 17;
- else k = _LOCKED;
- }
- free(temk);
- }
- return(k);
- }
- /************************************************************************
- * *
- * 37 ktSize - returns the size of the file in bytes *
- * *
- ************************************************************************/
-
- long ktSize(int fno)
- { if (!__FileOpen(fno)) return(0L);
- return(KT->fsize);
- }
- /************************************************************************
- * *
- * 38 ktRecords - returns the size of the file in records *
- * *
- ************************************************************************/
-
- long ktRecords(int fno,int typ)
- { long x,l;
- char a[8],b,c;
- if (!__FileOpen(fno)) return(0L);
-
- l = KT->start;
- for (x = 0;l < KT->fsize;)
- { __seekdata(l);
- __ktData(a,1);
- if (a[0] >= '0' && a[0] <= '9')
- l += __inx_size[_INDEXTYPE(a[0] - '0')]*sizeof(long)
- + 1 + sizeof(int);
- else { b = a[0] & 0x80;
- if (!typ || (typ > 0 && !b) || (typ < 0 && b))
- ++x;
- if (KT->dup) __ktData(a,KT->dup);
- __ktData(__tmplen.b,2*sizeof(int));
- l += 1 + KT->dup + 3*sizeof(int) +
- __tmplen.a[0] + __tmplen.a[1];
- }
- }
- return(x);
- }
- /************************************************************************
- * *
- * 39 ktMaxRead - sets the maximum number of bytes for any read *
- * *
- ************************************************************************/
-
- int ktMaxRead(int fno,int max)
- { if (__FileOpen(fno)) { if (max < 0 || (max > 0 && max < KT->minsiz))
- ktERRNO = 15;
- else { KT->maxread = max;
- return(KT->minsiz);
- }
- }
- return(0);
- }
-