Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
50
cde/lib/tt/mini_isam/Imakefile
Normal file
50
cde/lib/tt/mini_isam/Imakefile
Normal file
@@ -0,0 +1,50 @@
|
||||
XCOMM $XConsortium: Imakefile /main/4 1996/04/21 19:12:37 drk $
|
||||
#define DoNormalLib YES
|
||||
#define DoSharedLib NO
|
||||
#define DoDebugLib NO
|
||||
#define DoProfileLib NO
|
||||
#define LibName isam
|
||||
#define LibHeaders NO
|
||||
#define LibInstall NO
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../tooltalk.tmpl"
|
||||
|
||||
INCLUDES = -I.
|
||||
|
||||
SRCS = isaddindex.c isamaddindex.c isopen.c isamopen.c \
|
||||
isdelcurr.c isdelrec.c isamdelrec.c isbuild.c \
|
||||
isvars.c isrewrec.c iserase.c iscntl.c isstart.c \
|
||||
isaddprimary.c isrewcurr.c isclose.c isread.c \
|
||||
iswrite.c isamwrite.c issync.c isapplmr.c ismngfcb.c \
|
||||
issort.c ischange1key.c isfab.c isdiskbufs2.c isfd.c isbtree.c \
|
||||
isdel1key.c isfcb.c isfixrec.c issignals.c isapplmw.c \
|
||||
isfcbwatchfd.c isamhooks.c isfcbindex.c isalloc.c isbytearray.c \
|
||||
isdatconv.c isminmax.c isfname.c isvarrec.c isperm.c iserror.c \
|
||||
iskeycmp.c iskeycalc.c iskeyvalid.c isamerror.c iskeyaux.c \
|
||||
isfileio.c ispageio.c isdlink.c isbtree2.c \
|
||||
isbtree3.c isindfreel.c isindexconv.c isbsearch.c isadd1key.c \
|
||||
iskeyconv.c isversion.c isrepair.c iswrrec.c isrename.c \
|
||||
isindexinfo.c isgarbage.c iscurpos.c
|
||||
|
||||
OBJS = isaddindex.o isamaddindex.o isopen.o isamopen.o \
|
||||
isdelcurr.o isdelrec.o isamdelrec.o isbuild.o \
|
||||
isvars.o isrewrec.o iserase.o iscntl.o isstart.o \
|
||||
isaddprimary.o isrewcurr.o isclose.o isread.o \
|
||||
iswrite.o isamwrite.o issync.o isapplmr.o ismngfcb.o \
|
||||
issort.o ischange1key.o isfab.o isdiskbufs2.o isfd.o isbtree.o \
|
||||
isdel1key.o isfcb.o isfixrec.o issignals.o isapplmw.o \
|
||||
isfcbwatchfd.o isamhooks.o isfcbindex.o isalloc.o isbytearray.o \
|
||||
isdatconv.o isminmax.o isfname.o isvarrec.o isperm.o iserror.o \
|
||||
iskeycmp.o iskeycalc.o iskeyvalid.o isamerror.o iskeyaux.o \
|
||||
isfileio.o ispageio.o isdlink.o isbtree2.o \
|
||||
isbtree3.o isindfreel.o isindexconv.o isbsearch.o isadd1key.o \
|
||||
iskeyconv.o isversion.o isrepair.o iswrrec.o isrename.o \
|
||||
isindexinfo.o isgarbage.o iscurpos.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SpecialLibObjectRule(isversion.o,,$(TT_VERSION_DEFINE))
|
||||
|
||||
DependTarget()
|
||||
120
cde/lib/tt/mini_isam/isadd1key.c
Normal file
120
cde/lib/tt/mini_isam/isadd1key.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isadd1key.c /main/3 1995/10/23 11:33:17 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isadd1key.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isadd1key.c
|
||||
*
|
||||
* Description:
|
||||
* Add an entry to B tree.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern long *ismaxlong;
|
||||
|
||||
int
|
||||
_add1key(fcb, pkeydesc2, record, recnum, newkey)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
char *newkey;
|
||||
{
|
||||
char keybuf[MAXKEYSIZE];
|
||||
Btree *btree;
|
||||
char *pkey;
|
||||
|
||||
/*
|
||||
* Special case when there is no primary key.
|
||||
*/
|
||||
if (pkeydesc2->k2_nparts == 0)
|
||||
return (ISOK);
|
||||
|
||||
memset((char *)keybuf, 0, pkeydesc2->k2_len);
|
||||
_iskey_extract(pkeydesc2, record, keybuf);
|
||||
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
|
||||
/*
|
||||
* Duplicates allowed on this key.
|
||||
* Try to read the last duplicate (with the highest serial number).
|
||||
* If such duplicate exists, the inserted key entry will be
|
||||
* assigned next higher value for duplicate serial number.
|
||||
* If there is no such duplicate, assign duplicate serial number 1.
|
||||
*/
|
||||
strecno(recnum, keybuf + KEY_RECNO_OFF);
|
||||
memcpy(keybuf + KEY_DUPS_OFF, (char *)ismaxlong, LONGSIZE);
|
||||
_isbtree_search(btree, keybuf);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) != NULL &&
|
||||
memcmp(pkey + RECNOSIZE + DUPIDSIZE,
|
||||
keybuf + RECNOSIZE + DUPIDSIZE,
|
||||
pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE) == 0) {
|
||||
|
||||
/*
|
||||
* A duplicate exists. Assign +1 value for the new serial
|
||||
* number.
|
||||
*/
|
||||
stlong(ldlong(pkey + KEY_DUPS_OFF) + 1, keybuf + KEY_DUPS_OFF);
|
||||
|
||||
/*
|
||||
* Set isdupl to 1 to indicate allowed duplicates exist.
|
||||
*/
|
||||
isdupl = 1;
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* This is the first duplicate. Assign serial number 1.
|
||||
*/
|
||||
stlong(1L, keybuf + KEY_DUPS_OFF);
|
||||
}
|
||||
|
||||
_isbtree_insert(btree, keybuf);
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
else {
|
||||
|
||||
/* Duplicates not allowed on this key.
|
||||
* Set TID part to maximum value, causing the search path
|
||||
* to point just past the possible duplicate in the key file
|
||||
* If there is no duplicate, this is the correct spot to
|
||||
* insert the new key entry.
|
||||
*/
|
||||
|
||||
memcpy( keybuf + KEY_RECNO_OFF,(char *)ismaxlong, LONGSIZE);
|
||||
_isbtree_search (btree, keybuf);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) != NULL &&
|
||||
memcmp(pkey + RECNOSIZE, keybuf + RECNOSIZE,
|
||||
pkeydesc2->k2_len - RECNOSIZE) == 0) {
|
||||
_isbtree_destroy(btree);
|
||||
return (EDUPL);
|
||||
}
|
||||
|
||||
strecno(recnum, keybuf + KEY_RECNO_OFF);
|
||||
_isbtree_insert(btree, keybuf);
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return new key position.
|
||||
*/
|
||||
if (newkey != NULL)
|
||||
memcpy( newkey,keybuf, pkeydesc2->k2_len);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
68
cde/lib/tt/mini_isam/isaddindex.c
Normal file
68
cde/lib/tt/mini_isam/isaddindex.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isaddindex.c /main/3 1995/10/23 11:33:26 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isaddindex.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isaddindex.c
|
||||
*
|
||||
* Description:
|
||||
* Add secondary index to ISAM file
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* err = isaddindex(isfd, keydesc)
|
||||
*
|
||||
* Isaddindex() is used to add an alternate index to ISAM file.
|
||||
*
|
||||
* Errors:
|
||||
* EBADKEY error in keydesc
|
||||
* EDUPL there are duplicate keys and the keydesc does not allow
|
||||
* duplicate keys
|
||||
* EKEXISTS key with the same key descriptor already exists
|
||||
* ENOTEXCL ISAM file is not open in exclusive mode
|
||||
* ENOTOPEN the ISAM file is not open in ISINOUT mode.
|
||||
* EACCES Cannot create index file because of UNIX error.
|
||||
*/
|
||||
|
||||
int
|
||||
isaddindex(isfd, keydesc)
|
||||
int isfd;
|
||||
struct keydesc *keydesc;
|
||||
{
|
||||
int _amaddindex();
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISOUTPUT
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
ret = _amaddindex(&fab->isfhandle, keydesc, &fab->errcode);
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
80
cde/lib/tt/mini_isam/isaddprimary.c
Normal file
80
cde/lib/tt/mini_isam/isaddprimary.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isaddprimary.c /main/3 1995/10/23 11:33:35 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isaddprimary.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/* @(#)isaddprimary.c 1.7 93/09/07
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isaddprimary.c
|
||||
*
|
||||
* Description:
|
||||
* Add secondary index to ISAM file
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
Static int _am_addprimary();
|
||||
|
||||
|
||||
/*
|
||||
* err = isaddprimary(isfd, keydesc)
|
||||
*
|
||||
* Isaddprimary() is used to add primary index to ISAM file.
|
||||
*
|
||||
* This call is not part of the X/OPEN sprec.
|
||||
*
|
||||
* Errors:
|
||||
* EBADKEY error in keydesc
|
||||
* EDUPL there are duplicate keys and the keydesc does not allow
|
||||
* duplicate keys
|
||||
* EKEXISTS key with the same key descriptor already exists
|
||||
* EKEXISTS the ISAM file already has a primary index.
|
||||
* ENOTEXCL ISAM file is not open in exclusive mode
|
||||
* ENOTOPEN the ISAM file is not open in ISINOUT mode.
|
||||
* EACCES Cannot create index file because of UNIX error.
|
||||
*/
|
||||
|
||||
int
|
||||
isaddprimary(isfd, keydesc)
|
||||
int isfd;
|
||||
struct keydesc *keydesc;
|
||||
{
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISOUTPUT
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
ret = _am_addprimary(fab, keydesc);
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
Static int _am_addprimary(fab, keydesc)
|
||||
register Fab *fab;
|
||||
struct keydesc *keydesc;
|
||||
{
|
||||
return (_amaddprimary(&fab->isfhandle, keydesc, &fab->errcode));
|
||||
}
|
||||
91
cde/lib/tt/mini_isam/isalloc.c
Normal file
91
cde/lib/tt/mini_isam/isalloc.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isalloc.c /main/3 1995/10/23 11:33:43 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isalloc.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isalloc.c
|
||||
*
|
||||
* Description:
|
||||
* Functions that allocate and deallocate memory.
|
||||
* All errors are treated as fatal.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <malloc.h>
|
||||
|
||||
/* strdup is not defined in Ultrix' string.h, so it is implemented in a separate
|
||||
* file named strdup.ultrix.c
|
||||
*/
|
||||
#ifdef __ultrix__
|
||||
extern char *strdup();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* _ismalloc(nbytes)
|
||||
*
|
||||
* Allocate nbytes.
|
||||
*/
|
||||
|
||||
char *_ismalloc(nbytes)
|
||||
unsigned int nbytes;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if ((p = (char *) malloc (nbytes)) == NULL)
|
||||
_isfatal_error("malloc() failed");
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
char *_isrealloc(oldaddr, nbytes)
|
||||
char *oldaddr;
|
||||
unsigned int nbytes;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if ((p = (char *) realloc (oldaddr, nbytes)) == NULL)
|
||||
_isfatal_error("realloc() failed");
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isallocstring(str)
|
||||
*
|
||||
* Create a duplicate of string in dynamic memory.
|
||||
*/
|
||||
|
||||
char *
|
||||
_isallocstring(str)
|
||||
char *str;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if ((p = strdup(str)) == NULL)
|
||||
_isfatal_error("strdup() failed");
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfreestring(str)
|
||||
*
|
||||
* Free dynamically allocated string.
|
||||
*/
|
||||
|
||||
void
|
||||
_isfreestring(str)
|
||||
char *str;
|
||||
{
|
||||
assert(str != NULL);
|
||||
free(str);
|
||||
}
|
||||
290
cde/lib/tt/mini_isam/isam.h
Normal file
290
cde/lib/tt/mini_isam/isam.h
Normal file
@@ -0,0 +1,290 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isam.h /main/3 1995/10/23 11:33:51 rswiston $ */
|
||||
/*
|
||||
@(#)isam.h
|
||||
1.17 90/01/20
|
||||
SMI */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isam.h
|
||||
*
|
||||
* Description:
|
||||
* isam.h is to be included in NetISAM C application programs.
|
||||
*
|
||||
* Make sure all changes in this file are reflected in lib/db/tt_client_isam.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ISAM_H
|
||||
#define _ISAM_H
|
||||
|
||||
#include <limits.h>
|
||||
#ifndef LONG_BIT
|
||||
#define LONG_BIT 32
|
||||
#endif
|
||||
|
||||
extern short ldint();
|
||||
extern long ldlong();
|
||||
extern float ldfloat();
|
||||
extern double lddbl();
|
||||
extern short ldshort();
|
||||
extern ldchar(), stchar(), stlong(), stint(), stdbl(), stfloat();
|
||||
extern stbin(), ldbin();
|
||||
|
||||
extern int iserrno; /* isam error number code */
|
||||
extern long isrecnum; /* record number of last call */
|
||||
extern int isreclen; /* used for variable length recs */
|
||||
extern char isstat1; /* cobol status characters */
|
||||
extern char isstat2;
|
||||
|
||||
#define CHARTYPE 0
|
||||
#define CHARSIZE 1
|
||||
|
||||
#define INTTYPE 1
|
||||
#define INTSIZE 2
|
||||
|
||||
#define LONGTYPE 2
|
||||
#define LONGSIZE LONG_BIT/8
|
||||
|
||||
#define DOUBLETYPE 3
|
||||
#define DOUBLESIZE 8
|
||||
|
||||
#define FLOATTYPE 4
|
||||
#define FLOATSIZE 4
|
||||
|
||||
#define BINTYPE 5
|
||||
#define BINSIZE 1
|
||||
|
||||
#define MINTYPE 0
|
||||
#define MAXTYPE 6
|
||||
|
||||
#define ISDESC 0x80 /* add to make descending type */
|
||||
#define TYPEMASK 0x7f /* type mask */
|
||||
|
||||
#define BYTEMASK 0xff /* mask for one byte */
|
||||
#define BYTESHFT 8 /* shift for one byte */
|
||||
|
||||
/* mode parameter in isread() and isstart() */
|
||||
|
||||
#define ISFIRST 0 /* first record */
|
||||
#define ISLAST 1 /* last record */
|
||||
#define ISNEXT 2 /* next record */
|
||||
#define ISPREV 3 /* previous record */
|
||||
#define ISCURR 4 /* current record */
|
||||
|
||||
#define ISEQUAL 5 /* equal value */
|
||||
#define ISGREAT 6 /* greater value */
|
||||
#define ISGTEQ 7 /* >= value */
|
||||
#define ISLESS 8 /* < */
|
||||
#define ISLTEQ 9 /* <= */
|
||||
|
||||
/* isopen, isbuild lock modes */
|
||||
#define ISAUTOLOCK 0x200 /* automatic record lock */
|
||||
#define ISMANULOCK 0x400 /* manual record lock */
|
||||
#define ISEXCLLOCK 0x800 /* exclusive isam file lock */
|
||||
#define ISFASTLOCK 0x4000 /* no locking when EXCLLOCK! */
|
||||
|
||||
/* isread lock modes */
|
||||
#define ISLOCK 0x100 /* lock record before reading */
|
||||
#define ISSKIPLOCK 0x1000 /* advance record pointer to */
|
||||
/* locked record */
|
||||
/* isstart lock mode for automatic record locking */
|
||||
#define ISKEEPLOCK 0x2000 /* keep record locked */
|
||||
|
||||
/* Fix/Variable length records mode */
|
||||
#define ISFIXLEN 0
|
||||
#define ISVARLEN 0x10000
|
||||
|
||||
/* Access remote file via NFS */
|
||||
#define ISNFS 0x20000
|
||||
|
||||
|
||||
#define ISINPUT 0 /* open for input only */
|
||||
#define ISOUTPUT 1 /* open for output only */
|
||||
#define ISINOUT 2 /* open for input and output */
|
||||
|
||||
#define MAXKEYSIZE 150 /* max number of bytes in key */
|
||||
#define NPARTS 8 /* max number of key parts */
|
||||
|
||||
/*#define ISMAXRECLEN 8192 */ /* Maximum number of bytes in record */
|
||||
#define ISMAXRECLEN 32767 /* 32K - 1 */
|
||||
#define ISMINRECLEN 4 /* Minimum number of bytes in record */
|
||||
|
||||
struct keypart {
|
||||
unsigned short kp_start; /* starting byte of key part */
|
||||
short kp_leng; /* length in bytes */
|
||||
short kp_type; /* type of key part */
|
||||
};
|
||||
|
||||
struct keydesc {
|
||||
short k_flags; /* flags */
|
||||
short k_nparts; /* number of parts in key */
|
||||
struct keypart k_part[NPARTS]; /* each part */
|
||||
};
|
||||
|
||||
/* The next three defines are for compatibility with X/OPEN */
|
||||
#define k_start k_part[0].kp_start
|
||||
#define k_leng k_part[0].kp_leng
|
||||
#define k_type k_part[0].kp_type
|
||||
|
||||
#define ISNODUPS 000 /* no duplicates and */
|
||||
/* no compression */
|
||||
#define ISDUPS 001 /* duplicates allowed */
|
||||
#define COMPRESS 020 /* full compression */
|
||||
|
||||
struct dictinfo {
|
||||
short di_nkeys; /* number of keys defined */
|
||||
unsigned short di_recsize; /* data record size */
|
||||
short di_idxsize; /* index record size */
|
||||
long di_nrecords; /* number of records in file */
|
||||
};
|
||||
|
||||
/* msb in di_nkeys indicates that ISAM file supports variable length records */
|
||||
#define DICTVARLENBIT 0x8000
|
||||
|
||||
/* mask to access the true number of keys */
|
||||
#define DICTNKEYSMASK (DICTVARLENBIT - 1)
|
||||
|
||||
|
||||
#define ENOERROR 0 /* No error */
|
||||
#define EDUPL 100 /* duplicate record */
|
||||
#define ENOTOPEN 101 /* file not open */
|
||||
#define EBADARG 102 /* illegal argument */
|
||||
#define EBADKEY 103 /* illegal key desc */
|
||||
#define ETOOMANY 104 /* too many files open */
|
||||
#define EBADFILE 105 /* bad ISAM file format */
|
||||
#define ENOTEXCL 106 /* non-exclusive access */
|
||||
#define ELOCKED 107 /* record locked */
|
||||
#define EKEXISTS 108 /* key already exists */
|
||||
#define EPRIMKEY 109 /* is primary key */
|
||||
#define EENDFILE 110 /* end/begin of file */
|
||||
#define ENOREC 111 /* no record found */
|
||||
#define ENOCURR 112 /* no current record */
|
||||
#define EFLOCKED 113 /* file locked */
|
||||
#define EFNAME 114 /* file name too long */
|
||||
#define EBADMEM 116 /* cannot allocate memory */
|
||||
|
||||
/* NetISAM specific error codes non XOPEN compliant*/
|
||||
#define ETIMEOUT 1117 /* RPC timeout */
|
||||
#define ERPC 1118 /* Broken TCP/IP */
|
||||
#define ETCP 1119 /* Cannot connect to server */
|
||||
#define EIMPORT 1120 /* Cannot import */
|
||||
#define ENODAEMON 1121 /* no local daemon */
|
||||
#define EFATAL 1122 /* internal fatal error */
|
||||
#define ELANG 1123 /* Locale/LANG mismatch */
|
||||
|
||||
|
||||
#define ISOK 0 /* no error return code */
|
||||
#define ISERROR -1 /* error return code */
|
||||
|
||||
|
||||
extern struct keydesc *nokey; /* May be used as parameter
|
||||
* to isbuild() if no
|
||||
* primary key is to be built
|
||||
*/
|
||||
|
||||
/* ischeckindex() diagmode values */
|
||||
#define CHK_NODIAG 0 /* do not print any messages */
|
||||
#define CHK_DIAG 1 /* Access Level module will print to stderr */
|
||||
|
||||
/* values of corrupt parameter of ischeckindex() */
|
||||
#define CHK_OK 0 /* ISAM file is not corrupted */
|
||||
#define CHK_DAT 1 /* .dat file is corrupted */
|
||||
#define CHK_VAR 2 /* .var file is corrupted */
|
||||
#define CHK_IND 3 /* .ind file is corrupted */
|
||||
|
||||
|
||||
/* iscntl() definitions */
|
||||
/* For one isfd - use iscntl(isfd, func, ...) */
|
||||
#define ISCNTL_RPCS_TO_SET 1 /* short oper. timeout (in sec) */
|
||||
#define ISCNTL_RPCS_TO_GET 2 /* short oper. timeout (in sec) */
|
||||
#define ISCNTL_RPCL_TO_SET 3 /* long oper. timeout (in sec) */
|
||||
#define ISCNTL_RPCL_TO_GET 4 /* long oper. timeout (in sec) */
|
||||
#define ISCNTL_TCP_TO_SET 5 /* timeout to reconnect TCP?IP */
|
||||
#define ISCNTL_TCP_TO_GET 6 /* timeout to reconnect TCP?IP */
|
||||
#define ISCNTL_APPLMAGIC_WRITE 7 /* Write Appl. Magic */
|
||||
#define ISCNTL_APPLMAGIC_READ 8 /* Read Appl. Magic */
|
||||
#define ISCNTL_FSYNC 9 /* Flush pages to disk */
|
||||
#define ISCNTL_FDLIMIT_SET 10 /* Set UNIX fd usage limit */
|
||||
#define ISCNTL_FDLIMIT_GET 11 /* Get UNIX fd usage limit */
|
||||
#define ISCNTL_FATAL 12 /* Specify NetISAM fatal error hadler */
|
||||
#define ISCNTL_MASKSIGNALS 13 /* Enable or Disable masking signals during NetISAM operations */
|
||||
|
||||
#define ISAPPLMAGICLEN 32
|
||||
|
||||
/*
|
||||
* ALLISFD in iscntl() calls means that the operation should be done
|
||||
* on all open file descriptors, or the operation is not related to
|
||||
* any file descriptor (e.g: maskintg signals)
|
||||
*/
|
||||
#define ALLISFD (-2)
|
||||
|
||||
/* isshowlocks() and isshowhostlocks() return an array of struct showlock */
|
||||
#define IPADDRLEN 4 /* IP address length */
|
||||
struct showlock {
|
||||
short dev; /* Major/Minor device number,
|
||||
* actually type dev_t */
|
||||
long inode; /* inode number */
|
||||
long recnum; /* record number */
|
||||
char hostid[IPADDRLEN]; /* IP address of host */
|
||||
short pid; /* UNIX process ID */
|
||||
long uid; /* User ID */
|
||||
short type; /* See below */
|
||||
};
|
||||
|
||||
|
||||
/* NetISAM Programmer Toolkit related definitions */
|
||||
|
||||
struct isfldmap {
|
||||
char *flm_fldname;
|
||||
short flm_recoff;
|
||||
short flm_bufoff;
|
||||
short flm_type;
|
||||
short flm_length;
|
||||
};
|
||||
|
||||
struct istableinfo {
|
||||
char *tbi_tablename;
|
||||
int tbi_reclength;
|
||||
int tbi_nfields;
|
||||
struct isfldmap *tbi_fields;
|
||||
int tbi_nkeys;
|
||||
struct keydesc *tbi_keys;
|
||||
char **tbi_keynames;
|
||||
};
|
||||
|
||||
/* record descriptor isreadm/iswritem record descriptor */
|
||||
struct recorddesc {
|
||||
char *rec_buffer;
|
||||
long rec_number;
|
||||
short rec_length;
|
||||
short rec_locked;
|
||||
};
|
||||
|
||||
/*
|
||||
* The following defines and variable definitions are not used by NetISAM 1.0.
|
||||
* They are defined for compatibility with VSX 2.5.
|
||||
*/
|
||||
#define EBADCOLL (-1)
|
||||
|
||||
#define IO_OPEN 0x10 /* open() */
|
||||
#define IO_CREA 0x20 /* creat() */
|
||||
#define IO_SEEK 0x30 /* lseek() */
|
||||
#define IO_READ 0x40 /* read() */
|
||||
#define IO_WRIT 0x50 /* write() */
|
||||
#define IO_LOCK 0x60 /* lockf() */
|
||||
#define IO_IOCTL 0x70 /* ioctl() */
|
||||
#define IO_RENAME 0x80 /* rename() */
|
||||
#define IO_UNLINK 0x90 /* unlink() */
|
||||
|
||||
extern int iserrio;
|
||||
|
||||
|
||||
#endif /* !_ISAM_H */
|
||||
762
cde/lib/tt/mini_isam/isam_impl.h
Normal file
762
cde/lib/tt/mini_isam/isam_impl.h
Normal file
@@ -0,0 +1,762 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: isam_impl.h /main/4 1998/03/16 14:41:21 mgreess $ */
|
||||
/* @(#)isam_impl.h 1.11 93/09/07 */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isam_impl.h
|
||||
*
|
||||
* Description:
|
||||
* NetISAM implementation specific definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ISAM_IMPL_H
|
||||
#define _ISAM_IMPL_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
/* AIX does not define FD_SETSIZE in sys/types.h. */
|
||||
#if !defined(FD_SETSIZE)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* #include sys/types.h is to get u_long, u_short, dev_t
|
||||
*
|
||||
* #include sys/param.h is to get MAXHOSTNAMELEN
|
||||
*/
|
||||
|
||||
#include "isam.h"
|
||||
|
||||
/*
|
||||
* Static is used in definitions of local functions. It is defined to
|
||||
* "static" normally, but to an empty string when compiled for profiling
|
||||
* purposes (-p or -pg options to the cc compiler). If a function is
|
||||
* defined as static, then the profiling tools account the time spent in
|
||||
* this function to the physically previous global function which is
|
||||
* incorrect and makes the output of the profiler tools useless.
|
||||
*/
|
||||
#if defined(PROF) || defined(GPROF)
|
||||
#define Static
|
||||
#else
|
||||
#define Static static
|
||||
#endif
|
||||
|
||||
extern int isdupl;
|
||||
|
||||
typedef long Recno; /* record numbers */
|
||||
typedef long Blkno; /* block numbers */
|
||||
typedef long Time; /* standard UNIX time */
|
||||
typedef int Isfd; /* ISAM file descriptor */
|
||||
|
||||
typedef int Bool;
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define ISOPENMODE 0xff /* Mask to get ISINPUT/ISOUTPUT */
|
||||
/* or ISINOUT */
|
||||
#define ISLOCKMODE 0xff00 /* Mask to get lock mode */
|
||||
#define ISREADMODE 0xff /* Mask to get ISFIRST, etc. */
|
||||
|
||||
#define ISLENMODE 0x10000 /* Mask to get FIX/VAR length */
|
||||
|
||||
#define ISPAGESIZE 1024 /* page size */
|
||||
|
||||
#define N_CNTL_PAGES 2 /*
|
||||
* Number of control pages
|
||||
* at the beg. of .rec file
|
||||
*/
|
||||
#define ISCNTLSIZE (ISPAGESIZE * N_CNTL_PAGES)
|
||||
|
||||
|
||||
#define ISMAGIC "NetISAM" /* 'magic number' in ISAM files */
|
||||
|
||||
#ifndef ISVERSION
|
||||
#define ISVERSION "Unknown"
|
||||
#endif
|
||||
|
||||
#define MAXFCB_UNIXFD 30 /* Maximum number of UNIX fd
|
||||
* used by the FCB module
|
||||
*/
|
||||
|
||||
#define ISLEAFSLACK 10 /* Default slack in leaves */
|
||||
|
||||
/* Default RPC timeout values */
|
||||
#define ISRPCS_TO_DEF 60 /* secs for short oper. */
|
||||
#define ISRPCL_TO_DEF (120 * 60) /* secs for long oper. */
|
||||
#define ISTCP_TO_DEF (3 * 60) /* secs to reconnect TCP/IP */
|
||||
#define ISRPC_POLL_TO_DEF 30 /* interval to hear from polled client */
|
||||
#define ISTCP_RETRY_SLEEP 5 /* time between tries to
|
||||
* establish a connection
|
||||
*/
|
||||
|
||||
/*
|
||||
* The X/OPEN ISAM internal data representations.
|
||||
* The #define statements are used to declare type lengths and offsets
|
||||
* in structures in order for the definitions to be compiler independent.
|
||||
*/
|
||||
|
||||
#define TIMETYPE LONGTYPE /* standard UNIX time */
|
||||
#define TIMESIZE LONGSIZE
|
||||
|
||||
#define BLKNOTYPE LONGTYPE /* block (page) numbers */
|
||||
#define BLKNOSIZE LONGSIZE
|
||||
|
||||
#define RECNOTYPE LONGTYPE /* record numbers */
|
||||
#define RECNOSIZE LONGSIZE
|
||||
|
||||
/*
|
||||
* SHORTTYPE is a safeguard - if the X/OPEN ISAM changes INTTYPE to 4 bytes
|
||||
* all the internals of NetISAM will work. The only change will be
|
||||
* re-defining SHORTTYPE.
|
||||
*/
|
||||
|
||||
#define SHORTTYPE INTTYPE
|
||||
#define SHORTSIZE INTSIZE
|
||||
|
||||
/* The following defines are used in isstart() */
|
||||
#define WHOLEKEY 0
|
||||
#define USE_PHYS_ORDER(keydesc) (keydesc->k_nparts == 0)
|
||||
|
||||
/* Structure for storing and passing variable length byte array data */
|
||||
typedef struct bytearray {
|
||||
u_short length;
|
||||
char *data;
|
||||
} Bytearray;
|
||||
|
||||
extern Bytearray _bytearr_getempty(), _bytearr_dup(), _bytearr_new();
|
||||
extern void _bytearr_free();
|
||||
|
||||
|
||||
/* Client identification - used to identify owners of locks */
|
||||
/*
|
||||
#define IPADDRLEN 4
|
||||
*/
|
||||
|
||||
/* Definitions related to ISAM file descriptor (isfd.c file) */
|
||||
#define MAXISFD FD_SETSIZE
|
||||
#define NOISFD (-1) /* Not a valid file descriptor */
|
||||
|
||||
extern struct fab *_isfd_find();
|
||||
extern void _isfd_delete();
|
||||
extern Isfd _isfd_insert();
|
||||
|
||||
/* Definitions related to File access block (isfab.c file */
|
||||
|
||||
/* File open mode */
|
||||
enum openmode { OM_INPUT = 0, OM_OUTPUT = 1, OM_INOUT = 2, OM_BADMODE = 3};
|
||||
enum lockmode { LM_FAST = 0, LM_EXCL = 1, LM_AUTOMATIC = 2, LM_MANUAL = 3, LM_BADMODE = 4};
|
||||
|
||||
/* isread() read modes */
|
||||
enum readmode { RM_FIRST = 0, RM_LAST = 1, RM_NEXT = 2, RM_PREV = 3,
|
||||
RM_CURR = 4, RM_EQUAL = 5, RM_GREAT = 6, RM_GTEQ = 7,
|
||||
RM_LESS = 8, RM_LTEQ = 9, RM_BADMODE = 10 };
|
||||
|
||||
/* lock flag is passed to Access Method module for every record oriented op. */
|
||||
/* Bit position in the lock flag: */
|
||||
|
||||
enum openmode _getopenmode();
|
||||
enum readmode _getreadmode();
|
||||
|
||||
/* Error code structure */
|
||||
struct errcode {
|
||||
int iserrno;
|
||||
char isstat [4];
|
||||
};
|
||||
|
||||
typedef struct fab {
|
||||
Isfd isfd; /* ISAM file descriptor */
|
||||
enum openmode openmode; /* File access mode */
|
||||
enum lockmode lockmode; /* File lock mode */
|
||||
Bool locked; /* TRUE if file is locked */
|
||||
Bool varlength; /* TRUE if variable length records
|
||||
* supported by this ISAM file */
|
||||
int minreclen; /* Minimum record length */
|
||||
int maxreclen; /* Maximum record length */
|
||||
char *isamhost; /* IP host name */
|
||||
char *isfname; /* ISAM file local pathname */
|
||||
Bytearray isfhandle; /* ISAM file handle */
|
||||
Bytearray curpos; /* Current record position */
|
||||
struct errcode errcode; /* Error codes structure */
|
||||
} Fab;
|
||||
|
||||
/* values for filemode */
|
||||
#define LOCAL_FILE 0
|
||||
#define REMOTE_FILE 1
|
||||
#define NFS_FILE 2 /* File is remote, but is
|
||||
* accessed via NFS
|
||||
*/
|
||||
|
||||
#define FAB_ISFDSET(fab, isfd) (fab->isfd = isfd)
|
||||
|
||||
extern Fab *_fab_new();
|
||||
void _fab_destroy();
|
||||
|
||||
/* ISAM file identification for locking purposes. */
|
||||
typedef struct lckfid {
|
||||
dev_t diskid; /* Disk device id */
|
||||
ino_t inode; /* .rec file inode number */
|
||||
} Lckfid;
|
||||
|
||||
/* File Control Block */
|
||||
typedef struct fcb {
|
||||
char *isfname; /* ISAM file name */
|
||||
int blocksize; /* Block size */
|
||||
Bool rdonly; /* file is read-only */
|
||||
Lckfid lckfid; /* File id for locking */
|
||||
int datfd; /* UNIX file descr. of .rec file */
|
||||
int indfd; /* UNIX file descr. of .ind file */
|
||||
int varfd; /* UNIX file descr. of .var file */
|
||||
Blkno datsize; /* dat file size in blocks */
|
||||
Blkno indsize; /* ind file size in blocks */
|
||||
Blkno varsize; /* var file size in blocks */
|
||||
Bool varflag; /* TRUE if variable length*/
|
||||
long nrecords; /* Number of records */
|
||||
int minreclen; /* Minimum record length */
|
||||
int maxreclen; /* Maximum record length */
|
||||
Recno lastrecno; /* Last recno in use */
|
||||
Recno freerecno; /* Pointer to first free record */
|
||||
int lastkeyid; /* Last key identifier used */
|
||||
int changestamp1; /* Stamp 1 of last change */
|
||||
int changestamp2; /* Stamp 2 of last change */
|
||||
Blkno indfreelist; /* Head of freepage list of .ind */
|
||||
|
||||
int nkeys; /* Number of keys */
|
||||
struct keydesc2 *keys; /* Key descriptors */
|
||||
long varend; /* Offset of the last byte */
|
||||
/* in .var file */
|
||||
int lockfd; /* lock file fd for locking .rec for 5.0 */
|
||||
} Fcb;
|
||||
|
||||
#define FCB_NOPRIMARY_KEY(fcb) ((fcb)->keys[0].k2_nparts == 0)
|
||||
|
||||
/* Current Record Position (interpreted only by Access Method) */
|
||||
enum crpflag { CRP_UNDEF = 0, CRP_ON = 1, CRP_AFTER = 2, CRP_BEFORE = 3,
|
||||
CRP_BEFOREANY = 4, CRP_AFTERANY = 5};
|
||||
typedef struct crp {
|
||||
int keyid; /* Key index */
|
||||
enum crpflag flag; /* ON/BEFORE/AFTER/UNDEF */
|
||||
Recno recno; /* Record number */
|
||||
int matchkeylen; /* match so many bytes of key */
|
||||
char key[1]; /* Index position */
|
||||
} Crp;
|
||||
|
||||
#define PHYS_ORDER (-1) /* value for keyid when physical
|
||||
order is used*/
|
||||
|
||||
/*
|
||||
* keydesc2 is the 'internal copy'of keydesc.
|
||||
* keydesc2 contains all information needed by internally by NetISAM,
|
||||
* whereas keydesc conforms to the X/OPEN ISAM.
|
||||
*/
|
||||
|
||||
#define NPARTS2 (NPARTS+2) /* duplid and recno */
|
||||
#define DUPSMASK 001 /* Mask to get ISDUPS/ISNODUPS */
|
||||
#define ISPRIMKEY 040 /* this is primary key */
|
||||
#define ALLOWS_DUPS2(pkdesc2) (((pkdesc2)->k2_flags & DUPSMASK) == ISDUPS)
|
||||
#define ALLOWS_DUPS(pkdesc) (((pkdesc)->k_flags & DUPSMASK) == ISDUPS)
|
||||
|
||||
/* serial number of duplicate keys */
|
||||
#define DUPIDTYPE LONGTYPE
|
||||
#define DUPIDSIZE LONGSIZE
|
||||
|
||||
#define KEY_RECNO_OFF 0
|
||||
#define KEY_DUPS_OFF RECNOSIZE
|
||||
|
||||
#define stdupser(n, b) stlong((long)(n), (b))
|
||||
#define lddupser(b) ((int)ldlong(b))
|
||||
|
||||
struct keypart2 {
|
||||
u_short kp2_start; /* starting byte of key part */
|
||||
short kp2_leng; /* length in bytes */
|
||||
short kp2_type; /* type of key part */
|
||||
u_short kp2_offset; /* offset in key buffer */
|
||||
};
|
||||
|
||||
typedef struct keydesc2 {
|
||||
short k2_flags; /* flags */
|
||||
short k2_nparts; /* number of parts in key */
|
||||
short k2_len; /* length of the whole key */
|
||||
Blkno k2_rootnode; /* pointer to root node */
|
||||
int k2_keyid; /* Key identifier */
|
||||
struct keypart2 k2_part[NPARTS2]; /* each part */
|
||||
} Keydesc2;
|
||||
|
||||
typedef unsigned long rel_addr;
|
||||
/* Double linked list element */
|
||||
struct dlink {
|
||||
rel_addr dln_forward; /* Forward link */
|
||||
rel_addr dln_backward; /* Backward link */
|
||||
};
|
||||
|
||||
/* Disk buffer management definitions */
|
||||
|
||||
/* cache buffer header */
|
||||
typedef struct bufhdr {
|
||||
Fcb *isb_fcb; /* Pointer to FCB */
|
||||
int isb_unixfd; /* UNIX file descriptor */
|
||||
Blkno isb_blkno; /* block number */
|
||||
struct dlink isb_hash; /* hashed list*/
|
||||
struct dlink isb_aclist; /* available or changed list */
|
||||
struct dlink isb_flist; /* list of fixed blocks */
|
||||
char *isb_buf_w; /* malloc() buffer with dirty data */
|
||||
char *isb_buf_r; /* points to mapped segment */
|
||||
char *isb_buffer; /* set to isb_buf_r or isb_buf_w */
|
||||
char isb_flags; /* flags - defs. see below */
|
||||
struct bufhdr *isb_oldcopy; /* pointer to old copy */
|
||||
} Bufhdr;
|
||||
|
||||
/* mapped segment header */
|
||||
typedef struct maphdr {
|
||||
Fcb *m_fcb; /* Pointer to FCB */
|
||||
int m_unixfd; /* UNIX file descriptor */
|
||||
char *m_addr; /* Pointer to beginning of seg. */
|
||||
int m_segm_num; /* Segment number in the file */
|
||||
unsigned long m_stamp; /* Assigned when touched */
|
||||
} Maphdr;
|
||||
|
||||
|
||||
/* values of isb_flags */
|
||||
#define ISB_NODATA 00 /* block has no data */
|
||||
#define ISB_READ 01 /* page has valid data */
|
||||
#define ISB_CHANGE 02 /* page must be flushed */
|
||||
#define ISB_RFIXED 04 /* block is fixed for read*/
|
||||
#define ISB_WFIXED 010 /* block is fixed for write*/
|
||||
#define ISB_OLDCOPY 020 /* block is old copy */
|
||||
|
||||
/* mode values to is__cache_fix() */
|
||||
#define ISFIXREAD 1 /* fix for read */
|
||||
#define ISFIXWRITE 2 /* fix for update */
|
||||
#define ISFIXNOREAD 3 /* fix for update, don't read */
|
||||
|
||||
|
||||
/*
|
||||
* Macro to get pointer to structure if pointer to some element is known
|
||||
*/
|
||||
#define GETBASE(p,s,e) ((struct s *) ((char *)(p) - (int)&((struct s *)0)->e))
|
||||
|
||||
/* In memory sorting object */
|
||||
typedef struct issort {
|
||||
int ist_reclength; /* record length in bytes */
|
||||
int ist_allocrecs; /* memory allocated for so */
|
||||
/* many records */
|
||||
int ist_nrecs; /* number of records inserted */
|
||||
int ist_currec; /* current position */
|
||||
int (*ist_compf) (); /* comparison function */
|
||||
char *ist_array; /* array of records */
|
||||
} Issort;
|
||||
|
||||
|
||||
/* btree is object used for processing B-tree operations */
|
||||
|
||||
#define ISMAXBTRLEVEL 12 /* Maximum level of B-tree */
|
||||
|
||||
typedef struct btree {
|
||||
Fcb *fcb;
|
||||
Keydesc2 *keydesc2;
|
||||
int depth; /* depth of the B-tree */
|
||||
Bufhdr *bufhdr[ISMAXBTRLEVEL]; /* fixed blocks buf. headers */
|
||||
int curpos[ISMAXBTRLEVEL]; /* current position on block */
|
||||
} Btree;
|
||||
|
||||
/* Lock manager related definitions. */
|
||||
/* Entry in lock table */
|
||||
|
||||
/* Number of buckets for hashing by clientid. Must be a power of 2*/
|
||||
#ifndef HASHPROCSIZE
|
||||
#define HASHPROCSIZE 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Number of buckets for hashing by record number and fileid.
|
||||
* Must be a power of 2
|
||||
*/
|
||||
#ifndef HASHENTSIZE
|
||||
#define HASHENTSIZE 1024
|
||||
#endif
|
||||
|
||||
/* Pseudo record numbers used by file locking. */
|
||||
#define AVAIL_RECNO (0L) /* Entry is available */
|
||||
#define ALLFILE_RECNO (-1L) /* Entire file lock */
|
||||
#define OPENFILE_RECNO (-2L) /* Used by isopen() */
|
||||
|
||||
/* Lock table file header */
|
||||
struct lockfilehdr {
|
||||
int size; /* size of LOCKTABLEFILE
|
||||
* set to 0 forces reinitialization
|
||||
* at next lock request.
|
||||
*/
|
||||
int prochdsn; /* Number of lists hashed by
|
||||
* clientid */
|
||||
int enthdsn; /* Number of list hashed by
|
||||
* record number */
|
||||
int lockentriesn; /* total number of lock entries */
|
||||
struct dlink avail; /* Double linked list of
|
||||
* available lock entries */
|
||||
};
|
||||
|
||||
/* Exported filesystem options structure and constants*/
|
||||
|
||||
#define RW_CLIENTS_SIZE 1 /* Not currently needed */
|
||||
#define UID_SIZE 10 /* Big enough to hold a Unix UID */
|
||||
#define ROOT_OPT_SIZE 240 /* List of hosts for which root access
|
||||
is allowed -- can be quite long */
|
||||
#define SHARE_BUFFER_SIZE 400
|
||||
|
||||
struct export_opts {
|
||||
int read_write; /* 0 => read-only, 1 => read/write */
|
||||
char rw_clients[1]; /* Not interesting, len=1 to save space */
|
||||
char export_dir[1]; /* ditto here */
|
||||
char anon[UID_SIZE];
|
||||
char root[ROOT_OPT_SIZE];
|
||||
int secure; /* RPC authentication flag: 0 => AUTH_UNIX, 1 => AUTH_DES */
|
||||
};
|
||||
|
||||
|
||||
extern Fcb *_isfcb_create();
|
||||
extern Fcb *_isfcb_open();
|
||||
extern void _isfcb_remove();
|
||||
extern void _isfcb_close();
|
||||
extern void _isfcb_setreclength();
|
||||
extern void _isfcb_setprimkey();
|
||||
extern int _isfcb_cntlpg_w();
|
||||
|
||||
|
||||
#define DAT_SUFFIX ".rec"
|
||||
#define IND_SUFFIX ".ind"
|
||||
#define VAR_SUFFIX ".var"
|
||||
#define LOCK_SUFFIX ".lock" /* yh: lock file for .rec to solve mmap in 5.0 */
|
||||
|
||||
/* Values of deleted flag for fixed length records */
|
||||
#define FL_RECDELETED 0
|
||||
#define FL_RECEXISTS 1
|
||||
|
||||
/* Special values of tail pointer for variable length records */
|
||||
#define VL_RECDELETED ((long ) -1L)
|
||||
#define VL_RECNOTAIL ((long ) -2L)
|
||||
|
||||
|
||||
extern long lseek();
|
||||
|
||||
extern char *_ismalloc(), *_isrealloc(), *_isallocstring();
|
||||
extern void _isfree(), _isfreestring();
|
||||
extern void _isfatal_error(), _setiserrno2(), _seterr_errcode();
|
||||
extern void _makedat_isfname();
|
||||
extern void _makeind_isfname();
|
||||
extern void _makevar_isfname();
|
||||
extern void _amseterrcode();
|
||||
|
||||
extern void _isseekpg(), _isreadpg(), _iswritepg();
|
||||
|
||||
extern Bufhdr *_isdisk_fix(), *_isdisk_refix();
|
||||
extern void _isdisk_commit(), _isdisk_sync(), _isdisk_inval(),
|
||||
_isdisk_commit1(), _isdisk_unfix();
|
||||
extern void _isdisk_rollback();
|
||||
extern void _cp_tofile(), _cp_fromfile();
|
||||
Blkno _extend_file();
|
||||
|
||||
extern void _isdln_base_insert(), _isdln_base_remove(), _isdln_base_append(),
|
||||
_isdln_base_makeempty();
|
||||
extern struct dlink *_isdln_base_prev(), *_isdln_base_next(), *_isdln_base_first();
|
||||
|
||||
extern void _mngfcb_insert(), _mngfcb_delete();
|
||||
extern Fcb *_mngfcb_find();
|
||||
extern Bytearray *_mngfcb_victim();
|
||||
extern char *_getisfname();
|
||||
extern Bytearray _makeisfhandle();
|
||||
|
||||
extern Bytearray _makeisfhandle();
|
||||
extern Fcb *_openfcb();
|
||||
|
||||
extern Time _amtime_set(), _amtime_get();
|
||||
|
||||
extern void _islock_closefile(), _islock_unlockfile();
|
||||
|
||||
extern Keydesc2 *_isfcb_findkey(), *_isfcb_indfindkey();
|
||||
extern void stkey(), ldkey();
|
||||
|
||||
extern Issort *_issort_create();
|
||||
extern char *_issort_read();
|
||||
extern void _issort_destroy(), _issort_insert(), _issort_sort(),
|
||||
_issort_rewind();
|
||||
|
||||
extern void _iskeycmp_set();
|
||||
extern int _iskeycmp();
|
||||
|
||||
extern char *_isbsearch();
|
||||
|
||||
extern void _iskey_extract();
|
||||
extern Blkno _isindfreel_alloc();
|
||||
extern void _isindfreel_free();
|
||||
extern long _fl_getpos();
|
||||
|
||||
extern Btree *_isbtree_create();
|
||||
extern void _isbtree_destroy(), _isbtree_search(), _isbtree_insert(),
|
||||
_isbtree_remove();
|
||||
extern char *_isbtree_current(), *_isbtree_next();
|
||||
|
||||
extern void _iskey_fillmin(), _iskey_fillmax();
|
||||
|
||||
extern Bufhdr *_allockpage();
|
||||
|
||||
extern void _del1key();
|
||||
extern int _add1key(), _change1key();
|
||||
extern void _delkeys();
|
||||
extern char *_ismap_getaddr();
|
||||
extern void _ismap_endop(), _ismap_unmapfcb();
|
||||
|
||||
extern void _isam_entryhook(), _isam_exithook();
|
||||
|
||||
#define stshort(n,p) stint((n), (p))
|
||||
#define ldshort(p) ldint(p)
|
||||
|
||||
#define strecno(n,p) stlong((long)(n), (p))
|
||||
#define ldrecno(p) ((Recno)ldlong(p))
|
||||
|
||||
#define stblkno(n,p) stlong((long)(n), (p))
|
||||
#define ldblkno(p) ((Blkno)ldlong(p))
|
||||
|
||||
extern int _flrec_read(), _flrec_write(), _flrec_rewrite(), _flrec_delete(),
|
||||
_flrec_wrrec();
|
||||
extern int _vlrec_read(), _vlrec_write(), _vlrec_rewrite(), _vlrec_delete(),
|
||||
_vlrec_wrrec();
|
||||
|
||||
/*------------ UNIX file formats ---------------------------------------------*/
|
||||
|
||||
#define ISCNTLPGOFF ((Blkno) 0) /* offset of Control Page */
|
||||
|
||||
/* internal key descriptor */
|
||||
|
||||
#define KP2_START_OFF 0 /* see struct keypart2 */
|
||||
#define KP2_LENGTH_OFF SHORTSIZE
|
||||
#define KP2_TYPE_OFF (2*SHORTSIZE)
|
||||
#define KP2_OFFSET_OFF (3*SHORTSIZE)
|
||||
#define KP2_LEN (4*SHORTSIZE)
|
||||
|
||||
#define K2_FLAGS_OFF 0 /* see struct keydesc2 */
|
||||
#define K2_NPARTS_OFF SHORTSIZE
|
||||
#define K2_LEN_OFF (2*SHORTSIZE)
|
||||
#define K2_ROOT_OFF (3*SHORTSIZE)
|
||||
#define K2_KEYID_OFF (3*SHORTSIZE+BLKNOSIZE)
|
||||
#define K2_KEYPART_OFF (3*SHORTSIZE+2*BLKNOSIZE)
|
||||
#define K2_LEN (3*SHORTSIZE+2*BLKNOSIZE+ NPARTS2*KP2_LEN)
|
||||
|
||||
#define NULL_BLKNO 0L
|
||||
#define NULL_RECNO 0L
|
||||
#define PAGE1_BLKNO 0 /* Block number of control page */
|
||||
/*------------------------- Control Page layout -----------------------------*/
|
||||
|
||||
/* Magic number (must be equal to "NetISAM") */
|
||||
#define CP_MAGIC_OFF 0
|
||||
#define CP_MAGIC_LEN 8
|
||||
|
||||
/* Version stamp */
|
||||
#define CP_VERSION_OFF (CP_MAGIC_OFF+CP_MAGIC_LEN)
|
||||
#define CP_VERSION_LEN 8
|
||||
|
||||
/* Application stamp */
|
||||
#define CP_APPLMAGIC_OFF (CP_VERSION_OFF+ CP_VERSION_LEN)
|
||||
#define CP_APPLMAGIC_LEN ISAPPLMAGICLEN
|
||||
|
||||
/* Block size */
|
||||
#define CP_BLOCKSIZE_OFF (CP_APPLMAGIC_OFF+CP_APPLMAGIC_LEN)
|
||||
#define CP_BLOCKSIZE_LEN SHORTSIZE
|
||||
|
||||
/* file size in blocks */
|
||||
#define CP_DATSIZE_OFF (CP_BLOCKSIZE_OFF+CP_BLOCKSIZE_LEN)
|
||||
#define CP_DATSIZE_LEN BLKNOSIZE
|
||||
|
||||
/* file size in blocks */
|
||||
#define CP_INDSIZE_OFF (CP_DATSIZE_OFF+CP_DATSIZE_LEN)
|
||||
#define CP_INDSIZE_LEN BLKNOSIZE
|
||||
|
||||
/* file size in blocks */
|
||||
#define CP_VARSIZE_OFF (CP_INDSIZE_OFF+CP_INDSIZE_LEN)
|
||||
#define CP_VARSIZE_LEN BLKNOSIZE
|
||||
|
||||
/* 0/1 flag telling whether file supports variable length records. */
|
||||
#define CP_VARFLAG_OFF (CP_VARSIZE_OFF+CP_VARSIZE_LEN)
|
||||
#define CP_VARFLAG_LEN SHORTSIZE
|
||||
|
||||
/* number of record in the file */
|
||||
#define CP_NRECORDS_OFF (CP_VARFLAG_OFF+CP_VARFLAG_LEN)
|
||||
#define CP_NRECORDS_LEN LONGSIZE
|
||||
|
||||
/* minimum record length */
|
||||
#define CP_MINRECLEN_OFF (CP_NRECORDS_OFF+CP_NRECORDS_LEN)
|
||||
#define CP_MINRECLEN_LEN SHORTSIZE
|
||||
|
||||
/* maximum record length */
|
||||
#define CP_MAXRECLEN_OFF (CP_MINRECLEN_OFF+CP_MINRECLEN_LEN)
|
||||
#define CP_MAXRECLEN_LEN SHORTSIZE
|
||||
|
||||
/*
|
||||
* Left 0 and not used in NetISAM 1.0.
|
||||
* Will be set at restructuring to some optimal value x
|
||||
* (minreclen <= x <= maxreclen).
|
||||
* Record with length will be stored in .rec file only.
|
||||
* In NetISAM 1.0 x == minreclen.
|
||||
*/
|
||||
/* split record record length */
|
||||
#define CP_SPLITRECLEN_OFF (CP_MAXRECLEN_OFF+CP_MAXRECLEN_LEN)
|
||||
#define CP_SPLITRECLEN_LEN SHORTSIZE
|
||||
|
||||
/* Recno of last record */
|
||||
#define CP_LASTRECNO_OFF (CP_SPLITRECLEN_OFF+CP_SPLITRECLEN_LEN)
|
||||
#define CP_LASTRECNO_LEN RECNOSIZE
|
||||
|
||||
/* Head of deleted records list */
|
||||
#define CP_FREERECNO_OFF (CP_LASTRECNO_OFF+CP_LASTRECNO_LEN)
|
||||
#define CP_FREERECNO_LEN RECNOSIZE
|
||||
|
||||
/* 0/1 flag telling whether file has a primary key */
|
||||
#define CP_HASPRIMKEY_OFF (CP_FREERECNO_OFF+CP_FREERECNO_LEN)
|
||||
#define CP_HASPRIMKEY_LEN SHORTSIZE
|
||||
|
||||
/* Last key indentifier. */
|
||||
#define CP_LASTKEYID_OFF (CP_HASPRIMKEY_OFF+CP_HASPRIMKEY_LEN)
|
||||
#define CP_LASTKEYID_LEN LONGSIZE
|
||||
|
||||
/* Stamp 1 of last change */
|
||||
#define CP_CHANGESTAMP1_OFF (CP_LASTKEYID_OFF+CP_LASTKEYID_LEN)
|
||||
#define CP_CHANGESTAMP1_LEN LONGSIZE
|
||||
|
||||
/* Stamp 2 of last change */
|
||||
#define CP_CHANGESTAMP2_OFF (CP_CHANGESTAMP1_OFF+CP_CHANGESTAMP1_LEN)
|
||||
#define CP_CHANGESTAMP2_LEN LONGSIZE
|
||||
|
||||
/* .ind file free list */
|
||||
#define CP_INDFREELIST_OFF (CP_CHANGESTAMP2_OFF+CP_CHANGESTAMP2_LEN)
|
||||
#define CP_INDFREELIST_LEN BLKNOSIZE
|
||||
|
||||
/* number of keys */
|
||||
#define CP_NKEYS_OFF (CP_INDFREELIST_OFF+CP_INDFREELIST_LEN)
|
||||
#define CP_NKEYS_LEN SHORTSIZE
|
||||
|
||||
/* use 4 bytes of reserved space */
|
||||
#define CP_VAREND_OFF (CP_NKEYS_OFF+CP_NKEYS_LEN)
|
||||
#define CP_VAREND_LEN LONGSIZE
|
||||
|
||||
/* use 4 bytes of reserved space for time stamp*/
|
||||
#define CP_UNIQUE_OFF (CP_VAREND_OFF+CP_VAREND_LEN)
|
||||
#define CP_UNIQUE_LEN LONGSIZE
|
||||
|
||||
/* reserve some space for future */
|
||||
#define CP_RESERVE_OFF (CP_UNIQUE_OFF+CP_UNIQUE_LEN)
|
||||
#define CP_RESERVE_LEN 120 /* 128 was reserved originally */
|
||||
|
||||
/* table of key descriptors */
|
||||
#define CP_KEYS_OFF (CP_RESERVE_OFF+CP_RESERVE_LEN)
|
||||
|
||||
#define MAXNKEYS2 ((ISCNTLSIZE - CP_KEYS_OFF) / K2_LEN)
|
||||
#define MAXNKEYS 17
|
||||
|
||||
#if (MAXNKEYS2 < MAXNKEYS)
|
||||
Cause a compiler error here. There is not enought space in the control
|
||||
page to hold MAXNKEYS.
|
||||
#endif
|
||||
|
||||
/*------ page type indicator values -------------*/
|
||||
#define PT_INDEX 1 /* B-tree page */
|
||||
#define PT_FREELIST 2 /* free list */
|
||||
|
||||
/*-------------- B-Tree page layout -----------------------------------*/
|
||||
/* page type */
|
||||
#define BT_TYPE_OFF 0
|
||||
#define BT_TYPE_LEN SHORTSIZE
|
||||
|
||||
/* level (leaves have level 0) */
|
||||
#define BT_LEVEL_OFF (BT_TYPE_OFF+BT_TYPE_LEN)
|
||||
#define BT_LEVEL_LEN SHORTSIZE
|
||||
|
||||
/* page capacity */
|
||||
#define BT_CAPAC_OFF (BT_LEVEL_OFF+BT_LEVEL_LEN)
|
||||
#define BT_CAPAC_LEN SHORTSIZE
|
||||
|
||||
/* current number of keys */
|
||||
#define BT_NKEYS_OFF (BT_CAPAC_OFF+BT_CAPAC_LEN)
|
||||
#define BT_NKEYS_LEN SHORTSIZE
|
||||
|
||||
/* array of key entries */
|
||||
#define BT_KEYS_OFF (BT_NKEYS_OFF+BT_NKEYS_LEN)
|
||||
|
||||
/* down pointers are stored at the end of the page */
|
||||
|
||||
/*----------- Free List Page Layout --------------------------------------*/
|
||||
/* page type */
|
||||
#define FL_TYPE_OFF 0
|
||||
#define FL_TYPE_LEN SHORTSIZE
|
||||
|
||||
/* pointer to next block in the list */
|
||||
#define FL_NEXT_OFF (FL_TYPE_OFF + FL_TYPE_LEN)
|
||||
#define FL_NEXT_LEN BLKNOSIZE
|
||||
|
||||
/* number of free page pointers */
|
||||
#define FL_NPOINTERS_OFF (FL_NEXT_OFF + FL_NEXT_LEN)
|
||||
#define FL_NPOINTERS_LEN SHORTSIZE
|
||||
|
||||
/* free page pointers table */
|
||||
#define FL_POINTERS_OFF (FL_NPOINTERS_OFF + FL_NPOINTERS_LEN)
|
||||
|
||||
/* maximum number of pointers that can be stored in a page */
|
||||
#define FL_MAXNPOINTERS ((ISPAGESIZE - FL_POINTERS_OFF) / BLKNOSIZE)
|
||||
|
||||
#define FREELIST_NOPAGE ((Blkno) -1)
|
||||
|
||||
/* .var file related defines */
|
||||
#define VR_FRAMELEN_OFF 0
|
||||
#define VR_TAILLEN_OFF 2
|
||||
|
||||
|
||||
/* maximum and minimum values are in B-tree seaches */
|
||||
#if LONG_BIT == 64
|
||||
#define ISMAXLONG { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
|
||||
#define ISMINLONG { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
#else
|
||||
#define ISMAXLONG { 0x7f, 0xff, 0xff, 0xff }
|
||||
#define ISMINLONG { 0x80, 0x00, 0x00, 0x00 }
|
||||
#endif
|
||||
|
||||
#define ISMAXSHORT { 0x7f, 0xff }
|
||||
#define ISMINSHORT { 0x80, 0x00 }
|
||||
|
||||
#define ISMINCHAR ('\0')
|
||||
#define ISMAXCHAR ('\377')
|
||||
|
||||
#define ISMINBIN ('\0')
|
||||
#define ISMAXBIN ('\377')
|
||||
|
||||
/* double and float are declared using IEEE bit paterns */
|
||||
|
||||
#define ISMAXDOUBLE { 0x7f, 0xf0, 0, /* rest is 0 */ }
|
||||
#define ISMINDOUBLE { 0xff, 0xf0, 0, /* rest is 0 */ }
|
||||
|
||||
#define ISMAXFLOAT { 0x7f, 0x80, 0, /* rest is 0 */ }
|
||||
#define ISMINFLOAT { 0xff, 0x80, 0, /* rest is 0 */ }
|
||||
|
||||
|
||||
/* Hide these from user till we return error code */
|
||||
extern char isstat3;
|
||||
extern char isstat4;
|
||||
|
||||
#define OP_BUILD 0
|
||||
#define OP_OPEN 1
|
||||
|
||||
#endif
|
||||
|
||||
651
cde/lib/tt/mini_isam/isamaddindex.c
Normal file
651
cde/lib/tt/mini_isam/isamaddindex.c
Normal file
@@ -0,0 +1,651 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamaddindex.c /main/3 1995/10/23 11:34:12 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamaddindex.c 1.14 89/09/14 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isaddindex.c
|
||||
*
|
||||
* Description:
|
||||
* Add secondary index
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
extern int _iskeycmp();
|
||||
|
||||
static void _readallrecords(), _attach_dups_serial();
|
||||
static Blkno _buildbtree();
|
||||
static int _duplicate_exist();
|
||||
static checkavailfd();
|
||||
|
||||
/*
|
||||
* _amaddindex(isfhandle, keydesc, errcode)
|
||||
*
|
||||
* _amaddindex() build a secondary index
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* keydesc Key descriptor
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_amaddindex(isfhandle, keydesc, errcode)
|
||||
Bytearray *isfhandle;
|
||||
struct keydesc *keydesc;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Keydesc2 keydesc2;
|
||||
int err;
|
||||
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Check if 1 UNIX file decriptor is available.
|
||||
*/
|
||||
checkavailfd();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the limit on the number of keys is not exceeded.
|
||||
*/
|
||||
if (fcb->nkeys >= MAXNKEYS) {
|
||||
_amseterrcode(errcode, ETOOMANY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r(fcb);
|
||||
|
||||
/*
|
||||
* Check key descriptor for validity.
|
||||
*/
|
||||
if (_validate_keydesc(keydesc, fcb->minreclen) != ISOK) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert key descriptor to internal form.
|
||||
*/
|
||||
_iskey_xtoi (&keydesc2, keydesc);
|
||||
|
||||
/* Check if key already exists. */
|
||||
if (_isfcb_findkey(fcb ,&keydesc2) != (Keydesc2 *) 0) {
|
||||
_amseterrcode(errcode, EKEXISTS);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open (or even create) .ind file if that is not open (created) yet.
|
||||
*/
|
||||
if (_open2_indfile(fcb) != ISOK) {
|
||||
_amseterrcode(errcode, EACCES);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create index structure.
|
||||
*/
|
||||
if ((err = _create_index(fcb ,&keydesc2)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add key descriptor to FCB.
|
||||
*/
|
||||
if (_isfcb_altkeyadd(fcb, &keydesc2) == ISERROR) {
|
||||
_amseterrcode(errcode, ETOOMANY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* _amaddprimary(isfhandle, keydesc, errcode)
|
||||
*
|
||||
* _amaddprimary() build primary key
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* keydesc Key descriptor
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_amaddprimary(isfhandle, keydesc, errcode)
|
||||
Bytearray *isfhandle;
|
||||
struct keydesc *keydesc;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Keydesc2 keydesc2;
|
||||
int err;
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Check if 1 UNIX file decriptor is available.
|
||||
*/
|
||||
checkavailfd();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the limit on the numbrer of keys is not exceeded.
|
||||
*/
|
||||
if (fcb->nkeys >= MAXNKEYS) {
|
||||
_amseterrcode(errcode, ETOOMANY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r(fcb);
|
||||
|
||||
/*
|
||||
* Check key descriptor for validity.
|
||||
*/
|
||||
if (_validate_keydesc(keydesc, fcb->minreclen) != ISOK) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert key descriptor to internal form.
|
||||
*/
|
||||
_iskey_xtoi (&keydesc2, keydesc);
|
||||
|
||||
/* Check if key already exists. */
|
||||
if (_isfcb_findkey(fcb ,&keydesc2) != (Keydesc2 *) 0) {
|
||||
_amseterrcode(errcode, EKEXISTS);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that primary key does not already exist.
|
||||
*/
|
||||
if (!FCB_NOPRIMARY_KEY(fcb)) {
|
||||
_amseterrcode(errcode, EKEXISTS);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open (or even create) .ind file if that is not open (created) yet.
|
||||
*/
|
||||
if (_open2_indfile(fcb) != ISOK) {
|
||||
_amseterrcode(errcode, EACCES);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create index structure.
|
||||
*/
|
||||
if ((err = _create_index(fcb ,&keydesc2)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add key descriptor to FCB.
|
||||
*/
|
||||
if (_isfcb_primkeyadd(fcb, &keydesc2) == ISERROR) {
|
||||
_amseterrcode(errcode, ETOOMANY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* _create_index()
|
||||
*
|
||||
* Read data file, extract key from record, sort keys, create index.
|
||||
* Check unique constraint, create duplicate serial numbers.
|
||||
*/
|
||||
|
||||
int _create_index(fcb, pkeydesc2)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
{
|
||||
Issort *srt;
|
||||
int keylength = pkeydesc2->k2_len;
|
||||
|
||||
/*
|
||||
* Set comparison function for sorting.
|
||||
*
|
||||
* nparts + 1 is used to compare keys that allow duplicates.
|
||||
* The (nparts + 1) comparison will never be reached on ISNODUPS key.
|
||||
*/
|
||||
_iskeycmp_set(pkeydesc2, pkeydesc2->k2_nparts+1);
|
||||
|
||||
/*
|
||||
* Handle empty file as a special case, to avoid nasty behavior
|
||||
* in buildbtree() arithmetics.
|
||||
*/
|
||||
if (fcb->nrecords == 0L) {
|
||||
pkeydesc2->k2_rootnode = _buildbtree(fcb, pkeydesc2, (Issort *) NULL);
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a sorter for this key descriptor.
|
||||
*/
|
||||
srt = _issort_create(keylength, (int)fcb->nrecords, _iskeycmp);
|
||||
|
||||
/*
|
||||
* Read sequentially all records, extract keys, and
|
||||
* insert the keys into the sorter.
|
||||
*/
|
||||
_readallrecords(fcb, srt, pkeydesc2);
|
||||
|
||||
_issort_sort(srt); /* Sort the keys */
|
||||
|
||||
/*
|
||||
* Check for potential duplicates if the index is ISNODUPS.
|
||||
*/
|
||||
if (!ALLOWS_DUPS2(pkeydesc2)) {
|
||||
if (_duplicate_exist(srt, keylength)) {
|
||||
_issort_destroy(srt);
|
||||
return (EDUPL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach duplicate serial numbers to the keys that are ISDUPS.
|
||||
*/
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
_attach_dups_serial(srt, pkeydesc2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and build the B-tree
|
||||
*/
|
||||
pkeydesc2->k2_rootnode = _buildbtree(fcb, pkeydesc2, srt);
|
||||
|
||||
_issort_destroy(srt); /* Destroy sorter */
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _readallrecords()
|
||||
*
|
||||
* REad all records, extract keys, and insert them into sorter.
|
||||
*/
|
||||
|
||||
Static void
|
||||
_readallrecords(fcb, srt, pkeydesc2)
|
||||
Fcb *fcb;
|
||||
Issort *srt;
|
||||
Keydesc2 *pkeydesc2;
|
||||
{
|
||||
char record [ISMAXRECLEN];
|
||||
char keybuf [MAXKEYSIZE];
|
||||
Recno recnum;
|
||||
int reclen = 0;
|
||||
int (*rec_read)() = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
|
||||
for (recnum = 1; recnum <= fcb->lastrecno; recnum++) {
|
||||
|
||||
if (rec_read(fcb, record, recnum, &reclen) != ISOK)
|
||||
continue; /* Skip deleted record */
|
||||
|
||||
/*
|
||||
* Zero out the entire key buffer to allow for using
|
||||
* memcmp() as comparison function to compare whole keys.
|
||||
*/
|
||||
memset(keybuf, 0, pkeydesc2->k2_len);
|
||||
|
||||
/*
|
||||
* Extract key parts from record buffer.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf);
|
||||
|
||||
/*
|
||||
* Add recno to key
|
||||
*/
|
||||
strecno(recnum, keybuf + KEY_RECNO_OFF);
|
||||
|
||||
_issort_insert(srt, keybuf); /* Insert key into sorter */
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _attach_dups_serial()
|
||||
*
|
||||
* Attach serial numbers to duplicate keys
|
||||
*/
|
||||
|
||||
Static void
|
||||
_attach_dups_serial(srt, pkeydesc2)
|
||||
Issort *srt;
|
||||
Keydesc2 *pkeydesc2;
|
||||
{
|
||||
int netkeylength = pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE;
|
||||
char *curkey;
|
||||
char *lastkey = NULL;
|
||||
int dup_serial = 1;
|
||||
|
||||
_issort_rewind(srt);
|
||||
|
||||
while (curkey = _issort_read(srt)) {
|
||||
if (lastkey && memcmp(lastkey + RECNOSIZE + DUPIDSIZE,
|
||||
curkey + RECNOSIZE + DUPIDSIZE,
|
||||
netkeylength) == 0)
|
||||
dup_serial++;
|
||||
else
|
||||
dup_serial = 1;
|
||||
|
||||
/*
|
||||
* Store serial number in the key.
|
||||
*/
|
||||
stdupser(dup_serial, curkey + KEY_DUPS_OFF);
|
||||
|
||||
lastkey = curkey;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _buildbtree()
|
||||
*
|
||||
* Create B-tree.
|
||||
*/
|
||||
|
||||
Static Blkno
|
||||
_buildbtree(fcb, pkeydesc2, srt)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
Issort *srt;
|
||||
{
|
||||
Bufhdr *_allockpage();
|
||||
int depth;
|
||||
int nrecords = fcb->nrecords;
|
||||
int keyspernode[ISMAXBTRLEVEL];
|
||||
int one_more[ISMAXBTRLEVEL];
|
||||
char *nodebuf[ISMAXBTRLEVEL];
|
||||
Bufhdr *nodebufhd[ISMAXBTRLEVEL];
|
||||
Blkno pageblkno[ISMAXBTRLEVEL];
|
||||
int curindex[ISMAXBTRLEVEL];
|
||||
char *keyp;
|
||||
int keylength = pkeydesc2->k2_len;
|
||||
int leafcapac = getkeysperleaf(keylength);
|
||||
int nleafcapac = getkeyspernode(keylength);
|
||||
int perleaf;
|
||||
int blocks_in_this_level, blocks_in_prev_level;
|
||||
int slack = ISLEAFSLACK;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Handle an empty B-tree as a special case.
|
||||
*/
|
||||
if (fcb->nrecords == 0) {
|
||||
(void)_allockpage(fcb, leafcapac, 0, pageblkno + 0);
|
||||
return (pageblkno[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* COMPRESS changes the fill factor to 100%
|
||||
*/
|
||||
if ((pkeydesc2->k2_flags & COMPRESS) == COMPRESS)
|
||||
slack = 0;
|
||||
|
||||
/*
|
||||
* Figure out fill factors for each level.
|
||||
*/
|
||||
perleaf = ((double)leafcapac * (100.0 - (double) slack)) / 100.0;
|
||||
|
||||
/*
|
||||
* Make it more robust.
|
||||
*/
|
||||
if (perleaf >= leafcapac)
|
||||
perleaf = leafcapac;
|
||||
|
||||
if (perleaf < leafcapac/2 + 1)
|
||||
perleaf = leafcapac/2 + 1;
|
||||
|
||||
/*
|
||||
* Iterativelly determince values in keyspernode[] and one_mode[]
|
||||
*/
|
||||
blocks_in_this_level = nrecords / perleaf;
|
||||
if (blocks_in_this_level * leafcapac < nrecords)
|
||||
blocks_in_this_level++;
|
||||
|
||||
keyspernode[0] = nrecords / blocks_in_this_level;
|
||||
one_more[0] = nrecords % blocks_in_this_level;
|
||||
|
||||
|
||||
for (depth = 1; blocks_in_this_level > 1; depth++) {
|
||||
blocks_in_prev_level = blocks_in_this_level;
|
||||
|
||||
blocks_in_this_level = (blocks_in_prev_level-1) / nleafcapac + 1;
|
||||
keyspernode[depth] = blocks_in_prev_level / blocks_in_this_level;
|
||||
one_more[depth] = blocks_in_prev_level % blocks_in_this_level;
|
||||
}
|
||||
|
||||
if (depth >= ISMAXBTRLEVEL)
|
||||
_isfatal_error("Too many levels in B-tree");
|
||||
|
||||
/*
|
||||
* Make sure that we start reading keys from the beginning.
|
||||
*/
|
||||
_issort_rewind(srt);
|
||||
|
||||
/*
|
||||
* Boot the Main loop.
|
||||
*/
|
||||
for (i = 0; i < depth ; i++) {
|
||||
curindex[i] = ISPAGESIZE; /* Any big number will do */
|
||||
one_more[i]++;
|
||||
nodebufhd[i] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main loop.
|
||||
*/
|
||||
while ((keyp = _issort_read(srt)) != (char *) NULL) {
|
||||
|
||||
if (curindex[0] >= keyspernode[0] + (one_more[0] > 0)) {
|
||||
|
||||
/*
|
||||
* Commit all changed buffers here to avoid buffer pool overflow.
|
||||
*/
|
||||
if (nodebufhd[0]) {
|
||||
_isdisk_commit1(nodebufhd[0]);
|
||||
_isdisk_sync();
|
||||
}
|
||||
|
||||
/* Allocate new leaf. */
|
||||
nodebufhd[0] = _allockpage(fcb, leafcapac, 0, pageblkno+0);
|
||||
nodebuf[0] = nodebufhd[0]->isb_buffer;
|
||||
one_more[0]--;
|
||||
curindex[0] = 0;
|
||||
}
|
||||
|
||||
/* Copy key into the page. */
|
||||
memcpy( nodebuf[0] + BT_KEYS_OFF + keylength * curindex[0],keyp,
|
||||
keylength);
|
||||
stshort((short) curindex[0] + 1, nodebuf[0] + BT_NKEYS_OFF);
|
||||
|
||||
if (curindex[0]++ == 0) { /* Store first key in */
|
||||
/* higher levels */
|
||||
|
||||
for (i = 1;i < depth; i++) {
|
||||
if (curindex[i] >= keyspernode[i] + (one_more[i] > 0)) {
|
||||
|
||||
/* Unfix buffer. */
|
||||
if (nodebufhd[i])
|
||||
_isdisk_commit1(nodebufhd[i]);
|
||||
|
||||
nodebufhd[i] = _allockpage(fcb, nleafcapac, i, pageblkno+i);
|
||||
nodebuf[i] = nodebufhd[i]->isb_buffer;
|
||||
one_more[i]--;
|
||||
curindex[i] = 0;
|
||||
}
|
||||
|
||||
/* Copy key into page. */
|
||||
memcpy( nodebuf[i] + BT_KEYS_OFF + keylength * curindex[i],keyp,
|
||||
keylength);
|
||||
|
||||
/* Store pointer to level below. */
|
||||
stblkno(pageblkno[i-1], nodebuf[i] + ISPAGESIZE -
|
||||
(curindex[i]+1) * BLKNOSIZE);
|
||||
|
||||
stshort((short) curindex[i] + 1, nodebuf[i] + BT_NKEYS_OFF);
|
||||
if (curindex[i]++ > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (pageblkno [depth - 1]); /* Return blkno of B-tree root */
|
||||
}
|
||||
|
||||
/*
|
||||
* _duplicate_exist()
|
||||
*
|
||||
* Return 1 if there are duplicates in the sorted key object.
|
||||
*/
|
||||
|
||||
Static int _duplicate_exist(srt, keylength)
|
||||
Issort *srt;
|
||||
int keylength;
|
||||
{
|
||||
char *curkey;
|
||||
char *lastkey = (char *) 0;
|
||||
int netkeylength = keylength - RECNOSIZE;
|
||||
|
||||
_issort_rewind(srt);
|
||||
|
||||
while (curkey = _issort_read(srt)) {
|
||||
if (lastkey && memcmp(lastkey + RECNOSIZE, curkey + RECNOSIZE,
|
||||
netkeylength) == 0)
|
||||
return 1; /* Duplicate key found */
|
||||
|
||||
lastkey = curkey;
|
||||
}
|
||||
return 0; /* No duplicates found */
|
||||
}
|
||||
|
||||
|
||||
|
||||
Static
|
||||
checkavailfd()
|
||||
{
|
||||
Fcb *fcb;
|
||||
Bytearray *isfhandle2;
|
||||
|
||||
/*
|
||||
* Check that there are UNIX file descriptors available.
|
||||
*/
|
||||
while (_watchfd_check() < 1) {
|
||||
/*
|
||||
* Find victim (LRU FCB) and close it.
|
||||
*/
|
||||
if((isfhandle2 = _mngfcb_victim()) == NULL)
|
||||
_isfatal_error ("_openfcb() cannot find LRU victim");
|
||||
|
||||
fcb = _mngfcb_find(isfhandle2);
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle2);
|
||||
}
|
||||
}
|
||||
11
cde/lib/tt/mini_isam/isamdelcurr.c
Normal file
11
cde/lib/tt/mini_isam/isamdelcurr.c
Normal file
@@ -0,0 +1,11 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamdelcurr.c /main/3 1995/10/23 11:34:21 rswiston $ */
|
||||
/*
|
||||
* This file is obsolete and should be removed when convenient.
|
||||
* The only function that was here (_amdelcurr) was moved into
|
||||
* isdelcurr.c where the only reference to it existed, and the
|
||||
* function was made static.
|
||||
*/
|
||||
138
cde/lib/tt/mini_isam/isamdelrec.c
Normal file
138
cde/lib/tt/mini_isam/isamdelrec.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamdelrec.c /main/3 1995/10/23 11:34:30 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamdelrec.c 1.6 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isamdelrec.c
|
||||
*
|
||||
* Description: _amdelrec()
|
||||
* Delete record from ISAM file.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
void _delkeys();
|
||||
|
||||
/*
|
||||
* _amdelrec(isfhandle, recnum, errcode)
|
||||
*
|
||||
* _amdelrec() deletes a record from ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* recnum record number of the record to be deleted
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_amdelrec(isfhandle, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
Recno recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
char recbuf[ISMAXRECLEN];
|
||||
int reclen;
|
||||
int (*rec_read)();
|
||||
int (*rec_delete)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
rec_delete = (fcb->varflag?_vlrec_delete:_flrec_delete);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
/*
|
||||
* We must read the record first to be able to delete keys.
|
||||
*/
|
||||
if (rec_read(fcb, recbuf, recnum, &reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (rec_delete(fcb, recnum) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
fcb->nrecords--;
|
||||
|
||||
/*
|
||||
* Delete associated entries from all indexes.
|
||||
*/
|
||||
_delkeys(fcb, recbuf, recnum);
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isdelkeys()
|
||||
*
|
||||
* Delete key entry from all indexes.
|
||||
*/
|
||||
|
||||
void
|
||||
_delkeys(fcb, record, recnum)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
_del1key(fcb, fcb->keys + i, record, recnum);
|
||||
}
|
||||
}
|
||||
|
||||
90
cde/lib/tt/mini_isam/isamerror.c
Normal file
90
cde/lib/tt/mini_isam/isamerror.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamerror.c /main/3 1995/10/23 11:34:39 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamerror.c 1.4 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isamerror.c
|
||||
*
|
||||
* Description:
|
||||
* Error handling functions for the Access Method layer.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
#define ESENTINEL -100 /* Must not be a valid errno */
|
||||
|
||||
static struct errstattab {
|
||||
int iserrno;
|
||||
char isstat1;
|
||||
char isstat2;
|
||||
} errstattab[] = {
|
||||
{ ISOK, '0', '0'},
|
||||
{ ENOREC, '2', '3'},
|
||||
{ ENOCURR, '2', '1'},
|
||||
{ EENDFILE, '1', '0'},
|
||||
{ EDUPL, '2', '2'},
|
||||
{ ENOTOPEN, '9', '0'},
|
||||
{ EBADARG, '9', '0'},
|
||||
{ EBADKEY, '9', '0'},
|
||||
{ ETOOMANY, '9', '0'},
|
||||
{ EBADFILE, '9', '0'},
|
||||
{ ENOTEXCL, '9', '0'},
|
||||
{ ELOCKED, '9', '0'},
|
||||
{ EKEXISTS, '9', '0'},
|
||||
{ EPRIMKEY, '9', '0'},
|
||||
{ EFLOCKED, '9', '0'},
|
||||
{ EFNAME, '9', '0'},
|
||||
{ EFATAL, '9', '0'},
|
||||
|
||||
/* Unix errors */
|
||||
|
||||
{ ENOENT, '9', '0'},
|
||||
{ EACCES, '9', '0'},
|
||||
{ EEXIST, '9', '0'},
|
||||
{ ENOSPC, '9', '0'},
|
||||
|
||||
/* search sentinel */
|
||||
{ ESENTINEL, '9', '0'}
|
||||
};
|
||||
|
||||
/*
|
||||
* _amseterrcode(errcode, is_errno, is_stat1, is_stat2, is_stat3, is_stat4)
|
||||
*
|
||||
* Set errcode block with ISAM error codes.
|
||||
*/
|
||||
|
||||
void
|
||||
_amseterrcode(errcode, is_errno)
|
||||
struct errcode *errcode;
|
||||
int is_errno;
|
||||
{
|
||||
register struct errstattab *p;
|
||||
errcode->iserrno = is_errno;
|
||||
|
||||
/*
|
||||
* Search errstattab to get appropriate isstat[12] values.
|
||||
*/
|
||||
|
||||
for (p = errstattab; p->iserrno != ESENTINEL; p++) {
|
||||
if (p->iserrno == is_errno) {
|
||||
errcode->isstat[0] = p->isstat1;
|
||||
errcode->isstat[1] = p->isstat2;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_errno == 0 && isdupl == 1)
|
||||
errcode->isstat[1] = '2'; /* Indicate allowed duplicates */
|
||||
}
|
||||
|
||||
46
cde/lib/tt/mini_isam/isamhooks.c
Normal file
46
cde/lib/tt/mini_isam/isamhooks.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamhooks.c /main/3 1995/10/23 11:34:48 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamhooks.c 1.7 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isamhooks.c
|
||||
*
|
||||
* Description:
|
||||
* Entry and exit hooks that are called upon every entry (and exit)
|
||||
* to any Access Module Function.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
extern struct dlink *pavail;
|
||||
/*
|
||||
* _isam_entryhook()
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
_isam_entryhook()
|
||||
{
|
||||
isdupl = 0; /* Reset duplicate indicator */
|
||||
_setiserrno2(0, '0', '0');
|
||||
}
|
||||
|
||||
/*
|
||||
* _isam_exithook()
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
_isam_exithook()
|
||||
{
|
||||
_isdisk_inval(); /* Invalidate all buffers */
|
||||
}
|
||||
300
cde/lib/tt/mini_isam/isamopen.c
Normal file
300
cde/lib/tt/mini_isam/isamopen.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: isamopen.c /main/5 1998/04/10 08:03:57 mgreess $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamopen.c 1.10 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isamopen.c
|
||||
*
|
||||
* Description: _amopen()
|
||||
* Open an ISAM file.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "isam_impl.h"
|
||||
|
||||
/*
|
||||
* _amopen(isfname, varflag, minlen, maxlen, primkey,
|
||||
* isfhandle, curpos, errcode)
|
||||
*
|
||||
* _amopen() opens an ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfname ISAM file name
|
||||
*
|
||||
* Output params:
|
||||
* isfhandle a file handle to be used in subsequent operations on the file
|
||||
* varflag TRUE if file is for variable length records
|
||||
* minlen, maxlen minimum and maximum record length
|
||||
* curpos initial current record position
|
||||
* errcode {iserrno, isstat1-4}
|
||||
*
|
||||
* _amopen() returns 0 if successful, or -1 to indicate an error.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
_amopen(isfname, openmode, varflag, minlen, maxlen,
|
||||
isfhandle, curpos, errcode)
|
||||
char *isfname;
|
||||
enum openmode openmode;
|
||||
Bool *varflag;
|
||||
int *minlen, *maxlen;
|
||||
Bytearray *isfhandle;
|
||||
Bytearray *curpos;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
Bytearray isfhandle0;
|
||||
Crp *crp;
|
||||
int err;
|
||||
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Make isfhandle0.
|
||||
*/
|
||||
|
||||
isfhandle0 = _makeisfhandle(isfname);
|
||||
|
||||
/*
|
||||
* Invalidate the FCB cache entry to avoid a problem found when using
|
||||
* multiple servers.
|
||||
*/
|
||||
if ((fcb = _mngfcb_find(&isfhandle0)) != NULL) {
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(&isfhandle0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the FCB that corresponds to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&isfhandle0, errcode)) == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the FCB allows writes if INOUT or OUTPUT is needed.
|
||||
*/
|
||||
if (fcb->rdonly==TRUE && (openmode==OM_INOUT || openmode==OM_OUTPUT)) {
|
||||
_amseterrcode(errcode, EACCES);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill output parameters.
|
||||
*/
|
||||
*minlen = fcb->minreclen;
|
||||
*maxlen = fcb->maxreclen;
|
||||
*varflag = fcb->varflag;
|
||||
*isfhandle = isfhandle0;
|
||||
|
||||
/*
|
||||
* Initial current record position.
|
||||
*/
|
||||
if (FCB_NOPRIMARY_KEY(fcb)) {
|
||||
/* Use physical order. */
|
||||
crp = (Crp *) _ismalloc(sizeof(*crp));
|
||||
memset ((char *) crp, 0, sizeof(*crp));
|
||||
|
||||
crp->keyid = PHYS_ORDER;
|
||||
crp->flag = CRP_BEFOREANY;
|
||||
|
||||
curpos->length = sizeof(*crp);
|
||||
curpos->data = (char *) crp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Use primary key order.
|
||||
*/
|
||||
|
||||
crp = (Crp *) _ismalloc((unsigned)(sizeof(*crp) + fcb->keys[0].k2_len));
|
||||
memset((char *) crp, 0, (sizeof(*crp) + fcb->keys[0].k2_len));
|
||||
|
||||
crp->keyid = fcb->keys[0].k2_keyid;
|
||||
crp->flag = CRP_BEFOREANY;
|
||||
|
||||
_iskey_fillmin(&fcb->keys[0], crp->key);
|
||||
|
||||
curpos->length = sizeof(*crp) + fcb->keys[0].k2_len;
|
||||
curpos->data = (char *) crp;
|
||||
|
||||
/*
|
||||
* Set full key length as the number of bytes to match in key comparison
|
||||
*/
|
||||
crp->matchkeylen = fcb->keys[0].k2_len - RECNOSIZE;
|
||||
|
||||
if (ALLOWS_DUPS2(&fcb->keys[0]))
|
||||
crp->matchkeylen -= DUPIDSIZE;
|
||||
}
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_bytearr_free(&isfhandle0);
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fcb = _openfcb(isfhandle, errcode)
|
||||
*
|
||||
* Try to locate FCB in the FCB cache. If not found, open the FCB and
|
||||
* insert it into the cache.
|
||||
*
|
||||
* Return a pointer to the FCB, or NULL in the case of any error.
|
||||
*/
|
||||
|
||||
#define FDNEEDED 3 /* Needs 3 UNIX fd to open a file*/
|
||||
Fcb *
|
||||
_openfcb(isfhandle, errcode)
|
||||
Bytearray *isfhandle;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
Bytearray *isfhandle2;
|
||||
char errbuf[BUFSIZ];
|
||||
char *errmsg0;
|
||||
|
||||
if ((fcb = _mngfcb_find(isfhandle)) != NULL)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Check that there are UNIX file descriptors available.
|
||||
*/
|
||||
while (_watchfd_check() < FDNEEDED) {
|
||||
/*
|
||||
* Find victim (LRU FCB) and close it.
|
||||
*/
|
||||
if((isfhandle2 = _mngfcb_victim()) == NULL)
|
||||
_isfatal_error ("_openfcb() cannot find LRU victim");
|
||||
|
||||
fcb = _mngfcb_find(isfhandle2);
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open files, create FCB block.
|
||||
*/
|
||||
if ((fcb = _isfcb_open(_getisfname(isfhandle), errcode)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that ISAM file is not corrupted (only check magic number).
|
||||
*/
|
||||
if (_check_isam_magic(fcb) != ISOK) {
|
||||
_amseterrcode(errcode, EBADFILE);
|
||||
_isfcb_close(fcb);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read information from CNTL PAGE and store it in the FCB.
|
||||
*/
|
||||
if (_isfcb_cntlpg_r(fcb) == ISERROR)
|
||||
_isfatal_error("_openfcb() cannot read CNTL PAGE");
|
||||
|
||||
/*
|
||||
* Register UNIX file descriptors consumed.
|
||||
*/
|
||||
(void) _watchfd_incr(_isfcb_nfds(fcb));
|
||||
|
||||
/*
|
||||
* Insert new entry into the FCB cache.
|
||||
*/
|
||||
_mngfcb_insert(fcb, isfhandle);
|
||||
|
||||
out:
|
||||
|
||||
/*
|
||||
* Check that all file descriptors are open. This is needed to handle
|
||||
* user errors such as removing .ind or .var files.
|
||||
*/
|
||||
if (fcb->varflag==TRUE && fcb->varfd == -1) {
|
||||
char *fmt = "%s.var has been removed";
|
||||
if (strlen(fmt) + strlen(fcb->isfname) + 1 >= BUFSIZ)
|
||||
errmsg0 = (char*) malloc(strlen(fmt) + strlen(fcb->isfname) + 1);
|
||||
else
|
||||
errmsg0 = errbuf;
|
||||
|
||||
(void)sprintf(errmsg0, fmt, fcb->isfname);
|
||||
_isam_warning(errmsg0);
|
||||
_amseterrcode(errcode, EBADFILE);
|
||||
if (errmsg0 != errbuf) free(errmsg0);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((fcb->nkeys > 1 || !FCB_NOPRIMARY_KEY(fcb)) && fcb->indfd == -1) {
|
||||
char *fmt = "%s.ind has been removed";
|
||||
if (strlen(fmt) + strlen(fcb->isfname) + 1 >= BUFSIZ)
|
||||
errmsg0 = (char*) malloc(strlen(fmt) + strlen(fcb->isfname) + 1);
|
||||
else
|
||||
errmsg0 = errbuf;
|
||||
|
||||
(void)sprintf(errmsg0, fmt, fcb->isfname);
|
||||
_isam_warning(errmsg0);
|
||||
_amseterrcode(errcode, EBADFILE);
|
||||
if (errmsg0 != errbuf) free(errmsg0);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (fcb);
|
||||
|
||||
err:
|
||||
/*
|
||||
* Delete FCB and remove it from FCB cache. Close UNIX fds.
|
||||
*
|
||||
* This is needed to recover netisamd server if users remove .ind or
|
||||
* or .var files.
|
||||
*/
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle);
|
||||
|
||||
return (NULL);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* isfname = _getisfname(isfhandle)
|
||||
*
|
||||
* Get ISAM file name from ISAM file handle.
|
||||
*/
|
||||
|
||||
char *
|
||||
_getisfname(isfhandle)
|
||||
Bytearray *isfhandle;
|
||||
{
|
||||
return (isfhandle->data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* isfhandle = _makeisfhandle(isfname)
|
||||
*
|
||||
* Make ISAM file handle.
|
||||
*/
|
||||
|
||||
Bytearray
|
||||
_makeisfhandle(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
return (_bytearr_new((u_short)(strlen(isfname) + 1), isfname));
|
||||
}
|
||||
|
||||
191
cde/lib/tt/mini_isam/isamwrite.c
Normal file
191
cde/lib/tt/mini_isam/isamwrite.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isamwrite.c /main/3 1995/10/23 11:35:14 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isamwrite.c 1.6 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isamwrite.c
|
||||
*
|
||||
* Description: _amwrite()
|
||||
* Write record to ISAM file.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static int _addkeys2 ();
|
||||
extern long *ismaxlong;
|
||||
|
||||
/*
|
||||
* _amwrite(isfhandle, record, reclen, curpos,
|
||||
* recnum, errcode)
|
||||
*
|
||||
* _amwrite() writes a new record to ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* record record
|
||||
* reclen length of the record
|
||||
* curpos current record position
|
||||
*
|
||||
* Output params:
|
||||
* curpos new current position
|
||||
* recnum record number
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_amwrite(isfhandle, record, reclen, curpos, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
char *record;
|
||||
int reclen;
|
||||
Bytearray *curpos;
|
||||
Recno *recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Recno recnum2;
|
||||
Crp *crp;
|
||||
int err;
|
||||
int (*rec_write)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_write = (fcb->varflag?_vlrec_write:_flrec_write);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
if (rec_write(fcb, record, &recnum2, reclen) == ISERROR) {
|
||||
_isfatal_error("_amwrite() cannot write record");
|
||||
}
|
||||
|
||||
/*
|
||||
* Update all keys.
|
||||
*/
|
||||
if ((err = _addkeys2(fcb, record, recnum2, curpos)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
fcb->nrecords++;
|
||||
|
||||
*recnum = recnum2;
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Return new current record position.
|
||||
*/
|
||||
crp = (Crp *) curpos->data;
|
||||
|
||||
crp->flag = CRP_ON;
|
||||
crp->recno = recnum2;
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* If error is not EDUPL position undefined.
|
||||
*/
|
||||
if (errcode->iserrno != EDUPL) {
|
||||
((Crp *)curpos->data)->flag = CRP_UNDEF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _addkeys()
|
||||
*
|
||||
* Insert key entry to all indexes.
|
||||
*
|
||||
* Returns ISOK, or EDUPS.
|
||||
*/
|
||||
|
||||
int _addkeys (fcb, record, recnum)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if ((err = _add1key(fcb, fcb->keys + i, record, recnum,
|
||||
(char*)NULL)) != ISOK)
|
||||
return (err);
|
||||
}
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
Static int
|
||||
_addkeys2 (fcb, record, recnum, curpos)
|
||||
Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
Bytearray *curpos;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i;
|
||||
int err;
|
||||
Crp *crp;
|
||||
int keyid;
|
||||
Keydesc2 *keydesc2;
|
||||
|
||||
crp = (Crp *)curpos->data;
|
||||
keyid = crp->keyid;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
keydesc2 = fcb->keys + i;
|
||||
if ((err =_add1key(fcb, keydesc2, record, recnum,
|
||||
(keydesc2->k2_keyid == keyid) ?
|
||||
crp->key : (char *) NULL)) != ISOK)
|
||||
return (err);
|
||||
}
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
80
cde/lib/tt/mini_isam/isapplmr.c
Normal file
80
cde/lib/tt/mini_isam/isapplmr.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isapplmr.c /main/3 1995/10/23 11:35:25 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isapplmr.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isapplmr.c
|
||||
*
|
||||
* Description:
|
||||
* Read Application magic string
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include "isam_impl.h"
|
||||
|
||||
/*
|
||||
* string = isapplmr(isfd)
|
||||
*
|
||||
* Isapplmr() returns the aplication magic string written to the ISAM file
|
||||
* by isapplmw() function. No magic string is returned as "". The value
|
||||
* of -1 returned indicates an error (iserrno is set).
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isapplmr(isfd, buffer)
|
||||
int isfd;
|
||||
char *buffer;
|
||||
{
|
||||
register Fab *fab;
|
||||
Fcb *fcb = NULL;
|
||||
char cntl_page[CP_NKEYS_OFF];
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&fab->isfhandle, &fab->errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_isseekpg(fcb->datfd, ISCNTLPGOFF);
|
||||
(void)read(fcb->datfd, cntl_page, sizeof(cntl_page));
|
||||
strncpy(buffer, cntl_page + CP_APPLMAGIC_OFF, CP_APPLMAGIC_LEN);
|
||||
|
||||
_amseterrcode(&fab->errcode, ISOK);
|
||||
_isam_exithook();
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ISOK); /* Successful write */
|
||||
}
|
||||
93
cde/lib/tt/mini_isam/isapplmw.c
Normal file
93
cde/lib/tt/mini_isam/isapplmw.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isapplmw.c /main/3 1995/10/23 11:35:35 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isapplmw.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isapplmw.c
|
||||
*
|
||||
* Description:
|
||||
* Write Application magic string
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* string = isapplmw(isfd)
|
||||
*
|
||||
* Isapplmw() writes an application specific 'magic string' into ISAM
|
||||
* file. The 'file' program (using /etc/magic) may be used to report
|
||||
* this magic string.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isapplmw(isfd, magicstring)
|
||||
int isfd;
|
||||
char *magicstring;
|
||||
{
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
Fcb *fcb;
|
||||
char cntl_page[CP_NKEYS_OFF];
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISOUTPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_OUTPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the length of the magic string
|
||||
*/
|
||||
if ((int)strlen(magicstring) > CP_APPLMAGIC_LEN) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&fab->isfhandle, &fab->errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/* Write the new data */
|
||||
|
||||
_isseekpg(fcb->datfd, ISCNTLPGOFF);
|
||||
(void)read(fcb->datfd, cntl_page, sizeof(cntl_page));
|
||||
strncpy(cntl_page + CP_APPLMAGIC_OFF, magicstring, CP_APPLMAGIC_LEN);
|
||||
_isseekpg(fcb->datfd, ISCNTLPGOFF);
|
||||
(void)write(fcb->datfd, cntl_page, sizeof(cntl_page));
|
||||
|
||||
_amseterrcode(&fab->errcode, ISOK);
|
||||
_isam_exithook();
|
||||
ret = ISOK;
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
62
cde/lib/tt/mini_isam/isbsearch.c
Normal file
62
cde/lib/tt/mini_isam/isbsearch.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbsearch.c /main/3 1995/10/23 11:35:44 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbsearch.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbsearch.c
|
||||
*
|
||||
* Description:
|
||||
* Binary search function.
|
||||
* If differs from bsearch(3) in that if an exact match is not found,
|
||||
* the next lower key is returned. If key is lower than any key in table,
|
||||
* NULL value is returned.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
char *_isbsearch (key,table,nelems,keylen,cmpf)
|
||||
char *key;
|
||||
char *table;
|
||||
int nelems;
|
||||
int keylen;
|
||||
int (*cmpf) ();
|
||||
{
|
||||
register int len,l1,result; /* current length of array to search */
|
||||
register char *p,*low;
|
||||
|
||||
if (nelems <= 0) return (char *) 0;
|
||||
|
||||
/* Check if key is lower than any key in the table. */
|
||||
result = (*cmpf) (key,table);
|
||||
if (result < 0 ) return (char *) 0; /* Key is lower */
|
||||
else if (result == 0) return table; /* Exact match */
|
||||
|
||||
for (low = table,len = nelems; len > 0;) {
|
||||
l1 = len >> 1;
|
||||
p = low + keylen * l1;
|
||||
if ((result = (*cmpf) (key,p)) == 0) /* Exact match found */
|
||||
return p;
|
||||
|
||||
if (result > 0 ) { /* Key is in higher half */
|
||||
len -= l1 + 1;
|
||||
low = p + keylen;
|
||||
}
|
||||
else { /* Key is in lower half */
|
||||
len = l1 ;
|
||||
}
|
||||
}
|
||||
|
||||
/* No matching key found, return next lower key */
|
||||
return (result>0)?p:(p-keylen);
|
||||
}
|
||||
|
||||
|
||||
194
cde/lib/tt/mini_isam/isbtree.c
Normal file
194
cde/lib/tt/mini_isam/isbtree.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbtree.c /main/3 1995/10/23 11:35:52 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbtree.c 1.4 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbtree.c
|
||||
*
|
||||
* Description:
|
||||
* B-tree operations: SEARCH
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern int _iskeycmp();
|
||||
|
||||
/*
|
||||
* _isbtree_create()
|
||||
*
|
||||
* Create a B-tree path object that will used in subsequent operations.
|
||||
*/
|
||||
|
||||
Btree *
|
||||
_isbtree_create(fcb, pkeydesc2)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
{
|
||||
register Btree *p;
|
||||
|
||||
p = (Btree *) _ismalloc(sizeof(*p));
|
||||
memset((char *)p, 0, sizeof(*p));
|
||||
|
||||
p->fcb = fcb;
|
||||
p->keydesc2 = pkeydesc2;
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isbtr_destroy()
|
||||
*
|
||||
* Destroy B-tree path object
|
||||
*/
|
||||
|
||||
void
|
||||
_isbtree_destroy(btree)
|
||||
register Btree *btree;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < btree->depth;i++) {
|
||||
_isdisk_unfix(btree->bufhdr[i]);
|
||||
}
|
||||
free((char *)btree);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isbtree_search()
|
||||
*
|
||||
* Descend the B-tree, position pointer on or before the matched key.
|
||||
*/
|
||||
|
||||
void
|
||||
_isbtree_search(btree, key)
|
||||
register Btree *btree;
|
||||
char *key; /* Search for this key */
|
||||
{
|
||||
Keydesc2 *pkeydesc2 = btree->keydesc2;
|
||||
Blkno rootblkno = pkeydesc2->k2_rootnode;
|
||||
int keylength = pkeydesc2->k2_len;
|
||||
int index; /* Index to tables in btree */
|
||||
/* Has value of 1, next 2, etc. */
|
||||
int elevation; /* Level - leaves have value 0 */
|
||||
register char *p; /* Pointer to key page */
|
||||
int nkeys; /* Number of keys in the page */
|
||||
char *key2; /* Equal or next lower key */
|
||||
int curpos; /* index of key2 in key page */
|
||||
Blkno blkno;
|
||||
|
||||
/* Set comparison function. */
|
||||
_iskeycmp_set(pkeydesc2, pkeydesc2->k2_nparts + 1); /* +1 for recno field */
|
||||
|
||||
index = 0;
|
||||
blkno = rootblkno;
|
||||
do {
|
||||
btree->bufhdr[index] =
|
||||
_isdisk_fix(btree->fcb, btree->fcb->indfd, blkno, ISFIXREAD);
|
||||
p = btree->bufhdr[index]->isb_buffer; /* pointer to buffer */
|
||||
|
||||
/* Load some fields from the key page. */
|
||||
nkeys = ldshort(p+BT_NKEYS_OFF); /* Number of keys in the page */
|
||||
elevation = ldshort(p+BT_LEVEL_OFF); /* Level of the page */
|
||||
|
||||
/* Binary search in the key page to find equal or next lowere key. */
|
||||
key2 = _isbsearch(key, p+BT_KEYS_OFF, nkeys, keylength, _iskeycmp);
|
||||
|
||||
curpos = (key2) ? ((key2 - p - BT_NKEYS_OFF) / keylength) : 0;
|
||||
|
||||
btree->curpos[index] =
|
||||
(key2 == (char *)0 && elevation==0)? -1 : curpos;
|
||||
|
||||
if (elevation > 0)
|
||||
blkno = ldblkno(p + ISPAGESIZE - (curpos + 1) * BLKNOSIZE);
|
||||
|
||||
index++;
|
||||
} while (elevation > 0);
|
||||
|
||||
btree->depth = index;
|
||||
}
|
||||
|
||||
/*
|
||||
* _isbtree_current()
|
||||
*
|
||||
* Get pointer to the current key
|
||||
*/
|
||||
|
||||
char *
|
||||
_isbtree_current(btree)
|
||||
register Btree *btree;
|
||||
{
|
||||
int curpos;
|
||||
|
||||
assert(btree->depth > 0);
|
||||
if ((curpos = btree->curpos[btree->depth - 1]) == -1)
|
||||
return (NULL);
|
||||
else
|
||||
return (btree->bufhdr[btree->depth - 1]->isb_buffer
|
||||
+ BT_KEYS_OFF + curpos * btree->keydesc2->k2_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isbtree_next()
|
||||
*
|
||||
* Get pointer to the next key
|
||||
*/
|
||||
|
||||
char *
|
||||
_isbtree_next(btree)
|
||||
register Btree *btree;
|
||||
{
|
||||
int curpos;
|
||||
int depth = btree->depth;
|
||||
register char *p;
|
||||
register int level;
|
||||
Blkno blkno;
|
||||
|
||||
assert(depth > 0);
|
||||
|
||||
/*
|
||||
* Move up along the path, find first block where we can move to the right.
|
||||
*/
|
||||
for (level = depth - 1; level >= 0; level--) {
|
||||
p = btree->bufhdr[level]->isb_buffer;
|
||||
|
||||
if (btree->curpos[level] < ldshort(p + BT_NKEYS_OFF) - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (level < 0) {
|
||||
/* Logical end of the index file. No next record. */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
curpos = ++(btree->curpos[level]);
|
||||
|
||||
while (++level < depth) {
|
||||
|
||||
/* Get block number to block in next lower level. */
|
||||
if (level > 0)
|
||||
blkno = ldblkno(p + ISPAGESIZE - (curpos + 1) * BLKNOSIZE);
|
||||
|
||||
/* Unfix page in this level, fetch its right brother. */
|
||||
_isdisk_unfix(btree->bufhdr[level]);
|
||||
btree->bufhdr[level] =
|
||||
_isdisk_fix(btree->fcb, btree->fcb->indfd, blkno, ISFIXREAD);
|
||||
p = btree->bufhdr[level]->isb_buffer;
|
||||
|
||||
curpos = btree->curpos[level] = 0;
|
||||
}
|
||||
|
||||
return (p + BT_KEYS_OFF + curpos * btree->keydesc2->k2_len);
|
||||
}
|
||||
|
||||
275
cde/lib/tt/mini_isam/isbtree2.c
Normal file
275
cde/lib/tt/mini_isam/isbtree2.c
Normal file
@@ -0,0 +1,275 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbtree2.c /main/3 1995/10/23 11:36:02 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbtree2.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbtree2.c
|
||||
*
|
||||
* Description:
|
||||
* B-tree operations: INSERT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern int _iskeycmp();
|
||||
Static insert_key();
|
||||
|
||||
|
||||
/* _isbtree_insert() - Insert entry into B-tree ----------------------------*/
|
||||
|
||||
void
|
||||
_isbtree_insert(btree, key)
|
||||
register Btree *btree;
|
||||
char *key;
|
||||
{
|
||||
Keydesc2 *pkeydesc2 = btree->keydesc2;
|
||||
int keylength = pkeydesc2->k2_len;
|
||||
int nkeys; /* Number of keys in the page */
|
||||
int capac;
|
||||
char keybuf[MAXKEYSIZE];
|
||||
register int i;
|
||||
Blkno blkno;
|
||||
char *pkp, *pkp2, *pkp3;
|
||||
Bufhdr *kp2bhdr, *kp3bhdr;
|
||||
Blkno blkno2, blkno3;
|
||||
int level;
|
||||
int halfcapac;
|
||||
|
||||
|
||||
/*
|
||||
* Set key comparison function.
|
||||
*/
|
||||
_iskeycmp_set(pkeydesc2, pkeydesc2->k2_nparts+1); /* +1 for recno field */
|
||||
|
||||
/*
|
||||
* Initialize data structure before main loop.
|
||||
*/
|
||||
blkno = NULL_BLKNO;
|
||||
memcpy( keybuf,key, keylength);
|
||||
|
||||
/*
|
||||
* Main loop:
|
||||
* Starting from the leaf, insert key after current search position.
|
||||
* If necessary make block split and propage changes to upper levels.
|
||||
* Root split is handled differently because we don't want to change
|
||||
* root block number.
|
||||
*/
|
||||
|
||||
for (i = btree->depth - 1; i >= 0; i--) {
|
||||
|
||||
/* We have to fix the block for update. */
|
||||
btree->bufhdr[i] = _isdisk_refix(btree->bufhdr[i], ISFIXWRITE);
|
||||
pkp = btree->bufhdr[i]->isb_buffer;
|
||||
|
||||
level = ldshort(pkp + BT_LEVEL_OFF);
|
||||
capac = ldshort(pkp + BT_CAPAC_OFF); /* Block capacity */
|
||||
nkeys = ldshort(pkp + BT_NKEYS_OFF); /* Number of keys in block */
|
||||
|
||||
assert(level + i + 1 == btree->depth);
|
||||
assert(nkeys <= capac);
|
||||
|
||||
if (nkeys == capac) {
|
||||
/*
|
||||
* This block must be split.
|
||||
* Allocate new block, move half of the entries into the new
|
||||
* block, and insert the key into the appropriate
|
||||
* block. If this block is not root, the loop will iterate
|
||||
* to update upper levels.
|
||||
*/
|
||||
|
||||
/* Get new page. */
|
||||
kp2bhdr = _allockpage(btree->fcb, capac, level, &blkno2);
|
||||
pkp2 = kp2bhdr->isb_buffer;
|
||||
|
||||
halfcapac = (nkeys+1) >> 1; /* Same as nkeys/2 + 1 */
|
||||
|
||||
splitblock(btree, pkp, pkp2, btree->curpos[i]);
|
||||
|
||||
if (btree->curpos[i] > halfcapac - 2) {
|
||||
|
||||
/* Insert entry into right block. */
|
||||
insert_key(btree, pkp2, btree->curpos[i] - halfcapac, keybuf,
|
||||
blkno);
|
||||
}
|
||||
else {
|
||||
/* Insert entry into left block. */
|
||||
insert_key(btree, pkp, btree->curpos[i], keybuf, blkno);
|
||||
|
||||
if (btree->curpos[i] == -1) /* Leftmost entry inserted - */
|
||||
leftkey_up(btree, i); /* propagate to upper levels. */
|
||||
}
|
||||
|
||||
/* Set variables for next loop iteration. */
|
||||
memcpy( keybuf,pkp2 + BT_KEYS_OFF, keylength); /* Leftmost key */
|
||||
blkno = blkno2;
|
||||
|
||||
/*
|
||||
* Next loop iteration will insert entry pointing to
|
||||
* new allocated page into next upper level.
|
||||
*/
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Block split is not necessary. Simply insert key into
|
||||
* the block. If the inserted key becomes the leftmost entry
|
||||
* in the block, update upper levels.
|
||||
*/
|
||||
|
||||
insert_key(btree, pkp, btree->curpos[i], keybuf, blkno);
|
||||
|
||||
if (btree->curpos[i] == -1 && i > 0)
|
||||
leftkey_up(btree, i);
|
||||
|
||||
break; /* from main loop */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (i < 0) {
|
||||
|
||||
/*
|
||||
* Root was split.
|
||||
* Allocate new page. However, to keep root block the same,
|
||||
* the new page is used for the left son of root.
|
||||
*
|
||||
* pkp is the new root, pkp3 is the left son,
|
||||
* and pkp3 is the right of the root.
|
||||
*/
|
||||
|
||||
kp3bhdr = _allockpage(btree->fcb, capac, 1, &blkno3);
|
||||
pkp3 = kp3bhdr->isb_buffer;
|
||||
|
||||
memcpy( pkp3,pkp, ISPAGESIZE);
|
||||
|
||||
stshort((short) getkeyspernode(keylength), pkp + BT_CAPAC_OFF);
|
||||
stshort((short) 0, pkp + BT_NKEYS_OFF);
|
||||
stshort((short)btree->depth, pkp + BT_LEVEL_OFF);
|
||||
|
||||
insert_key(btree, pkp, -1, pkp3 + BT_KEYS_OFF, blkno3);
|
||||
insert_key(btree, pkp, 0 , keybuf, blkno);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------- insert supporting local functions -------------------------------*/
|
||||
|
||||
/* leftkey_up() - Update upper levels with new leftmost entry -----------*/
|
||||
leftkey_up(btree, level)
|
||||
register Btree *btree;
|
||||
int level;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
char *pkp;
|
||||
char *key;
|
||||
|
||||
pkp = btree->bufhdr[level]->isb_buffer;
|
||||
key = pkp + BT_KEYS_OFF; /* Leftmost key */
|
||||
|
||||
while (--level >= 0) {
|
||||
|
||||
btree->bufhdr[level] = _isdisk_refix(btree->bufhdr[level], ISFIXWRITE);
|
||||
pkp = btree->bufhdr[level]->isb_buffer;
|
||||
|
||||
memcpy( pkp + BT_KEYS_OFF + (btree->curpos[level] * keylength),key,
|
||||
keylength);
|
||||
|
||||
if (btree->curpos[level] > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert_key - Insert key into block ------------------------*/
|
||||
Static insert_key(btree, pkp, pos, key, blkno)
|
||||
register Btree *btree;
|
||||
char *pkp;
|
||||
int pos;
|
||||
char *key;
|
||||
Blkno blkno;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
int nkeys = ldshort(pkp + BT_NKEYS_OFF);
|
||||
int capac = ldshort(pkp + BT_CAPAC_OFF);
|
||||
int level = ldshort(pkp + BT_LEVEL_OFF);
|
||||
|
||||
assert(nkeys < capac);
|
||||
|
||||
/* Shift nkeys - pos - 1 entries to the right. */
|
||||
/* memmove() handle overlaps correctly */
|
||||
|
||||
memmove(pkp + BT_KEYS_OFF + (pos + 2) * keylength,
|
||||
pkp + BT_KEYS_OFF + (pos + 1) * keylength,
|
||||
(nkeys - pos - 1) * keylength);
|
||||
|
||||
/* Copy new key entry into the block. */
|
||||
memcpy( pkp + BT_KEYS_OFF + (pos + 1) * keylength,key, keylength);
|
||||
|
||||
/* For non-leaf nodes, insert block number into table of down pointers. */
|
||||
if (level > 0) {
|
||||
|
||||
memcpy(pkp + ISPAGESIZE - (nkeys + 1) * BLKNOSIZE,
|
||||
pkp + ISPAGESIZE - nkeys * BLKNOSIZE,
|
||||
(nkeys - pos - 1) * BLKNOSIZE);
|
||||
|
||||
stblkno(blkno, pkp + ISPAGESIZE - (pos + 2) * BLKNOSIZE);
|
||||
}
|
||||
|
||||
stshort((short) (nkeys + 1), pkp + BT_NKEYS_OFF);
|
||||
}
|
||||
|
||||
/* splitblock() - Split block into two -----------------------------*/
|
||||
splitblock(btree, fullpage, newpage, pos)
|
||||
register Btree *btree;
|
||||
register char *fullpage, *newpage;
|
||||
int pos;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
int nkeys, capac, level;
|
||||
int halfcapac;
|
||||
int newpage_nkeys;
|
||||
int fullpage_nkeys;
|
||||
|
||||
nkeys = ldshort(fullpage + BT_NKEYS_OFF);
|
||||
capac = ldshort(fullpage + BT_NKEYS_OFF);
|
||||
level = ldshort(fullpage + BT_LEVEL_OFF);
|
||||
|
||||
assert(nkeys == capac);
|
||||
|
||||
halfcapac = (capac + 1) >> 1; /* same as capac/2 + 1 */
|
||||
|
||||
if (pos > halfcapac - 2) {
|
||||
|
||||
/* New entry will go into right page(fullpage). */
|
||||
fullpage_nkeys = halfcapac;
|
||||
newpage_nkeys = halfcapac - 1;
|
||||
}
|
||||
else {
|
||||
|
||||
/* New entry will go into left page (newpage). */
|
||||
fullpage_nkeys = halfcapac - 1;
|
||||
newpage_nkeys = halfcapac;
|
||||
}
|
||||
|
||||
/* Move newpage_nkeys keys into newpage. */
|
||||
memcpy(newpage + BT_KEYS_OFF,
|
||||
fullpage + BT_KEYS_OFF + fullpage_nkeys * keylength,
|
||||
keylength * newpage_nkeys);
|
||||
|
||||
/* If non-leaf, move corresponding entries from block number table. */
|
||||
if (level > 0) {
|
||||
memcpy(newpage + ISPAGESIZE - newpage_nkeys * BLKNOSIZE,
|
||||
fullpage + ISPAGESIZE - nkeys * BLKNOSIZE,
|
||||
newpage_nkeys * BLKNOSIZE);
|
||||
}
|
||||
|
||||
stshort((short) fullpage_nkeys, fullpage + BT_NKEYS_OFF);
|
||||
stshort((short) newpage_nkeys, newpage + BT_NKEYS_OFF);
|
||||
}
|
||||
326
cde/lib/tt/mini_isam/isbtree3.c
Normal file
326
cde/lib/tt/mini_isam/isbtree3.c
Normal file
@@ -0,0 +1,326 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbtree3.c /main/3 1995/10/23 11:36:12 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbtree3.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbtree3.c
|
||||
*
|
||||
* Description:
|
||||
* B-tree operations: REMOVE
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern int _iskeycmp();
|
||||
static remove_entry();
|
||||
|
||||
/* _isbtree_remove() - Remove entry from B-tree ----------------------------*/
|
||||
|
||||
void
|
||||
_isbtree_remove(btree)
|
||||
register Btree *btree;
|
||||
{
|
||||
struct keydesc2 *pkeydesc2 = btree->keydesc2;
|
||||
int nkeys; /* Number of keys in the page */
|
||||
register int i;
|
||||
char *pkp, *pkp2, *pkp3;
|
||||
struct bufhdr *kp2bhdr;
|
||||
Blkno blkno2;
|
||||
int level;
|
||||
int capac, halfcapac;
|
||||
int move_keys;
|
||||
|
||||
/* Set comparison function. */
|
||||
_iskeycmp_set(pkeydesc2, pkeydesc2->k2_nparts+1); /* +1 for recno field */
|
||||
|
||||
/*
|
||||
* Main loop.
|
||||
* Remove he current entry from leaf.
|
||||
* If it was leftmost entry, propagate new leftmost to upper levels.
|
||||
* If block has less than capac/2 + 1 entries, either move some entries
|
||||
* from next left or right block, or merge with next left or right
|
||||
* block.
|
||||
*/
|
||||
|
||||
for (i = btree->depth - 1; i >= 0; i--) {
|
||||
|
||||
/* Re-fix the current page for update. */
|
||||
btree->bufhdr[i] = _isdisk_refix(btree->bufhdr[i], ISFIXWRITE);
|
||||
pkp = btree->bufhdr[i]->isb_buffer;
|
||||
|
||||
level = ldshort(pkp + BT_LEVEL_OFF);
|
||||
capac = ldshort(pkp + BT_CAPAC_OFF); /* Block capacity */
|
||||
nkeys = ldshort(pkp + BT_NKEYS_OFF); /* Number of keys in block */
|
||||
|
||||
halfcapac = (capac+1) >> 1; /* same as capac/2 + 1 */
|
||||
|
||||
assert(level + i + 1 == btree->depth);
|
||||
assert(i == 0 || nkeys >= halfcapac);
|
||||
|
||||
/* Remove entry from this page. */
|
||||
remove_entry(btree, pkp, btree->curpos[i]);
|
||||
nkeys--;
|
||||
|
||||
/* Must propagate new leftmost key up. */
|
||||
if (btree->curpos[i] == 0 && i > 0)
|
||||
leftkey_up(btree, i);
|
||||
|
||||
if (nkeys >= halfcapac || i == 0) {
|
||||
|
||||
/*
|
||||
* Page is still balanced. No changes are necessary.
|
||||
* Also, no chages are needed if this is root block.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
|
||||
if(btree->curpos[i-1] > 0) {
|
||||
|
||||
/*
|
||||
* Block pkp is not the leftmost descendent of its parent.
|
||||
* Either merge with left brother, or move a few entries
|
||||
* from it.
|
||||
*/
|
||||
|
||||
pkp3 = btree->bufhdr[i-1]->isb_buffer;
|
||||
|
||||
blkno2 = ldblkno(pkp3 + ISPAGESIZE -
|
||||
(btree->curpos[i-1]) * BLKNOSIZE);
|
||||
|
||||
/* Fix the left brother. */
|
||||
kp2bhdr = _isdisk_fix(btree->fcb, btree->fcb->indfd,
|
||||
blkno2, ISFIXWRITE);
|
||||
pkp2 = kp2bhdr->isb_buffer;
|
||||
|
||||
if (ldshort(pkp2 + BT_NKEYS_OFF) + nkeys > capac) {
|
||||
|
||||
/*
|
||||
* Current page cannot be merged with the left brother.
|
||||
* Move some entries from the left brother into current.
|
||||
*/
|
||||
|
||||
move_keys = (ldshort(pkp2 + BT_NKEYS_OFF) - halfcapac +1)/2;
|
||||
assert(move_keys > 0);
|
||||
|
||||
move_from_left (btree, pkp2, pkp, move_keys);
|
||||
|
||||
leftkey_up(btree, i); /* Propagate new leftmost key */
|
||||
|
||||
break; /* From main loop */
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Current page and left brotehr will be merged.
|
||||
* Move all entries from current into left, and free
|
||||
* current.
|
||||
*/
|
||||
|
||||
/* Move all entries from current into left. */
|
||||
move_from_right(btree, pkp2, pkp, nkeys);
|
||||
|
||||
/* Free current page. */
|
||||
_isindfreel_free(btree->fcb, btree->bufhdr[i]->isb_blkno);
|
||||
|
||||
btree->bufhdr[i] = kp2bhdr; /* Update search path */
|
||||
|
||||
/* The loop must iterate to delete entry in parent block. */
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Block pkp is the leftmost descendent of its parent.
|
||||
* Either merge with right brother, or move a few entries
|
||||
* from it.
|
||||
*/
|
||||
|
||||
pkp3 = btree->bufhdr[i-1]->isb_buffer;
|
||||
|
||||
blkno2 = ldblkno(pkp3 + ISPAGESIZE -
|
||||
(btree->curpos[i-1] + 2) * BLKNOSIZE);
|
||||
|
||||
/* Fix the right brother. */
|
||||
kp2bhdr = _isdisk_fix(btree->fcb, btree->fcb->indfd,
|
||||
blkno2, ISFIXWRITE);
|
||||
pkp2 = kp2bhdr->isb_buffer;
|
||||
|
||||
if (ldshort(pkp2 + BT_NKEYS_OFF) + nkeys > capac) {
|
||||
|
||||
/*
|
||||
* Current page cannot be merged with the right brother.
|
||||
* Move some entries from the right brother into current.
|
||||
*/
|
||||
|
||||
move_keys = (ldshort(pkp2 + BT_NKEYS_OFF) - halfcapac +1)/2;
|
||||
assert(move_keys > 0);
|
||||
|
||||
move_from_right(btree, pkp, pkp2, move_keys);
|
||||
|
||||
/* Update search path to go through right brother. */
|
||||
btree->curpos[i-1]++;
|
||||
btree->bufhdr[i] = kp2bhdr;
|
||||
btree->curpos[i] = 0;
|
||||
leftkey_up(btree, i); /* Propagate new leftmost key */
|
||||
|
||||
break; /* From main loop */
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Current page and right brother will be merged.
|
||||
* Move all entries from right into current, and free
|
||||
* right.
|
||||
*/
|
||||
|
||||
/* Move all entries from right brother into current. */
|
||||
move_from_right(btree, pkp, pkp2, ldshort(pkp2 + BT_NKEYS_OFF));
|
||||
|
||||
/* Free right brother page. */
|
||||
_isindfreel_free(btree->fcb, kp2bhdr->isb_blkno);
|
||||
|
||||
/* Update search path to point at right brother*/
|
||||
btree->curpos[i-1]++;
|
||||
/* The loop must iterate to delete entry in parent block. */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end of main loop */
|
||||
|
||||
if (btree->depth > 1) {
|
||||
pkp = btree->bufhdr[0]->isb_buffer;
|
||||
|
||||
if (ldshort(pkp + BT_NKEYS_OFF) < 2) {
|
||||
|
||||
/*
|
||||
* Root now has only 1 entry and it is not the sole block.
|
||||
* Replace root with its only descendant, don't change
|
||||
* root blkno.
|
||||
*/
|
||||
pkp2 = btree->bufhdr[1]->isb_buffer;
|
||||
memcpy( pkp,pkp2, ISPAGESIZE);
|
||||
|
||||
/* Free page. */
|
||||
_isindfreel_free(btree->fcb, btree->bufhdr[1]->isb_blkno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------- remove supporting local functions -------------------------------*/
|
||||
|
||||
static remove_entry(btree, pkp, pos)
|
||||
register Btree *btree;
|
||||
char *pkp;
|
||||
int pos;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
int nkeys = ldshort(pkp + BT_NKEYS_OFF);
|
||||
int level = ldshort(pkp + BT_LEVEL_OFF);
|
||||
|
||||
assert(nkeys > 0);
|
||||
assert(pos >= 0 && pos < nkeys);
|
||||
|
||||
/* Shift nkeys - pos - 1 entries to the left. */
|
||||
memcpy(pkp + BT_KEYS_OFF + pos * keylength,
|
||||
pkp + BT_KEYS_OFF + (pos + 1) * keylength,
|
||||
(nkeys - pos - 1) * keylength);
|
||||
|
||||
/* For non-leaf nodes, remove block number from table of down pointers. */
|
||||
if (level > 0) {
|
||||
|
||||
memmove(pkp + ISPAGESIZE - (nkeys - 1) * BLKNOSIZE,
|
||||
pkp + ISPAGESIZE - nkeys * BLKNOSIZE,
|
||||
(nkeys - pos - 1) * BLKNOSIZE);
|
||||
}
|
||||
|
||||
stshort((short) (nkeys - 1), pkp + BT_NKEYS_OFF);
|
||||
}
|
||||
|
||||
move_from_right(btree, l, r, move_keys)
|
||||
Btree *btree;
|
||||
char *l, *r;
|
||||
int move_keys;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
int lnkeys = ldshort(l + BT_NKEYS_OFF);
|
||||
int rnkeys = ldshort(r + BT_NKEYS_OFF);
|
||||
int level = ldshort(r + BT_LEVEL_OFF);
|
||||
|
||||
/* Move move_keys from l into r block. */
|
||||
memcpy( l + BT_KEYS_OFF + lnkeys * keylength,r + BT_KEYS_OFF,
|
||||
move_keys * keylength);
|
||||
|
||||
/* Move remaining entries in r to the left side. */
|
||||
memcpy( r + BT_KEYS_OFF,r + BT_KEYS_OFF + move_keys * keylength,
|
||||
(rnkeys - move_keys) * keylength);
|
||||
|
||||
/* If non-leaf, move the pointers stored at the end of block. */
|
||||
if (level > 0) {
|
||||
memcpy(l + ISPAGESIZE - (lnkeys + move_keys) * BLKNOSIZE,
|
||||
r + ISPAGESIZE - move_keys * BLKNOSIZE,
|
||||
move_keys * BLKNOSIZE);
|
||||
|
||||
memmove(r + ISPAGESIZE - (rnkeys - move_keys) * BLKNOSIZE,
|
||||
r + ISPAGESIZE - rnkeys * BLKNOSIZE,
|
||||
(rnkeys - move_keys) * BLKNOSIZE);
|
||||
}
|
||||
|
||||
lnkeys += move_keys;
|
||||
rnkeys -= move_keys;
|
||||
|
||||
stshort((short) lnkeys, l + BT_NKEYS_OFF);
|
||||
stshort((short) rnkeys, r + BT_NKEYS_OFF);
|
||||
}
|
||||
|
||||
move_from_left(btree, l, r, move_keys)
|
||||
Btree *btree;
|
||||
char *l, *r;
|
||||
int move_keys;
|
||||
{
|
||||
int keylength = btree->keydesc2->k2_len;
|
||||
int lnkeys = ldshort(l + BT_NKEYS_OFF);
|
||||
int rnkeys = ldshort(r + BT_NKEYS_OFF);
|
||||
int level = ldshort(r + BT_LEVEL_OFF);
|
||||
|
||||
/* Move entries in r to the right side to create space for move_keys. */
|
||||
memmove( r + BT_KEYS_OFF + move_keys * keylength,r + BT_KEYS_OFF,
|
||||
rnkeys * keylength);
|
||||
|
||||
/* Move move_keys from l into r block. */
|
||||
memcpy( r + BT_KEYS_OFF,l + BT_KEYS_OFF + (lnkeys - move_keys) * keylength,
|
||||
move_keys * keylength);
|
||||
|
||||
/* If non-leaf, move the pointers stored at the end of block. */
|
||||
if (level > 0) {
|
||||
|
||||
memcpy(r + ISPAGESIZE - (rnkeys + move_keys) * BLKNOSIZE,
|
||||
r + ISPAGESIZE - rnkeys * BLKNOSIZE,
|
||||
rnkeys * BLKNOSIZE);
|
||||
|
||||
memcpy(r + ISPAGESIZE - move_keys * BLKNOSIZE,
|
||||
l + ISPAGESIZE - lnkeys * BLKNOSIZE,
|
||||
move_keys * BLKNOSIZE);
|
||||
}
|
||||
|
||||
lnkeys -= move_keys;
|
||||
rnkeys += move_keys;
|
||||
|
||||
stshort((short) lnkeys, l + BT_NKEYS_OFF);
|
||||
stshort((short) rnkeys, r + BT_NKEYS_OFF);
|
||||
}
|
||||
|
||||
|
||||
351
cde/lib/tt/mini_isam/isbuild.c
Normal file
351
cde/lib/tt/mini_isam/isbuild.c
Normal file
@@ -0,0 +1,351 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbuild.c /main/3 1995/10/23 11:36:21 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbuild.c 1.12 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbuild.c
|
||||
*
|
||||
* Description:
|
||||
* Create an ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <netdb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
extern char _isam_version[];
|
||||
static char *_version_ = _isam_version;
|
||||
|
||||
static int _ambuild();
|
||||
|
||||
/*
|
||||
* isfd = isbuild(isfname, recordlength, primkey, mode)
|
||||
*
|
||||
* Isbuild() determines on which machine the ISAM file is to be built,
|
||||
* checks the permissions for creating a file by this user running on
|
||||
* this client machine by using the access(2) UNIX call.
|
||||
* If the file is remote, it is created by the netisamd daemon running
|
||||
* on the machine hosting the ISAM file. The chown(2) is then used to
|
||||
* change the ownership of the file to the client.
|
||||
* All UNIX files created will have their permissions set to 0666, allowing
|
||||
* thus both read and write access to anybody.
|
||||
*
|
||||
* Isbuild() returns an ISAM file descriptor (isfd) is the call was successful,
|
||||
* or a value of -1 if the call failed.
|
||||
*
|
||||
* Errors:
|
||||
* EBADARG Improper mode parameter
|
||||
* EBADARG isreclen >= recordlength and ISVARLEN specified
|
||||
* E2BIG recordlength greater than system imposed limit (8196)
|
||||
* EBADKEY Invalid key descriptor
|
||||
* EBADFILE ISAM file is corrupted or it is not an NetISAM file
|
||||
* EFNAME Invalid ISAM file name
|
||||
* ETOOMANY Too many ISAM file descriptors are in use (128 is the limit)
|
||||
*
|
||||
* The following error numbers are "borrowed" from UNIX.
|
||||
* EACCES UNIX file system protection denies creation of the file
|
||||
* EEXIST - ISAM file already exists
|
||||
* EEXIST - A UNIX file with the same name exists
|
||||
*/
|
||||
|
||||
int
|
||||
isbuild(isfname, recordlength, primkey, mode)
|
||||
char *isfname;
|
||||
int recordlength;
|
||||
struct keydesc *primkey;
|
||||
int mode;
|
||||
{
|
||||
Fab *fab;
|
||||
Isfd isfd;
|
||||
enum openmode openmode;
|
||||
int minreclen; /* Minimum record length */
|
||||
int origumask;
|
||||
|
||||
/* Get file open mode part of the mode parameter. */
|
||||
if ((openmode = _getopenmode(mode)) == OM_BADMODE) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Minimum record length.
|
||||
*/
|
||||
|
||||
minreclen = ((mode & ISLENMODE) == ISVARLEN) ? isreclen : recordlength;
|
||||
|
||||
/* Check recordlength against system imposed limit. */
|
||||
if (recordlength > ISMAXRECLEN) {
|
||||
_setiserrno2(E2BIG, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
/* Check that ssminreclen >= ISMINRECLEN. */
|
||||
if (minreclen < ISMINRECLEN) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
/* Check that minreclen <= recordlength */
|
||||
if (minreclen > recordlength) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
/* Create a Fab object. */
|
||||
fab = _fab_new(isfname,
|
||||
openmode,
|
||||
(Bool)((mode & ISLENMODE) == ISVARLEN),
|
||||
minreclen,
|
||||
recordlength);
|
||||
if (fab == NULL) {
|
||||
return (NOISFD); /* iserrno is set by fab_new */
|
||||
}
|
||||
|
||||
/* Get an ISAM file descriptor for this fab */
|
||||
if ((isfd = _isfd_insert(fab)) == NOISFD) {
|
||||
/* Table of ISAM file descriptors would overflow. */
|
||||
_fab_destroy(fab);
|
||||
_setiserrno2(ETOOMANY, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
FAB_ISFDSET(fab, isfd);
|
||||
|
||||
/*
|
||||
* Extract umask. It is send to the Acces Layer (which may reside
|
||||
* on a remote machine).
|
||||
*/
|
||||
origumask = umask(0);
|
||||
(void)umask(origumask);
|
||||
|
||||
/*
|
||||
* Call lower layers.
|
||||
*/
|
||||
|
||||
if (_ambuild(fab->isfname, fab->openmode, fab->varlength,
|
||||
fab->minreclen, fab->maxreclen, primkey, getuid(),
|
||||
getgid(), origumask, &fab->isfhandle, &fab->curpos,
|
||||
&fab->errcode)) {
|
||||
_seterr_errcode(&fab->errcode);
|
||||
_fab_destroy(fab);
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
return ((int)isfd); /* Successful isopen() */
|
||||
}
|
||||
|
||||
/*
|
||||
* _ambuild(isfname, openmode, varflag, minlen, maxlen,
|
||||
* primkey, owner, group, umask, isfhandle, curpos, errcode)
|
||||
*
|
||||
* _ambuild() creates a new ISAM file with the name isfname.
|
||||
*
|
||||
* Input params:
|
||||
* isfname ISAM file name
|
||||
* varflag is 0/1 flag set to 1 if the file is for variable lengths records
|
||||
* minlen minimum length of record in bytes
|
||||
* maxlen maximum length of record in bytes
|
||||
* primkey definition of the primary key
|
||||
* owner, group set the ownership of the file to this user and group
|
||||
* umask application's value of umask
|
||||
*
|
||||
* Output params:
|
||||
* isfhandle a file handle to be used in subsequent operations on the file
|
||||
* curpos initial current record position
|
||||
* errcode {iserrno, isstat1-4}
|
||||
*
|
||||
* _ambuild() returns 0 if successful, or -1 to indicate an error.
|
||||
*/
|
||||
#define FDNEEDED 3 /* Needs at most 3 UNIX fds to open ISAM file */
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
_ambuild(isfname, openmode, varflag, minlen, maxlen, primkey,
|
||||
owner, group, umask, isfhandle, curpos, errcode)
|
||||
char *isfname;
|
||||
enum openmode openmode;
|
||||
Bool varflag;
|
||||
int minlen, maxlen;
|
||||
struct keydesc *primkey;
|
||||
int owner, group;
|
||||
Bytearray *isfhandle;
|
||||
Bytearray *curpos;
|
||||
struct errcode *errcode;
|
||||
int umask;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Bytearray *isfhandle2;
|
||||
Bytearray isfhandle0;
|
||||
Keydesc2 keydesc2;
|
||||
int err;
|
||||
Crp *crp;
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Validate the primary key descriptor.
|
||||
*/
|
||||
if (!USE_PHYS_ORDER(primkey) &&
|
||||
_validate_keydesc(primkey, minlen) == ISERROR) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make isfhandle0.
|
||||
*/
|
||||
isfhandle0 = _makeisfhandle(isfname);
|
||||
|
||||
/*
|
||||
* Check that there is not entry with the same name in FCB cache.
|
||||
*/
|
||||
if ((fcb = _mngfcb_find(&isfhandle0)) != NULL) {
|
||||
fcb = _mngfcb_find(&isfhandle0);
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(&isfhandle0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that there are UNIX file descriptors available.
|
||||
*/
|
||||
while (_watchfd_check() < FDNEEDED) {
|
||||
/*
|
||||
* Find victim (LRU FCB) and close it.
|
||||
*/
|
||||
if((isfhandle2 = _mngfcb_victim()) == NULL)
|
||||
_isfatal_error ("_openfcb() cannot find LRU victim");
|
||||
|
||||
fcb = _mngfcb_find(isfhandle2);
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create UNIX files, return isfhandle and File Control Block (fcb).
|
||||
*/
|
||||
if ((fcb = _isfcb_create(isfname, 1, (primkey->k_nparts != 0), (int)varflag,
|
||||
owner, group, umask, errcode)) == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add length info to the FCB.
|
||||
*/
|
||||
_isfcb_setreclength(fcb, varflag, minlen, maxlen);
|
||||
|
||||
if (!USE_PHYS_ORDER(primkey)) {
|
||||
/*
|
||||
* Convert key descriptor to internal form.
|
||||
*/
|
||||
_iskey_xtoi (&keydesc2, primkey);
|
||||
|
||||
/*
|
||||
* Create index structure.
|
||||
*/
|
||||
if ((err = _create_index(fcb , &keydesc2)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add primary key descriptor to FCB.
|
||||
*/
|
||||
if (_isfcb_primkeyadd(fcb, &keydesc2) == ISERROR) {
|
||||
_amseterrcode(errcode, ETOOMANY);
|
||||
goto ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial current record position.
|
||||
*/
|
||||
if (FCB_NOPRIMARY_KEY(fcb)) {
|
||||
/* Use physical order. */
|
||||
crp = (Crp *) _ismalloc(sizeof(*crp));
|
||||
memset ((char *) crp, 0, sizeof(*crp));
|
||||
|
||||
crp->keyid = PHYS_ORDER;
|
||||
crp->flag = CRP_BEFOREANY;
|
||||
|
||||
curpos->length = sizeof(*crp);
|
||||
curpos->data = (char *) crp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Use primary key order.
|
||||
*/
|
||||
|
||||
crp = (Crp *) _ismalloc((unsigned)(sizeof(*crp) + fcb->keys[0].k2_len));
|
||||
memset((char *) crp, 0, (sizeof(*crp) + fcb->keys[0].k2_len));
|
||||
|
||||
crp->keyid = fcb->keys[0].k2_keyid;
|
||||
crp->flag = CRP_BEFOREANY;
|
||||
|
||||
_iskey_fillmin(&fcb->keys[0], crp->key);
|
||||
|
||||
curpos->length = sizeof(*crp) + fcb->keys[0].k2_len;
|
||||
curpos->data = (char *) crp;
|
||||
|
||||
/*
|
||||
* Set full key length as the number of bytes to match in key comparison
|
||||
*/
|
||||
crp->matchkeylen = fcb->keys[0].k2_len - RECNOSIZE;
|
||||
|
||||
if (ALLOWS_DUPS2(&fcb->keys[0]))
|
||||
crp->matchkeylen -= DUPIDSIZE;
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
/*
|
||||
* Register the number of UNIX fd consumed.
|
||||
*/
|
||||
(void) _watchfd_incr(_isfcb_nfds(fcb));
|
||||
|
||||
/*
|
||||
* Insert new entry into FCB cache.
|
||||
*/
|
||||
_mngfcb_insert(fcb, &isfhandle0);
|
||||
*isfhandle = isfhandle0;
|
||||
|
||||
/* Commit all work in disk cache. */
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Create Control Page (CNTLPAGE).
|
||||
*/
|
||||
if (_isfcb_cntlpg_w(fcb) == ISERROR) {
|
||||
_issignals_unmask();
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
_issignals_unmask();
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
if (fcb != NULL) {
|
||||
_isfcb_remove(fcb);
|
||||
_isfcb_close(fcb);
|
||||
}
|
||||
|
||||
_bytearr_free(&isfhandle0);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
103
cde/lib/tt/mini_isam/isbytearray.c
Normal file
103
cde/lib/tt/mini_isam/isbytearray.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isbytearray.c /main/3 1995/10/23 11:36:32 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isbytearray.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isbytearray.c
|
||||
*
|
||||
* Description:
|
||||
* Byte array handling functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
/*
|
||||
* _bytearr_getempty()
|
||||
*
|
||||
* Return an empty byte array.
|
||||
*/
|
||||
|
||||
Bytearray
|
||||
_bytearr_getempty()
|
||||
{
|
||||
static Bytearray empty_bytearray = { 0, NULL};
|
||||
|
||||
return (empty_bytearray);
|
||||
}
|
||||
|
||||
/*
|
||||
* bytearray = _bytearr_new(len, data)
|
||||
*
|
||||
* Create a byte array object.
|
||||
*/
|
||||
|
||||
Bytearray
|
||||
_bytearr_new(len, data)
|
||||
u_short len;
|
||||
char *data;
|
||||
{
|
||||
Bytearray bytearray;
|
||||
|
||||
bytearray.length = len;
|
||||
bytearray.data = _ismalloc(len);
|
||||
memcpy( bytearray.data,data, (int)len);
|
||||
|
||||
return (bytearray);
|
||||
}
|
||||
|
||||
/*
|
||||
* new = _bytearr_dup(old)
|
||||
*
|
||||
* Duplicate a byte array object.
|
||||
*/
|
||||
|
||||
Bytearray
|
||||
_bytearr_dup(old)
|
||||
Bytearray *old;
|
||||
{
|
||||
return (_bytearr_new(old->length, old->data));
|
||||
}
|
||||
|
||||
/*
|
||||
* _bytearr_free(barrray)
|
||||
*
|
||||
* Free byte array buffer, set barray to an empty byte array.
|
||||
*/
|
||||
|
||||
void
|
||||
_bytearr_free(barray)
|
||||
register Bytearray *barray;
|
||||
{
|
||||
if (barray->data)
|
||||
free(barray->data);
|
||||
|
||||
*barray = _bytearr_getempty();
|
||||
}
|
||||
|
||||
/*
|
||||
* _bytearr_cmp(l, r)
|
||||
*
|
||||
* Compare two byte array objects. Return 0 if they are equal, non-zero if
|
||||
* they differ.
|
||||
*/
|
||||
|
||||
int
|
||||
_bytearr_cmp(l,r)
|
||||
register Bytearray *l, *r;
|
||||
{
|
||||
if (l->length == r->length)
|
||||
return (memcmp(l->data, r->data, (int)l->length));
|
||||
else
|
||||
return (1); /* not equal */
|
||||
}
|
||||
|
||||
180
cde/lib/tt/mini_isam/ischange1key.c
Normal file
180
cde/lib/tt/mini_isam/ischange1key.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: ischange1key.c /main/3 1995/10/23 11:36:41 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ischange1key.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ischange1key.c
|
||||
*
|
||||
* Description:
|
||||
* Update an index if necessary.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern long *ismaxlong;
|
||||
|
||||
int
|
||||
_change1key(fcb, pkeydesc2, record, oldrecord, recnum, newkey)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
char *record;
|
||||
char *oldrecord;
|
||||
Recno recnum;
|
||||
char *newkey;
|
||||
{
|
||||
char keybuf1[MAXKEYSIZE];
|
||||
char keybuf2[MAXKEYSIZE];
|
||||
Btree *btree;
|
||||
char *pkey;
|
||||
|
||||
/*
|
||||
* Special case when there is no primary key.
|
||||
*/
|
||||
if (pkeydesc2->k2_nparts == 0)
|
||||
return (ISOK);
|
||||
|
||||
/* Get old key value. */
|
||||
memset((char *)keybuf1, 0, pkeydesc2->k2_len);
|
||||
_iskey_extract(pkeydesc2, oldrecord, keybuf1);
|
||||
strecno(recnum, keybuf1);
|
||||
|
||||
/* Get new key value. */
|
||||
memset((char *)keybuf2, 0, pkeydesc2->k2_len);
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
strecno(recnum, keybuf2);
|
||||
|
||||
|
||||
/*
|
||||
* See if the key changed.
|
||||
*/
|
||||
if (memcmp(keybuf1, keybuf2, pkeydesc2->k2_len)) {
|
||||
|
||||
/*
|
||||
* Delete the old key entry from B tree.
|
||||
*/
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
|
||||
/*
|
||||
* We must now scan all the duplicates till we found one with
|
||||
* matching recno. We are positioned just before the first duplicate.
|
||||
* Remember that the duplicates are ordered by their serial number.
|
||||
*
|
||||
* If too many duplicate entries exists, the performance will be
|
||||
* poor.
|
||||
*/
|
||||
while ((pkey = _isbtree_next(btree)) != NULL) {
|
||||
if (ldrecno(pkey + KEY_RECNO_OFF) == recnum)
|
||||
break; /* We found the entry */
|
||||
}
|
||||
|
||||
if (pkey == NULL)
|
||||
_isfatal_error("_del1key() cannot find entry in B tree");
|
||||
|
||||
_isbtree_remove(btree);
|
||||
}
|
||||
else {
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL ||
|
||||
ldrecno(pkey + KEY_RECNO_OFF) != recnum)
|
||||
_isfatal_error("_del1key() cannot find entry in B tree");
|
||||
|
||||
_isbtree_remove(btree);
|
||||
}
|
||||
_isbtree_destroy(btree);
|
||||
|
||||
/*
|
||||
* Insert new key entry into B tree.
|
||||
*/
|
||||
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
|
||||
/*
|
||||
* Duplicates allowed on this key.
|
||||
* Try to read the last duplicate (with the highest serial number).
|
||||
* If such duplicate exists, the inserted key entry will be
|
||||
* assigned next higher value for duplicate serial number.
|
||||
* If there is no such duplicate, assign duplicate serial number 1.
|
||||
*/
|
||||
strecno(recnum, keybuf2 + KEY_RECNO_OFF);
|
||||
memcpy( keybuf2 + KEY_DUPS_OFF,(char *)ismaxlong, LONGSIZE);
|
||||
_isbtree_search(btree, keybuf2);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) != NULL &&
|
||||
memcmp(pkey + RECNOSIZE + DUPIDSIZE,
|
||||
keybuf2 + RECNOSIZE + DUPIDSIZE,
|
||||
pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE) == 0) {
|
||||
|
||||
/*
|
||||
* A duplicate exists. Assign +1 value for the new serial
|
||||
* number.
|
||||
*/
|
||||
stlong(ldlong(pkey + KEY_DUPS_OFF) + 1, keybuf2 + KEY_DUPS_OFF);
|
||||
|
||||
/*
|
||||
* Indicate that there are allowed duplicate key values.
|
||||
*/
|
||||
isdupl = 1;
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* This is the first duplicate. Assign serial number 1.
|
||||
*/
|
||||
stlong(1L, keybuf2 + KEY_DUPS_OFF);
|
||||
}
|
||||
|
||||
_isbtree_insert(btree, keybuf2);
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
|
||||
|
||||
|
||||
else {
|
||||
|
||||
/* Duplicates not allowed on this key.
|
||||
* Set TID part to maximum value, causing the search path
|
||||
* to point just past the possible duplicate in the key file
|
||||
* If there is no duplicate, this is the correct spot to
|
||||
* insert the new key entry.
|
||||
*/
|
||||
|
||||
memcpy( keybuf2 + KEY_RECNO_OFF,(char *)ismaxlong, LONGSIZE);
|
||||
_isbtree_search (btree, keybuf2);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) != NULL &&
|
||||
memcmp(pkey + RECNOSIZE, keybuf2 + RECNOSIZE,
|
||||
pkeydesc2->k2_len - RECNOSIZE) == 0) {
|
||||
_isbtree_destroy(btree);
|
||||
return (EDUPL);
|
||||
}
|
||||
|
||||
strecno(recnum, keybuf2 + KEY_RECNO_OFF);
|
||||
_isbtree_insert(btree, keybuf2);
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return new key position.
|
||||
*/
|
||||
if (newkey != NULL)
|
||||
memcpy( newkey,keybuf2, pkeydesc2->k2_len);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
75
cde/lib/tt/mini_isam/isclose.c
Normal file
75
cde/lib/tt/mini_isam/isclose.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isclose.c /main/3 1995/10/23 11:36:50 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isclose.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isclose.c
|
||||
*
|
||||
* Description:
|
||||
* Close an ISAM file
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* isclose(isfd)
|
||||
*
|
||||
* Isclose() closes the ISAM file associated with the file descriptor isfd.
|
||||
* There may be other ISAM file descriptors in use which are associated
|
||||
* with the same ISAM file; are not effected by isclose().
|
||||
*
|
||||
* Isclose() returns -1 if an errors was detected, or 0 if the file was closed
|
||||
* successfully.
|
||||
*
|
||||
* Errors:
|
||||
* ENOTOPEN isfd is not ISAM file descriptor of an open ISAM file.
|
||||
*/
|
||||
|
||||
int
|
||||
isclose(isfd)
|
||||
int isfd;
|
||||
{
|
||||
Fab *fab;
|
||||
Fcb *fcb;
|
||||
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&fab->isfhandle, &fab->errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete FCB and remove it from FCB cache. Close UNIX fds.
|
||||
*
|
||||
* This is desirable when ISAM files are removed from other processes,
|
||||
* or simply by 'rm file.*'.
|
||||
*/
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(&fab->isfhandle);
|
||||
|
||||
_isam_exithook();
|
||||
|
||||
_fab_destroy(fab); /* Deallocate Fab object */
|
||||
_isfd_delete(isfd);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
104
cde/lib/tt/mini_isam/iscntl.c
Normal file
104
cde/lib/tt/mini_isam/iscntl.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iscntl.c /main/3 1995/10/23 11:36:59 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iscntl.c 1.8 94/11/17";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iscntl.c
|
||||
*
|
||||
* Description:
|
||||
* Generic control function
|
||||
*/
|
||||
|
||||
#include <varargs.h>
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
/*
|
||||
* err = iscntl(isfd, args)
|
||||
*
|
||||
* Functions:
|
||||
*
|
||||
* iscntl(isfd, ISCNTL_RPCS_TO_SET, tout) - Set timeout for short operations
|
||||
* iscntl(isfd, ISCNTL_RPCL_TO_SET, tout) - Set timeout for long operations
|
||||
* iscntl(isfd, ISCNTL_RPCS_TO_GET) - Get timeout for short operations
|
||||
* iscntl(isfd, ISCNTL_RPCL_TO_GET) - Get timeout for long operations
|
||||
* iscntl(isfd, ISCNTL_TCP_TO_SET) - Set TCP reconnect timeout
|
||||
* iscntl(isfd, ISCNTL_TCP_TO_GET) - Get TCP reconnect timeout
|
||||
*
|
||||
* iscntl(isfd, ISCNTL_APPLMAGIC_WRITE, string) - Write application magic
|
||||
* iscntl(isfd, ISCNTL_APPLMAGIC_READ, buf) - Read application magic
|
||||
*
|
||||
* iscntl(ALLISFD, ISCNTL_FDLIMIT_SET, n) - Set limit on UNIX fd use
|
||||
* iscntl(ALLISFD, ISCNTL_FDLIMIT_GET) - Set limit on UNIX fd use
|
||||
*
|
||||
* oldfunc = iscntl(ALLISFD, ISCNTL_FATAL, func) - Set fatal error handler
|
||||
* int func(msg) - Apllication handler
|
||||
* if 0 is returned, NetISAM will use openlog("NetISAM") and
|
||||
* syslog(ERR_LOG, msg) to log the error.
|
||||
*
|
||||
* iscntl(ALLISFD, ISCNTL_MASKSIGNALS, bool) 1 mask, 0 don't mask
|
||||
*
|
||||
* iscntl(isfd, ISCNTL_FSYNC) - synchronize a file's in-core state
|
||||
* with that on disk
|
||||
*
|
||||
*/
|
||||
|
||||
typedef int (* intfunc)();
|
||||
|
||||
int
|
||||
iscntl(isfd, func, va_alist)
|
||||
int isfd;
|
||||
int func;
|
||||
va_dcl
|
||||
{
|
||||
extern int (*_isfatal_error_set_func())();
|
||||
va_list pvar;
|
||||
int ret;
|
||||
|
||||
va_start(pvar);
|
||||
switch (func) {
|
||||
|
||||
case ISCNTL_MASKSIGNALS:
|
||||
ret = _issignals_cntl(va_arg(pvar, int));
|
||||
break;
|
||||
|
||||
case ISCNTL_FATAL:
|
||||
ret = (int)_isfatal_error_set_func(va_arg(pvar, intfunc));
|
||||
break;
|
||||
|
||||
case ISCNTL_FDLIMIT_SET:
|
||||
ret = _watchfd_max_set(va_arg(pvar, int));
|
||||
break;
|
||||
|
||||
case ISCNTL_FDLIMIT_GET:
|
||||
ret = _watchfd_max_get();
|
||||
break;
|
||||
|
||||
case ISCNTL_APPLMAGIC_WRITE:
|
||||
ret = _isapplmw(isfd, (va_arg(pvar, char *)));
|
||||
break;
|
||||
|
||||
case ISCNTL_APPLMAGIC_READ:
|
||||
ret = _isapplmr(isfd, (va_arg(pvar, char *)));
|
||||
break;
|
||||
|
||||
case ISCNTL_FSYNC:
|
||||
ret = _isfsync(isfd);
|
||||
break;
|
||||
|
||||
default:
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
ret = ISERROR;
|
||||
}
|
||||
|
||||
va_end(pvar);
|
||||
return (ret);
|
||||
}
|
||||
98
cde/lib/tt/mini_isam/iscurpos.c
Normal file
98
cde/lib/tt/mini_isam/iscurpos.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iscurpos.c /main/3 1995/10/23 11:37:08 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iscurpos.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)iscurpos.c 1.2 95/01/06
|
||||
*
|
||||
* Description:
|
||||
* Save and restore current record position functions.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/file.h>
|
||||
|
||||
/*
|
||||
* err = isgetcurpos(isfd, len, buf)
|
||||
*
|
||||
* Get current record position and save it in user buffer.
|
||||
*
|
||||
* The user buffer buf is filled with (if the information is N bytes):
|
||||
* buf[0], buf[1] total length as u_short (set to N + 2)
|
||||
* buf[2] .. buf[N + 1] current record position information
|
||||
*/
|
||||
|
||||
int
|
||||
isgetcurpos(isfd, len, buf)
|
||||
int isfd;
|
||||
int *len;
|
||||
char **buf;
|
||||
{
|
||||
Fab *fab;
|
||||
u_short total_len;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
total_len = sizeof(total_len) + fab->curpos.length;
|
||||
|
||||
if (*buf != NULL && *len < (int)total_len) {
|
||||
_setiserrno2(E2BIG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if (*buf == NULL) {
|
||||
*len = total_len;
|
||||
*buf = _ismalloc((unsigned int)total_len);
|
||||
}
|
||||
|
||||
memcpy(*buf, (char *) &total_len, sizeof(total_len));
|
||||
memcpy(*buf+sizeof(total_len), fab->curpos.data, (int)fab->curpos.length);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* err = issetcurpos(isfd, buf)
|
||||
*
|
||||
* Get current record position and save it in user buffer.
|
||||
*/
|
||||
|
||||
int
|
||||
issetcurpos(isfd, buf)
|
||||
int isfd;
|
||||
char *buf;
|
||||
{
|
||||
Fab *fab;
|
||||
u_short len;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
memcpy((char *)&len, buf, sizeof(len));
|
||||
len -= sizeof (len);
|
||||
|
||||
_bytearr_free(&fab->curpos);
|
||||
fab->curpos = _bytearr_new(len, buf + sizeof(len));
|
||||
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
323
cde/lib/tt/mini_isam/isdatconv.c
Normal file
323
cde/lib/tt/mini_isam/isdatconv.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isdatconv.c /main/3 1995/10/23 11:37:16 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdatconv.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isdatconv.c
|
||||
*
|
||||
* Description:
|
||||
* Conversion function between machine dependent and the X/OPEN
|
||||
* machine independent formats.
|
||||
*
|
||||
* Some pieces of code may not be very "structured", but they result in
|
||||
* optimized code with the -O compiler option.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
#define BLANK ' '
|
||||
|
||||
/* conversion functions for sparc architecture */
|
||||
|
||||
/* ldlong() - Load a long integer from a potentially unaligned address */
|
||||
|
||||
long
|
||||
ldlong(p)
|
||||
register char *p;
|
||||
{
|
||||
int i;
|
||||
#if LONG_BIT == 64
|
||||
register unsigned long val;
|
||||
#else
|
||||
register unsigned int val;
|
||||
#endif
|
||||
|
||||
val = 0;
|
||||
for (i=0; i<LONGSIZE ; i++)
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
|
||||
return ((long)val);
|
||||
}
|
||||
|
||||
/* stlong() - Store a long integer at a potentially unaligned address */
|
||||
|
||||
int
|
||||
stlong(val, p)
|
||||
register long val;
|
||||
register char *p;
|
||||
{
|
||||
int i;
|
||||
p += LONGSIZE;
|
||||
|
||||
for (i=0; i<LONGSIZE ; i++)
|
||||
*--p = (val >> 8*i) & 255;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ldint() - Load a short integer from a potentially unaligned address */
|
||||
|
||||
short
|
||||
ldint(p)
|
||||
register char *p;
|
||||
{
|
||||
register unsigned int val;
|
||||
|
||||
val = *((unsigned char *)p++);
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
|
||||
return ((short)val);
|
||||
}
|
||||
|
||||
|
||||
/* ldunshort - load a unshort integer : for 64K record length */
|
||||
|
||||
u_short
|
||||
ldunshort(p)
|
||||
register char *p;
|
||||
{
|
||||
register unsigned int val;
|
||||
|
||||
val = *((unsigned char *)p++);
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
|
||||
return ((u_short)val);
|
||||
}
|
||||
|
||||
/* stint() - Store a short integer at a potentially unaligned address */
|
||||
|
||||
int
|
||||
stint(val, p)
|
||||
register short val;
|
||||
register char *p;
|
||||
{
|
||||
p += SHORTSIZE;
|
||||
*--p = val & 255;
|
||||
*--p = (val >> 8) & 255;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ldchar() - Load character field */
|
||||
|
||||
int
|
||||
ldchar(src, len, dst)
|
||||
char *src;
|
||||
register char *dst;
|
||||
int len;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
/* Load the entire string. */
|
||||
memcpy((void *) dst, (const void *) src, len);
|
||||
|
||||
/* Remove trailing blanks. */
|
||||
p = dst + len;
|
||||
while (--p >= dst) {
|
||||
if (*p != BLANK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*++p = '\0';
|
||||
}
|
||||
|
||||
int
|
||||
stchar(src, dst, len)
|
||||
register char *src;
|
||||
register char *dst;
|
||||
register int len;
|
||||
{
|
||||
register char c;
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
/* Copy up to NULL character. */
|
||||
do {
|
||||
if ((c = *src++) == '\0')
|
||||
break;
|
||||
*dst++ = c;
|
||||
} while (--len > 0);
|
||||
|
||||
/* Pad with blanks. */
|
||||
if (len > 0)
|
||||
(void) memset((void *) dst, BLANK, len);
|
||||
}
|
||||
|
||||
/* ldchar2() - Load character field (C style, NULL padded) */
|
||||
|
||||
int
|
||||
ldchar2(src, len, dst)
|
||||
char *src;
|
||||
register char *dst;
|
||||
int len;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
/* Load the entire string. */
|
||||
memcpy((void *) dst, (const void *) src, len);
|
||||
*(dst + len) = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
stchar2(src, dst, len)
|
||||
register char *src;
|
||||
register char *dst;
|
||||
register int len;
|
||||
{
|
||||
register char c;
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
/* Copy up to a NULL character. */
|
||||
do {
|
||||
if ((c = *src++) == '\0')
|
||||
break;
|
||||
*dst++ = c;
|
||||
} while (--len > 0);
|
||||
|
||||
/* Pad with NULLs. */
|
||||
if (len > 0)
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
|
||||
/* ldfloat() - Load a float number from a potentially unaligned address */
|
||||
|
||||
float
|
||||
ldfloat(p)
|
||||
register char *p;
|
||||
{
|
||||
union {
|
||||
float fval;
|
||||
int ival;
|
||||
} uval;
|
||||
register unsigned int val;
|
||||
|
||||
val = *((unsigned char *)p++);
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
val = (val << 8) + *((unsigned char *)p++);
|
||||
|
||||
uval.ival = val;
|
||||
return (uval.fval);
|
||||
}
|
||||
|
||||
/* stfloat() - Store a float number at a potentially unaligned address */
|
||||
|
||||
int
|
||||
stfloat(f, p)
|
||||
float f; /* Bug - it is passed as double */
|
||||
register char *p;
|
||||
{
|
||||
register unsigned val;
|
||||
union {
|
||||
float fval;
|
||||
int ival;
|
||||
} uval;
|
||||
|
||||
uval.fval = f; /* This fixes compiler bug */
|
||||
val = uval.ival;
|
||||
|
||||
p += LONGSIZE;
|
||||
*--p = val & 255;
|
||||
*--p = (val >> 8) & 255;
|
||||
*--p = (val >> 16) & 255;
|
||||
*--p = (val >> 24) & 255;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if sparc | mc68000 /* MRJ */
|
||||
|
||||
/* ldbld() - Load a double float number from a potentially unaligned address */
|
||||
|
||||
double
|
||||
lddbl(p)
|
||||
register char *p;
|
||||
{
|
||||
double val;
|
||||
|
||||
memcpy((void *)&val, (const void *) p, DOUBLESIZE);
|
||||
return (val);
|
||||
}
|
||||
|
||||
/* stdbl() - Store a double float number at a potentially unaligned address */
|
||||
|
||||
int
|
||||
stdbl(val, p)
|
||||
double val;
|
||||
register char *p;
|
||||
{
|
||||
memcpy ( p,(char *)&val, DOUBLESIZE);
|
||||
}
|
||||
|
||||
#else /* 386i -- do it the long way round.... */
|
||||
|
||||
/* ldbld() - Load a double float number from a potentially unaligned address */
|
||||
|
||||
double
|
||||
lddbl(p)
|
||||
register char *p;
|
||||
{
|
||||
union {
|
||||
double rval;
|
||||
char sval[DOUBLESIZE];
|
||||
} x;
|
||||
|
||||
char *q;
|
||||
int i;
|
||||
|
||||
q = x.sval;
|
||||
p += DOUBLESIZE;
|
||||
|
||||
for (i=0; i<DOUBLESIZE; i++)
|
||||
*q++ = *--p;
|
||||
return (x.rval);
|
||||
}
|
||||
|
||||
/* stdbl() - Store a double float number at a potentially unaligned address */
|
||||
|
||||
int
|
||||
stdbl(val, p)
|
||||
double val;
|
||||
register char *p;
|
||||
{
|
||||
union {
|
||||
double rval;
|
||||
char sval[DOUBLESIZE];
|
||||
} x;
|
||||
|
||||
char *q;
|
||||
int i;
|
||||
|
||||
x.rval = val;
|
||||
q = x.sval;
|
||||
p += DOUBLESIZE;
|
||||
|
||||
for (i=0; i<DOUBLESIZE; i++)
|
||||
*--p = *q++ ;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
#endif /* sparc */
|
||||
|
||||
|
||||
78
cde/lib/tt/mini_isam/isdel1key.c
Normal file
78
cde/lib/tt/mini_isam/isdel1key.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isdel1key.c /main/3 1995/10/23 11:37:24 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdel1key.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isdel1key.c
|
||||
*
|
||||
* Description:
|
||||
* Delete a key entry from index
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
void
|
||||
_del1key(fcb, pkeydesc2, record, recnum)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *pkeydesc2;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
{
|
||||
char keybuf[MAXKEYSIZE];
|
||||
Btree *btree;
|
||||
char *pkey;
|
||||
|
||||
/*
|
||||
* Special case when there is no primary key.
|
||||
*/
|
||||
if (pkeydesc2->k2_nparts == 0)
|
||||
return;
|
||||
|
||||
memset((char *)keybuf, 0,pkeydesc2->k2_len);
|
||||
_iskey_extract(pkeydesc2,record,keybuf);
|
||||
strecno(recnum, keybuf);
|
||||
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
_isbtree_search(btree, keybuf);
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
|
||||
/*
|
||||
* We must now scan all the duplicates till we found one with
|
||||
* matching recno. We are positioned just before the first duplicate.
|
||||
* Remember that the duplicates are ordered by their serial number.
|
||||
*
|
||||
* If too many duplicate entries exists, the performance will be
|
||||
* poor.
|
||||
*/
|
||||
while ((pkey = _isbtree_next(btree)) != NULL) {
|
||||
if (ldrecno(pkey + KEY_RECNO_OFF) == recnum)
|
||||
break; /* We found the entry */
|
||||
}
|
||||
|
||||
if (pkey == NULL)
|
||||
_isfatal_error("_del1key() cannot find entry in B tree");
|
||||
|
||||
_isbtree_remove(btree);
|
||||
}
|
||||
else {
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL ||
|
||||
ldrecno(pkey + KEY_RECNO_OFF) != recnum)
|
||||
_isfatal_error("_del1key() cannot find entry in B tree");
|
||||
|
||||
_isbtree_remove(btree);
|
||||
}
|
||||
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
190
cde/lib/tt/mini_isam/isdelcurr.c
Normal file
190
cde/lib/tt/mini_isam/isdelcurr.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isdelcurr.c /main/3 1995/10/23 11:37:32 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdelcurr.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isdelcurr.c
|
||||
*
|
||||
* Description:
|
||||
* Delete current record from ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amdelcurr();
|
||||
|
||||
/*
|
||||
* err = isdelcurr(isfd, record)
|
||||
*
|
||||
* Isdelcurr() modifies the current record in ISAM file.
|
||||
* All indexes of the ISAM file are updated.
|
||||
*
|
||||
* Current record position is not changed.
|
||||
* isrecnum is set to to the deleted record.
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* ELOCKED The record or file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was not opened with ISINOUT mode.
|
||||
* ENOCURR Record with record number recnum does not exist, or it
|
||||
* was deleted by another process.
|
||||
*/
|
||||
|
||||
int
|
||||
isdelcurr(isfd)
|
||||
int isfd;
|
||||
{
|
||||
int _am_delcurr();
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
int recnum;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if ((ret = _amdelcurr(&fab->isfhandle, &fab->curpos,
|
||||
&recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amdelcurr(isfhandle, curpos, recnum, errcode)
|
||||
*
|
||||
* _amdelcurr() deletes a record from ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* curpos Curent record position
|
||||
*
|
||||
* Output params:
|
||||
* recnum record number of the deleted record
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amdelcurr(isfhandle, curpos, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
Bytearray *curpos;
|
||||
Recno *recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Crp *crp;
|
||||
char recbuf[ISMAXRECLEN];
|
||||
int reclen;
|
||||
int (*rec_read)();
|
||||
int (*rec_delete)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
rec_delete = (fcb->varflag?_vlrec_delete:_flrec_delete);
|
||||
|
||||
/*
|
||||
* Get info from current record position structure.
|
||||
*/
|
||||
crp = (Crp *) curpos->data;
|
||||
|
||||
if (crp->flag != CRP_ON) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
/*
|
||||
* We must read the record first to be able to delete keys.
|
||||
*/
|
||||
if (rec_read(fcb, recbuf, crp->recno, &reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (rec_delete(fcb, crp->recno) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
*recnum = crp->recno;
|
||||
|
||||
fcb->nrecords--;
|
||||
|
||||
/*
|
||||
* Delete associated entries from all indexes.
|
||||
*/
|
||||
_delkeys(fcb, recbuf, crp->recno);
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
75
cde/lib/tt/mini_isam/isdelrec.c
Normal file
75
cde/lib/tt/mini_isam/isdelrec.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isdelrec.c /main/3 1995/10/23 11:37:39 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdelrec.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isdelrec.c
|
||||
*
|
||||
* Description:
|
||||
* Delete a record in ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* err = isdelrec(isfd, recnum)
|
||||
*
|
||||
* Isdelete() deletes a record from ISAM file. The record is identified
|
||||
* by its record number. All indexes of the ISAM file are updated.
|
||||
*
|
||||
* Current record position is not changed.
|
||||
* isrecnum is set to recnum.
|
||||
*
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* ELOCKED The file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was not opened with ISINOUT mode.
|
||||
* ENOREC Record with record number recnum does not exist.
|
||||
*/
|
||||
|
||||
int
|
||||
isdelrec(isfd, recnum)
|
||||
int isfd;
|
||||
long recnum;
|
||||
{
|
||||
int _amdelrec();
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if ((ret = _amdelrec(&fab->isfhandle, recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
507
cde/lib/tt/mini_isam/isdiskbufs2.c
Normal file
507
cde/lib/tt/mini_isam/isdiskbufs2.c
Normal file
@@ -0,0 +1,507 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isdiskbufs2.c /main/3 1995/10/23 11:37:47 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdiskbufs2.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _isdiskbufs.c
|
||||
*
|
||||
* Description:
|
||||
* ISAM disk buffer managament
|
||||
*
|
||||
*/
|
||||
|
||||
/************************ NON MAPPED I/O version ***************************/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern struct dlink *_isdln_next(), *_isdln_first();
|
||||
|
||||
#define ISMAXBUFFERS 200 /* Use 20 buffers */
|
||||
#define ISHASHHDRS 256 /* Must be a power of two */
|
||||
#define ISHASHMASK (ISHASHHDRS-1)
|
||||
|
||||
#define __hashblkno(fcb,blkno) (((int)(fcb)+(blkno)) & ISHASHMASK)
|
||||
|
||||
|
||||
#define base ((char *)0)
|
||||
#define _isdln_insert(l,e) _isdln_base_insert(base,(l),(e))
|
||||
#define _isdln_append(l,e) _isdln_base_append(base,(l),(e))
|
||||
#define _isdln_remove(e) _isdln_base_remove(base,(e))
|
||||
#define _isdln_first(l) _isdln_base_first(base,(l))
|
||||
#define _isdln_next(l) _isdln_base_next(base,(l))
|
||||
#define _isdln_prev(l) _isdln_base_prev(base,(l))
|
||||
#define _isdln_makeempty(l) _isdln_base_makeempty(base,(l))
|
||||
#define _isdln_isempty(l) _isdln_base_isempty(base,(l))
|
||||
|
||||
/*---------------------- Local data ---------------------------------------*/
|
||||
static Bufhdr *_getavail(), *_findblock();
|
||||
static void _disk_init(), _commit1buffer(), _rollback1buffer(), _flush1buffer();
|
||||
static void _makenodata();
|
||||
|
||||
Bufhdr bufhdrs [ISMAXBUFFERS];
|
||||
struct dlink hashhdrs [ISHASHHDRS]; /* Heads of hashed lists */
|
||||
|
||||
struct dlink availlist; /* Available buffer list */
|
||||
struct dlink *pavail = &availlist;
|
||||
|
||||
struct dlink changelist; /* Change buffer list */
|
||||
struct dlink *pchangl = &changelist;
|
||||
|
||||
struct dlink fixlist; /* Fixed buffer list */
|
||||
struct dlink *pfixl = &fixlist;
|
||||
|
||||
static int availn; /* Number of available buffers */
|
||||
static int minavailn; /* Minimum available buffers */
|
||||
static int maxavailn; /* Stop flushing when
|
||||
* when maxavailn buffers
|
||||
* are available */
|
||||
|
||||
|
||||
#define ISB_FIXED (ISB_RFIXED | ISB_WFIXED)
|
||||
#define MINAVAILN 40 /* in procent of total # buffers */
|
||||
#define MAXAVAILN 60 /* in procent of total # buffers */
|
||||
|
||||
|
||||
|
||||
Bufhdr *
|
||||
_isdisk_fix(fcb, unixfd, blkno, mode)
|
||||
Fcb *fcb;
|
||||
int unixfd; /* .rec, .ind., .var */
|
||||
Blkno blkno;
|
||||
int mode;
|
||||
{
|
||||
register Bufhdr *p, *p2;
|
||||
struct dlink *hashl;
|
||||
|
||||
/*
|
||||
* Initialize some local data.
|
||||
*/
|
||||
_disk_init();
|
||||
|
||||
if (fcb->datfd == unixfd)
|
||||
assert(blkno != 0); /* Never access control page */
|
||||
|
||||
hashl = (hashhdrs +__hashblkno(fcb,blkno));
|
||||
|
||||
/* Try to find the page in buffer pool. */
|
||||
if ((p = _findblock(fcb, unixfd, blkno)) == NULL) {
|
||||
|
||||
/* Page is not in the pool - install it. */
|
||||
if (mode != ISFIXNOREAD) {
|
||||
p = _getavail(); /* Get free page from pool */
|
||||
_isdln_insert(hashl,&p->isb_hash); /* Insert into hash list */
|
||||
|
||||
_isseekpg(unixfd, blkno);
|
||||
_isreadpg(unixfd, p->isb_buffer);
|
||||
|
||||
p->isb_flags = ISB_READ;
|
||||
p->isb_oldcopy = NULL;
|
||||
p->isb_fcb = fcb;
|
||||
p->isb_unixfd = unixfd;
|
||||
p->isb_blkno = blkno;
|
||||
}
|
||||
else
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p && (p->isb_flags & ISB_FIXED)==0) {
|
||||
|
||||
/* Remove buffer from pavail (or pchangl) list. */
|
||||
_isdln_remove(&p->isb_aclist);
|
||||
|
||||
|
||||
if (!(p->isb_flags & ISB_CHANGE))
|
||||
availn--;
|
||||
|
||||
}
|
||||
|
||||
if (mode == ISFIXREAD) {
|
||||
assert(p);
|
||||
|
||||
if(!(p->isb_flags & ISB_FIXED)) {
|
||||
|
||||
/* Add buffer to pfixl list. */
|
||||
_isdln_append(pfixl,&p->isb_flist);
|
||||
p->isb_flags |= ISB_RFIXED;
|
||||
|
||||
}
|
||||
return (p);
|
||||
} /* if (p) */
|
||||
else {
|
||||
|
||||
/* If buffer is already fixed for write, no other actions are necces. */
|
||||
if (p && p->isb_flags & ISB_FIXED) {
|
||||
assert((p->isb_flags & ISB_RFIXED) == 0); /* Buffer cannot be */
|
||||
/* fixed for read when is fixed */
|
||||
/* being fixed for write */
|
||||
return (p);
|
||||
}
|
||||
|
||||
/* Create shadow page */
|
||||
p2 = _getavail(); /* Get free page from pool */
|
||||
availn--;
|
||||
_isdln_remove(&p2->isb_aclist); /* Remove from pavail */
|
||||
_isdln_insert(hashl,&p2->isb_hash); /* Insert into hash list */
|
||||
_isdln_insert(pfixl,&p2->isb_flist); /* Insert into pfixl list */
|
||||
|
||||
p2->isb_fcb = fcb;
|
||||
p2->isb_unixfd = unixfd;
|
||||
p2->isb_blkno = blkno;
|
||||
p2->isb_flags = ISB_READ|ISB_WFIXED; /* Mark buffer as dirty */
|
||||
|
||||
if (mode == ISFIXWRITE) /* Copy buffer content */
|
||||
memcpy(p2->isb_buffer,p->isb_buffer,ISPAGESIZE);
|
||||
|
||||
p2->isb_oldcopy = p;
|
||||
|
||||
/* Make old copy */
|
||||
if (p) {
|
||||
assert ((p->isb_flags & ISB_FIXED) == 0);
|
||||
assert((p->isb_flags & ISB_OLDCOPY) == 0);
|
||||
|
||||
p->isb_flags |= ISB_OLDCOPY;
|
||||
_isdln_remove(&p->isb_hash);
|
||||
}
|
||||
|
||||
return (p2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_unfix (p)
|
||||
register Bufhdr *p;
|
||||
{
|
||||
if (!(p->isb_flags & ISB_FIXED))
|
||||
assert(p->isb_flags & ISB_FIXED);
|
||||
|
||||
if (p->isb_flags & ISB_WFIXED) /* Unfix at commit/abort time */
|
||||
return;
|
||||
|
||||
p->isb_flags &= ~ISB_FIXED; /* Clear bit */
|
||||
_isdln_remove(&p->isb_flist); /* Remove from pfixl */
|
||||
|
||||
/* Append to pavail or pchangl list. */
|
||||
if (p->isb_flags & ISB_CHANGE)
|
||||
_isdln_append(pchangl,&p->isb_aclist); /* Append to pchangl list */
|
||||
else {
|
||||
_isdln_append(pavail,&p->isb_aclist); /* Append to pavail list */
|
||||
availn++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_commit1 (p)
|
||||
Bufhdr *p;
|
||||
{
|
||||
_commit1buffer(p);
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_commit()
|
||||
{
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
while ((e = _isdln_first(pfixl)) != pfixl) {
|
||||
p = GETBASE(e,bufhdr,isb_flist); /* Get pointer to bufhdr */
|
||||
assert(p->isb_flags & ISB_WFIXED);
|
||||
_commit1buffer(p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_rollback()
|
||||
{
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
while ((e = _isdln_first(pfixl)) != pfixl) {
|
||||
p = GETBASE(e,bufhdr,isb_flist); /* Get pointer to bufhdr */
|
||||
assert(p->isb_flags & ISB_FIXED);
|
||||
if (p->isb_flags & ISB_WFIXED)
|
||||
_rollback1buffer(p);
|
||||
else
|
||||
_isdisk_unfix(p);
|
||||
}
|
||||
}
|
||||
|
||||
Bufhdr *
|
||||
_isdisk_refix(p, newmode)
|
||||
Bufhdr *p;
|
||||
int newmode;
|
||||
{
|
||||
Blkno blkno = p->isb_blkno;
|
||||
Fcb *fcb = p->isb_fcb;
|
||||
int unixfd = p->isb_unixfd;
|
||||
|
||||
assert(newmode == ISFIXWRITE);
|
||||
|
||||
if (p->isb_flags & ISB_RFIXED) {
|
||||
_isdisk_unfix(p);
|
||||
return (_isdisk_fix(fcb, unixfd, blkno, ISFIXWRITE));
|
||||
}
|
||||
else
|
||||
return (p);
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_sync()
|
||||
{
|
||||
extern time_t _istimeget();
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
while ((e = _isdln_first(pchangl)) != pchangl) {
|
||||
p = GETBASE(e,bufhdr,isb_aclist); /* Get pointer to bufhdr */
|
||||
assert(p->isb_flags & ISB_CHANGE);
|
||||
assert((p->isb_flags & ISB_FIXED)==0);
|
||||
_flush1buffer(p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_isdisk_inval()
|
||||
{
|
||||
extern time_t _istimeget();
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
/* ensure pavail is initialized before using it */
|
||||
|
||||
if (pavail->dln_forward == 0) {
|
||||
_isdln_makeempty(pavail);
|
||||
}
|
||||
|
||||
e = pavail;
|
||||
|
||||
while ((e = _isdln_prev(e)) != pavail) {
|
||||
p = GETBASE(e,bufhdr,isb_aclist); /* Get pointer to bufhdr */
|
||||
|
||||
if ((p->isb_flags & ISB_READ) == 0)
|
||||
break;
|
||||
|
||||
_isdln_remove(&p->isb_hash);
|
||||
p->isb_flags = ISB_NODATA; /* Mark as no data in the buffer */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ISDEBUG
|
||||
_isdisk_dumphd()
|
||||
{
|
||||
register Bufhdr *p;
|
||||
int i;
|
||||
|
||||
(void)printf("\nInd isfd blkno mode temp oldcopy\n");
|
||||
for (p = bufhdrs, i = 0; i < ISMAXBUFFERS; p++,i++)
|
||||
if (p->isb_flags != ISB_NODATA)
|
||||
(void) printf("%3d: %3d %6d %2x %3d\n",i,
|
||||
_isfd_getisfd(p->isb_pisfd),
|
||||
p->isb_blkno,p->isb_flags,
|
||||
p->isb_oldcopy?(p->isb_oldcopy - bufhdrs):-1);
|
||||
}
|
||||
|
||||
aclistdump(lh)
|
||||
struct dlink *lh;
|
||||
{
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
for (e = _isdln_first(lh); e != lh; e = _isdln_next(e)) {
|
||||
p = GETBASE(e,bufhdr,isb_aclist); /* Get pointer to bufhdr */
|
||||
(void) printf("%3d: %3d %6d %2x %3d\n",p-bufhdrs,
|
||||
_isfd_getisfd(p->isb_pisfd),
|
||||
p->isb_blkno,p->isb_flags,
|
||||
p->isb_oldcopy?(p->isb_oldcopy - bufhdrs):-1);
|
||||
}
|
||||
}
|
||||
|
||||
flistdump(lh)
|
||||
struct dlink *lh;
|
||||
{
|
||||
register Bufhdr *p;
|
||||
struct dlink *e;
|
||||
|
||||
for (e = _isdln_first(lh); e != lh; e = _isdln_next(e)) {
|
||||
p = GETBASE(e,bufhdr,isb_flist); /* Get pointer to bufhdr */
|
||||
(void) printf("%3d: %3d %6d %2x %3d\n",p-bufhdrs,
|
||||
_isfd_getisfd(p->isb_pisfd),
|
||||
p->isb_blkno,p->isb_flags,
|
||||
p->isb_oldcopy?(p->isb_oldcopy - bufhdrs):-1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------ Local functions ---------------------------------*/
|
||||
|
||||
Static void
|
||||
_disk_init()
|
||||
{
|
||||
static Bool initialized = FALSE;
|
||||
register int i;
|
||||
|
||||
if (initialized == TRUE)
|
||||
return;
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
/* Initialize hash queue list heads. */
|
||||
for (i = 0; i < ISHASHHDRS; i++) {
|
||||
_isdln_makeempty(hashhdrs+i);
|
||||
}
|
||||
|
||||
/* initialize pavail, pchangel, and pfixl lists to empty. */
|
||||
|
||||
_isdln_makeempty(pavail);
|
||||
_isdln_makeempty(pchangl);
|
||||
_isdln_makeempty(pfixl);
|
||||
|
||||
/* Link all buffers into pavail list. */
|
||||
for (i = 0; i < ISMAXBUFFERS; i++) {
|
||||
bufhdrs[i].isb_buffer = _ismalloc(ISPAGESIZE);
|
||||
_isdln_append(pavail,&bufhdrs[i].isb_aclist);
|
||||
availn++;
|
||||
}
|
||||
|
||||
/* Set maxavailn and minavailn. */
|
||||
minavailn = (ISMAXBUFFERS * MINAVAILN) / 100;
|
||||
maxavailn = (ISMAXBUFFERS * MAXAVAILN) / 100;
|
||||
}
|
||||
|
||||
/* _getavail() - get available buffer in disk */
|
||||
Static Bufhdr *
|
||||
_getavail()
|
||||
{
|
||||
register Bufhdr *p;
|
||||
register struct dlink *q;
|
||||
|
||||
if ((q = _isdln_first(pavail)) == pavail) {
|
||||
_isfatal_error("No buffer in pool available");
|
||||
}
|
||||
|
||||
p = GETBASE(q,bufhdr,isb_aclist);
|
||||
|
||||
if (p->isb_flags & ISB_READ) { /* Remove from hash queue */
|
||||
_isdln_remove(&p->isb_hash);
|
||||
p->isb_flags = ISB_NODATA; /* Mark as no data in the buffer */
|
||||
}
|
||||
|
||||
return ((Bufhdr *) p);
|
||||
}
|
||||
|
||||
/* _findblock() - Find block in buffer pool */
|
||||
Static Bufhdr *
|
||||
_findblock(fcb, unixfd, blkno)
|
||||
Fcb *fcb;
|
||||
int unixfd;
|
||||
Blkno blkno;
|
||||
{
|
||||
register Bufhdr *p;
|
||||
struct dlink *lh, *e;
|
||||
int hashval;
|
||||
|
||||
hashval = __hashblkno(fcb,blkno);
|
||||
|
||||
lh = hashhdrs + hashval; /* lh is list head */
|
||||
for (e = _isdln_first(lh); e != lh; e = _isdln_next(e)) {
|
||||
p = GETBASE(e,bufhdr,isb_hash); /* Get pointer to bufhdr */
|
||||
if (p->isb_blkno == blkno && p->isb_fcb == fcb && p->isb_unixfd == unixfd) {
|
||||
assert(p->isb_flags != ISB_NODATA);
|
||||
return(p);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* _commit1buffer() - Commit changes to buffer */
|
||||
Static void
|
||||
_commit1buffer(p)
|
||||
register Bufhdr *p;
|
||||
{
|
||||
assert(p->isb_flags & ISB_WFIXED); /* Fixed for read buffers should */
|
||||
/* go through _isdisk_unfix() */
|
||||
|
||||
/* Free old permanent buffer if any exists. */
|
||||
if (p->isb_oldcopy) {
|
||||
_makenodata(p->isb_oldcopy); /* Make this buffer available */
|
||||
}
|
||||
|
||||
/* Remove buffer from list of fixed buffers. */
|
||||
/* Append buffer to list of changed buffers. */
|
||||
_isdln_remove(&p->isb_flist);
|
||||
_isdln_append(pchangl,&p->isb_aclist);
|
||||
p->isb_flags &= ~ISB_FIXED;
|
||||
p->isb_flags |= ISB_CHANGE;
|
||||
}
|
||||
|
||||
/* _rollback1buffer() - Rollback changes to buffer */
|
||||
Static void
|
||||
_rollback1buffer(p)
|
||||
register Bufhdr *p;
|
||||
{
|
||||
register Bufhdr *p2;
|
||||
|
||||
assert(p->isb_flags & ISB_WFIXED); /* Fixed for read buffers should */
|
||||
/* go through _isdisk_unfix() */
|
||||
|
||||
/* Re-install old copy if that exists. */
|
||||
if ((p2 = p->isb_oldcopy) != NULL) {
|
||||
if (p2->isb_flags & ISB_CHANGE) {
|
||||
_isdln_append(pchangl,&p2->isb_aclist);
|
||||
}
|
||||
else {
|
||||
_isdln_append(pavail,&p2->isb_aclist);
|
||||
availn++;
|
||||
}
|
||||
p2->isb_flags &= ~ISB_OLDCOPY; /* Clear bit */
|
||||
|
||||
/* See implementation of _isdln_append() that this will work. */
|
||||
_isdln_append(&p->isb_hash,&p2->isb_hash); /* Insert into hash list */
|
||||
}
|
||||
|
||||
|
||||
_isdln_remove(&p->isb_hash); /* Remove bufer from hash list */
|
||||
_isdln_remove(&p->isb_flist); /* Remove bufer from pfixl */
|
||||
_makenodata(p); /* Make this buffer available */
|
||||
}
|
||||
|
||||
/* _makenodata() - make buffer available with no data in it*/
|
||||
Static void
|
||||
_makenodata(p)
|
||||
register Bufhdr *p;
|
||||
{
|
||||
assert(p->isb_flags & ISB_READ);
|
||||
|
||||
p->isb_flags = ISB_NODATA;
|
||||
_isdln_insert(pavail,&p->isb_aclist);
|
||||
availn++;
|
||||
}
|
||||
|
||||
/* _flush1buffer() - flush buffer to disk */
|
||||
Static void
|
||||
_flush1buffer(p)
|
||||
register Bufhdr *p;
|
||||
{
|
||||
assert(p->isb_flags & ISB_CHANGE);
|
||||
|
||||
_isseekpg(p->isb_unixfd, p->isb_blkno);
|
||||
_iswritepg(p->isb_unixfd, p->isb_buffer);
|
||||
|
||||
p->isb_flags &= ~ISB_CHANGE; /* clear change flag */
|
||||
|
||||
_isdln_remove(&p->isb_aclist); /* Remove from pchangl */
|
||||
_isdln_append(pavail,&p->isb_aclist); /* Append to pavail */
|
||||
availn++;
|
||||
}
|
||||
103
cde/lib/tt/mini_isam/isdlink.c
Normal file
103
cde/lib/tt/mini_isam/isdlink.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: isdlink.c /main/4 1999/09/29 15:03:15 mgreess $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isdlink.c 1.4 89/09/01 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isdlink.c
|
||||
*
|
||||
* Description:
|
||||
* Double link list functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
/* _isdln_base_insert () - Insert element into list (at the front) -----------*/
|
||||
void _isdln_base_insert (base,l,e)
|
||||
register char *base;
|
||||
register struct dlink *l,*e;
|
||||
{
|
||||
e->dln_forward = l->dln_forward;
|
||||
l->dln_forward = (char *)e - base;
|
||||
|
||||
e->dln_backward = (char *)l - base;
|
||||
((struct dlink *)(base + e->dln_forward))->dln_backward = (char *)e - base;
|
||||
}
|
||||
|
||||
/* _isdln_base_append () - Append element to list (at the end) -------------*/
|
||||
void _isdln_base_append (base,l,e)
|
||||
register char *base;
|
||||
register struct dlink *l,*e;
|
||||
{
|
||||
e->dln_backward = l->dln_backward;
|
||||
l->dln_backward = (char *)e - base;
|
||||
|
||||
e->dln_forward = (char *)l - base;
|
||||
((struct dlink *)(base + e->dln_backward))->dln_forward = (char *)e - base;
|
||||
}
|
||||
|
||||
/* _isdln_base_remove () - Remove element from list -------------------------*/
|
||||
void _isdln_base_remove (base,e)
|
||||
register char *base;
|
||||
register struct dlink *e;
|
||||
{
|
||||
((struct dlink *)(base + e->dln_backward))->dln_forward = e->dln_forward;
|
||||
((struct dlink *)(base + e->dln_forward))->dln_backward = e->dln_backward;
|
||||
}
|
||||
|
||||
/* _isdln_base_first () - Return first element of the list -------------------*/
|
||||
struct dlink * _isdln_base_first(base,l)
|
||||
register char *base;
|
||||
register struct dlink *l;
|
||||
{
|
||||
struct dlink *val = (struct dlink *)(base + l->dln_forward);
|
||||
|
||||
if (val == NULL) {
|
||||
if (NULL == (struct dlink *)(base + l->dln_forward) &&
|
||||
NULL == (struct dlink *)(base + l->dln_backward))
|
||||
_isdln_base_makeempty(base, l);
|
||||
val = l;
|
||||
}
|
||||
return(val);
|
||||
}
|
||||
|
||||
/* _isdln_base_next () - Return next element in the list --------------------*/
|
||||
struct dlink * _isdln_base_next(base,l)
|
||||
register char *base;
|
||||
register struct dlink *l;
|
||||
{
|
||||
return (((struct dlink *)(base + l->dln_forward)));
|
||||
}
|
||||
|
||||
/* _isdln_base_prev () - Return previous element in the list ----------------*/
|
||||
struct dlink * _isdln_base_prev(base,l)
|
||||
register char *base;
|
||||
register struct dlink *l;
|
||||
{
|
||||
return (((struct dlink *)(base + l->dln_backward)));
|
||||
}
|
||||
|
||||
/* _isdln_base_makeempty () - Make head of empty list -----------------------*/
|
||||
void _isdln_base_makeempty(base,l)
|
||||
register char *base;
|
||||
register struct dlink *l;
|
||||
{
|
||||
l->dln_forward = l->dln_backward = (char *)l - base;
|
||||
}
|
||||
|
||||
/* _isdln_base_isempty () - Test if list is empty---------------------------*/
|
||||
int _isdln_base_isempty(base,l)
|
||||
register char *base;
|
||||
register struct dlink *l;
|
||||
{
|
||||
return (l->dln_forward == (char *)l - base &&
|
||||
l->dln_backward == (char *)l - base);
|
||||
}
|
||||
170
cde/lib/tt/mini_isam/iserase.c
Normal file
170
cde/lib/tt/mini_isam/iserase.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iserase.c /main/3 1995/10/23 11:38:08 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iserase.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iserase.c
|
||||
*
|
||||
* Description:
|
||||
* Erase an ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static void _unlink_datfile(), _unlink_indfile(), _unlink_varfile();
|
||||
static int _amerase();
|
||||
|
||||
/*
|
||||
* isfd = iserase(isfname, mode)
|
||||
*
|
||||
*
|
||||
* Errors:
|
||||
* EBADFILE ISAM file is corrupted or it is not an NetISAM file
|
||||
* EFLOCKED The file is exclusively locked by other process.
|
||||
* EFNAME Invalid ISAM file name
|
||||
* EFNAME ISAM file does not exist
|
||||
* ETOOMANY Too many ISAM file descriptors are in use (128 is the limit)
|
||||
*
|
||||
* The following error code is "borrowed" from UNIX:
|
||||
* EACCES UNIX file system protection denies access to the file:
|
||||
* - mode is INOUT or OUTPUT and ISAM file is on
|
||||
* a Read-Only mounted file system
|
||||
* - UNIX file permissions don't allow access to the file
|
||||
*/
|
||||
|
||||
int
|
||||
iserase(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
Isfd isfd, isfd_nfs;
|
||||
Fab *fab, *fab_nfs;
|
||||
|
||||
/*
|
||||
* Open the file
|
||||
*/
|
||||
if ((isfd = isopen(isfname, ISINOUT)) == -1)
|
||||
return (ISERROR); /* iserrno is set */
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_isfatal_error("iserase() cannot find FAB");
|
||||
_setiserrno2(EFATAL, '9', '0');
|
||||
return ISERROR;
|
||||
}
|
||||
|
||||
if (_amerase(&fab->isfhandle, &fab->errcode)
|
||||
&& fab->errcode.iserrno != ENOENT) {
|
||||
_seterr_errcode(&fab->errcode);
|
||||
(void)isclose(isfd);
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_fab_destroy(fab); /* Deallocate Fab object */
|
||||
_isfd_delete(isfd);
|
||||
|
||||
return (ISOK); /* Successful iserase() */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amerase(isfhandle)
|
||||
*
|
||||
* _amerase() erases ISAM file
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
*
|
||||
* Output params:
|
||||
* errcode Error code
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amerase(isfhandle, errcode)
|
||||
Bytearray *isfhandle;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
char *isfname = _getisfname(isfhandle);
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete FCB and remove it from FCB cache.
|
||||
*/
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle);
|
||||
|
||||
/*
|
||||
* Unlink all UNIX files.
|
||||
*/
|
||||
_unlink_datfile(isfname);
|
||||
_unlink_indfile(isfname);
|
||||
_unlink_varfile(isfname);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
Static void
|
||||
_unlink_datfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makedat_isfname(namebuf);
|
||||
|
||||
(void)unlink(namebuf);
|
||||
}
|
||||
|
||||
|
||||
Static void
|
||||
_unlink_indfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
|
||||
(void)unlink(namebuf);
|
||||
}
|
||||
|
||||
|
||||
Static void
|
||||
_unlink_varfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makevar_isfname(namebuf);
|
||||
|
||||
(void)unlink(namebuf);
|
||||
}
|
||||
140
cde/lib/tt/mini_isam/iserror.c
Normal file
140
cde/lib/tt/mini_isam/iserror.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iserror.c /main/3 1995/10/23 11:38:16 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iserror.c 1.10 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iserror.c
|
||||
*
|
||||
* Description:
|
||||
* NetISAM error handling functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#ifdef __ultrix__
|
||||
#define LOG_USER LOG_INFO
|
||||
#endif
|
||||
/*
|
||||
* _isfatal_error(msg)
|
||||
*
|
||||
* Fatal error. Display message and terminate program.
|
||||
*/
|
||||
|
||||
static int (*fatal_error_user_handler)(); /* set by iscntl(..,ISCNTL_FATAL,..) */
|
||||
|
||||
void
|
||||
_isfatal_error(msg)
|
||||
char *msg;
|
||||
{
|
||||
int logerr;
|
||||
|
||||
if (fatal_error_user_handler) {
|
||||
logerr = fatal_error_user_handler(msg); /* User returns 1 in order
|
||||
* to use syslog()
|
||||
*/
|
||||
}
|
||||
else
|
||||
logerr = 1;
|
||||
|
||||
if (logerr) {
|
||||
openlog("NetISAM", LOG_PID, LOG_USER);
|
||||
|
||||
/* Free one UNIX for syslog */
|
||||
(void)close(0);
|
||||
|
||||
syslog(LOG_ERR, "Fatal error: %s - UNIX errno %d", msg, errno);
|
||||
|
||||
closelog();
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void
|
||||
_isfatal_error1(msg)
|
||||
char *msg;
|
||||
{
|
||||
extern int _is_rpcnetisamd; /* is 1 if this is rpc.netisamd */
|
||||
extern int _is_netisamlockd; /* is 1 if this is netisamlockd */
|
||||
int logerr;
|
||||
|
||||
if (fatal_error_user_handler) {
|
||||
logerr = fatal_error_user_handler(msg); /* User returns 1 in order
|
||||
* to use syslog()
|
||||
*/
|
||||
}
|
||||
else
|
||||
logerr = 1;
|
||||
|
||||
if (logerr) {
|
||||
openlog("NetISAM", LOG_PID, LOG_USER);
|
||||
|
||||
/* Free one UNIX for syslog */
|
||||
(void)close(0);
|
||||
|
||||
syslog(LOG_ERR, "Fatal error: %s - UNIX errno %d", msg, errno);
|
||||
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
|
||||
_isam_warning(msg)
|
||||
char *msg;
|
||||
{
|
||||
openlog("NetISAM", LOG_PID, LOG_USER);
|
||||
syslog(LOG_ERR, msg);
|
||||
}
|
||||
|
||||
/* Set user specified fatal_error handler */
|
||||
int (*_isfatal_error_set_func(func))()
|
||||
int (*func)();
|
||||
{
|
||||
int (*oldfunc)();
|
||||
|
||||
oldfunc = fatal_error_user_handler;
|
||||
fatal_error_user_handler = func;
|
||||
|
||||
return (oldfunc);
|
||||
}
|
||||
|
||||
/*
|
||||
* _setiserrno2(error, isstat1, isstat2)
|
||||
*
|
||||
* Set iserrno variable.
|
||||
*/
|
||||
|
||||
void
|
||||
_setiserrno2(error, is1, is2)
|
||||
int error;
|
||||
int is1, is2;
|
||||
{
|
||||
iserrno = error;
|
||||
isstat1 = is1;
|
||||
isstat2 = is2;
|
||||
}
|
||||
|
||||
/*
|
||||
* _seterr_errcode(errcode)
|
||||
*
|
||||
* Set all error and status variable from errcode structure.
|
||||
*/
|
||||
|
||||
void
|
||||
_seterr_errcode(errcode)
|
||||
register struct errcode *errcode;
|
||||
{
|
||||
iserrno = errcode->iserrno;
|
||||
isstat1 = errcode->isstat[0];
|
||||
isstat2 = errcode->isstat[1];
|
||||
isstat3 = errcode->isstat[2];
|
||||
isstat4 = errcode->isstat[3];
|
||||
}
|
||||
80
cde/lib/tt/mini_isam/isfab.c
Normal file
80
cde/lib/tt/mini_isam/isfab.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfab.c /main/3 1995/10/23 11:38:24 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfab.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfab.c
|
||||
*
|
||||
* Description:
|
||||
* The ISAM file access block functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
/*
|
||||
* fab = *fab_new(isfname, mode, varlen, minreclen, maxreclen)
|
||||
*
|
||||
* Fab_new() creates an File access block (fab object) that is used
|
||||
* for all subsequent operations in this file. Return a pointer to
|
||||
* the fab object, or NULL in the case of an error.
|
||||
*/
|
||||
|
||||
Fab *
|
||||
_fab_new(isfname, openmode,
|
||||
varlen, minreclen, maxreclen)
|
||||
char *isfname; /* Local path on the host */
|
||||
enum openmode openmode;
|
||||
Bool varlen; /* 0/1 flag */
|
||||
int minreclen, maxreclen;
|
||||
{
|
||||
register Fab *fab;
|
||||
|
||||
/* Allocate memory for the fab object. */
|
||||
fab = (Fab *) _ismalloc(sizeof(*fab));
|
||||
memset((char *)fab, 0, sizeof(*fab));
|
||||
|
||||
if (fab == NULL) {
|
||||
iserrno = EFATAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Set fields in the fab objects. */
|
||||
fab->openmode = openmode;
|
||||
fab->varlength = varlen;
|
||||
fab->minreclen = minreclen;
|
||||
fab->maxreclen = maxreclen;
|
||||
fab->isfname = _isallocstring(isfname);
|
||||
|
||||
if (fab->isfname == NULL) {
|
||||
free((char *)fab);
|
||||
iserrno = EFATAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (fab);
|
||||
}
|
||||
|
||||
void
|
||||
_fab_destroy(fab)
|
||||
register Fab *fab;
|
||||
{
|
||||
assert(fab != NULL);
|
||||
assert(fab->isfname != NULL);
|
||||
|
||||
_isfreestring(fab->isfname);
|
||||
|
||||
_bytearr_free(&fab->isfhandle);
|
||||
_bytearr_free(&fab->curpos);
|
||||
|
||||
free((char *)fab);
|
||||
}
|
||||
873
cde/lib/tt/mini_isam/isfcb.c
Normal file
873
cde/lib/tt/mini_isam/isfcb.c
Normal file
@@ -0,0 +1,873 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfcb.c /main/3 1995/10/23 11:38:34 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfcb.c 1.9 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfcb.c
|
||||
*
|
||||
* Description: _ambuild()
|
||||
* File Control Block functions
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
static int _create_datfile(), _create_indfile(), _create_varfile();
|
||||
static void _remove_datfile(), _remove_indfile(), _remove_varfile();
|
||||
Static int _open_datfile(), _open_indfile(), _open_varfile();
|
||||
|
||||
/*
|
||||
* _isfcb_create(isfname, crdat, crind, crvar, owner, group, u_mask, errcode)
|
||||
*
|
||||
* Create ISAM file: create UNIX files (dat/ind/var),
|
||||
* and initialize File Control Block.
|
||||
*
|
||||
* Return 0 if create is successful, or -1 if any error. In the case of
|
||||
*an error, the errcode block is set.
|
||||
*/
|
||||
|
||||
Fcb *
|
||||
_isfcb_create(isfname, crdat, crind, crvar, owner, group, u_mask, errcode)
|
||||
char *isfname;
|
||||
int crdat, crind, crvar; /* 0/1 flags */
|
||||
int owner, group;
|
||||
struct errcode *errcode;
|
||||
int u_mask;
|
||||
{
|
||||
register Fcb *fcb;
|
||||
int dat_fd = -1;
|
||||
int ind_fd = -1;
|
||||
int var_fd = -1;
|
||||
int oldumask = umask (u_mask); /* Change umask to client's */
|
||||
|
||||
/*
|
||||
* Create the UNIX file for .rec file.
|
||||
*/
|
||||
if (crdat && (dat_fd = _create_datfile (isfname)) == -1) {
|
||||
_amseterrcode(errcode, errno);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a primary is specified, create .ind file.
|
||||
*/
|
||||
if (crind && (ind_fd = _create_indfile (isfname)) == -1) {
|
||||
_amseterrcode(errcode, errno);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the ISAM file is for variable length records, create .var file.
|
||||
*/
|
||||
if (crvar && (var_fd = _create_varfile (isfname)) == -1) {
|
||||
_amseterrcode(errcode, errno);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change user and group onwer ship of the file.
|
||||
* This has affect only when executed by the netisamd daemon.
|
||||
*/
|
||||
if (dat_fd != -1)
|
||||
(void) fchown(dat_fd, owner, group);
|
||||
if (ind_fd != -1)
|
||||
(void) fchown(ind_fd, owner, group);
|
||||
if (var_fd != -1)
|
||||
(void) fchown(var_fd, owner, group);
|
||||
|
||||
/*
|
||||
* Allocate File Control Block.
|
||||
*/
|
||||
fcb = (Fcb *) _ismalloc(sizeof(*fcb));
|
||||
memset ((char *) fcb, 0, sizeof(*fcb));
|
||||
|
||||
fcb->isfname = _isallocstring(isfname);
|
||||
fcb->rdonly = FALSE;
|
||||
fcb->datfd = dat_fd;
|
||||
fcb->indfd = ind_fd;
|
||||
fcb->varfd = var_fd;
|
||||
|
||||
fcb->datsize = N_CNTL_PAGES; /* Control Pages */
|
||||
fcb->indfreelist = FREELIST_NOPAGE;
|
||||
|
||||
/* Key descriptor */
|
||||
fcb->nkeys = 1;
|
||||
fcb->keys = (Keydesc2 *) _ismalloc(sizeof(fcb->keys[0]));
|
||||
memset((char *)fcb->keys, 0, sizeof(fcb->keys[0]));
|
||||
|
||||
return (fcb);
|
||||
|
||||
ERROR:
|
||||
/* Undo whatever was done. */
|
||||
if (dat_fd != -1) {
|
||||
(void) close(dat_fd);
|
||||
_remove_datfile(isfname);
|
||||
}
|
||||
if (ind_fd != -1) {
|
||||
(void) close(ind_fd);
|
||||
_remove_indfile(isfname);
|
||||
}
|
||||
if (var_fd != -1) {
|
||||
(void) close(var_fd);
|
||||
_remove_varfile(isfname);
|
||||
}
|
||||
|
||||
(void) umask(oldumask);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_setlength(fcb, varflag, minreclen, maxreclen)
|
||||
*
|
||||
* Set FCB attributes pertaining to record length.
|
||||
*/
|
||||
|
||||
void
|
||||
_isfcb_setreclength(fcb, varflag, minreclen, maxreclen)
|
||||
register Fcb *fcb;
|
||||
Bool varflag;
|
||||
int minreclen, maxreclen;
|
||||
{
|
||||
fcb->varflag = varflag;
|
||||
fcb->minreclen = minreclen;
|
||||
fcb->maxreclen = maxreclen;
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_open(isfname, errcode)
|
||||
*
|
||||
* Open ISAM file: open UNIX files and create File Control Block.
|
||||
*
|
||||
* Return 0 if open is successful, or -1 if any error. In the case of an error,
|
||||
* the errcode block is set.
|
||||
*
|
||||
* Note that rdonly is not fuly implemented. Now, all ISAM files are assumed
|
||||
* to have permissions set to 0666 and may be opened in RW mode.
|
||||
* If read-only media are used then the _open_datfile() function would have to
|
||||
* try first to open the file in RW mode, and of that failed, try to
|
||||
* open it in RO mode. The rdonly flag is used to reject any isamopen() with
|
||||
* INOUT or OUTPUT mode on such files.
|
||||
*/
|
||||
|
||||
Fcb *
|
||||
_isfcb_open(isfname, errcode)
|
||||
char *isfname;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
register Fcb *fcb;
|
||||
int dat_fd = -1;
|
||||
int ind_fd = -1;
|
||||
int var_fd = -1;
|
||||
Bool rdonly; /* set to 1 if file is Read-Only */
|
||||
|
||||
/*
|
||||
* Open the UNIX file for .rec file.
|
||||
*/
|
||||
if ((dat_fd = _open_datfile (isfname, &rdonly)) == -1 || errno == EMFILE) {
|
||||
_amseterrcode(errcode, errno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open .ind file.
|
||||
*/
|
||||
ind_fd = _open_indfile (isfname, rdonly);
|
||||
|
||||
/*
|
||||
* Open .var file.
|
||||
*/
|
||||
var_fd = _open_varfile (isfname, rdonly);
|
||||
|
||||
|
||||
/*
|
||||
* Allocate File Control Block.
|
||||
*/
|
||||
fcb = (Fcb *) _ismalloc(sizeof(*fcb));
|
||||
memset ((char *) fcb, 0, sizeof(*fcb));
|
||||
|
||||
fcb->isfname = _isallocstring(isfname);
|
||||
fcb->rdonly = rdonly;
|
||||
fcb->datfd = dat_fd;
|
||||
fcb->indfd = ind_fd;
|
||||
fcb->varfd = var_fd;
|
||||
|
||||
/* Key descriptor */
|
||||
fcb->nkeys = 1;
|
||||
fcb->keys = (Keydesc2 *) _ismalloc(sizeof(fcb->keys[0]));
|
||||
memset((char *)fcb->keys, 0, sizeof(fcb->keys[0]));
|
||||
|
||||
return (fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_nfds(fcb)
|
||||
*
|
||||
* Return the number of UNIX fd consumed by the fcb block.
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_nfds(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
register int count = 0;
|
||||
|
||||
if (fcb->datfd != -1)
|
||||
count++;
|
||||
|
||||
if (fcb->indfd != -1)
|
||||
count++;
|
||||
|
||||
if (fcb->varfd != -1)
|
||||
count++;
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isfcb_remove(fcb)
|
||||
*
|
||||
* Remove UNIX files associated with an FCB.
|
||||
*/
|
||||
|
||||
void
|
||||
_isfcb_remove(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
if (fcb->datfd)
|
||||
_remove_datfile(fcb->isfname);
|
||||
|
||||
if (fcb->indfd)
|
||||
_remove_indfile(fcb->isfname);
|
||||
|
||||
if (fcb->varfd)
|
||||
_remove_varfile(fcb->isfname);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_close(fcb)
|
||||
*
|
||||
* Close UNIX files associated with an FCB, deallocate the FCB block.
|
||||
*/
|
||||
|
||||
void
|
||||
_isfcb_close(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
assert (fcb != NULL);
|
||||
assert (fcb->isfname != NULL);
|
||||
|
||||
(void) close(fcb->datfd);
|
||||
(void) close(fcb->indfd);
|
||||
(void) close(fcb->varfd);
|
||||
|
||||
_isfreestring(fcb->isfname);
|
||||
free((char *)fcb->keys);
|
||||
free((char *)fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_cntlpg_w(fcb)
|
||||
*
|
||||
* Write information from the control block to the disk.
|
||||
* Note that the Control Page transfer bypasses the disk buffer manager.
|
||||
*
|
||||
* Return 0 if write was successful, return -1 if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_cntlpg_w(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
char cntl_page[ISCNTLSIZE];
|
||||
int dat_fd = fcb->datfd;
|
||||
int i;
|
||||
|
||||
/* Clear the page. */
|
||||
memset (cntl_page, 0, sizeof(cntl_page));
|
||||
|
||||
/* Set Magic number. */
|
||||
(void)strcpy(cntl_page + CP_MAGIC_OFF, ISMAGIC);
|
||||
|
||||
/* Set Block size */
|
||||
stshort(ISPAGESIZE, cntl_page + CP_BLOCKSIZE_OFF);
|
||||
|
||||
/* Set NetISAM version stamp. */
|
||||
(void)strcpy(cntl_page + CP_VERSION_OFF, ISVERSION);
|
||||
|
||||
/* .rec file size in blocks. */
|
||||
stlong((long)fcb->datsize, cntl_page + CP_DATSIZE_OFF);
|
||||
|
||||
/* .ind file size in blocks. */
|
||||
stlong((long)fcb->indsize, cntl_page + CP_INDSIZE_OFF);
|
||||
|
||||
/* .var file size in blocks. */
|
||||
stlong((long)fcb->varsize, cntl_page + CP_VARSIZE_OFF);
|
||||
|
||||
/* Variable length 0/1 flag. */
|
||||
stshort((short)fcb->varflag, cntl_page + CP_VARFLAG_OFF);
|
||||
|
||||
/* Number of records. */
|
||||
stlong((long)fcb->nrecords, cntl_page + CP_NRECORDS_OFF);
|
||||
|
||||
/* Minimum and maximum record length. */
|
||||
stshort((short)fcb->minreclen, cntl_page + CP_MINRECLEN_OFF);
|
||||
stshort((short)fcb->maxreclen, cntl_page + CP_MAXRECLEN_OFF);
|
||||
|
||||
/* Last record number. */
|
||||
strecno(fcb->lastrecno, cntl_page + CP_LASTRECNO_OFF);
|
||||
|
||||
/* Free record number. */
|
||||
strecno(fcb->freerecno, cntl_page + CP_FREERECNO_OFF);
|
||||
|
||||
/* Number of keys */
|
||||
stshort((short)fcb->nkeys, cntl_page + CP_NKEYS_OFF);
|
||||
|
||||
/* Last key id */
|
||||
stlong((long)fcb->lastkeyid, cntl_page + CP_LASTKEYID_OFF);
|
||||
|
||||
/* ind. free list head */
|
||||
stlong((long)fcb->indfreelist, cntl_page + CP_INDFREELIST_OFF);
|
||||
|
||||
/* offset of the end of .var file */
|
||||
stlong((long)fcb->varend, cntl_page + CP_VAREND_OFF);
|
||||
|
||||
/* Key descriptors. */
|
||||
for (i = 0; i < fcb->nkeys; i++) {
|
||||
stkey(fcb->keys + i, cntl_page + CP_KEYS_OFF + i * K2_LEN);
|
||||
}
|
||||
|
||||
/* Increment stamp1 and stamp2 to indicate change in the Control Page. */
|
||||
fcb->changestamp1++;
|
||||
fcb->changestamp2++;
|
||||
|
||||
stlong((long)fcb->changestamp1, cntl_page + CP_CHANGESTAMP1_OFF);
|
||||
stlong((long)fcb->changestamp2, cntl_page + CP_CHANGESTAMP2_OFF);
|
||||
|
||||
/*
|
||||
* Write the buffer to the disk.
|
||||
*/
|
||||
_isseekpg(dat_fd, ISCNTLPGOFF);
|
||||
_iswritepg(dat_fd, cntl_page);
|
||||
_iswritepg(dat_fd, cntl_page + ISPAGESIZE);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_cntlpg_w2(fcb)
|
||||
*
|
||||
* Write information from the control block to the disk.
|
||||
* Write only selected fields of the control block to avoid the overhead
|
||||
* of coding and decoding.
|
||||
* Note that the Control Page transfer bypasses the disk buffer manager.
|
||||
*
|
||||
* Return 0 if write was successful, return -1 if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_cntlpg_w2(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
char cntl_page[CP_VAREND_OFF+CP_VAREND_LEN];
|
||||
int dat_fd = fcb->datfd;
|
||||
|
||||
/*
|
||||
* Read the page from disk.
|
||||
*/
|
||||
_isseekpg(dat_fd, ISCNTLPGOFF);
|
||||
(void)read(dat_fd, cntl_page, sizeof(cntl_page));
|
||||
|
||||
/* .rec file size in blocks. */
|
||||
stlong((long)fcb->datsize, cntl_page + CP_DATSIZE_OFF);
|
||||
|
||||
/* .ind file size in blocks. */
|
||||
stlong((long)fcb->indsize, cntl_page + CP_INDSIZE_OFF);
|
||||
|
||||
/* .var file size in blocks. */
|
||||
stlong((long)fcb->varsize, cntl_page + CP_VARSIZE_OFF);
|
||||
|
||||
/* Number of records. */
|
||||
stlong((long)fcb->nrecords, cntl_page + CP_NRECORDS_OFF);
|
||||
|
||||
/* Last record number. */
|
||||
strecno(fcb->lastrecno, cntl_page + CP_LASTRECNO_OFF);
|
||||
|
||||
/* Free record number. */
|
||||
strecno(fcb->freerecno, cntl_page + CP_FREERECNO_OFF);
|
||||
|
||||
/* ind. free list head */
|
||||
stlong((long)fcb->indfreelist, cntl_page + CP_INDFREELIST_OFF);
|
||||
|
||||
/* end of .var file */
|
||||
stlong((long)fcb->varend, cntl_page + CP_VAREND_OFF);
|
||||
|
||||
/* Increment stamp2 to indicate change in the Control Page. */
|
||||
fcb->changestamp2++;
|
||||
stlong((long)fcb->changestamp2, cntl_page + CP_CHANGESTAMP2_OFF);
|
||||
|
||||
|
||||
/*
|
||||
* Write the buffer to the disk.
|
||||
*/
|
||||
_isseekpg(dat_fd, ISCNTLPGOFF);
|
||||
(void)write(dat_fd, cntl_page, sizeof(cntl_page));
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_cntlpg_r(fcb)
|
||||
*
|
||||
* Read information from control page and store it in the FCB.
|
||||
* Note that the Control Page transfer bypasses the disk buffer manager.
|
||||
*
|
||||
* Return 0 if read was successful, return -1 if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_cntlpg_r(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
char cntl_page[ISCNTLSIZE];
|
||||
int dat_fd = fcb->datfd;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Read the page from the disk.
|
||||
*/
|
||||
_isseekpg(dat_fd, ISCNTLPGOFF);
|
||||
_isreadpg(dat_fd, cntl_page);
|
||||
_isreadpg(dat_fd, cntl_page + ISPAGESIZE);
|
||||
|
||||
/* block size */
|
||||
fcb->blocksize = ldshort(cntl_page + CP_BLOCKSIZE_OFF);
|
||||
|
||||
/* .rec file size in blocks. */
|
||||
fcb->datsize = ldlong(cntl_page + CP_DATSIZE_OFF);
|
||||
|
||||
/* .ind file size in blocks. */
|
||||
fcb->indsize = ldlong(cntl_page + CP_INDSIZE_OFF);
|
||||
|
||||
/* .var file size in blocks. */
|
||||
fcb->varsize = ldlong(cntl_page + CP_VARSIZE_OFF);
|
||||
|
||||
/* Variable length 0/1 flag. */
|
||||
fcb->varflag = (Bool)ldshort(cntl_page + CP_VARFLAG_OFF);
|
||||
|
||||
/* Number of records. */
|
||||
fcb->nrecords = ldlong(cntl_page + CP_NRECORDS_OFF);
|
||||
|
||||
/* Minimum and maximum record length. */
|
||||
fcb->minreclen = ldunshort(cntl_page + CP_MINRECLEN_OFF);
|
||||
fcb->maxreclen = ldunshort(cntl_page + CP_MAXRECLEN_OFF);
|
||||
|
||||
/* Last record number. */
|
||||
fcb->lastrecno = ldrecno(cntl_page + CP_LASTRECNO_OFF);
|
||||
|
||||
/* Free record number. */
|
||||
fcb->freerecno = ldrecno(cntl_page + CP_FREERECNO_OFF);
|
||||
|
||||
/* Last key id */
|
||||
fcb->lastkeyid = ldlong(cntl_page + CP_LASTKEYID_OFF);
|
||||
|
||||
/* .ind free list head. */
|
||||
fcb->indfreelist = ldlong(cntl_page + CP_INDFREELIST_OFF);
|
||||
|
||||
/* end of .var file */
|
||||
fcb->varend = ldlong(cntl_page + CP_VAREND_OFF);
|
||||
|
||||
/* Number of keys */
|
||||
fcb->nkeys = ldshort(cntl_page + CP_NKEYS_OFF);
|
||||
|
||||
/*
|
||||
* Read key descriptors.
|
||||
*/
|
||||
fcb->keys = (Keydesc2 *)
|
||||
_isrealloc((char *)fcb->keys,
|
||||
(unsigned) (sizeof(Keydesc2) * fcb->nkeys));
|
||||
memset((char *)fcb->keys, 0, sizeof(Keydesc2) * fcb->nkeys);
|
||||
|
||||
for (i = 0; i < fcb->nkeys; i++) {
|
||||
ldkey(fcb->keys + i, cntl_page + CP_KEYS_OFF + i * K2_LEN);
|
||||
}
|
||||
|
||||
/* Changestamp1 */
|
||||
fcb->changestamp1 = ldlong(cntl_page + CP_CHANGESTAMP1_OFF);
|
||||
|
||||
/* Changestamp2 */
|
||||
fcb->changestamp2 = ldlong(cntl_page + CP_CHANGESTAMP2_OFF);
|
||||
|
||||
/*
|
||||
* Open .ind file in situations when some other process has created
|
||||
* keys and this process has just learned it now.
|
||||
*/
|
||||
if (fcb->nkeys > 1 || !FCB_NOPRIMARY_KEY(fcb)) {
|
||||
/*
|
||||
if (_open2_indfile(fcb) != ISOK)
|
||||
_isfatal_error("_open2_indfile()");
|
||||
*/
|
||||
(void)_open2_indfile(fcb);
|
||||
}
|
||||
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isfcb_cntlpg_r2(fcb)
|
||||
*
|
||||
* Read information from the control block on the disk.
|
||||
* Read only selected fields of the control block to avoid the overhead
|
||||
* of coding and decoding.
|
||||
* Note that the Control Page transfer bypasses the disk buffer manager.
|
||||
*
|
||||
* Return 0 if write was successful, return -1 if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_cntlpg_r2(fcb)
|
||||
register Fcb *fcb;
|
||||
{
|
||||
char cntl_page[CP_VAREND_OFF+CP_VAREND_LEN];
|
||||
int dat_fd = fcb->datfd;
|
||||
|
||||
/*
|
||||
* Read the page from disk.
|
||||
*/
|
||||
_isseekpg(dat_fd, ISCNTLPGOFF);
|
||||
(void)read(dat_fd, cntl_page, sizeof(cntl_page));
|
||||
|
||||
/*
|
||||
* Check changestamp1. If the stamp has changed, we must read the entire
|
||||
* page and update the FCB.
|
||||
*/
|
||||
if (ldlong(cntl_page + CP_CHANGESTAMP1_OFF) != fcb->changestamp1) {
|
||||
(void)_isfcb_cntlpg_r(fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
*_isfcb_cntlpg_r2() is called if transaction is rolled back.
|
||||
* We cannot test changestamp2; we must read the info into the FCB
|
||||
* always.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Check changestamp2. If the stamp has not changed, the FCB contains
|
||||
* up-to-date information.
|
||||
*/
|
||||
if (ldlong(cntl_page + CP_CHANGESTAMP2_OFF) == fcb->changestamp2) {
|
||||
return (ISOK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* .rec file size in blocks. */
|
||||
fcb->datsize = ldlong(cntl_page + CP_DATSIZE_OFF);
|
||||
|
||||
/* .ind file size in blocks. */
|
||||
fcb->indsize = ldlong(cntl_page + CP_INDSIZE_OFF);
|
||||
|
||||
/* .var file size in blocks. */
|
||||
fcb->varsize = ldlong(cntl_page + CP_VARSIZE_OFF);
|
||||
|
||||
/* Number of records. */
|
||||
fcb->nrecords = ldlong(cntl_page + CP_NRECORDS_OFF);
|
||||
|
||||
/* Last record number. */
|
||||
fcb->lastrecno = ldrecno(cntl_page + CP_LASTRECNO_OFF);
|
||||
|
||||
/* Free record number. */
|
||||
fcb->freerecno = ldrecno(cntl_page + CP_FREERECNO_OFF);
|
||||
|
||||
/* .ind free list head. */
|
||||
fcb->indfreelist = ldlong(cntl_page + CP_INDFREELIST_OFF);
|
||||
|
||||
/* end of .var file */
|
||||
fcb->varend = ldlong(cntl_page + CP_VAREND_OFF);
|
||||
|
||||
/* Changestamp2 */
|
||||
fcb->changestamp2 = ldlong(cntl_page + CP_CHANGESTAMP2_OFF);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _create_datfile(isfname)
|
||||
*
|
||||
* Create .rec file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_create_datfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
int fd;
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makedat_isfname(namebuf);
|
||||
|
||||
fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
|
||||
if (fd > -1) {
|
||||
fcntl(fd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* _create_indfile(isfname)
|
||||
*
|
||||
* Create .ind file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_create_indfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
int fd;
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
|
||||
fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
|
||||
if (fd > -1) {
|
||||
fcntl(fd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* _create_varfile(isfname)
|
||||
*
|
||||
* Create .var file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_create_varfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
int fd;
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makevar_isfname(namebuf);
|
||||
|
||||
fd = open (namebuf, O_CREAT | O_EXCL | O_RDWR, 0666);
|
||||
if (fd > -1) {
|
||||
fcntl(fd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _remove_datfile(isfname)
|
||||
*
|
||||
* Remove .rec file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static void
|
||||
_remove_datfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makedat_isfname(namebuf);
|
||||
|
||||
(void) unlink(namebuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* _remove_indfile(isfname)
|
||||
*
|
||||
* Remove .ind file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static void
|
||||
_remove_indfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
|
||||
(void) unlink(namebuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* _remove_varfile(isfname)
|
||||
*
|
||||
* Remove .var file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static void
|
||||
_remove_varfile(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makevar_isfname(namebuf);
|
||||
|
||||
(void) unlink(namebuf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _open_datfile(isfname)
|
||||
*
|
||||
* Open .rec file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_open_datfile(isfname, rdonly)
|
||||
char *isfname;
|
||||
Bool *rdonly;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
int ret;
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makedat_isfname(namebuf);
|
||||
|
||||
if ((ret = open (namebuf, O_RDWR)) != -1) {
|
||||
*rdonly = FALSE;
|
||||
fcntl(ret, F_SETFD, 1); /* Close on exec */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
*rdonly = TRUE;
|
||||
ret = open (namebuf, O_RDONLY);
|
||||
if (ret > -1) {
|
||||
fcntl(ret, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* _open_indfile(isfname)
|
||||
*
|
||||
* Open .ind file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_open_indfile(isfname, rdonly)
|
||||
char *isfname;
|
||||
Bool rdonly;
|
||||
{
|
||||
int fd;
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
|
||||
fd = open (namebuf, (rdonly==TRUE)?O_RDONLY:O_RDWR);
|
||||
if (fd > -1) {
|
||||
fcntl(fd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* _open_varfile(isfname)
|
||||
*
|
||||
* Open .var file for ISAM file isfname.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_open_varfile(isfname, rdonly)
|
||||
char *isfname;
|
||||
Bool rdonly;
|
||||
{
|
||||
int fd;
|
||||
char namebuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
_makevar_isfname(namebuf);
|
||||
|
||||
fd = open (namebuf, (rdonly==TRUE)?O_RDONLY:O_RDWR);
|
||||
if (fd > -1) {
|
||||
fcntl(fd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
int
|
||||
_check_isam_magic(fcb)
|
||||
Fcb *fcb;
|
||||
{
|
||||
char magicbuffer[CP_MAGIC_LEN];
|
||||
|
||||
(void)lseek(fcb->datfd, 0L, 0);
|
||||
if (read(fcb->datfd, magicbuffer, CP_MAGIC_LEN) < CP_MAGIC_LEN ||
|
||||
/* The following test for compatibilty with `SunISAM 1.0 Beta files. */
|
||||
strncmp(magicbuffer, "SunISAM", strlen(ISMAGIC)) != 0 &&
|
||||
strncmp(magicbuffer, ISMAGIC, strlen(ISMAGIC)) != 0) {
|
||||
return ISERROR;
|
||||
}
|
||||
else
|
||||
return ISOK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _open2_indfile(fcb)
|
||||
*
|
||||
* Open (or create) .ind file for ISAM file if the .ind file
|
||||
* is not open already (or does not exist).
|
||||
*/
|
||||
|
||||
int
|
||||
_open2_indfile(fcb)
|
||||
Fcb *fcb;
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
struct stat buf;
|
||||
int openmode;
|
||||
|
||||
if (fcb->indfd != -1)
|
||||
return (ISOK);
|
||||
|
||||
(void) strcpy(namebuf, fcb->isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
|
||||
(void)fstat(fcb->datfd, &buf);
|
||||
|
||||
openmode = (fcb->rdonly) ? O_RDONLY : O_RDWR;
|
||||
|
||||
if (fcb->indsize == 0)
|
||||
openmode |= O_CREAT;
|
||||
|
||||
fcb->indfd = open(namebuf, openmode, buf.st_mode);
|
||||
if (fcb->indfd > -1) {
|
||||
fcntl(fcb->indfd, F_SETFD, 1); /* Close on exec */
|
||||
}
|
||||
|
||||
if(fcb->indfd == -1 && (openmode & O_CREAT)) {
|
||||
_isfatal_error("Cannot create .ind file");
|
||||
}
|
||||
|
||||
if (fcb->indfd != -1) {
|
||||
(void) _watchfd_incr(1);
|
||||
(void)fchown(fcb->indfd, buf.st_uid, buf.st_gid);
|
||||
}
|
||||
|
||||
return ((fcb->indfd == -1) ? ISERROR : ISOK);
|
||||
}
|
||||
219
cde/lib/tt/mini_isam/isfcbindex.c
Normal file
219
cde/lib/tt/mini_isam/isfcbindex.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfcbindex.c /main/3 1995/10/23 11:38:43 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfcbindex.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfcbindex.c
|
||||
*
|
||||
* Description:
|
||||
* Functions that deal with the key descriptors in FCB
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
Static int _keypart2cmp();
|
||||
/*
|
||||
* _isfcb_primkeyadd(fcb, keydesc2)
|
||||
*
|
||||
* Add priamry key descriptor to FCB.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_primkeyadd(fcb, keydesc2)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *keydesc2;
|
||||
{
|
||||
/*
|
||||
* Assign keyid.
|
||||
*/
|
||||
keydesc2->k2_keyid = ++fcb->lastkeyid;
|
||||
|
||||
fcb->keys[0] = *keydesc2;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_primkeyel(fcb)
|
||||
*
|
||||
* Delete primary key
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_primkeydel(fcb)
|
||||
Fcb *fcb;
|
||||
{
|
||||
if (FCB_NOPRIMARY_KEY(fcb))
|
||||
return (EBADARG);
|
||||
|
||||
memset((char *)&fcb->keys[0], 0, sizeof(fcb->keys[0]));
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfcb_altkeyadd(fcb, keydesc2)
|
||||
*
|
||||
* Add alternate key descriptor to FCB.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_altkeyadd(fcb, keydesc2)
|
||||
Fcb *fcb;
|
||||
Keydesc2 *keydesc2;
|
||||
{
|
||||
assert (fcb->nkeys < MAXNKEYS);
|
||||
|
||||
/*
|
||||
* Assign keyid.
|
||||
*/
|
||||
keydesc2->k2_keyid = ++fcb->lastkeyid;
|
||||
|
||||
/*
|
||||
* Reallocate fcb->keys table.
|
||||
*/
|
||||
fcb->keys = (Keydesc2 *)
|
||||
_isrealloc((char *)fcb->keys,
|
||||
(unsigned) (sizeof(Keydesc2) * (fcb->nkeys + 1)));
|
||||
|
||||
fcb->keys[fcb->nkeys] = *keydesc2;
|
||||
|
||||
fcb->nkeys++;
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pkeydesc2 = _isfcb_findkey(fcb, keydesc2)
|
||||
*
|
||||
* Find key descriptor.
|
||||
*
|
||||
*/
|
||||
|
||||
Keydesc2 *
|
||||
_isfcb_findkey(fcb, keydesc2)
|
||||
register Fcb *fcb;
|
||||
Keydesc2 *keydesc2;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register Keydesc2 *kp2;
|
||||
register int j, i;
|
||||
int nparts;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
kp2 = fcb->keys + i;
|
||||
|
||||
if (keydesc2->k2_nparts == kp2->k2_nparts) {
|
||||
|
||||
nparts = keydesc2->k2_nparts;
|
||||
for (j = 0; j < nparts; j++) {
|
||||
if (_keypart2cmp(keydesc2->k2_part + j, kp2->k2_part + j) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == nparts)
|
||||
return (kp2);
|
||||
}
|
||||
}
|
||||
|
||||
return ((struct keydesc2 *) 0); /* Key descriptor not found */
|
||||
}
|
||||
|
||||
/*
|
||||
* pkeydesc2 = _isfcb_altkeydel(fcb, keydesc2)
|
||||
*
|
||||
* Delete key descriptor from FCB.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_isfcb_altkeydel(fcb, keydesc2)
|
||||
register Fcb *fcb;
|
||||
Keydesc2 *keydesc2;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i, j;
|
||||
register Keydesc2 *kp2;
|
||||
int nparts;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
kp2 = fcb->keys + i;
|
||||
|
||||
if (keydesc2->k2_nparts == kp2->k2_nparts) {
|
||||
|
||||
nparts = keydesc2->k2_nparts;
|
||||
for (j = 0; j < nparts; j++) {
|
||||
if (_keypart2cmp(keydesc2->k2_part + j, kp2->k2_part + j) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == nparts)
|
||||
break; /* Key found */
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= nkeys)
|
||||
return (EBADKEY); /* Key descriptor not found */
|
||||
|
||||
if (i == 0) {
|
||||
return (EPRIMKEY); /* Cannot delete primary key */
|
||||
}
|
||||
|
||||
/*
|
||||
* Shift the end of the table toward the beginning to delete the entry.
|
||||
*/
|
||||
if (i < nkeys - 1) {
|
||||
memcpy( (char *)(fcb->keys + i),(char *)(fcb->keys + i + 1),
|
||||
(nkeys - 1 - i) * sizeof (fcb->keys[0]));
|
||||
}
|
||||
|
||||
fcb->nkeys--;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/* compare key parts */
|
||||
Static int
|
||||
_keypart2cmp(l,r)
|
||||
register struct keypart2 *l, *r;
|
||||
{
|
||||
return !(l->kp2_type == r->kp2_type && l->kp2_start == r->kp2_start &&
|
||||
l->kp2_leng == r->kp2_leng);
|
||||
}
|
||||
|
||||
/*
|
||||
* pkeydesc2 = _isfcb_indfindkey(fcb, keyind)
|
||||
*
|
||||
* Find key descriptor by its keyind value.
|
||||
*
|
||||
*/
|
||||
|
||||
Keydesc2 *
|
||||
_isfcb_indfindkey(fcb, keyid)
|
||||
register Fcb *fcb;
|
||||
int keyid;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register Keydesc2 *keys = fcb->keys;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (keys[i].k2_keyid == keyid)
|
||||
break;
|
||||
}
|
||||
|
||||
return ((i == nkeys) ? NULL : keys + i);
|
||||
}
|
||||
127
cde/lib/tt/mini_isam/isfcbwatchfd.c
Normal file
127
cde/lib/tt/mini_isam/isfcbwatchfd.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfcbwatchfd.c /main/3 1995/10/23 11:38:51 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfcbwatchfd.c 1.8 93/09/07 Copyr 1988-1993 Sun Microsystems, Inc";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfcbwatchfd.c
|
||||
*
|
||||
* Description:
|
||||
* Watch the limit on UNIX file descriptors used by the FCB module.
|
||||
*/
|
||||
|
||||
#if defined(_AIX)
|
||||
#define _POSIX_SYSCONF
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
#define _POSIX_SYSCONF
|
||||
#endif
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef _POSIX_SYSCONF
|
||||
#include <unistd.h>
|
||||
#endif /* _POSIX_SYSCONF */
|
||||
|
||||
static int _limit = MAXFCB_UNIXFD; /* Imposed limit */
|
||||
static int _in_use = 0; /* Current number of
|
||||
* open file descriptors
|
||||
*/
|
||||
|
||||
/*
|
||||
* _watchfd_incr(n)
|
||||
*
|
||||
* Register that n additional UNIX file descriptors were open.
|
||||
*
|
||||
* Return the new number of open file descriptors.
|
||||
*/
|
||||
|
||||
int
|
||||
_watchfd_incr(n)
|
||||
{
|
||||
_in_use += n;
|
||||
assert(_in_use <= _limit);
|
||||
return (_in_use);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _watch_decr(n)
|
||||
*
|
||||
* Register that n open file descriptors were closed.
|
||||
*
|
||||
* Return the new number of open file descriptors.
|
||||
*/
|
||||
|
||||
int
|
||||
_watchfd_decr(n)
|
||||
{
|
||||
_in_use -= n;
|
||||
assert(_in_use >= 0);
|
||||
return (_in_use);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _watch_check()
|
||||
*
|
||||
* Return number of fd that are still available.
|
||||
*/
|
||||
|
||||
int
|
||||
_watchfd_check()
|
||||
{
|
||||
return (_limit - _in_use);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _watchfd_max_set(n)
|
||||
*
|
||||
* Set the maximum number of UNIX fds that may be comsumed by ISAM files.
|
||||
*/
|
||||
|
||||
int
|
||||
_watchfd_max_set(n)
|
||||
int n;
|
||||
{
|
||||
int oldlimit = _limit;
|
||||
|
||||
#ifdef _POSIX_SYSCONF
|
||||
if (n < 3 || n > sysconf(_SC_OPEN_MAX)) {
|
||||
#else
|
||||
int dtab_size = 0;
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
|
||||
dtab_size = rl.rlim_cur;
|
||||
|
||||
if (n < 3 || n > dtab_size) {
|
||||
#endif
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_limit = n;
|
||||
return (oldlimit);
|
||||
}
|
||||
|
||||
/*
|
||||
* _watchfd_max_get()
|
||||
*
|
||||
* Get the maximum number of UNIX fds that may be comsumed by ISAM files.
|
||||
*/
|
||||
|
||||
int
|
||||
_watchfd_max_get()
|
||||
{
|
||||
return (_limit);
|
||||
}
|
||||
85
cde/lib/tt/mini_isam/isfd.c
Normal file
85
cde/lib/tt/mini_isam/isfd.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfd.c /main/3 1995/10/23 11:39:10 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfd.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfd.c
|
||||
*
|
||||
* Description:
|
||||
* The ISAM file descriptors (isfd) are used as index to a table of
|
||||
* pointers to File Access Block objects. Isfd.c maintains the table
|
||||
* of the pointers (isfdtab).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static Fab *isfdtab[MAXISFD]; /* Table of pointers */
|
||||
|
||||
|
||||
/*
|
||||
* _isfd_insert(fab)
|
||||
*
|
||||
* Insert a pointer to an Fab object to table of ISAM file descriptors.
|
||||
* Return an ISAM file descriptor, or NOISFD if the table is full.
|
||||
*/
|
||||
|
||||
Isfd
|
||||
_isfd_insert(fab)
|
||||
Fab *fab;
|
||||
{
|
||||
register Isfd i;
|
||||
|
||||
for (i = 0; i < MAXISFD; i++) {
|
||||
if (isfdtab[i] == NULL) /* Empty entry found */
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXISFD)
|
||||
return (NOISFD); /* isfdtab is full */
|
||||
|
||||
isfdtab[i] = fab;
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _isfd_find(isfd)
|
||||
*
|
||||
* Return a pointer to Fab object associated with the ISAM file
|
||||
* descriptor isfd. If isfd is not a file descriptor of an open ISAM file,
|
||||
* return NULL.
|
||||
*/
|
||||
|
||||
Fab *
|
||||
_isfd_find(isfd)
|
||||
register Isfd isfd;
|
||||
{
|
||||
if (isfd < 0 || isfd >= MAXISFD || isfdtab[isfd] == NULL)
|
||||
return (NULL);
|
||||
else
|
||||
return (isfdtab[isfd]);
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfd_delete(isfd)
|
||||
*
|
||||
* Delete an entry from isfdtab. No check is made the entry exists.
|
||||
*/
|
||||
|
||||
void
|
||||
_isfd_delete(isfd)
|
||||
register Isfd isfd;
|
||||
{
|
||||
if (isfd >= 0 && isfd < MAXISFD)
|
||||
isfdtab[isfd] = NULL;
|
||||
}
|
||||
|
||||
156
cde/lib/tt/mini_isam/isfileio.c
Normal file
156
cde/lib/tt/mini_isam/isfileio.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfileio.c /main/3 1995/10/23 11:39:26 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfileio.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfileio.c
|
||||
*
|
||||
* Description:
|
||||
* I/O operations on UNIX files associated with FCB
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static int _getoffset();
|
||||
static Blkno _getblkno();
|
||||
|
||||
|
||||
/*
|
||||
* _cp_tofile(fcb, unixfd, data, pos, len)
|
||||
*
|
||||
* Copy data to a file associated with FCB (unixfd distinguishes among
|
||||
* .rec, .ind., and .var file). The data are copied from buffer data to
|
||||
* the file at offset pos. The number of bytes to copy is in len.
|
||||
*/
|
||||
|
||||
void
|
||||
_cp_tofile(fcb, unixfd, data, pos, len)
|
||||
Fcb *fcb;
|
||||
int unixfd;
|
||||
char *data;
|
||||
long pos;
|
||||
int len;
|
||||
{
|
||||
int offset; /* Offset within a page */
|
||||
Blkno blkno;
|
||||
Bufhdr *bufhdr;
|
||||
int nbytes;
|
||||
|
||||
/*
|
||||
* Data may span multiple blocks.
|
||||
*/
|
||||
while (len > 0) {
|
||||
blkno = _getblkno(pos);
|
||||
offset = _getoffset(pos);
|
||||
nbytes = (len < ISPAGESIZE - offset) ? len : ISPAGESIZE - offset;
|
||||
|
||||
bufhdr = _isdisk_fix(fcb, unixfd, blkno, ISFIXWRITE);
|
||||
memcpy( bufhdr->isb_buffer + offset,data, nbytes);
|
||||
_isdisk_unfix(bufhdr);
|
||||
|
||||
pos += nbytes;
|
||||
data += nbytes;
|
||||
len -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _cp_fromfile(fcb, unixfd, data, pos, len)
|
||||
*
|
||||
* Copy data from a file associated with FCB (unixfd distinguishes among
|
||||
* .rec, .ind., and .var file). The data are copied to buffer data from
|
||||
* the file at offset pos. The number of bytes to copy is in len.
|
||||
*/
|
||||
|
||||
void
|
||||
_cp_fromfile(fcb, unixfd, data, pos, len)
|
||||
Fcb *fcb;
|
||||
int unixfd;
|
||||
char *data;
|
||||
long pos;
|
||||
int len;
|
||||
{
|
||||
int offset; /* Offset within a page */
|
||||
Blkno blkno;
|
||||
Bufhdr *bufhdr;
|
||||
int nbytes;
|
||||
|
||||
/*
|
||||
* Data may span multiple blocks.
|
||||
*/
|
||||
while (len > 0) {
|
||||
blkno = _getblkno(pos);
|
||||
offset = _getoffset(pos);
|
||||
nbytes = (len < ISPAGESIZE - offset) ? len : ISPAGESIZE - offset;
|
||||
|
||||
bufhdr = _isdisk_fix(fcb, unixfd, blkno, ISFIXREAD);
|
||||
memcpy( data,bufhdr->isb_buffer + offset, nbytes);
|
||||
_isdisk_unfix(bufhdr);
|
||||
|
||||
pos += nbytes;
|
||||
data += nbytes;
|
||||
len -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* extend_file(fcb, unixfd, oldsize)
|
||||
*
|
||||
* Extend UNIX file by one block.
|
||||
*/
|
||||
|
||||
Blkno
|
||||
_extend_file(fcb, unixfd, oldsize)
|
||||
Fcb *fcb;
|
||||
int unixfd;
|
||||
Blkno oldsize;
|
||||
{
|
||||
Bufhdr *bufhdr;
|
||||
char buf[ISPAGESIZE];
|
||||
|
||||
/*
|
||||
* We must write something to the buffer, or we will get
|
||||
* segmentation fault when using mapped I/O.
|
||||
*/
|
||||
_isseekpg(unixfd, oldsize);
|
||||
_iswritepg(unixfd, buf);
|
||||
|
||||
bufhdr = _isdisk_fix(fcb, unixfd, oldsize, ISFIXNOREAD);
|
||||
_isdisk_unfix(bufhdr);
|
||||
|
||||
return (oldsize + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* off = _getoffset(pos)
|
||||
*
|
||||
* Calculate offset relative to the beginning of page
|
||||
*/
|
||||
|
||||
Static int
|
||||
_getoffset(pos)
|
||||
long pos;
|
||||
{
|
||||
return ((int)(pos % ISPAGESIZE));
|
||||
}
|
||||
|
||||
/*
|
||||
* blkno = _getblkno(pos)
|
||||
*
|
||||
* Calculate block number of the block containing position pos.
|
||||
*/
|
||||
|
||||
Static Blkno
|
||||
_getblkno(pos)
|
||||
long pos;
|
||||
{
|
||||
return ((int)(pos / ISPAGESIZE));
|
||||
}
|
||||
397
cde/lib/tt/mini_isam/isfixrec.c
Normal file
397
cde/lib/tt/mini_isam/isfixrec.c
Normal file
@@ -0,0 +1,397 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfixrec.c /main/3 1995/10/23 11:39:42 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfixrec.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfixrec.c
|
||||
*
|
||||
* Description:
|
||||
* Fixed length record access (FLRA) module.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
/* Local functions */
|
||||
long _fl_getpos(); /* Get offset in .rec file */
|
||||
int _fl_deleted(); /* 0/1 returns 1 if record is deleted */
|
||||
static void remove_from_chain(); /* used by _flrec_wrrec() */
|
||||
|
||||
/*
|
||||
* _flrec_write(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Write a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* record record buffer
|
||||
* reclen record length (NOT USED)
|
||||
*
|
||||
* Output params:
|
||||
* recnum record number of the new record
|
||||
*
|
||||
* Returns 0 if record was written succesfully, or -1 if any error.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_flrec_write(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno *recnum;
|
||||
int reclen;
|
||||
{
|
||||
Recno recnum2;
|
||||
long rec_position;
|
||||
char delflag = FL_RECEXISTS;
|
||||
char recnobuf [RECNOSIZE];
|
||||
|
||||
/*
|
||||
* Reuse a deleted record if one exits.
|
||||
* Otherwise, extend .rec file by a record.
|
||||
*/
|
||||
if (fcb->freerecno != NULL_RECNO) {
|
||||
recnum2 = fcb->freerecno;
|
||||
|
||||
/*
|
||||
* Remove record from the chain of deleted records.
|
||||
*/
|
||||
rec_position = _fl_getpos(fcb, recnum2); /* Offset in .rec file */
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf, rec_position + 1, RECNOSIZE);
|
||||
fcb->freerecno = ldrecno(recnobuf);
|
||||
}
|
||||
else {
|
||||
recnum2 = ++(fcb->lastrecno);
|
||||
|
||||
/*
|
||||
* Extend .rec file size if necessary.
|
||||
*/
|
||||
while (_fl_getpos(fcb, recnum2 + 1) > fcb->datsize * ISPAGESIZE) {
|
||||
fcb->datsize = _extend_file(fcb, fcb->datfd, fcb->datsize);
|
||||
}
|
||||
rec_position = _fl_getpos(fcb, recnum2); /* Offset in .rec file */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy record to the .at file. Mark record as undeleted.
|
||||
*/
|
||||
_cp_tofile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + 1, fcb->minreclen);
|
||||
|
||||
*recnum = recnum2;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _flrec_read(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Read a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* reclen filled with the record size for compatibilty with
|
||||
* variable length records
|
||||
*
|
||||
* Output params:
|
||||
* record record buffer is filled with data
|
||||
*
|
||||
* Returns 0 if record was read succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_flrec_read(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int *reclen;
|
||||
{
|
||||
long rec_position;
|
||||
char delflag;
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _fl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
if (delflag == FL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy record from the .at file.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, record, rec_position + 1, fcb->minreclen);
|
||||
|
||||
*reclen = fcb->minreclen;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* pos = _fl_getpos(fcb, recnum)
|
||||
*
|
||||
* Calculate the position of record in .rec file.
|
||||
*/
|
||||
|
||||
long
|
||||
_fl_getpos(fcb, recnum)
|
||||
Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
return ((long)(ISCNTLSIZE + (fcb->minreclen + 1) * (recnum -1)));
|
||||
}
|
||||
|
||||
/*
|
||||
* _flrec_rewrite(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Rewrite a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* record new record
|
||||
* int reclen (NOT USED)
|
||||
*
|
||||
* Returns 0 if record was rewritten succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_flrec_rewrite(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int reclen;
|
||||
{
|
||||
long rec_position;
|
||||
char delflag;
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _fl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
if (delflag == FL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy new record to the .rec file.
|
||||
*/
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + 1, fcb->minreclen);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _flrec_delete(fcb, recnum)
|
||||
*
|
||||
* Rewrite a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
*
|
||||
* Returns 0 if record was rewritten succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_flrec_delete(fcb, recnum)
|
||||
register Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
long rec_position;
|
||||
char delflag;
|
||||
char recnobuf [RECNOSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _fl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
if (delflag == FL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the delete flag to FL_RECDELETED.
|
||||
*/
|
||||
delflag = FL_RECDELETED;
|
||||
_cp_tofile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
|
||||
/*
|
||||
* Insert record into chain of deleted records.
|
||||
*/
|
||||
strecno(fcb->freerecno, recnobuf);
|
||||
_cp_tofile(fcb, fcb->datfd, recnobuf, rec_position + 1, RECNOSIZE);
|
||||
fcb->freerecno = recnum;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _flrec_wrrec(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Write a record by record number.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* record record buffer
|
||||
* int reclen (NOT USED)
|
||||
*
|
||||
* Returns 0 if record was written succesfully, or error code if any error.
|
||||
*
|
||||
* Note that _flrec_wrrec() commits updates and syncs the FCB to avoid
|
||||
* buffer pool overflow.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_flrec_wrrec(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int reclen;
|
||||
{
|
||||
long rec_position;
|
||||
char delflag;
|
||||
Recno recnum2;
|
||||
char recnumbuf [RECNOSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is not negative.
|
||||
*/
|
||||
if (recnum < 1)
|
||||
return (EBADARG);
|
||||
|
||||
rec_position = _fl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
if (recnum > fcb->lastrecno) {
|
||||
|
||||
/*
|
||||
* If the recnum is bigger than the highest record number in the .rec
|
||||
* file, extend the .rec file.
|
||||
*/
|
||||
while (_fl_getpos(fcb, recnum + 1) > fcb->datsize * ISPAGESIZE) {
|
||||
fcb->datsize = _extend_file(fcb, fcb->datfd, fcb->datsize);
|
||||
|
||||
/* Sync the updates to avoid buffer pool overflow. */
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark all records in the range <fcb->lastrecno+1, recnum> as
|
||||
* deleted.
|
||||
*/
|
||||
delflag = FL_RECDELETED;
|
||||
for (recnum2 = fcb->lastrecno + 1; recnum2 <= recnum; recnum2++) {
|
||||
_cp_tofile(fcb, fcb->datfd, &delflag, _fl_getpos(fcb, recnum2), 1);
|
||||
strecno(fcb->freerecno, recnumbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, recnumbuf,
|
||||
_fl_getpos(fcb, recnum2) + 1, RECNOSIZE);
|
||||
fcb->freerecno = recnum2;
|
||||
|
||||
/* Sync the updates to avoid buffer pool overflow. */
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
fcb->lastrecno = recnum;
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the disk structures are in a consistent state now,
|
||||
* the .rec was extended by a few records marked as 'deleted'.
|
||||
* This is important for subsequent rollbacks.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* If recnum specifies a record that has existed, check whether it
|
||||
* has been deleted. _flrec_wrrec() does not override existing record.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
if (delflag == FL_RECEXISTS) {
|
||||
return (EDUPL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the record from the chain of deleted records.
|
||||
*/
|
||||
remove_from_chain(fcb, recnum);
|
||||
|
||||
/*
|
||||
* Copy new record to the .rec file.
|
||||
*/
|
||||
delflag = FL_RECEXISTS;
|
||||
_cp_tofile(fcb, fcb->datfd, &delflag, rec_position, 1);
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + 1, fcb->minreclen);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* remvoe_from_chain(fcb, recnum)
|
||||
*
|
||||
* Remove record from the chain of deleted records.
|
||||
*/
|
||||
|
||||
static void
|
||||
remove_from_chain(fcb, recnum)
|
||||
Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
char recnobuf1 [RECNOSIZE] , recnobuf2 [RECNOSIZE];
|
||||
long pos1, pos2;
|
||||
Recno recnum2;
|
||||
|
||||
pos1 = _fl_getpos(fcb, recnum);
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf1, pos1 + 1, RECNOSIZE);
|
||||
|
||||
if (fcb->freerecno == recnum) {
|
||||
fcb->freerecno = ldrecno(recnobuf1);
|
||||
}
|
||||
else {
|
||||
recnum2 = fcb->freerecno;
|
||||
do {
|
||||
pos2 = _fl_getpos(fcb, recnum2);
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf2, pos2 + 1, RECNOSIZE);
|
||||
recnum2 = ldrecno(recnobuf2);
|
||||
} while (recnum2 != recnum && recnum2 != NULL_RECNO);
|
||||
|
||||
_cp_tofile(fcb, fcb->datfd, recnobuf1, pos2 + 1, RECNOSIZE);
|
||||
}
|
||||
}
|
||||
108
cde/lib/tt/mini_isam/isfname.c
Normal file
108
cde/lib/tt/mini_isam/isfname.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isfname.c /main/3 1995/10/23 11:40:04 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isfname.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfname.c
|
||||
*
|
||||
* Description:
|
||||
* Functions to translate ISAM file name to .rec, .ind, and .var file
|
||||
* names. Also, several auxiliary functions that deal with path names.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
void _removelast();
|
||||
char *_lastelement();
|
||||
|
||||
/*
|
||||
* _makedat_isfname(isfname)
|
||||
*
|
||||
* Return path to .rec file corresponding to the ISAM file isfname.
|
||||
* Conversion is done in place.
|
||||
*/
|
||||
|
||||
void
|
||||
_makedat_isfname(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
/* Append .rec */
|
||||
(void) strcat(isfname, DAT_SUFFIX);
|
||||
}
|
||||
|
||||
/*
|
||||
* _makeind_isfname(isfname)
|
||||
*
|
||||
* Return path to .ind file corresponding to the ISAM file isfname.
|
||||
* Conversion is done in place.
|
||||
*/
|
||||
|
||||
void
|
||||
_makeind_isfname(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
/* Append .ind */
|
||||
(void) strcat(isfname, IND_SUFFIX);
|
||||
}
|
||||
|
||||
/*
|
||||
* _makevar_isfname(isfname)
|
||||
*
|
||||
* Return path to .var file corresponding to the ISAM file isfname.
|
||||
* Conversion is done in place.
|
||||
*/
|
||||
|
||||
void
|
||||
_makevar_isfname(isfname)
|
||||
char *isfname;
|
||||
{
|
||||
/* Append .var */
|
||||
(void) strcat(isfname, VAR_SUFFIX);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _removelast(path)
|
||||
*
|
||||
* Remove last element of path. E.g. /usr/db/part yields /usr/db.
|
||||
*/
|
||||
|
||||
void
|
||||
_removelast(path)
|
||||
char *path;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
for (p = path + strlen(path); *--p != '/' && p >= path; )
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* _lastelement(path)
|
||||
*
|
||||
* Return pointer to the last element in the path.
|
||||
* E.g.: _lastelement("/usr/temp") returns "temp".
|
||||
*/
|
||||
|
||||
char *
|
||||
_lastelement(path)
|
||||
char *path;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = path + strlen(path);
|
||||
|
||||
while (*--p != '/' && p > path)
|
||||
{ ; }
|
||||
|
||||
return ((*p == '/') ? (p + 1) : p);
|
||||
}
|
||||
105
cde/lib/tt/mini_isam/isgarbage.c
Normal file
105
cde/lib/tt/mini_isam/isgarbage.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: isgarbage.c /main/5 1998/04/10 08:04:25 mgreess $ */
|
||||
#include "isam_impl.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int
|
||||
isgarbage(char * isfname)
|
||||
{
|
||||
char isfname2[MAXPATHLEN];
|
||||
int isfd = -1, isfd2 = -1;
|
||||
char buffer[ISMAXRECLEN];
|
||||
char *recbuf;
|
||||
struct dictinfo info;
|
||||
struct keydesc keybuf;
|
||||
struct stat statbuf;
|
||||
int count = 0,i;
|
||||
|
||||
(void)strcpy(isfname2, isfname);
|
||||
(void)strcat(isfname2, "~");
|
||||
|
||||
if ((isfd = isopen(isfname, ISEXCLLOCK + ISINPUT)) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (isindexinfo(isfd, (struct keydesc *)&info, 0) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (strlen(isfname) + 5 >= ISMAXRECLEN)
|
||||
recbuf = (char*) malloc(strlen(isfname) + 5);
|
||||
else
|
||||
recbuf = buffer;
|
||||
|
||||
sprintf(recbuf, "%s.rec", isfname);
|
||||
if (stat(recbuf, &statbuf) < 0) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
iserase(isfname2); /* Delete any old backup (~) files. */
|
||||
|
||||
if ((isfd2 = isbuild(isfname2, info.di_recsize, nokey,
|
||||
(DICTVARLENBIT&info.di_nkeys?ISVARLEN: ISFIXLEN)
|
||||
+ ISEXCLLOCK + ISINOUT)) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/* Copy all records */
|
||||
|
||||
while (isread(isfd, recbuf, ISNEXT) == ISOK) {
|
||||
iswrite(isfd2, recbuf);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != info.di_nrecords) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/* Build all indexes from index info */
|
||||
|
||||
for (i = 1; i <= (info.di_nkeys & DICTNKEYSMASK); i++) {
|
||||
if (isindexinfo(isfd, &keybuf, i) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
if (i == 1 && keybuf.k_nparts != 0) {
|
||||
/* Add primary index */
|
||||
if (isaddprimary(isfd2, &keybuf) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
}
|
||||
else if (i > 1) {
|
||||
/* Add secondary index */
|
||||
if (isaddindex(isfd2, &keybuf) == ISERROR) {
|
||||
goto ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)isclose(isfd);
|
||||
(void)isclose(isfd2);
|
||||
|
||||
iserase(isfname); /* cannot abort at this point ! */
|
||||
if (isrename(isfname2, isfname) == ISERROR) {
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
if (isfd != -1)
|
||||
(void)isclose(isfd);
|
||||
|
||||
if (isfd2 != -1) {
|
||||
(void)isclose(isfd2);
|
||||
(void)iserase(isfname2);
|
||||
}
|
||||
if (recbuf != buffer) free(recbuf);
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
101
cde/lib/tt/mini_isam/isindexconv.c
Normal file
101
cde/lib/tt/mini_isam/isindexconv.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isindexconv.c /main/3 1995/10/23 11:40:48 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isindexconv.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isindexconv.c
|
||||
*
|
||||
* Description:
|
||||
* Encode/decode key descriptor
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
void
|
||||
stkey(pkeydesc2, p)
|
||||
Keydesc2 *pkeydesc2;
|
||||
char *p;
|
||||
{
|
||||
int i;
|
||||
register struct keypart2 *ppart;
|
||||
register char *pp;
|
||||
int nparts;
|
||||
|
||||
stshort(pkeydesc2->k2_flags, p + K2_FLAGS_OFF);
|
||||
stshort(pkeydesc2->k2_nparts, p + K2_NPARTS_OFF);
|
||||
stshort(pkeydesc2->k2_len, p + K2_LEN_OFF);
|
||||
stblkno(pkeydesc2->k2_rootnode, p + K2_ROOT_OFF);
|
||||
stlong((long)pkeydesc2->k2_keyid, p + K2_KEYID_OFF);
|
||||
|
||||
ppart = pkeydesc2->k2_part;
|
||||
pp = p + K2_KEYPART_OFF;
|
||||
nparts = pkeydesc2->k2_nparts + 1; /* +1 for recno part */
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) /* +1 for dups serial number*/
|
||||
nparts++;
|
||||
|
||||
for (i = 0; i < nparts;i++) {
|
||||
stshort(ppart->kp2_start, pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
stshort(ppart->kp2_leng, pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
stshort(ppart->kp2_type, pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
stshort(ppart->kp2_offset, pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
ppart++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ldkey(pkeydesc2,p)
|
||||
register struct keydesc2 *pkeydesc2;
|
||||
register char *p;
|
||||
{
|
||||
int i;
|
||||
register struct keypart2 *ppart;
|
||||
register char *pp;
|
||||
int nparts;
|
||||
|
||||
memset ((char *) pkeydesc2, 0, sizeof (*pkeydesc2));
|
||||
pkeydesc2->k2_flags = ldshort(p + K2_FLAGS_OFF);
|
||||
pkeydesc2->k2_nparts = ldshort(p + K2_NPARTS_OFF);
|
||||
pkeydesc2->k2_len = ldshort(p + K2_LEN_OFF);
|
||||
pkeydesc2->k2_rootnode = ldblkno(p + K2_ROOT_OFF);
|
||||
pkeydesc2->k2_keyid = ldlong(p + K2_KEYID_OFF);
|
||||
|
||||
ppart = pkeydesc2->k2_part;
|
||||
pp = p + K2_KEYPART_OFF;
|
||||
nparts = pkeydesc2->k2_nparts + 1; /* +1 for recno part */
|
||||
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) /* +1 for dups serial number*/
|
||||
nparts++;
|
||||
|
||||
for (i = 0; i < nparts;i++) {
|
||||
ppart->kp2_start = ldunshort(pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
ppart->kp2_leng = ldshort(pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
ppart->kp2_type = ldshort(pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
ppart->kp2_offset = ldunshort(pp);
|
||||
pp += SHORTSIZE;
|
||||
|
||||
ppart++;
|
||||
}
|
||||
}
|
||||
154
cde/lib/tt/mini_isam/isindexinfo.c
Normal file
154
cde/lib/tt/mini_isam/isindexinfo.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isindexinfo.c /main/3 1995/10/23 11:40:56 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isindexinfo.c 1.2 91/05/16 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isindexinfo.c
|
||||
*
|
||||
* Description:
|
||||
* Access file status information
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#define ZERO 0
|
||||
|
||||
/*
|
||||
* err = isindexinfo(isfd, buffer, number)
|
||||
*
|
||||
* Return information about index.
|
||||
* Return information about the data file (if number == 0).
|
||||
*
|
||||
* (this function is overloaded).
|
||||
*
|
||||
* Errors:
|
||||
* EBADARG number is out of range
|
||||
* ENOTOPEN isfd is not ISAM file descriptor of open ISAM file
|
||||
*/
|
||||
|
||||
#define dibuf ((struct dictinfo *)buffer)
|
||||
|
||||
int
|
||||
isindexinfo(isfd, buffer, number)
|
||||
int isfd;
|
||||
struct keydesc *buffer;
|
||||
int number;
|
||||
{
|
||||
register Fab *fab;
|
||||
int ret;
|
||||
Fcb *fcb = NULL;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the Access Method or RPC client function, depending whether
|
||||
* the file is local or remote.
|
||||
*/
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&fab->isfhandle, &fab->errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r(fcb);
|
||||
|
||||
/*
|
||||
* Validate number argument.
|
||||
*/
|
||||
if (number < 0 || number > fcb->nkeys) {
|
||||
_amseterrcode(&fab->errcode, EBADARG);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
|
||||
/*
|
||||
* Return dictinfo structure.
|
||||
*/
|
||||
dibuf->di_nkeys = fcb->nkeys;
|
||||
dibuf->di_recsize = fcb->maxreclen;
|
||||
dibuf->di_idxsize = fcb->keys[0].k2_len;
|
||||
dibuf->di_nrecords = fcb->nrecords;
|
||||
|
||||
/* Set msb of di_nkeys for variable length records. */
|
||||
if (fcb->varflag == TRUE)
|
||||
dibuf->di_nkeys |= DICTVARLENBIT;
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Return index information.
|
||||
*/
|
||||
_iskey_itox(fcb->keys + number - 1, buffer);
|
||||
}
|
||||
|
||||
_amseterrcode(&fab->errcode, ISOK);
|
||||
|
||||
/* XXX This fixes a core dump that occurs when isindexinfo is
|
||||
* called on brand new tables
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
*/
|
||||
|
||||
_isam_exithook();
|
||||
ret = ISOK;
|
||||
goto CLEANUP;
|
||||
|
||||
ERROR:
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
_isam_exithook();
|
||||
ret = ISERROR;
|
||||
|
||||
CLEANUP:
|
||||
|
||||
if (ret == ISOK)
|
||||
isreclen = fab->minreclen; /* for variable length */
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
/*
|
||||
* This is a patch to conform with the VSX 3.0 test that checks
|
||||
* that k_leng == 2 and k_type == 1 for index 1 if the ISAM file
|
||||
* has no primary key. I suspect that these numbers are returned by
|
||||
* C-ISAM and the author of VSX tests diligently checks them even
|
||||
* though they have no meaning.
|
||||
*/
|
||||
if (ret == ISOK && number == 1 && buffer->k_nparts == 0) {
|
||||
buffer->k_leng = 2;
|
||||
buffer->k_type = INTTYPE;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
112
cde/lib/tt/mini_isam/isindfreel.c
Normal file
112
cde/lib/tt/mini_isam/isindfreel.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isindfreel.c /main/3 1995/10/23 11:41:03 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isindfreel.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isfreelist.c
|
||||
*
|
||||
* Description:
|
||||
* Free list maintenance functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern Bufhdr *_isdisk_fix();
|
||||
|
||||
/*
|
||||
* blkno = _isfreel_alloc()
|
||||
*
|
||||
* Allocate a new index page.
|
||||
*/
|
||||
|
||||
Blkno
|
||||
_isindfreel_alloc(fcb)
|
||||
Fcb *fcb;
|
||||
{
|
||||
Bufhdr *pbhdr;
|
||||
char *p;
|
||||
int npointers;
|
||||
Blkno blkno;
|
||||
|
||||
if (fcb->indfreelist == FREELIST_NOPAGE) {
|
||||
|
||||
/*
|
||||
* We must write something to the buffer, or we will get
|
||||
* segmentation fault when using mapped I/O.
|
||||
*/
|
||||
fcb->indsize = _extend_file(fcb, fcb->indfd, fcb->indsize);
|
||||
|
||||
return (fcb->indsize - 1);
|
||||
}
|
||||
|
||||
pbhdr = _isdisk_fix(fcb, fcb->indfd, fcb->indfreelist, ISFIXWRITE);
|
||||
p = pbhdr->isb_buffer;
|
||||
|
||||
npointers = ldshort(p + FL_NPOINTERS_OFF);
|
||||
|
||||
if (npointers > 0) {
|
||||
blkno = ldblkno(p + FL_POINTERS_OFF + npointers * BLKNOSIZE);
|
||||
npointers--;
|
||||
stshort((short)npointers, p + FL_NPOINTERS_OFF);
|
||||
|
||||
return (ldblkno(p + FL_POINTERS_OFF + npointers * BLKNOSIZE));
|
||||
}
|
||||
else {
|
||||
blkno = fcb->indfreelist;
|
||||
fcb->indfreelist = ldblkno(p + FL_NEXT_OFF);
|
||||
|
||||
return (blkno);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _isfreel_free()
|
||||
*
|
||||
* Free an index page.
|
||||
*/
|
||||
|
||||
void
|
||||
_isindfreel_free(fcb, blkno)
|
||||
Fcb *fcb;
|
||||
Blkno blkno;
|
||||
{
|
||||
Bufhdr *pbhdr;
|
||||
char *p;
|
||||
int npointers;
|
||||
|
||||
if (fcb->indfreelist != FREELIST_NOPAGE) {
|
||||
pbhdr = _isdisk_fix(fcb, fcb->indfd, fcb->indfreelist, ISFIXWRITE);
|
||||
p = pbhdr->isb_buffer;
|
||||
|
||||
npointers = ldshort(p + FL_NPOINTERS_OFF);
|
||||
|
||||
if (npointers < FL_MAXNPOINTERS) {
|
||||
stblkno(blkno, p + FL_POINTERS_OFF + npointers * BLKNOSIZE);
|
||||
npointers++;
|
||||
stshort((short)npointers, p + FL_NPOINTERS_OFF);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pbhdr = _isdisk_fix(fcb, fcb->indfd, blkno, ISFIXWRITE);
|
||||
p = pbhdr->isb_buffer;
|
||||
|
||||
/* Mark page to indicate that it is in the free list. */
|
||||
stshort((short)PT_FREELIST, p + FL_TYPE_OFF);
|
||||
|
||||
stshort((short)0, p + FL_NPOINTERS_OFF);
|
||||
stblkno(fcb->indfreelist, p + FL_NEXT_OFF);
|
||||
|
||||
fcb->indfreelist = blkno;
|
||||
}
|
||||
98
cde/lib/tt/mini_isam/iskeyaux.c
Normal file
98
cde/lib/tt/mini_isam/iskeyaux.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iskeyaux.c /main/3 1995/10/23 11:41:11 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iskeyaux.c 1.7 89/07/27 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* iskeyaux.c
|
||||
*
|
||||
* Description:
|
||||
* Auxiliary key related functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
Blkno _isgetfreekpage();
|
||||
|
||||
/*
|
||||
* _isindex_extract()
|
||||
*
|
||||
* Extract key parts from record buffer
|
||||
*/
|
||||
|
||||
void
|
||||
_iskey_extract (pkeydesc2, recp, keyp)
|
||||
Keydesc2 * pkeydesc2;
|
||||
char *recp;
|
||||
char *keyp;
|
||||
{
|
||||
register int i;
|
||||
register struct keypart2 *ppart;
|
||||
int nparts;
|
||||
|
||||
nparts = pkeydesc2->k2_nparts;
|
||||
ppart = pkeydesc2->k2_part;
|
||||
|
||||
/*
|
||||
* XXX - This is a kludge to fix a problem with keys of an odd (ODD as
|
||||
* not even) length that are extended to the nearest multiple of 2.
|
||||
*
|
||||
* It would be better to use bzero() here and not to call it in
|
||||
* add1key etc. But this change was done just during the FCS process
|
||||
* and may be robust even though it's not the cleanest thing under
|
||||
* the sun.
|
||||
*/
|
||||
|
||||
keyp[pkeydesc2->k2_len - 1] = '\0';
|
||||
|
||||
for (i = 0; i < nparts; i++) {
|
||||
memcpy( keyp + ppart->kp2_offset,recp + ppart->kp2_start,
|
||||
ppart->kp2_leng);
|
||||
ppart++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _allockpage()
|
||||
*
|
||||
* Allocate an initialize new key page.
|
||||
*/
|
||||
|
||||
Bufhdr *
|
||||
_allockpage(fcb, capac, level, blkno)
|
||||
Fcb *fcb;
|
||||
int capac;
|
||||
int level;
|
||||
Blkno *blkno; /* Output parameter */
|
||||
{
|
||||
Bufhdr *pbufhdr;
|
||||
char *p;
|
||||
|
||||
*blkno = _isindfreel_alloc(fcb);
|
||||
|
||||
/* Fix the block in cache */
|
||||
pbufhdr = _isdisk_fix(fcb, fcb->indfd, *blkno, ISFIXNOREAD);
|
||||
|
||||
p = pbufhdr->isb_buffer;
|
||||
|
||||
memset(p, 0, ISPAGESIZE);
|
||||
|
||||
/* Mark page as B-tree page. */
|
||||
stshort((short)PT_INDEX, p + BT_TYPE_OFF);
|
||||
|
||||
/* Store page capacity. */
|
||||
stshort((short)capac, p + BT_CAPAC_OFF);
|
||||
|
||||
/* Store B-tree level. */
|
||||
stshort((short)level, p + BT_LEVEL_OFF);
|
||||
|
||||
return (pbufhdr);
|
||||
}
|
||||
54
cde/lib/tt/mini_isam/iskeycalc.c
Normal file
54
cde/lib/tt/mini_isam/iskeycalc.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iskeycalc.c /main/3 1995/10/23 11:41:29 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iskeycalc.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iskeycalc.c
|
||||
*
|
||||
* Description:
|
||||
* Key related calculation functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
/* getkeysperleaf() - Calculate number of keys per leaf node */
|
||||
int
|
||||
getkeysperleaf (keylen)
|
||||
int keylen;
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ((ISPAGESIZE - BT_KEYS_OFF) / keylen);
|
||||
|
||||
return (le_odd (n)); /* n or n-1 */
|
||||
}
|
||||
|
||||
/* getkeyspernode() - Calculate number of keys per non-leaf node */
|
||||
int
|
||||
getkeyspernode (keylen)
|
||||
int keylen;
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ((ISPAGESIZE - BT_KEYS_OFF) / (keylen + BLKNOSIZE));
|
||||
|
||||
return (le_odd (n)); /* n or n-1 */
|
||||
}
|
||||
|
||||
|
||||
/* le_odd(n) - Get next lower or equal odd number */
|
||||
int
|
||||
le_odd(n)
|
||||
int n;
|
||||
{
|
||||
return ((n - 1) | 1);
|
||||
}
|
||||
162
cde/lib/tt/mini_isam/iskeycmp.c
Normal file
162
cde/lib/tt/mini_isam/iskeycmp.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iskeycmp.c /main/3 1995/10/23 11:41:41 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iskeycmp.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iskeycmp.c
|
||||
*
|
||||
* Description:
|
||||
* ISAM index comparison functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static struct keypart2 *_curtab; /* Current comparison */
|
||||
/* descriptor table */
|
||||
static int _ncurtab; /* Number of entries */
|
||||
|
||||
/*
|
||||
* _iskeycmp_set()
|
||||
*
|
||||
* Set key decriptor and number of parts for subsequent key comparison.s
|
||||
*/
|
||||
|
||||
void
|
||||
_iskeycmp_set (pkeydesc2, nparts)
|
||||
Keydesc2 *pkeydesc2;
|
||||
int nparts; /* Use only so many parts */
|
||||
{
|
||||
_ncurtab = nparts;
|
||||
_curtab = pkeydesc2->k2_part;
|
||||
assert(_ncurtab <= pkeydesc2->k2_nparts + 1); /* + 1 for recno */
|
||||
}
|
||||
|
||||
/*
|
||||
* Return number that is > 0 if l > r,
|
||||
* = 0 if l = r,
|
||||
* < 0 if l < r.
|
||||
*/
|
||||
|
||||
int
|
||||
_iskeycmp(lkey, rkey)
|
||||
char *lkey, *rkey;
|
||||
{
|
||||
int i, ret;
|
||||
register struct keypart2 *p;
|
||||
register char *l, *r;
|
||||
register long llong, rlong;
|
||||
double ldouble, rdouble;
|
||||
|
||||
ret = 0;
|
||||
for (i = 0, p = _curtab; ret == 0 && i < _ncurtab;i++, p++) {
|
||||
|
||||
l = lkey + p->kp2_offset;
|
||||
r = rkey + p->kp2_offset;
|
||||
|
||||
switch (p->kp2_type) {
|
||||
case CHARTYPE:
|
||||
case BINTYPE:
|
||||
ret = memcmp(l, r, p->kp2_leng);
|
||||
break;
|
||||
|
||||
case LONGTYPE:
|
||||
llong = ldlong(l);
|
||||
rlong = ldlong(r);
|
||||
|
||||
if (llong > rlong)
|
||||
ret = 1;
|
||||
else if (llong < rlong)
|
||||
ret = -1;
|
||||
break;
|
||||
|
||||
case SHORTTYPE:
|
||||
llong = (long)ldshort(l);
|
||||
rlong = (long)ldshort(r);
|
||||
|
||||
if (llong > rlong)
|
||||
ret = 1;
|
||||
else if (llong < rlong)
|
||||
ret = -1;
|
||||
break;
|
||||
|
||||
case DOUBLETYPE:
|
||||
ldouble = lddbl(l);
|
||||
rdouble = lddbl(r);
|
||||
|
||||
if (ldouble > rdouble)
|
||||
ret = 1;
|
||||
else if (ldouble < rdouble)
|
||||
ret = -1;
|
||||
break;
|
||||
|
||||
case FLOATTYPE:
|
||||
ldouble = (double)ldfloat(l);
|
||||
rdouble = (double)ldfloat(r);
|
||||
|
||||
if (ldouble > rdouble)
|
||||
ret = 1;
|
||||
else if (ldouble < rdouble)
|
||||
ret = -1;
|
||||
break;
|
||||
|
||||
case CHARTYPE + ISDESC:
|
||||
case BINTYPE + ISDESC:
|
||||
ret = memcmp(r, l, p->kp2_leng);
|
||||
break;
|
||||
|
||||
case LONGTYPE + ISDESC:
|
||||
llong = ldlong(l);
|
||||
rlong = ldlong(r);
|
||||
|
||||
if (llong > rlong)
|
||||
ret = -1;
|
||||
else if (llong < rlong)
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SHORTTYPE + ISDESC:
|
||||
llong = (long)ldshort(l);
|
||||
rlong = (long)ldshort(r);
|
||||
|
||||
if (llong > rlong)
|
||||
ret = -1;
|
||||
else if (llong < rlong)
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case DOUBLETYPE + ISDESC:
|
||||
ldouble = lddbl(l);
|
||||
rdouble = lddbl(r);
|
||||
|
||||
if (ldouble > rdouble)
|
||||
ret = -1;
|
||||
else if (ldouble < rdouble)
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case FLOATTYPE + ISDESC:
|
||||
ldouble = (double)ldfloat(l);
|
||||
rdouble = (double)ldfloat(r);
|
||||
|
||||
if (ldouble > rdouble)
|
||||
ret = -1;
|
||||
else if (ldouble < rdouble)
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
_isfatal_error("Bad data conversion descriptor");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
110
cde/lib/tt/mini_isam/iskeyconv.c
Normal file
110
cde/lib/tt/mini_isam/iskeyconv.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iskeyconv.c /main/3 1995/10/23 11:41:54 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iskeyconv.c 1.4 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iskeyconv.c
|
||||
*
|
||||
* Description:
|
||||
* Conversion functions between internal and external key descriptor
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
/*
|
||||
* _iskey_itox(pikdesc,pxkdesc)
|
||||
*
|
||||
* Convert internal key desc. to X/OPEN key descriptor.
|
||||
*/
|
||||
|
||||
_iskey_itox(pikdesc,pxkdesc)
|
||||
register struct keydesc2 *pikdesc; /* NetISAM internal format */
|
||||
register struct keydesc *pxkdesc; /* X/OPEN format */
|
||||
{
|
||||
int nparts;
|
||||
register int i;
|
||||
|
||||
memset ((char *)pxkdesc, 0, sizeof (*pxkdesc));
|
||||
|
||||
pxkdesc->k_flags = pikdesc->k2_flags;
|
||||
nparts = pxkdesc->k_nparts = pikdesc->k2_nparts;
|
||||
|
||||
for (i = 0; i < nparts;i++) {
|
||||
pxkdesc->k_part[i].kp_start = pikdesc->k2_part[i].kp2_start;
|
||||
pxkdesc->k_part[i].kp_leng = pikdesc->k2_part[i].kp2_leng;
|
||||
pxkdesc->k_part[i].kp_type = pikdesc->k2_part[i].kp2_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _iskey_xtoi()
|
||||
*
|
||||
* Convert X/OPEN key descriptor to internal key descriptor.
|
||||
*
|
||||
*/
|
||||
|
||||
_iskey_xtoi(pikdesc,pxkdesc)
|
||||
register struct keydesc2 *pikdesc; /* NetISAM internal format */
|
||||
register struct keydesc *pxkdesc; /* X/OPEN format */
|
||||
{
|
||||
int nparts;
|
||||
register int i;
|
||||
int offset; /* Keep track of offset in key */
|
||||
|
||||
memset ((char *)pikdesc, 0, sizeof (*pikdesc));
|
||||
|
||||
pikdesc->k2_flags = pxkdesc->k_flags;
|
||||
nparts = pikdesc->k2_nparts = pxkdesc->k_nparts;
|
||||
|
||||
offset = 0;
|
||||
/*
|
||||
* Every key entry starts with record number.
|
||||
*/
|
||||
offset += RECNOSIZE;
|
||||
|
||||
/*
|
||||
* If index allows duplicates, the key is augmented with duplicate
|
||||
* serial number.
|
||||
*/
|
||||
if ((pxkdesc->k_flags & DUPSMASK) == ISDUPS)
|
||||
offset += DUPIDSIZE;
|
||||
|
||||
for (i = 0; i < nparts; i++) {
|
||||
pikdesc->k2_part[i].kp2_start = pxkdesc->k_part[i].kp_start;
|
||||
pikdesc->k2_part[i].kp2_leng = pxkdesc->k_part[i].kp_leng;
|
||||
pikdesc->k2_part[i].kp2_type = pxkdesc->k_part[i].kp_type;
|
||||
pikdesc->k2_part[i].kp2_offset = offset;
|
||||
|
||||
offset += pxkdesc->k_part[i].kp_leng;
|
||||
}
|
||||
|
||||
/* Append recno to key descriptors. */
|
||||
pikdesc->k2_part[i].kp2_start = 0; /* not used */
|
||||
pikdesc->k2_part[i].kp2_leng = RECNOSIZE;
|
||||
pikdesc->k2_part[i].kp2_type = RECNOTYPE;
|
||||
pikdesc->k2_part[i].kp2_offset = KEY_RECNO_OFF; /* at the beginning of key */
|
||||
|
||||
if ((pxkdesc->k_flags & DUPSMASK) == ISDUPS) {
|
||||
/* Append duplicate serial number to key descriptors. */
|
||||
pikdesc->k2_part[i].kp2_start = 0; /* not used */
|
||||
pikdesc->k2_part[i].kp2_leng = DUPIDSIZE;
|
||||
pikdesc->k2_part[i].kp2_type = DUPIDTYPE;
|
||||
pikdesc->k2_part[i].kp2_offset = KEY_DUPS_OFF; /* after recno field */
|
||||
}
|
||||
|
||||
/* Round up to next multiple of 2. */
|
||||
offset = (offset+1) & ~1;
|
||||
|
||||
pikdesc->k2_len = offset; /* Length of the entire key */
|
||||
}
|
||||
101
cde/lib/tt/mini_isam/iskeyvalid.c
Normal file
101
cde/lib/tt/mini_isam/iskeyvalid.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iskeyvalid.c /main/3 1995/10/23 11:42:06 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iskeyvalid.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iskeydesc.c
|
||||
*
|
||||
* Description:
|
||||
* Functions dealing with the keydesc structure.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static int _check_typelen();
|
||||
|
||||
/*
|
||||
* _validate_keydesc(keydesc, minreclen)
|
||||
*
|
||||
* Validate key descriptor. minreclen is needed to make suree that all
|
||||
* the key parts have a meaningful offset.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_validate_keydesc(keydesc, minreclen)
|
||||
register struct keydesc *keydesc;
|
||||
int minreclen;
|
||||
{
|
||||
int nparts;
|
||||
register int i;
|
||||
int type, start, length;
|
||||
int keylen = 0;
|
||||
|
||||
nparts = keydesc->k_nparts;
|
||||
|
||||
if (nparts <= 0 || nparts > NPARTS)
|
||||
return (ISERROR);
|
||||
|
||||
for (i = 0; i < nparts;i++) {
|
||||
|
||||
type = keydesc->k_part[i].kp_type & ~ISDESC;
|
||||
start = keydesc->k_part[i].kp_start;
|
||||
length = keydesc->k_part[i].kp_leng;
|
||||
|
||||
if(_check_typelen(type, length) == ISERROR)
|
||||
return (ISERROR);
|
||||
|
||||
if (type < MINTYPE || type >= MAXTYPE)
|
||||
return (ISERROR);
|
||||
|
||||
if (start < 0 || start + length > minreclen)
|
||||
return (ISERROR);
|
||||
|
||||
keylen += length;
|
||||
}
|
||||
|
||||
if(keylen > MAXKEYSIZE)
|
||||
return (ISERROR);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _check_typelen()
|
||||
*
|
||||
* Check length against the length of the corresponding type.
|
||||
*/
|
||||
|
||||
static int
|
||||
_check_typelen(type, length)
|
||||
int type;
|
||||
int length;
|
||||
{
|
||||
switch (type) {
|
||||
case INTTYPE:
|
||||
return ((length == INTSIZE) ? ISOK : ISERROR);
|
||||
case LONGTYPE:
|
||||
return ((length == LONGSIZE) ? ISOK : ISERROR);
|
||||
case FLOATTYPE:
|
||||
return ((length == FLOATSIZE) ? ISOK : ISERROR);
|
||||
case DOUBLETYPE:
|
||||
return ((length == DOUBLESIZE) ? ISOK : ISERROR);
|
||||
case CHARTYPE:
|
||||
case BINTYPE:
|
||||
return ((length > 0) ? ISOK : ISERROR);
|
||||
default:
|
||||
return (ISERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
183
cde/lib/tt/mini_isam/isminmax.c
Normal file
183
cde/lib/tt/mini_isam/isminmax.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isminmax.c /main/3 1995/10/23 11:42:16 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isminmax.c 1.4 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isminmax.c
|
||||
*
|
||||
* Description:
|
||||
* NetISAM minimum and maximum values functions
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
static unsigned char ismaxlongarr[LONGSIZE] = ISMAXLONG;
|
||||
static unsigned char isminlongarr[LONGSIZE] = ISMINLONG;
|
||||
|
||||
static unsigned char ismaxshortarr[SHORTSIZE] = ISMAXSHORT;
|
||||
static unsigned char isminshortarr[SHORTSIZE] = ISMINSHORT;
|
||||
|
||||
static unsigned char ismaxdoublearr[DOUBLESIZE] = ISMAXDOUBLE;
|
||||
static unsigned char ismindoublearr[DOUBLESIZE] = ISMINDOUBLE;
|
||||
|
||||
static unsigned char ismaxfloatarr[FLOATSIZE] = ISMAXFLOAT;
|
||||
static unsigned char isminfloatarr[FLOATSIZE] = ISMINFLOAT;
|
||||
|
||||
/* These two are used globally. */
|
||||
long *ismaxlong = (long *)ismaxlongarr;
|
||||
long *isminlong = (long *)isminlongarr;
|
||||
|
||||
static short *ismaxshort = (short *)ismaxshortarr;
|
||||
static short *isminshort = (short *)isminshortarr;
|
||||
|
||||
static double *ismaxdouble = (double *)ismaxdoublearr;
|
||||
static double *ismindouble = (double *)ismindoublearr;
|
||||
|
||||
static float *ismaxfloat = (float *)ismaxfloatarr;
|
||||
static float *isminfloat = (float *)isminfloatarr;
|
||||
|
||||
|
||||
/*
|
||||
* _iskey_fillmax()
|
||||
*
|
||||
* Fill key buffer with maximum values
|
||||
*/
|
||||
|
||||
void
|
||||
_iskey_fillmax(pkeydesc2, keybuf)
|
||||
struct keydesc2 *pkeydesc2;
|
||||
register char *keybuf;
|
||||
{
|
||||
register int i;
|
||||
register struct keypart2 *ppart;
|
||||
int nparts;
|
||||
|
||||
nparts = pkeydesc2->k2_nparts;
|
||||
ppart = pkeydesc2->k2_part;
|
||||
|
||||
for (i = 0; i < nparts + 1;i++) { /* +1 is for recnum part */
|
||||
switch (ppart->kp2_type) {
|
||||
case CHARTYPE:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMAXCHAR,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case BINTYPE:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMAXBIN,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case LONGTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxlong, LONGSIZE);
|
||||
break;
|
||||
case SHORTTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxshort, SHORTSIZE);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxfloat, FLOATSIZE);
|
||||
break;
|
||||
case DOUBLETYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxdouble, DOUBLESIZE);
|
||||
break;
|
||||
|
||||
case CHARTYPE + ISDESC:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMINCHAR,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case BINTYPE + ISDESC:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMINBIN,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case LONGTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminlong, LONGSIZE);
|
||||
break;
|
||||
case SHORTTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminshort, SHORTSIZE);
|
||||
break;
|
||||
case FLOATTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminfloat, FLOATSIZE);
|
||||
break;
|
||||
case DOUBLETYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismindouble, DOUBLESIZE);
|
||||
break;
|
||||
default:
|
||||
_isfatal_error("_iskey_fillmax");
|
||||
}
|
||||
ppart++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _iskey_fillmin()
|
||||
*
|
||||
* Fill key buffer with minimum values
|
||||
*/
|
||||
|
||||
void
|
||||
_iskey_fillmin(pkeydesc2, keybuf)
|
||||
struct keydesc2 *pkeydesc2;
|
||||
register char *keybuf;
|
||||
{
|
||||
register int i;
|
||||
register struct keypart2 *ppart;
|
||||
int nparts;
|
||||
|
||||
nparts = pkeydesc2->k2_nparts;
|
||||
ppart = pkeydesc2->k2_part;
|
||||
|
||||
for (i = 0; i < nparts + 1;i++) { /* +1 is for recnum part */
|
||||
switch (ppart->kp2_type) {
|
||||
case CHARTYPE:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMINCHAR,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case BINTYPE:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMINBIN,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case LONGTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminlong, LONGSIZE);
|
||||
break;
|
||||
case SHORTTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminshort, SHORTSIZE);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)isminfloat, FLOATSIZE);
|
||||
break;
|
||||
case DOUBLETYPE:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismindouble, DOUBLESIZE);
|
||||
break;
|
||||
|
||||
case CHARTYPE + ISDESC:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMAXCHAR,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case BINTYPE + ISDESC:
|
||||
(void) memset (keybuf + ppart->kp2_offset, ISMAXBIN,
|
||||
ppart->kp2_leng);
|
||||
break;
|
||||
case LONGTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxlong, LONGSIZE);
|
||||
break;
|
||||
case SHORTTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxshort, SHORTSIZE);
|
||||
break;
|
||||
case FLOATTYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxfloat, FLOATSIZE);
|
||||
break;
|
||||
case DOUBLETYPE + ISDESC:
|
||||
memcpy ( keybuf + ppart->kp2_offset,(char *)ismaxdouble, DOUBLESIZE);
|
||||
break;
|
||||
default:
|
||||
_isfatal_error("_iskey_fillmin");
|
||||
}
|
||||
ppart++;
|
||||
}
|
||||
}
|
||||
214
cde/lib/tt/mini_isam/ismngfcb.c
Normal file
214
cde/lib/tt/mini_isam/ismngfcb.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: ismngfcb.c /main/3 1995/10/23 11:42:28 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ismngfcb.c 1.4 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ismngfcb.c
|
||||
*
|
||||
* Description:
|
||||
* Manager of open FCB blocks.
|
||||
*
|
||||
* This module keeps track of usage of the FCB blocks and finds a victim
|
||||
* on LRU basis.
|
||||
* It also provides associative access to the FCB by their isfhandles.
|
||||
*
|
||||
*/
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
#define FCBHASHSIZE 101 /* Should be a prime for best hash */
|
||||
|
||||
#if (MAXFCB_UNIXFD > FCBHASHSIZE)
|
||||
/*
|
||||
* Cause a syntax error. FCBHASHSIZE must be increased to be > MAXFCB_UNIXFD.
|
||||
* A good estimate is a prime approximately equal (2 * MAXFCB_UNIXFD).
|
||||
*/
|
||||
MUST INCREASE FCBHASHSIZE
|
||||
#endif
|
||||
|
||||
struct hashtable {
|
||||
Bytearray isfhandle;
|
||||
Fcb *fcb;
|
||||
long mrused;
|
||||
} hashtable [FCBHASHSIZE];
|
||||
#define unused(entry) ((entry).fcb == NULL)
|
||||
|
||||
static int _hashisfhandle();
|
||||
|
||||
static mrused_last = 0; /* stamp generator */
|
||||
|
||||
|
||||
/*
|
||||
* _mngfcb_insert(fcb, isfhandle)
|
||||
*
|
||||
* Insert new FCB entry.
|
||||
*/
|
||||
|
||||
void
|
||||
_mngfcb_insert(fcb, isfhandle)
|
||||
Fcb *fcb;
|
||||
Bytearray *isfhandle;
|
||||
{
|
||||
int hashval = _hashisfhandle(isfhandle);
|
||||
register int ind;
|
||||
int ntries;
|
||||
|
||||
/* Try to find an unused entry in the hash table. */
|
||||
ind = hashval;
|
||||
for (ntries = 0; ntries < FCBHASHSIZE; ntries++) {
|
||||
if (unused(hashtable[ind]))
|
||||
break;
|
||||
if (++ind == FCBHASHSIZE)
|
||||
ind = 0; /* Wrap the table */
|
||||
}
|
||||
|
||||
if (ntries == FCBHASHSIZE) {
|
||||
_isfatal_error("FCB hash table overflow");
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an entry at the index ind.
|
||||
* Duplicate the file handle and mark the entry with the current stamp.
|
||||
*/
|
||||
hashtable[ind].isfhandle = _bytearr_dup(isfhandle);
|
||||
hashtable[ind].fcb = fcb;
|
||||
hashtable[ind].mrused = mrused_last++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fcb = _mngfcb_find(isfhandle)
|
||||
*
|
||||
* Return a pointer to the FCB, or NULL if the FCB is not found.
|
||||
* If the FCB is found, it is "touched" for the LRU algorithm purpose.
|
||||
*/
|
||||
|
||||
Fcb *
|
||||
_mngfcb_find(isfhandle)
|
||||
Bytearray *isfhandle;
|
||||
{
|
||||
int hashval = _hashisfhandle(isfhandle);
|
||||
register int ind;
|
||||
int ntries;
|
||||
|
||||
/* Find the entry. */
|
||||
ind = hashval;
|
||||
for (ntries = 0; ntries < FCBHASHSIZE; ntries++) {
|
||||
if (_bytearr_cmp(&hashtable[ind].isfhandle, isfhandle) == 0)
|
||||
break;
|
||||
if (++ind == FCBHASHSIZE)
|
||||
ind = 0; /* Wrap the table */
|
||||
}
|
||||
|
||||
if (ntries == FCBHASHSIZE) {
|
||||
return (NULL); /* Not found */
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Mark the entry with the current stamp.
|
||||
*/
|
||||
hashtable[ind].mrused = mrused_last++;
|
||||
return hashtable[ind].fcb;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _mngfcb_delete(isfname)
|
||||
*
|
||||
* Delete an entry.
|
||||
*/
|
||||
|
||||
void
|
||||
_mngfcb_delete(isfhandle)
|
||||
Bytearray *isfhandle;
|
||||
{
|
||||
int hashval = _hashisfhandle(isfhandle);
|
||||
register int ind;
|
||||
int ntries;
|
||||
|
||||
/* Find the entry */
|
||||
ind = hashval;
|
||||
for (ntries = 0; ntries < FCBHASHSIZE; ntries++) {
|
||||
if (_bytearr_cmp(&hashtable[ind].isfhandle, isfhandle) == 0)
|
||||
break;
|
||||
if (++ind == FCBHASHSIZE)
|
||||
ind = 0; /* Wrap the table */
|
||||
}
|
||||
|
||||
if (ntries == FCBHASHSIZE) {
|
||||
_isfatal_error("_mngfcb_delete cannot find entry");
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Clear the entry.
|
||||
*/
|
||||
_bytearr_free(&hashtable[ind].isfhandle);
|
||||
memset ((char *) &hashtable[ind], 0, sizeof(hashtable[ind]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* isfhandle = _mngfcb_victim()
|
||||
*
|
||||
* Find LRU used FCB.
|
||||
*/
|
||||
|
||||
Bytearray *
|
||||
_mngfcb_victim()
|
||||
{
|
||||
int victim_ind = -1;
|
||||
long victim_time = 0; /* Assign to shut up lint */
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < FCBHASHSIZE; i++) {
|
||||
|
||||
if (unused(hashtable[i])) /* Skip empty slots in table */
|
||||
continue;
|
||||
|
||||
if (victim_ind == -1 || victim_time > hashtable[i].mrused) {
|
||||
victim_ind = i;
|
||||
victim_time = hashtable[i].mrused;
|
||||
}
|
||||
}
|
||||
return ((victim_ind == -1) ? NULL : &hashtable[victim_ind].isfhandle);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _hashisfhandle(isfhandle)
|
||||
*
|
||||
* Hash isfhandle into an integer.
|
||||
*/
|
||||
|
||||
Static int
|
||||
_hashisfhandle(isfhandle)
|
||||
Bytearray *isfhandle;
|
||||
{
|
||||
register char *p;
|
||||
register unsigned h, g;
|
||||
register int len;
|
||||
|
||||
len = isfhandle->length;
|
||||
p = isfhandle->data;
|
||||
h = 0;
|
||||
|
||||
while (len-- > 0) {
|
||||
h = (h << 4) + (*p++);
|
||||
if (g = h&0xf0000000) {
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
return (h % FCBHASHSIZE);
|
||||
}
|
||||
106
cde/lib/tt/mini_isam/isopen.c
Normal file
106
cde/lib/tt/mini_isam/isopen.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isopen.c /main/3 1995/10/23 11:42:40 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isopen.c 1.12 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isopen.c
|
||||
*
|
||||
* Description:
|
||||
* Open an ISAM file.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <netdb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
extern char _isam_version[];
|
||||
static char *_version_ = _isam_version;
|
||||
|
||||
static int _am_open();
|
||||
/*
|
||||
* isfd = isopen(isfname, mode)
|
||||
*
|
||||
* Isopen() determines on which machine the ISAM file resides,
|
||||
* checks if the file exists, creates a File access block,
|
||||
* and initilizes it. It also checks permissions. Returns an ISAM file
|
||||
* descriptor (isfd), or a value of -1 if the open failed.
|
||||
*
|
||||
* Errors:
|
||||
* EBADARG Improper mode parameter
|
||||
* EBADFILE ISAM file is corrupted or it is not an NetISAM file
|
||||
* EFLOCKED The file is exclusively locked by other process.
|
||||
* EFNAME Invalid ISAM file name
|
||||
* EFNAME ISAM file does not exist
|
||||
* ETOOMANY Too many ISAM file descriptors are in use (128 is the limit)
|
||||
*
|
||||
* The following error code is "borrowed" from UNIX:
|
||||
* EACCES UNIX file system protection denies access to the file:
|
||||
* - mode is INOUT or OUTPUT and ISAM file is on
|
||||
* a Read-Only mounted file system
|
||||
* - UNIX file permissions don't allow access to the file
|
||||
*/
|
||||
|
||||
int
|
||||
isopen(isfname, mode)
|
||||
char *isfname;
|
||||
int mode;
|
||||
{
|
||||
Fab *fab;
|
||||
Isfd isfd;
|
||||
enum openmode openmode;
|
||||
|
||||
/*
|
||||
* Check if the user is allowed to access the ISAM file.
|
||||
* Use UNIX and NFS permissions.
|
||||
*/
|
||||
|
||||
/* Get file open mode part of the mode parameter. */
|
||||
if ((openmode = _getopenmode(mode)) == OM_BADMODE) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
/* Create a Fab object. */
|
||||
fab = _fab_new(isfname,
|
||||
openmode,
|
||||
(Bool)((mode & ISLENMODE) == ISVARLEN),
|
||||
0,
|
||||
0);
|
||||
if (fab == NULL) {
|
||||
return (NOISFD); /* iserrno is set by fab_new */
|
||||
}
|
||||
|
||||
/* Get an ISAM file descriptor for this fab */
|
||||
if ((isfd = _isfd_insert(fab)) == NOISFD) {
|
||||
/* Table of ISAM file descriptors would overflow. */
|
||||
_fab_destroy(fab);
|
||||
_setiserrno2(ETOOMANY, '9', '0');
|
||||
return (NOISFD);
|
||||
}
|
||||
FAB_ISFDSET(fab, isfd);
|
||||
if (_am_open(fab)) {
|
||||
_seterr_errcode(&fab->errcode);
|
||||
_fab_destroy(fab);
|
||||
return (NOISFD);
|
||||
}
|
||||
|
||||
isreclen = fab->maxreclen;
|
||||
|
||||
return ((int)isfd); /* Successful isopen() */
|
||||
}
|
||||
|
||||
Static int _am_open(fab)
|
||||
register Fab *fab;
|
||||
{
|
||||
return (_amopen(fab->isfname, fab->openmode, &fab->varlength,
|
||||
&fab->minreclen, &fab->maxreclen, &fab->isfhandle,
|
||||
&fab->curpos, &fab->errcode));
|
||||
}
|
||||
69
cde/lib/tt/mini_isam/ispageio.c
Normal file
69
cde/lib/tt/mini_isam/ispageio.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: ispageio.c /main/3 1995/10/23 11:42:51 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ispageio.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ispageio.c
|
||||
*
|
||||
* Description:
|
||||
* I/O functions for file pages.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
/*
|
||||
* _isseekpg(fd, pgno)
|
||||
*
|
||||
* Set current file pointer to the page pgno.
|
||||
*/
|
||||
|
||||
void
|
||||
_isseekpg(fd, pgno)
|
||||
int fd;
|
||||
Blkno pgno;
|
||||
{
|
||||
long offset = pgno * ISPAGESIZE;
|
||||
|
||||
if (lseek(fd, offset, 0) != offset)
|
||||
_isfatal_error("lseek failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* _isreadpg(fd, buf)
|
||||
*
|
||||
* Read eon block from UNIX file into a buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
_isreadpg(fd, buf)
|
||||
int fd;
|
||||
char *buf;
|
||||
{
|
||||
if (read(fd, buf, ISPAGESIZE) != ISPAGESIZE)
|
||||
_isfatal_error("read failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* _iswritepg(fd, buf)
|
||||
*
|
||||
* Write one block to UNIX file.
|
||||
*/
|
||||
|
||||
void
|
||||
_iswritepg(fd, buf)
|
||||
int fd;
|
||||
char *buf;
|
||||
{
|
||||
if (write(fd, buf, ISPAGESIZE) != ISPAGESIZE)
|
||||
_isfatal_error("write failed");
|
||||
}
|
||||
79
cde/lib/tt/mini_isam/isperm.c
Normal file
79
cde/lib/tt/mini_isam/isperm.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isperm.c /main/3 1995/10/23 11:43:03 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isperm.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isperm.c
|
||||
*
|
||||
* Description:
|
||||
* Extract permissions from mode functions.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
|
||||
/*
|
||||
* _getopenmode(mode)
|
||||
*
|
||||
* Extract open mode (ISINPUT, ISOUTPUT, ISINOUT) from mode.
|
||||
*/
|
||||
|
||||
enum openmode
|
||||
_getopenmode(mode)
|
||||
int mode;
|
||||
{
|
||||
switch (mode & ISOPENMODE) {
|
||||
case ISINPUT:
|
||||
return (OM_INPUT);
|
||||
case ISOUTPUT:
|
||||
return (OM_OUTPUT);
|
||||
case ISINOUT:
|
||||
return (OM_INOUT);
|
||||
default:
|
||||
return (OM_BADMODE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _getreadmode(mode)
|
||||
*
|
||||
* Extract read mode from mode.
|
||||
*/
|
||||
|
||||
enum readmode
|
||||
_getreadmode(mode)
|
||||
int mode;
|
||||
{
|
||||
switch (mode & ISREADMODE) {
|
||||
case ISFIRST:
|
||||
return (RM_FIRST);
|
||||
case ISLAST:
|
||||
return (RM_LAST);
|
||||
case ISNEXT:
|
||||
return (RM_NEXT);
|
||||
case ISPREV:
|
||||
return (RM_PREV);
|
||||
case ISCURR:
|
||||
return (RM_CURR);
|
||||
case ISEQUAL:
|
||||
return (RM_EQUAL);
|
||||
case ISGREAT:
|
||||
return (RM_GREAT);
|
||||
case ISGTEQ:
|
||||
return (RM_GTEQ);
|
||||
case ISLESS:
|
||||
return (RM_LESS);
|
||||
case ISLTEQ:
|
||||
return (RM_LTEQ);
|
||||
default:
|
||||
return (RM_BADMODE);
|
||||
}
|
||||
}
|
||||
796
cde/lib/tt/mini_isam/isread.c
Normal file
796
cde/lib/tt/mini_isam/isread.c
Normal file
@@ -0,0 +1,796 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isread.c /main/3 1995/10/23 11:43:35 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isread.c 1.9 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isread.c
|
||||
*
|
||||
* Description:
|
||||
* Read a record from ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amread();
|
||||
|
||||
/*
|
||||
* err = isread(isfd, record, mode)
|
||||
*
|
||||
* Isread() reads a new record from an ISAM file.
|
||||
*
|
||||
* Current record position is set.
|
||||
* isrecnum is set to indicate the read record.
|
||||
*
|
||||
* If the ISAM file is for variable length records, the isreclen variable
|
||||
* is set to indicate the actual length of the record.
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* ELOCKED The record or the entire file is locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was opened with ISOUTPUT mode.
|
||||
* EBADARG Bad mode parameter.
|
||||
* ENOCURR Mode is ISCURR and the current record position is not set.
|
||||
* ENOREC Specified record cannot be found (random access read)
|
||||
* EENDFILE The end file of is reached (sequential read).
|
||||
* EBADKEY Index was deleted by other process (can happen only
|
||||
* when lock file is purged).
|
||||
*/
|
||||
|
||||
int
|
||||
isread(isfd, record, mode)
|
||||
int isfd;
|
||||
char *record;
|
||||
int mode;
|
||||
{
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
Recno recnum;
|
||||
int ret;
|
||||
enum readmode readmode;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract read mode.
|
||||
*/
|
||||
if ((readmode = _getreadmode(mode)) == RM_BADMODE) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* All keys must be in the minimum record length.
|
||||
* So send just the minimum length part of the record.
|
||||
*/
|
||||
reclen = fab->minreclen;
|
||||
|
||||
/*
|
||||
* Call the Access Method
|
||||
*/
|
||||
recnum = isrecnum;
|
||||
|
||||
if ((ret = _amread(&fab->isfhandle, record, &reclen,
|
||||
readmode, &fab->curpos, &recnum,
|
||||
&fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
isreclen = reclen;
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful read */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amread(isfhandle, record, reclen, readmode, curpos, recnum, errcode)
|
||||
*
|
||||
* _amread() reads a record from ISAM file
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* readmode Specifies access mode (random or sequential)
|
||||
* curpos current record position
|
||||
* recnum copy if isrecnum
|
||||
*
|
||||
* Output params:
|
||||
* curpos new current position
|
||||
* recnum record number
|
||||
* errcode error status of the operation
|
||||
* reclen actual length of the record
|
||||
* record filled with data
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amread(isfhandle, record, reclen, readmode, curpos, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
enum readmode readmode;
|
||||
char *record;
|
||||
int *reclen;
|
||||
Bytearray *curpos;
|
||||
Recno *recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
Recno recnum2;
|
||||
int err;
|
||||
Crp *crp;
|
||||
Btree *btree = NULL;
|
||||
Keydesc2 *pkeydesc2;
|
||||
char keybuf1[MAXKEYSIZE], keybuf2[MAXKEYSIZE];
|
||||
char *pkey, *pkeynext;
|
||||
int skipbytes;
|
||||
int ret;
|
||||
Bytearray oldcurpos;
|
||||
int (*rec_read)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
/*
|
||||
* Save the old record position.
|
||||
*/
|
||||
oldcurpos = _bytearr_dup(curpos);
|
||||
|
||||
/*
|
||||
* Get info from current record position structure.
|
||||
*/
|
||||
crp = (Crp *) curpos->data;
|
||||
|
||||
if (crp->keyid == PHYS_ORDER) {
|
||||
/*
|
||||
* Physical order in use.
|
||||
*/
|
||||
|
||||
switch (readmode) {
|
||||
case RM_EQUAL:
|
||||
recnum2 = *recnum; /* passed from isrecnum */
|
||||
if ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_GREAT:
|
||||
recnum2 = *recnum + 1;
|
||||
if (recnum2 < 1) recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_GTEQ:
|
||||
recnum2 = *recnum;
|
||||
if (recnum2 < 1) recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_LESS:
|
||||
recnum2 = *recnum - 1;
|
||||
if (recnum2 > fcb->lastrecno) recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_LTEQ:
|
||||
recnum2 = *recnum;
|
||||
if (recnum2 > fcb->lastrecno) recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_FIRST:
|
||||
recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case RM_CURR:
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_BEFORE:
|
||||
case CRP_AFTER:
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
case CRP_BEFOREANY:
|
||||
recnum2 = 1;
|
||||
break;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if( rec_read(fcb, record, recnum2, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case RM_NEXT:
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_AFTER:
|
||||
recnum2 = crp->recno + 1;
|
||||
break;
|
||||
case CRP_BEFOREANY:
|
||||
recnum2 = 1;
|
||||
break;
|
||||
case CRP_BEFORE:
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
case CRP_AFTERANY:
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case RM_PREV:
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_BEFORE:
|
||||
recnum2 = crp->recno - 1;
|
||||
break;
|
||||
case CRP_AFTER:
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
case CRP_BEFOREANY:
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case RM_LAST:
|
||||
recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, record, recnum2, reclen)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_isfatal_error("Invalid readmode");
|
||||
}
|
||||
|
||||
*recnum = recnum2;
|
||||
|
||||
/*
|
||||
* Set new current record position.
|
||||
*/
|
||||
crp->recno = recnum2;
|
||||
crp->flag = CRP_ON;
|
||||
|
||||
} /* physical order */
|
||||
else {
|
||||
/*
|
||||
* Find key descriptor in FCB
|
||||
*/
|
||||
if ((pkeydesc2 = _isfcb_indfindkey(fcb, crp->keyid)) == NULL) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* skipkeybytes is set to the number of bytes in the beginning
|
||||
* of the key:
|
||||
* RECNOSIZE for ISNODUPS keys to skip recno part
|
||||
* RECNOSIZE + DUPIDSIZE to skip recno and duplicate serial number
|
||||
*/
|
||||
skipbytes = RECNOSIZE;
|
||||
if (ALLOWS_DUPS2(pkeydesc2))
|
||||
skipbytes += DUPIDSIZE;
|
||||
|
||||
/*
|
||||
* Create B tree object.
|
||||
*/
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
|
||||
switch (readmode) {
|
||||
case RM_EQUAL:
|
||||
case RM_GTEQ:
|
||||
/*
|
||||
* Make sure that you will read the first duplicate.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy((void *)(keybuf1 + skipbytes),
|
||||
(const void *)(keybuf2 + skipbytes), crp->matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (readmode == RM_EQUAL &&
|
||||
memcmp(keybuf1 + skipbytes, pkey + skipbytes,
|
||||
crp->matchkeylen) != 0) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_GREAT:
|
||||
/*
|
||||
* Make sure that you will read past all matching records.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy((void *)(keybuf1 + skipbytes),
|
||||
(const void *)(keybuf2 + skipbytes), crp->matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_LESS:
|
||||
/*
|
||||
* Make sure that you will read before all matching records.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy((void *)(keybuf1 + skipbytes),
|
||||
(const void *)(keybuf2 + skipbytes), crp->matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_LTEQ:
|
||||
/*
|
||||
* Make sure that you will read the last duplicate.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy((void *)(keybuf1 + skipbytes),
|
||||
(const void *)(keybuf2 + skipbytes), crp->matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_CURR:
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_BEFORE:
|
||||
case CRP_AFTER:
|
||||
/*
|
||||
* We have check if the record has not been deleted
|
||||
* since the current record position was set up.
|
||||
*/
|
||||
_isbtree_search(btree, crp->key);
|
||||
pkey = _isbtree_current(btree);
|
||||
|
||||
if (pkey == NULL ||
|
||||
ldrecno(pkey + KEY_RECNO_OFF) != crp->recno) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case CRP_BEFOREANY:
|
||||
_isbtree_search(btree, crp->key);
|
||||
pkey = _isbtree_next(btree);
|
||||
|
||||
if (pkey == NULL) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
break;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_NEXT:
|
||||
|
||||
/*
|
||||
* Validate that current position has been set.
|
||||
*/
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_BEFORE:
|
||||
case CRP_BEFOREANY:
|
||||
break;
|
||||
case CRP_AFTERANY:
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Position pointer to current position.
|
||||
*/
|
||||
_isbtree_search(btree, crp->key);
|
||||
|
||||
if (crp->flag == CRP_BEFORE)
|
||||
pkey = _isbtree_current(btree);
|
||||
else
|
||||
/* crp->flag == CRP_ON || crp->flag == CRP_BEFOREANY */
|
||||
pkey = _isbtree_next(btree);
|
||||
|
||||
if (pkey == NULL) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_PREV:
|
||||
|
||||
/*
|
||||
* Validate that current position has been set.
|
||||
*/
|
||||
switch (crp->flag) {
|
||||
case CRP_ON:
|
||||
case CRP_BEFORE:
|
||||
/*
|
||||
* To get to the previous record, we must decrement
|
||||
* the TID part for unique keys, or duplicate serial number
|
||||
* for non-unique keys.
|
||||
*/
|
||||
memcpy((void *)keybuf1,
|
||||
(const void *)crp->key, pkeydesc2->k2_len);
|
||||
if (ALLOWS_DUPS2(pkeydesc2)) {
|
||||
stlong(ldlong(keybuf1 + KEY_DUPS_OFF) - 1,
|
||||
keybuf1 + KEY_DUPS_OFF);
|
||||
}
|
||||
else {
|
||||
strecno(ldrecno(keybuf1 + KEY_RECNO_OFF) - 1,
|
||||
keybuf1 + KEY_RECNO_OFF);
|
||||
}
|
||||
break;
|
||||
case CRP_AFTER:
|
||||
memcpy((void *)keybuf1, (const void *)crp->key, pkeydesc2->k2_len);
|
||||
break;
|
||||
case CRP_BEFOREANY:
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
default:
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Position pointer to current position.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
pkey = _isbtree_current(btree);
|
||||
|
||||
if (pkey == NULL) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_FIRST:
|
||||
/*
|
||||
* Fill key buffer with -infinity.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree before any key entry.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
case RM_LAST:
|
||||
/*
|
||||
* Fill key buffer with +infinity.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree before any key entry.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
crp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy((void *)crp->key, (const void *)pkey, pkeydesc2->k2_len);
|
||||
|
||||
if( rec_read(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, EENDFILE);
|
||||
goto ERROR;
|
||||
}
|
||||
recnum2 = crp->recno;
|
||||
break;
|
||||
|
||||
default:
|
||||
_isfatal_error("Invalid readmode");
|
||||
}
|
||||
|
||||
*recnum = recnum2;
|
||||
crp->flag = CRP_ON;
|
||||
|
||||
/*
|
||||
* Set up isdupl to handle isstat2 value for keys that allow
|
||||
* duplicate values.
|
||||
*/
|
||||
if (ALLOWS_DUPS2(pkeydesc2) && (pkeynext = _isbtree_next(btree)) &&
|
||||
memcmp(pkey + skipbytes, pkeynext + skipbytes,
|
||||
crp->matchkeylen) == 0) {
|
||||
isdupl = 1;
|
||||
}
|
||||
|
||||
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
ret = ISOK;
|
||||
|
||||
/* Clean-up work. */
|
||||
_isdisk_commit(); /* This will only check
|
||||
* that we unfixed all fixed
|
||||
* buffers */
|
||||
_isdisk_inval();
|
||||
_bytearr_free(&oldcurpos);
|
||||
|
||||
_isam_exithook();
|
||||
return (ret);
|
||||
|
||||
ERROR:
|
||||
|
||||
*reclen = 0;
|
||||
|
||||
_isdisk_inval();
|
||||
|
||||
_bytearr_free(&oldcurpos);
|
||||
|
||||
/*
|
||||
* If error is ENOREC, set the current record position undefined.
|
||||
*/
|
||||
if (errcode->iserrno == ENOREC || errcode->iserrno == EENDFILE) {
|
||||
((Crp *)curpos->data)->flag = CRP_UNDEF;
|
||||
}
|
||||
|
||||
if (btree != NULL)
|
||||
_isbtree_destroy(btree);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
265
cde/lib/tt/mini_isam/isrename.c
Normal file
265
cde/lib/tt/mini_isam/isrename.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isrename.c /main/3 1995/10/23 11:43:48 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isrename.c 1.10 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isrename.c
|
||||
*
|
||||
* Description:
|
||||
* Rename an ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
void _removelast();
|
||||
static void _removelast2();
|
||||
char *_lastelement();
|
||||
static void _rename_datfile(), _rename_indfile(), _rename_varfile();
|
||||
static int _amrename();
|
||||
|
||||
/*
|
||||
* isfd = isrename(oldname, newname)
|
||||
*
|
||||
*
|
||||
* Errors:
|
||||
* EBADFILE ISAM file is corrupted or it is not an NetISAM file
|
||||
* EFLOCKED The file is exclusively locked by other process.
|
||||
* EFNAME Invalid ISAM file name
|
||||
* EFNAME ISAM file does not exist
|
||||
* ETOOMANY Too many ISAM file descriptors are in use (128 is the limit)
|
||||
*
|
||||
* The following error code is "borrowed" from UNIX:
|
||||
* EACCES UNIX file system protection denies access to the file:
|
||||
* - mode is INOUT or OUTPUT and ISAM file is on
|
||||
* a Read-Only mounted file system
|
||||
* - UNIX file permissions don't allow access to the file
|
||||
*/
|
||||
|
||||
int
|
||||
isrename(oldname, newname)
|
||||
char *oldname, *newname;
|
||||
{
|
||||
Isfd isfd, isfd2;
|
||||
Fab *fab;
|
||||
char olddir [MAXPATHLEN];
|
||||
char newdir [MAXPATHLEN];
|
||||
char datfname[MAXPATHLEN];
|
||||
|
||||
/*
|
||||
* Check that the odl and new filename are in the same directory.
|
||||
*/
|
||||
(void)strcpy(olddir, oldname);
|
||||
_removelast2(olddir);
|
||||
(void)strcpy(newdir, newname);
|
||||
_removelast2(newdir);
|
||||
|
||||
if (strcmp(newdir, olddir) != 0) {
|
||||
_setiserrno2(EFNAME, 9, 0);
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file
|
||||
*/
|
||||
if ((isfd = isopen(oldname, ISINOUT)) == -1)
|
||||
return (ISERROR); /* iserrno is set */
|
||||
|
||||
/*
|
||||
* Reject rename if 'newfile' exists.
|
||||
*/
|
||||
if ((isfd2 = isopen(newname, ISINOUT)) != -1 || iserrno != ENOENT) {
|
||||
|
||||
_setiserrno2(EEXIST, 9, 0);
|
||||
if (isfd2 >= 0) (void)isclose(isfd2);
|
||||
return (ISERROR); /* iserrno is set */
|
||||
}
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_isfatal_error("isrename() cannot find FAB");
|
||||
_setiserrno2(EFATAL,'9','0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if (_amrename(&fab->isfhandle, _lastelement(newname), &fab->errcode)) {
|
||||
_seterr_errcode(&fab->errcode);
|
||||
(void)isclose(isfd);
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_fab_destroy(fab); /* Deallocate Fab object */
|
||||
_isfd_delete(isfd);
|
||||
|
||||
/*
|
||||
* We must unlink() the .rec file, or isbuild() with the same
|
||||
* following immediatly would fail because for NFS files the client
|
||||
* still thinks that the file exists for a few seconds.
|
||||
*/
|
||||
|
||||
(void)strcpy(datfname, oldname);
|
||||
_makedat_isfname(datfname);
|
||||
(void)unlink(datfname);
|
||||
|
||||
return (ISOK); /* Successful isrename() */
|
||||
}
|
||||
|
||||
/*
|
||||
* _removelast2(path)
|
||||
*
|
||||
* Remove last element of path. E.g. /usr/db/part yields /usr/db.
|
||||
* Unlike _removelast() that path does not have to start with '/'.
|
||||
*/
|
||||
|
||||
Static void
|
||||
_removelast2(path)
|
||||
char *path;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
for (p = path + strlen(path); *--p != '/' && p >= path; )
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* _amrename(isfhandle, newname)
|
||||
*
|
||||
* _amrename() renames ISAM file
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
*
|
||||
* Output params:
|
||||
* errcode Error code
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static int
|
||||
_amrename(isfhandle, newname, errcode)
|
||||
Bytearray *isfhandle;
|
||||
char *newname;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
char *isfname = _getisfname(isfhandle);
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete FCB and remove it from FCB cache.
|
||||
*/
|
||||
(void) _watchfd_decr(_isfcb_nfds(fcb));
|
||||
_isfcb_close(fcb);
|
||||
_mngfcb_delete(isfhandle);
|
||||
|
||||
/*
|
||||
* Rename all UNIX files.
|
||||
*/
|
||||
_rename_datfile(isfname, newname);
|
||||
_rename_indfile(isfname, newname);
|
||||
_rename_varfile(isfname, newname);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
Static void
|
||||
_rename_datfile(isfname, newname)
|
||||
char *isfname;
|
||||
char *newname; /* with no prefix */
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
char newbuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
(void) strcpy(newbuf, isfname);
|
||||
|
||||
/*
|
||||
* Replace the last element of the old path with newname.
|
||||
*/
|
||||
_removelast(newbuf);
|
||||
if (strcmp(newbuf, "/") != 0)
|
||||
(void) strcat(newbuf, "/");
|
||||
(void)strcat(newbuf, newname);
|
||||
|
||||
_makedat_isfname(namebuf);
|
||||
_makedat_isfname(newbuf);
|
||||
|
||||
(void)rename(namebuf, newbuf);
|
||||
}
|
||||
|
||||
Static void
|
||||
_rename_indfile(isfname, newname)
|
||||
char *isfname;
|
||||
char *newname; /* with no prefix */
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
char newbuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
(void) strcpy(newbuf, isfname);
|
||||
|
||||
/*
|
||||
* Replace the last element of the old path with newname.
|
||||
*/
|
||||
_removelast(newbuf);
|
||||
if (strcmp(newbuf, "/") != 0)
|
||||
(void) strcat(newbuf, "/");
|
||||
(void)strcat(newbuf, newname);
|
||||
|
||||
_makeind_isfname(namebuf);
|
||||
_makeind_isfname(newbuf);
|
||||
|
||||
(void)rename(namebuf, newbuf);
|
||||
}
|
||||
|
||||
Static void
|
||||
_rename_varfile(isfname, newname)
|
||||
char *isfname;
|
||||
char *newname; /* with no prefix */
|
||||
{
|
||||
char namebuf[MAXPATHLEN];
|
||||
char newbuf[MAXPATHLEN];
|
||||
|
||||
(void) strcpy(namebuf, isfname);
|
||||
(void) strcpy(newbuf, isfname);
|
||||
|
||||
/*
|
||||
* Replace the last element of the old path with newname.
|
||||
*/
|
||||
_removelast(newbuf);
|
||||
if (strcmp(newbuf, "/") != 0)
|
||||
(void) strcat(newbuf, "/");
|
||||
(void)strcat(newbuf, newname);
|
||||
|
||||
_makevar_isfname(namebuf);
|
||||
_makevar_isfname(newbuf);
|
||||
|
||||
(void)rename(namebuf, newbuf);
|
||||
}
|
||||
|
||||
441
cde/lib/tt/mini_isam/isrepair.c
Normal file
441
cde/lib/tt/mini_isam/isrepair.c
Normal file
@@ -0,0 +1,441 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: isrepair.c /main/5 1998/04/10 08:04:42 mgreess $ */
|
||||
/* @(#)isrepair.c 1.7 93/07/30
|
||||
* Copyright (c) 1988, 1993 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isrepair.c
|
||||
*
|
||||
* Description:
|
||||
* Repair an ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
* err = isrepair(isfname, verbose)
|
||||
*
|
||||
* isrepair repairs an ISAM file.
|
||||
*
|
||||
* The algorithm used is as the following:
|
||||
* 1. Read the control page of the possibly damaged file. We assume
|
||||
* that the control page is not damaged.
|
||||
* 2. Open a new ISAM file with ~ suffix.
|
||||
* 3. Scan .rec file (and .var file if variable length records file)
|
||||
* retrieve all records not marked as deleted, and write them
|
||||
* to the ~ ISAM file.
|
||||
* 4. Delete the old ISAM file.
|
||||
* 5. Rename ~ file to the original file name.
|
||||
* 6. Build all indexes.
|
||||
*
|
||||
* verbose option (if set to nonzero) will print messages to stdout.
|
||||
*/
|
||||
|
||||
Static char *rp_readrecord_v(), *rp_readrecord_f();
|
||||
Static printkey();
|
||||
Static cmd_error();
|
||||
Static int typeletter();
|
||||
Static rp_readcntlpg();
|
||||
static int isnoprintf(const char *, ...);
|
||||
isrepair(isfname, verbose)
|
||||
char *isfname;
|
||||
int verbose;
|
||||
{
|
||||
extern char *rp_readrecord_v(), *rp_readrecord_f();
|
||||
char cntlpg[ISCNTLSIZE];
|
||||
int datfd, indfd, varfd;
|
||||
int minreclen, maxreclen;
|
||||
int nrecords_fromcntl;
|
||||
int varflag;
|
||||
char nameBuf [MAXPATHLEN];
|
||||
char *namebuf;
|
||||
int isfd = -1;
|
||||
struct keydesc2 keydesc2;
|
||||
int i;
|
||||
long offset, recfile_end;
|
||||
char *prec;
|
||||
long recnum;
|
||||
int nrecords_found, diff;
|
||||
long lastrecno;
|
||||
struct keydesc keydesc;
|
||||
int (*print)(const char *, ...);
|
||||
sigset_t oldmask;
|
||||
sigset_t allsignals;
|
||||
char Buffer[BUFSIZ];
|
||||
char *buffer;
|
||||
|
||||
|
||||
print = verbose ? printf : isnoprintf;
|
||||
datfd = indfd = varfd = -1;
|
||||
|
||||
/*
|
||||
* Open UNIX files.
|
||||
*/
|
||||
if (strlen(isfname) + 10 >= MAXPATHLEN)
|
||||
namebuf = (char*) malloc(strlen(isfname) + 10);
|
||||
else
|
||||
namebuf = nameBuf;
|
||||
|
||||
(void)strcpy(namebuf, isfname);
|
||||
_makedat_isfname(namebuf);
|
||||
datfd = open(namebuf, O_RDONLY);
|
||||
if (datfd > -1) {
|
||||
fcntl(datfd, F_SETFD, 1);
|
||||
}
|
||||
|
||||
(void)strcpy(namebuf, isfname);
|
||||
_makeind_isfname(namebuf);
|
||||
indfd = open(namebuf, O_RDONLY);
|
||||
if (indfd > -1) {
|
||||
fcntl(indfd, F_SETFD, 1);
|
||||
}
|
||||
|
||||
(void)strcpy(namebuf, isfname);
|
||||
_makevar_isfname(namebuf);
|
||||
varfd = open(namebuf, O_RDONLY);
|
||||
if (varfd > -1) {
|
||||
fcntl(varfd, F_SETFD, 1);
|
||||
}
|
||||
|
||||
(void)print("Reading control page from %s.rec file...\n",
|
||||
isfname);
|
||||
if (rp_readcntlpg(datfd, cntlpg) == ISERROR) {
|
||||
(void)print("Cannot read the control page\n");
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check magic. Repair only ISAM files!!!
|
||||
*/
|
||||
|
||||
if (strncmp(cntlpg + CP_MAGIC_OFF, ISMAGIC, strlen(ISMAGIC)) != 0) {
|
||||
(void)print("Bad magic in %s.rec\n", isfname);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
varflag = ldint(cntlpg + CP_VARFLAG_OFF);
|
||||
minreclen = ldint(cntlpg + CP_MINRECLEN_OFF);
|
||||
maxreclen = ldint(cntlpg + CP_MAXRECLEN_OFF);
|
||||
|
||||
/*
|
||||
* Check for maxreclen field value of -1. This could have occured due to
|
||||
* ISMAXRECLEN being incorrectly set to 65535 in an earlier version. If
|
||||
* this field is -1 and it's a variable length record, reset to the new
|
||||
* value of MAXRECLEN. This means that this field will be repaired when
|
||||
* the control block is written back to disk.
|
||||
*/
|
||||
|
||||
if (maxreclen == -1 && varflag) {
|
||||
maxreclen = ISMAXRECLEN;
|
||||
}
|
||||
|
||||
lastrecno = ldlong(cntlpg + CP_LASTRECNO_OFF);
|
||||
nrecords_fromcntl = ldlong(cntlpg + CP_NRECORDS_OFF);
|
||||
|
||||
/*
|
||||
* Open output file. Use ~ as suffix.
|
||||
*/
|
||||
(void)sprintf(namebuf, "%s~", isfname);
|
||||
(void)print("Opening temporary ISAM file '%s'...\n",
|
||||
namebuf);
|
||||
isreclen = minreclen;
|
||||
if ((isfd = isbuild(namebuf, maxreclen, nokey, ISINOUT + ISEXCLLOCK +
|
||||
(varflag?ISVARLEN:0))) == ISERROR) {
|
||||
(void)print("Cannot open temporary ISAM file %s\n",
|
||||
namebuf);
|
||||
if (iserrno == EEXIST)
|
||||
(void)print("File %s already exists\n", namebuf);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan .rec file and read all undeleted records.
|
||||
*/
|
||||
(void)print("Salvaging records from %s.rec%s file...\n",
|
||||
isfname, varflag?" (and .var file)" : "");
|
||||
|
||||
offset = ISCNTLSIZE;
|
||||
recfile_end = lseek(datfd, 0L, 2);
|
||||
recnum = 1;
|
||||
nrecords_found = 0;
|
||||
|
||||
while (recnum <= lastrecno && offset < recfile_end - minreclen) {
|
||||
|
||||
if (varflag) {
|
||||
prec = rp_readrecord_v(datfd, varfd, offset, minreclen, maxreclen);
|
||||
offset += minreclen + LONGSIZE;
|
||||
}
|
||||
else {
|
||||
prec = rp_readrecord_f(datfd, offset, minreclen);
|
||||
offset += minreclen + 1;
|
||||
}
|
||||
|
||||
if (prec != NULL) {
|
||||
if (iswrrec(isfd, recnum, prec) == ISERROR) {
|
||||
cmd_error("iswrrec", print);
|
||||
goto ERROR;
|
||||
}
|
||||
nrecords_found++;
|
||||
}
|
||||
recnum++;
|
||||
}
|
||||
|
||||
diff = nrecords_found - nrecords_fromcntl;
|
||||
|
||||
if (diff == 0)
|
||||
(void)print("All records found - total %d records\n",
|
||||
nrecords_found);
|
||||
else
|
||||
(void)print("%d records found - %d records %s than in header\n",
|
||||
nrecords_found, diff, diff > 0 ?
|
||||
"more" : "less");
|
||||
|
||||
/*
|
||||
* Close all file descriptors.
|
||||
*/
|
||||
(void)close(datfd);
|
||||
(void)close(indfd);
|
||||
(void)close(varfd);
|
||||
(void)isclose(isfd);
|
||||
|
||||
(void) sigfillset(&allsignals);
|
||||
(void) sigprocmask(SIG_SETMASK, &allsignals, &oldmask);
|
||||
|
||||
(void)print("Erasing ISAM file '%s'...\n", isfname);
|
||||
/* if (iserase(isfname) != ISOK) {
|
||||
cmd_error("iserase", print);
|
||||
goto ERROR;
|
||||
}
|
||||
*/
|
||||
if (strlen(isfname) + 5 >= MAXPATHLEN)
|
||||
buffer = (char*) malloc(strlen(isfname) + 5);
|
||||
else
|
||||
buffer = Buffer;
|
||||
|
||||
(void)sprintf(buffer,"%s.rec", isfname);
|
||||
(void)unlink(buffer);
|
||||
(void)sprintf(buffer,"%s.ind", isfname);
|
||||
(void)unlink(buffer);
|
||||
(void)sprintf(buffer,"%s.var", isfname);
|
||||
(void)unlink(buffer);
|
||||
|
||||
(void)sprintf(namebuf, "%s~", isfname);
|
||||
(void)print("Renaming ISAM file '%s' to '%s'...\n",
|
||||
namebuf, isfname);
|
||||
if (isrename(namebuf, isfname) != ISOK) {
|
||||
cmd_error("isrename", print);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-open the file and add keys.
|
||||
*/
|
||||
if (ldshort(cntlpg + CP_NKEYS_OFF) > 0) {
|
||||
(void)print("Adding keys...\n");
|
||||
|
||||
if ((isfd = isopen(isfname, ISEXCLLOCK + ISINOUT +
|
||||
(varflag?ISVARLEN:0))) == ISERROR) {
|
||||
cmd_error("isopen", print);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < ldshort(cntlpg + CP_NKEYS_OFF); i++) {
|
||||
ldkey(&keydesc2, cntlpg + CP_KEYS_OFF + i * K2_LEN);
|
||||
_iskey_itox(&keydesc2, &keydesc);
|
||||
|
||||
if (keydesc.k_nparts == 0) /* special case for no primary */
|
||||
continue;
|
||||
|
||||
printkey (i+1, &keydesc, print);
|
||||
|
||||
if (i == 0) {
|
||||
if (isaddprimary(isfd, &keydesc) == ISERROR) {
|
||||
cmd_error("isaddprimary", print);
|
||||
(void)isclose(isfd);
|
||||
goto ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isaddindex(isfd, &keydesc) == ISERROR) {
|
||||
cmd_error("isaddindex", print);
|
||||
(void)isclose(isfd);
|
||||
goto ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)isclose(isfd);
|
||||
(void)sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
|
||||
print("...File repaired\n");
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
(void)print("\007Didn't repair ISAM file '%s'\n", isfname);
|
||||
(void)close(datfd);
|
||||
(void)close(indfd);
|
||||
(void)close(varfd);
|
||||
(void)isclose(isfd);
|
||||
if (namebuf != nameBuf) free(namebuf);
|
||||
if (buffer != Buffer) free(buffer);
|
||||
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/******* low level data access used by the 'repair' utility ******************/
|
||||
|
||||
static char recordbuffer[ISMAXRECLEN + LONGSIZE];
|
||||
|
||||
/* rp_readcntlpg() - Read the control page */
|
||||
Static
|
||||
rp_readcntlpg(datfd, cntlpg)
|
||||
int datfd;
|
||||
char *cntlpg;
|
||||
{
|
||||
if (read (datfd, cntlpg, ISCNTLSIZE) != ISCNTLSIZE)
|
||||
return (ISERROR);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/* rp_readrecord_f() - Read a record from .rec file */
|
||||
Static char *
|
||||
rp_readrecord_f(datfd, offset, reclen)
|
||||
int datfd;
|
||||
long offset;
|
||||
int reclen;
|
||||
{
|
||||
if (lseek(datfd, offset, 0) != offset)
|
||||
return ((char *) NULL);
|
||||
|
||||
if (read(datfd, recordbuffer, reclen + 1) != (reclen + 1))
|
||||
return ((char *) NULL);
|
||||
|
||||
if (recordbuffer[0] == FL_RECDELETED)
|
||||
return ((char *) NULL);
|
||||
|
||||
return (recordbuffer + 1);
|
||||
}
|
||||
|
||||
/* rp_readrecord_v() - Read a record from .rec file */
|
||||
Static char *
|
||||
rp_readrecord_v(datfd, varfd, offset, minreclen, maxreclen)
|
||||
int datfd, varfd;
|
||||
long offset;
|
||||
int minreclen, maxreclen;
|
||||
{
|
||||
long tailoff;
|
||||
char frameheadbuf [2 * SHORTSIZE];
|
||||
int taillen;
|
||||
|
||||
if (lseek(datfd, offset, 0) != offset)
|
||||
return ((char *) NULL);
|
||||
|
||||
if (read(datfd, recordbuffer, minreclen + LONGSIZE) != (minreclen + LONGSIZE))
|
||||
return ((char *) NULL);
|
||||
|
||||
if ((tailoff = ldlong(recordbuffer)) == VL_RECDELETED)
|
||||
return ((char *) NULL);
|
||||
|
||||
isreclen = minreclen;
|
||||
|
||||
/* Recover tail of the record */
|
||||
if (tailoff != VL_RECNOTAIL) {
|
||||
|
||||
if (lseek(varfd, tailoff, 0) != tailoff)
|
||||
goto OKEXIT;
|
||||
|
||||
if (read(varfd, frameheadbuf, 2 * SHORTSIZE) != 2 * SHORTSIZE)
|
||||
goto OKEXIT;
|
||||
|
||||
taillen = (int) ldshort(frameheadbuf + VR_TAILLEN_OFF);
|
||||
|
||||
if (taillen <= 0 || taillen + minreclen > maxreclen)
|
||||
goto OKEXIT;
|
||||
|
||||
if (read(varfd, recordbuffer + LONGSIZE + isreclen, taillen) != taillen)
|
||||
goto OKEXIT;
|
||||
|
||||
isreclen += taillen;
|
||||
}
|
||||
|
||||
OKEXIT:
|
||||
return (recordbuffer + LONGSIZE);
|
||||
}
|
||||
|
||||
static int
|
||||
isnoprintf(const char *s, ...)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
static
|
||||
printkey(n, pkdesc, print)
|
||||
int n;
|
||||
struct keydesc *pkdesc;
|
||||
int (*print)();
|
||||
{
|
||||
int i;
|
||||
struct keypart *pk;
|
||||
|
||||
if (pkdesc->k_nparts == 0) {
|
||||
print("%3d: --- NO PRIMARY KEY ---\n", n);
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 1)
|
||||
print("P%3d: %s ", n, (pkdesc->k_flags&ISDUPS) ?
|
||||
"DUPS " : "NODUPS");
|
||||
else
|
||||
print(" %3d: %s ", n, (pkdesc->k_flags&ISDUPS) ?
|
||||
"DUPS " : "NODUPS");
|
||||
|
||||
|
||||
for (i = 0; i < pkdesc->k_nparts; i++) {
|
||||
pk = pkdesc->k_part + i;
|
||||
print(" %d%c%d%s", pk->kp_start,
|
||||
typeletter(pk->kp_type & ~ISDESC), pk->kp_leng,
|
||||
(pk->kp_type & ISDESC)?"D":" ");
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
static
|
||||
cmd_error(str,print)
|
||||
char *str;
|
||||
int (*print)();
|
||||
{
|
||||
(void)print("%s: ISAM error %d\n", str, iserrno);
|
||||
}
|
||||
|
||||
static int
|
||||
typeletter(type)
|
||||
int type;
|
||||
{
|
||||
switch (type) {
|
||||
case INTTYPE:
|
||||
return 'I';
|
||||
case LONGTYPE:
|
||||
return 'L';
|
||||
case FLOATTYPE:
|
||||
return 'F';
|
||||
case DOUBLETYPE:
|
||||
return 'D';
|
||||
case CHARTYPE:
|
||||
return 'C';
|
||||
case BINTYPE:
|
||||
return 'B';
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
247
cde/lib/tt/mini_isam/isrewcurr.c
Normal file
247
cde/lib/tt/mini_isam/isrewcurr.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isrewcurr.c /main/3 1995/10/23 11:44:15 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isrewcurr.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isrewcurr.c
|
||||
*
|
||||
* Description:
|
||||
* Rewrite current record in ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amrewcurr(), _changekeys2();
|
||||
|
||||
/*
|
||||
* err = isrewcurr(isfd, record)
|
||||
*
|
||||
* Isrewcurr() modifies the current record in ISAM file.
|
||||
* All indexes of the ISAM file are updated.
|
||||
*
|
||||
* Current record position is changed in relation to the new key value.
|
||||
* isrecnum is set to the changed record.
|
||||
*
|
||||
* If the ISAM file is for variable length records, the isreclen variable
|
||||
* must be set to indicate the actual length of the record, which must
|
||||
* be between the minimum and maximum length, as specified in isbuild().
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* EDUPL The write woul result in a duplicate on a key that
|
||||
* does not allow duplicates.
|
||||
* ELOCKED The file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was not opened with ISINOUT mode.
|
||||
* ENOCURR Record with record number recnum does not exist, or it
|
||||
* was deleted by another process.
|
||||
*/
|
||||
|
||||
int
|
||||
isrewcurr(isfd, record)
|
||||
int isfd;
|
||||
char *record;
|
||||
{
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
int ret;
|
||||
int recnum;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine record length. Check it against min and max record length.
|
||||
*/
|
||||
reclen = (fab->varlength == TRUE) ? isreclen : fab->minreclen;
|
||||
if (reclen < fab->minreclen || reclen > fab->maxreclen) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if ((ret = _amrewcurr(&fab->isfhandle, record, reclen, &fab->curpos,
|
||||
&recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amrewcurr(isfhandle, record, reclen, curpos, recnum, errcode)
|
||||
*
|
||||
* _amrewcurr() rewrites the current record in ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* record record
|
||||
* reclen length of the record
|
||||
* curpos curent record position
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
* curpos new current position
|
||||
* recnum record number fo current record
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amrewcurr(isfhandle, record, reclen, curpos, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
char *record;
|
||||
int reclen;
|
||||
Recno *recnum;
|
||||
Bytearray *curpos;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
Crp *crp;
|
||||
Bytearray newcurpos;
|
||||
int err;
|
||||
char oldrecord[ISMAXRECLEN];
|
||||
int reclen2;
|
||||
int (*rec_read)();
|
||||
int (*rec_rewrite)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
rec_rewrite = (fcb->varflag?_vlrec_rewrite:_flrec_rewrite);
|
||||
|
||||
/*
|
||||
* Get info from current record position structure.
|
||||
*/
|
||||
crp = (Crp *) curpos->data;
|
||||
|
||||
|
||||
if (crp->flag != CRP_ON) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
/*
|
||||
* We must read the record first to be able to delete keys.
|
||||
*/
|
||||
if (rec_read(fcb, oldrecord, crp->recno, &reclen2) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (rec_rewrite(fcb, record, crp->recno, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOCURR);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update keys, set new key position.
|
||||
*/
|
||||
newcurpos = _bytearr_dup(curpos);
|
||||
if ((err = _changekeys2 (fcb, record, oldrecord, crp->recno, &newcurpos))
|
||||
!= ISOK) {
|
||||
_bytearr_free(&newcurpos);
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
_bytearr_free(curpos);
|
||||
*curpos = newcurpos;
|
||||
|
||||
/*
|
||||
* This takes care of new record position if the physical order is in use.
|
||||
*/
|
||||
*recnum = crp->recno;
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update control page.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
Static int
|
||||
_changekeys2(fcb, record, oldrecord, recnum, curpos)
|
||||
Fcb *fcb;
|
||||
char *record;
|
||||
char *oldrecord;
|
||||
Recno recnum;
|
||||
Bytearray *curpos;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i;
|
||||
int err;
|
||||
Crp *crp;
|
||||
int keyid;
|
||||
Keydesc2 *keydesc2;
|
||||
|
||||
crp = (Crp *)curpos->data;
|
||||
keyid = crp->keyid;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
keydesc2 = fcb->keys + i;
|
||||
if ((err =_change1key(fcb, keydesc2, record, oldrecord, recnum,
|
||||
(keydesc2->k2_keyid == keyid) ?
|
||||
crp->key : (char *) NULL)) != ISOK)
|
||||
return (err);
|
||||
}
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
213
cde/lib/tt/mini_isam/isrewrec.c
Normal file
213
cde/lib/tt/mini_isam/isrewrec.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isrewrec.c /main/3 1995/10/23 11:44:28 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isrewrec.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isrewrec.c
|
||||
*
|
||||
* Description:
|
||||
* Rewrite a record in ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amrewrec(), _changekeys();
|
||||
|
||||
/*
|
||||
* err = isrewrec(isfd, recnum, record)
|
||||
*
|
||||
* Isrewrec() modifies a record in ISAM file. The record is identified
|
||||
* by its record number. All indexes of the ISAM file are updated.
|
||||
*
|
||||
* Current record position is not changed.
|
||||
* isrecnum is set to recnum.
|
||||
*
|
||||
* If the ISAM file is for variable length records, the isreclen variable
|
||||
* must be set to indicate the actual length of the record, which must
|
||||
* be between the minimum and maximum length, as specified in isbuild().
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* EDUPL The write woul result in a duplicate on a key that
|
||||
* does not allow duplicates.
|
||||
* ELOCKED The file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was not opened with ISINOUT mode.
|
||||
* ENOREC Record with record number recnum does not exist.
|
||||
*/
|
||||
|
||||
int
|
||||
isrewrec(isfd, recnum, record)
|
||||
int isfd;
|
||||
long recnum;
|
||||
char *record;
|
||||
{
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine record length. Check it against min and max record length.
|
||||
*/
|
||||
reclen = (fab->varlength == TRUE) ? isreclen : fab->minreclen;
|
||||
if (reclen < fab->minreclen || reclen > fab->maxreclen) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if ((ret = _amrewrec(&fab->isfhandle, record,
|
||||
reclen, recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amrewrec(isfhandle, record, reclen, recnum, errcode)
|
||||
*
|
||||
* _amrewrec() rewrites a record in ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* record record
|
||||
* reclen length of the record
|
||||
* recnum record number of record to be deleted
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amrewrec(isfhandle, record, reclen, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
char *record;
|
||||
int reclen;
|
||||
Recno recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb;
|
||||
char oldrecbuf[ISMAXRECLEN];
|
||||
int err;
|
||||
int reclen2;
|
||||
int (*rec_read)();
|
||||
int (*rec_rewrite)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
rec_rewrite = (fcb->varflag?_vlrec_rewrite:_flrec_rewrite);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
/*
|
||||
* We must read the record first to be able to delete keys.
|
||||
*/
|
||||
if (rec_read(fcb, oldrecbuf, recnum, &reclen2) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (rec_rewrite(fcb, record, recnum, reclen) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update all keys.
|
||||
*/
|
||||
if ((err = _changekeys(fcb, record, oldrecbuf, recnum)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update control page.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
_changekeys (fcb, record, oldrecord, recnum)
|
||||
Fcb *fcb;
|
||||
char *record;
|
||||
char *oldrecord;
|
||||
Recno recnum;
|
||||
{
|
||||
int nkeys = fcb->nkeys;
|
||||
register int i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if ((err =_change1key(fcb, fcb->keys + i, record, oldrecord, recnum,
|
||||
(char *)NULL))
|
||||
!= ISOK)
|
||||
return (err);
|
||||
}
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
76
cde/lib/tt/mini_isam/issignals.c
Normal file
76
cde/lib/tt/mini_isam/issignals.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: issignals.c /main/3 1995/10/23 11:44:41 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)issignals.c 1.7 89/08/30 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* issignals.c
|
||||
*
|
||||
* Description:
|
||||
* Signal masking functions
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <signal.h>
|
||||
|
||||
/*
|
||||
* _issignal_mask() is called at the beginning of each ISAM update operation
|
||||
* to mask signals for the duration of the operation. _issignals_unmask()
|
||||
* is called at the end of the operation to restore the original signal
|
||||
* mask.
|
||||
*
|
||||
* _issignals_cntl() enables/disables this signal masking facility.
|
||||
* (the default is "mask the signals").
|
||||
*
|
||||
* The variable already_masked is used to provide more robustness: it
|
||||
* will prevent permanent signal masking due to bugs in the ISAM package.
|
||||
* The permanent masking of signals would happen if _issignals_mask()
|
||||
* were called twice in a row.
|
||||
*/
|
||||
|
||||
|
||||
static int do_mask = 1; /* default value */
|
||||
static int already_masked;
|
||||
static sigset_t oldmask;
|
||||
static sigset_t allsignals;
|
||||
|
||||
|
||||
_issignals_cntl(opt)
|
||||
int opt; /* 1 will enable masking */
|
||||
/* 0 will disable masking */
|
||||
{
|
||||
int oldmask = do_mask;
|
||||
|
||||
do_mask = opt ? 1 : 0;
|
||||
|
||||
return (oldmask);
|
||||
}
|
||||
|
||||
_issignals_mask()
|
||||
{
|
||||
if (do_mask && !already_masked) {
|
||||
(void) sigfillset(&allsignals);
|
||||
(void) sigdelset(&allsignals, SIGTRAP);
|
||||
(void) sigdelset(&allsignals, SIGSEGV);
|
||||
(void) sigdelset(&allsignals, SIGILL);
|
||||
(void) sigdelset(&allsignals, SIGBUS);
|
||||
(void) sigprocmask(SIG_SETMASK, &allsignals, &oldmask);
|
||||
already_masked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
_issignals_unmask()
|
||||
{
|
||||
if (do_mask) {
|
||||
(void)sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
already_masked = 0;
|
||||
}
|
||||
}
|
||||
132
cde/lib/tt/mini_isam/issort.c
Normal file
132
cde/lib/tt/mini_isam/issort.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: issort.c /main/3 1995/10/23 11:44:55 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)issort.c 1.3 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* issort.c
|
||||
*
|
||||
* Description:
|
||||
* ISAM sort package (sort in memory)
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
extern char *_isunix_malloc();
|
||||
|
||||
/*
|
||||
* _issort_create()
|
||||
*
|
||||
* Create a sorter
|
||||
*/
|
||||
|
||||
Issort *
|
||||
_issort_create(reclen,nrecs,compfunc)
|
||||
int reclen;
|
||||
int nrecs;
|
||||
int (*compfunc)();
|
||||
{
|
||||
Issort *p;
|
||||
|
||||
p = (Issort *)_ismalloc(sizeof(*p)); /* Allocate new sorter */
|
||||
memset((char *)p, 0,sizeof(*p));
|
||||
|
||||
p->ist_reclength = reclen; /* Record length in bytes */
|
||||
p->ist_allocrecs = nrecs; /* Maximum number of records */
|
||||
/* that can inserted */
|
||||
p->ist_nrecs = 0; /* Current number of records */
|
||||
p->ist_currec; /* Current position */
|
||||
p->ist_compf = compfunc; /* Comparison function */
|
||||
|
||||
p->ist_array = _ismalloc((unsigned)(reclen * nrecs)); /* Allocate array */
|
||||
/* for storing records */
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* _issort_destroy()
|
||||
*
|
||||
* Destroy a sorter
|
||||
*/
|
||||
|
||||
void
|
||||
_issort_destroy(srt)
|
||||
Issort *srt;
|
||||
{
|
||||
assert(srt->ist_array != (char *) 0);
|
||||
|
||||
(void) free(srt->ist_array);
|
||||
(void) free((char *)srt);
|
||||
}
|
||||
|
||||
/*
|
||||
* _issort_insert()
|
||||
*
|
||||
* Insert record to sorter
|
||||
*/
|
||||
|
||||
void
|
||||
_issort_insert(srt,record)
|
||||
register Issort *srt;
|
||||
char *record;
|
||||
{
|
||||
assert(srt->ist_nrecs < srt->ist_allocrecs);
|
||||
|
||||
memcpy(srt->ist_array + srt->ist_nrecs * srt->ist_reclength,record,
|
||||
srt->ist_reclength);
|
||||
|
||||
srt->ist_currec = srt->ist_nrecs++;
|
||||
}
|
||||
|
||||
/*
|
||||
* _issort_sort()
|
||||
*
|
||||
* Sort records
|
||||
*/
|
||||
|
||||
void
|
||||
_issort_sort(srt)
|
||||
Issort *srt;
|
||||
{
|
||||
if (srt->ist_nrecs > 1)
|
||||
qsort(srt->ist_array,srt->ist_nrecs,srt->ist_reclength,srt->ist_compf);
|
||||
|
||||
_issort_rewind(srt); /* Rewind for subsequent reads */
|
||||
}
|
||||
|
||||
/*
|
||||
* _issort_rewind()
|
||||
*
|
||||
* Rewind sorter
|
||||
*/
|
||||
|
||||
void
|
||||
_issort_rewind(srt)
|
||||
Issort *srt;
|
||||
{
|
||||
srt->ist_currec = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* _issort_read()
|
||||
*
|
||||
* Read record from sorter
|
||||
*/
|
||||
|
||||
char *
|
||||
_issort_read(srt)
|
||||
register Issort *srt;
|
||||
{
|
||||
return((srt->ist_currec < srt->ist_nrecs) ?
|
||||
(srt->ist_array + srt->ist_currec++ * srt->ist_reclength) :
|
||||
(char *) 0);
|
||||
}
|
||||
612
cde/lib/tt/mini_isam/isstart.c
Normal file
612
cde/lib/tt/mini_isam/isstart.c
Normal file
@@ -0,0 +1,612 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isstart.c /main/3 1995/10/23 11:45:08 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isstart.c 1.9 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isstart.c
|
||||
*
|
||||
* Description:
|
||||
* Select index and set record position.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amstart();
|
||||
|
||||
/*
|
||||
* err = isstart(isfd, keydesc, length, record, mode)
|
||||
*
|
||||
* Isstart() selects index for subsequent read operations and set new
|
||||
* current record position.
|
||||
*
|
||||
* isrecnum is set to indicate the start record.
|
||||
*
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was opened with ISOUTPUT mode.
|
||||
* EBADARG Bad mode parameter.
|
||||
* EBADARG keylen is out of range.
|
||||
* ENOREC Specified record cannot be found (random access read).
|
||||
* EBADKEY Error in the key descriptor.
|
||||
*/
|
||||
|
||||
int
|
||||
isstart(isfd, keydesc, length, record, mode)
|
||||
int isfd;
|
||||
struct keydesc *keydesc;
|
||||
int length;
|
||||
char *record;
|
||||
int mode;
|
||||
{
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
Recno recnum;
|
||||
int ret;
|
||||
enum readmode readmode;
|
||||
char dummy_record [1]; /* used for ISFIRST and ISLAST */
|
||||
char *precord;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract read mode.
|
||||
*/
|
||||
if ((readmode = _getreadmode(mode)) == RM_BADMODE) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some arguments are used only when a particular mode is specified.
|
||||
*/
|
||||
if (readmode == RM_FIRST || readmode == RM_LAST || USE_PHYS_ORDER(keydesc)) {
|
||||
precord = dummy_record;
|
||||
reclen = 0;
|
||||
}
|
||||
else {
|
||||
precord = record;
|
||||
reclen = fab->minreclen;
|
||||
}
|
||||
|
||||
reclen = fab->minreclen;
|
||||
|
||||
recnum = isrecnum;
|
||||
|
||||
if ((ret = _amstart(&fab->isfhandle, precord, reclen,
|
||||
readmode, keydesc, length, &fab->curpos,
|
||||
&recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful start */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amstart(isfhandle, record, reclen, readmode,
|
||||
* keydesc, keylen, curpos, recnum, errcode)
|
||||
*
|
||||
* _amstart() reads a record from ISAM file
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* readmode Specifies access mode (random or sequential)
|
||||
* curpos old record position
|
||||
* recnum copy of isrecnum
|
||||
* keydesc key descriptor
|
||||
* keylen # of bytes of key to match
|
||||
* record extract key from this record buffer
|
||||
*
|
||||
* Output params:
|
||||
* curpos new current position
|
||||
* recnum record number
|
||||
* errcode error status of the operation
|
||||
* reclen actual length of the record
|
||||
*
|
||||
* Note:
|
||||
* Successfull isstart() returns the new curpos and frees the old curpos.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
_amstart(isfhandle, record, reclen, readmode,
|
||||
keydesc, keylen, curpos, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
enum readmode readmode;
|
||||
char *record;
|
||||
int *reclen;
|
||||
Bytearray *curpos;
|
||||
Recno *recnum;
|
||||
struct errcode *errcode;
|
||||
struct keydesc *keydesc;
|
||||
int keylen;
|
||||
{
|
||||
Fcb *fcb;
|
||||
Recno recnum2;
|
||||
int err;
|
||||
Crp *newcrp = NULL;
|
||||
char recbuf [ISMAXRECLEN];
|
||||
Keydesc2 keydesc2;
|
||||
Keydesc2 *pkeydesc2;
|
||||
int newcrpsize = 0;
|
||||
char keybuf1 [MAXKEYSIZE], keybuf2 [MAXKEYSIZE];
|
||||
int matchkeylen;
|
||||
int skipbytes;
|
||||
char *pkey;
|
||||
Btree *btree = NULL;
|
||||
int reclen2;
|
||||
int (*rec_read)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_read = (fcb->varflag?_vlrec_read:_flrec_read);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
if (USE_PHYS_ORDER(keydesc)) {
|
||||
/*
|
||||
* Physical order in use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allocate new current position structure.
|
||||
*/
|
||||
newcrpsize = sizeof(*newcrp);
|
||||
newcrp = (Crp *) _ismalloc(sizeof(*newcrp));
|
||||
memset ((char *)newcrp, 0, sizeof(*newcrp));
|
||||
newcrp->keyid = PHYS_ORDER;
|
||||
|
||||
switch (readmode) {
|
||||
case RM_EQUAL:
|
||||
recnum2 = *recnum; /* passed from isrecnum */
|
||||
if ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = recnum2;
|
||||
break;
|
||||
|
||||
case RM_GREAT:
|
||||
recnum2 = *recnum + 1;
|
||||
if (recnum2 < 1) recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = recnum2;
|
||||
break;
|
||||
|
||||
case RM_GTEQ:
|
||||
recnum2 = *recnum;
|
||||
if (recnum2 < 1) recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = recnum2;
|
||||
break;
|
||||
|
||||
case RM_LESS:
|
||||
recnum2 = *recnum - 1;
|
||||
if (recnum2 > fcb->lastrecno) recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = recnum2;
|
||||
break;
|
||||
|
||||
case RM_LTEQ:
|
||||
recnum2 = *recnum;
|
||||
if (recnum2 > fcb->lastrecno) recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err != ISOK) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = recnum2;
|
||||
break;
|
||||
|
||||
case RM_FIRST:
|
||||
recnum2 = 1;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2++;
|
||||
|
||||
if (err == ISOK) {
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = recnum2;
|
||||
}
|
||||
else {
|
||||
newcrp->flag = CRP_AFTERANY;
|
||||
}
|
||||
break;
|
||||
case RM_LAST:
|
||||
recnum2 = fcb->lastrecno;
|
||||
/*
|
||||
* Skip deleted records.
|
||||
*/
|
||||
while ((err = rec_read(fcb, recbuf, recnum2, &reclen2)) != ISOK &&
|
||||
err == ENOREC)
|
||||
recnum2--;
|
||||
|
||||
if (err == ISOK) {
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = recnum2;
|
||||
}
|
||||
else {
|
||||
newcrp->flag = CRP_BEFOREANY;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_isfatal_error("Invalid readmode");
|
||||
}
|
||||
|
||||
*recnum = recnum2;
|
||||
|
||||
/*
|
||||
* Build new curpos, deallocate old curpos.
|
||||
*/
|
||||
_bytearr_free(curpos);
|
||||
*curpos = _bytearr_new(sizeof(*newcrp), (char *)newcrp);
|
||||
|
||||
} /* physical order */
|
||||
else {
|
||||
|
||||
/*
|
||||
* Use order defined by some key.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check key descriptor for validity.
|
||||
*/
|
||||
if (_validate_keydesc(keydesc, fcb->minreclen) != ISOK) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert key descriptor to internal form.
|
||||
*/
|
||||
_iskey_xtoi (&keydesc2, keydesc);
|
||||
|
||||
/* Find key decriptor in the FCB. */
|
||||
if ((pkeydesc2 = _isfcb_findkey(fcb ,&keydesc2)) == NULL) {
|
||||
_amseterrcode(errcode, EBADKEY);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* skipkeybytes is set to the number of bytes in the beginning
|
||||
* of the key:
|
||||
* RECNOSIZE for ISNODUPS keys to skip recno part
|
||||
* RECNOSIZE + DUPIDSIZE to skip recno and duplicate serial number
|
||||
*/
|
||||
skipbytes = RECNOSIZE;
|
||||
if (ALLOWS_DUPS2(pkeydesc2))
|
||||
skipbytes += DUPIDSIZE;
|
||||
|
||||
/*
|
||||
* Validate keylen.
|
||||
*/
|
||||
if (keylen < 0 || keylen > pkeydesc2->k2_len - skipbytes) {
|
||||
_amseterrcode(errcode, EBADARG);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case if keylen == 0: use the entire key.
|
||||
*/
|
||||
if (keylen == 0)
|
||||
matchkeylen = pkeydesc2->k2_len - skipbytes;
|
||||
else
|
||||
matchkeylen = keylen;
|
||||
|
||||
/*
|
||||
* Allocate new current record position.
|
||||
*/
|
||||
newcrpsize = sizeof(Crp) + pkeydesc2->k2_len;
|
||||
newcrp = (Crp *) _ismalloc((unsigned)newcrpsize);
|
||||
memset((char *)newcrp, 0, newcrpsize);
|
||||
|
||||
newcrp->keyid = pkeydesc2->k2_keyid; /* Key identifier in FCB */
|
||||
newcrp->matchkeylen = matchkeylen; /* number of bytes to match */
|
||||
|
||||
/*
|
||||
* Create B tree object.
|
||||
*/
|
||||
btree = _isbtree_create(fcb, pkeydesc2);
|
||||
|
||||
switch (readmode) {
|
||||
case RM_EQUAL:
|
||||
case RM_GTEQ:
|
||||
/*
|
||||
* Make sure that you will read the first duplicate.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy( keybuf1 + skipbytes,keybuf2 + skipbytes, matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
if (readmode == RM_EQUAL &&
|
||||
memcmp(keybuf1 + skipbytes, pkey + skipbytes,
|
||||
matchkeylen) != 0) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
break;
|
||||
|
||||
case RM_GREAT:
|
||||
/*
|
||||
* Make sure that you will read past all matching records.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy( keybuf1 + skipbytes,keybuf2 + skipbytes, matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree after the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
break;
|
||||
|
||||
case RM_LESS:
|
||||
/*
|
||||
* Make sure that you will read before all matching records.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy( keybuf1 + skipbytes,keybuf2 + skipbytes, matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree after the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
break;
|
||||
|
||||
case RM_LTEQ:
|
||||
/*
|
||||
* Make sure that you will the last duplicate.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Extract key fields from record.
|
||||
*/
|
||||
_iskey_extract(pkeydesc2, record, keybuf2);
|
||||
memcpy( keybuf1 + skipbytes,keybuf2 + skipbytes, matchkeylen);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree in before the searched value.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
_amseterrcode(errcode, ENOREC);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
break;
|
||||
|
||||
case RM_FIRST:
|
||||
/*
|
||||
* Fill key buffer with -infinity.
|
||||
*/
|
||||
_iskey_fillmin(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree before any key entry.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_next(btree)) == NULL) {
|
||||
newcrp->flag = CRP_AFTERANY;
|
||||
}
|
||||
else {
|
||||
newcrp->flag = CRP_BEFORE;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
}
|
||||
break;
|
||||
|
||||
case RM_LAST:
|
||||
/*
|
||||
* Fill key buffer with +infinity.
|
||||
*/
|
||||
_iskey_fillmax(pkeydesc2, keybuf1);
|
||||
|
||||
/*
|
||||
* Position pointer in the B-tree after all entries.
|
||||
*/
|
||||
_isbtree_search(btree, keybuf1);
|
||||
|
||||
if ((pkey = _isbtree_current(btree)) == NULL) {
|
||||
newcrp->flag = CRP_BEFOREANY;
|
||||
}
|
||||
else {
|
||||
newcrp->flag = CRP_AFTER;
|
||||
newcrp->recno = ldrecno(pkey + KEY_RECNO_OFF);
|
||||
memcpy( newcrp->key,pkey, pkeydesc2->k2_len);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_isfatal_error("Invalid readmode");
|
||||
}
|
||||
|
||||
*recnum = newcrp->recno;
|
||||
|
||||
/*
|
||||
* Build new curpos, deallocate old curpos data.
|
||||
*/
|
||||
_bytearr_free(curpos);
|
||||
*curpos = _bytearr_new((u_short)newcrpsize, (char *)newcrp);
|
||||
|
||||
_isbtree_destroy(btree);
|
||||
}
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
/* Clean-up work. */
|
||||
if (newcrp != NULL)
|
||||
free((char *)newcrp);
|
||||
|
||||
_isdisk_commit(); /* This will only check
|
||||
* that we unfixed all fixed
|
||||
* buffers */
|
||||
_isdisk_inval();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
|
||||
if (btree != NULL)
|
||||
_isbtree_destroy(btree);
|
||||
|
||||
/*
|
||||
* If error is EBADKEY, make the current position undefined.
|
||||
*/
|
||||
if (errcode->iserrno == EBADKEY) {
|
||||
((Crp *)curpos->data)->flag = CRP_UNDEF;
|
||||
}
|
||||
|
||||
/*
|
||||
* If error is ENOREC, switch to the new key, but set the current
|
||||
* record position undefined.
|
||||
*/
|
||||
if (errcode->iserrno == ENOREC && newcrp != NULL) {
|
||||
_bytearr_free(curpos);
|
||||
*curpos = _bytearr_new((u_short)newcrpsize, (char *)newcrp);
|
||||
((Crp *)curpos->data)->flag = CRP_UNDEF;
|
||||
}
|
||||
|
||||
if (newcrp != NULL)
|
||||
free((char *)newcrp);
|
||||
_isdisk_inval();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
112
cde/lib/tt/mini_isam/issync.c
Normal file
112
cde/lib/tt/mini_isam/issync.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: issync.c /main/3 1995/10/23 11:45:20 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)issync.c 1.7 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* issync.c
|
||||
*
|
||||
* Description:
|
||||
* Sync all kernel buffers to the disk.
|
||||
*
|
||||
* Note: issync() flushes changed kernel buffers that are local to
|
||||
* the application that issued the call.
|
||||
*
|
||||
* See sync(2) UNIX manual for what actually happens if sync() is called.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* int issync()
|
||||
*/
|
||||
|
||||
int
|
||||
issync()
|
||||
{
|
||||
return iscntl(ALLISFD, ISCNTL_FSYNC);
|
||||
}
|
||||
|
||||
/*
|
||||
* int isfsync(fd)
|
||||
*/
|
||||
|
||||
int
|
||||
isfsync(isfd)
|
||||
int isfd;
|
||||
{
|
||||
return iscntl(isfd, ISCNTL_FSYNC);
|
||||
}
|
||||
|
||||
|
||||
_issync()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXISFD; i++)
|
||||
(void)_isfsync(i);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
_isfsync(isfd)
|
||||
int isfd;
|
||||
{
|
||||
register Fab *fab;
|
||||
Fcb *fcb;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(&fab->isfhandle, &fab->errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
ret = ISERROR;
|
||||
}
|
||||
else {
|
||||
|
||||
if (fcb->datfd != -1)
|
||||
(void)fsync(fcb->datfd);
|
||||
|
||||
if (fcb->indfd != -1)
|
||||
(void)fsync(fcb->indfd);
|
||||
|
||||
if (fcb->varfd != -1)
|
||||
(void)fsync(fcb->varfd);
|
||||
|
||||
_amseterrcode(&fab->errcode, ISOK);
|
||||
_isam_exithook();
|
||||
ret = ISOK;
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
581
cde/lib/tt/mini_isam/isvarrec.c
Normal file
581
cde/lib/tt/mini_isam/isvarrec.c
Normal file
@@ -0,0 +1,581 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isvarrec.c /main/3 1995/10/23 11:45:36 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isvarrec.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isvarrec.c
|
||||
*
|
||||
* Description:
|
||||
* Fixed length record access (VLRA) module.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
/* Local functions */
|
||||
long _vl_getpos(); /* Get offset in .rec file */
|
||||
int _vl_deleted(); /* 0/1 returns 1 if record is deleted */
|
||||
static void remove_from_chain2(); /* used by _vlrec_wrrec() */
|
||||
long _istail_insert();
|
||||
static void _istail_delete();
|
||||
static _istail_read();
|
||||
|
||||
/*
|
||||
* _vlrec_write(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Write a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* record record buffer
|
||||
* reclen record length (NOT USED)
|
||||
*
|
||||
* Output params:
|
||||
* recnum record number of the new record
|
||||
*
|
||||
* Returns 0 if record was written succesfully, or -1 if any error.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_vlrec_write(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno *recnum;
|
||||
int reclen;
|
||||
{
|
||||
Recno recnum2;
|
||||
long rec_position;
|
||||
long tailoff = VL_RECNOTAIL;
|
||||
char recnobuf [RECNOSIZE];
|
||||
char tailoffbuf[LONGSIZE];
|
||||
|
||||
/*
|
||||
* Reuse a deleted record if one exits.
|
||||
* Otherwise, extend .rec file by a record.
|
||||
*/
|
||||
if (fcb->freerecno != NULL_RECNO) {
|
||||
recnum2 = fcb->freerecno;
|
||||
|
||||
/*
|
||||
* Remove record from the chain of deleted records.
|
||||
*/
|
||||
rec_position = _vl_getpos(fcb, recnum2); /* Offset in .rec file */
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf, rec_position + LONGSIZE, RECNOSIZE);
|
||||
fcb->freerecno = ldrecno(recnobuf);
|
||||
}
|
||||
else {
|
||||
recnum2 = ++(fcb->lastrecno);
|
||||
|
||||
/*
|
||||
* Extend .rec file size if necessary.
|
||||
*/
|
||||
while (_vl_getpos(fcb, recnum2 + 1) > fcb->datsize * ISPAGESIZE) {
|
||||
fcb->datsize = _extend_file(fcb, fcb->datfd, fcb->datsize);
|
||||
}
|
||||
rec_position = _vl_getpos(fcb, recnum2); /* Offset in .rec file */
|
||||
}
|
||||
|
||||
/*
|
||||
* Store variable part of record (the 'tail') in .var file.
|
||||
*/
|
||||
tailoff = _istail_insert(fcb, record + fcb->minreclen,
|
||||
reclen - fcb->minreclen);
|
||||
|
||||
/*
|
||||
* Copy record to the .rec file. Mark record as undeleted.
|
||||
*/
|
||||
stlong(tailoff, tailoffbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + LONGSIZE, fcb->minreclen);
|
||||
|
||||
*recnum = recnum2;
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _vlrec_read(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Read a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* reclen filled with the record size for compatibilty with
|
||||
* variable length records
|
||||
*
|
||||
* Output params:
|
||||
* record record buffer is filled with data
|
||||
*
|
||||
* Returns 0 if record was read succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_vlrec_read(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int *reclen;
|
||||
{
|
||||
long rec_position;
|
||||
long tailoff;
|
||||
char tailoffbuf[LONGSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _vl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
tailoff = ldlong(tailoffbuf);
|
||||
if (tailoff == VL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy record from the .at file.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, record, rec_position + LONGSIZE, fcb->minreclen);
|
||||
|
||||
*reclen = fcb->minreclen;
|
||||
|
||||
/*
|
||||
* Get the 'tail' of the record if any.
|
||||
*/
|
||||
*reclen += _istail_read(fcb, tailoff, record + fcb->minreclen);
|
||||
|
||||
if (*reclen > fcb->maxreclen)
|
||||
_isfatal_error("Corrupted file: too long variable length record");
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* pos = _vl_getpos(fcb, recnum)
|
||||
*
|
||||
* Calculate the position of record in .rec file.
|
||||
*/
|
||||
|
||||
long
|
||||
_vl_getpos(fcb, recnum)
|
||||
Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
return ((long)(ISCNTLSIZE + (fcb->minreclen + LONGSIZE) * (recnum -1)));
|
||||
}
|
||||
|
||||
/*
|
||||
* _vlrec_rewrite(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Rewrite a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* record new record
|
||||
* int reclen (NOT USED)
|
||||
*
|
||||
* Returns 0 if record was rewritten succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_vlrec_rewrite(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int reclen;
|
||||
{
|
||||
long rec_position;
|
||||
long tailoff;
|
||||
char tailoffbuf[LONGSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _vl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
tailoff = ldlong(tailoffbuf);
|
||||
if (tailoff == VL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store variable part of record (the 'tail') in .var file.
|
||||
*/
|
||||
tailoff = _istail_modify(fcb, tailoff, record + fcb->minreclen,
|
||||
reclen - fcb->minreclen);
|
||||
|
||||
/*
|
||||
* Copy new record to the .rec file.
|
||||
*/
|
||||
stlong(tailoff, tailoffbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + LONGSIZE, fcb->minreclen);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _vlrec_delete;(fcb, recnum)
|
||||
*
|
||||
* Rewrite a record.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
*
|
||||
* Returns 0 if record was rewritten succesfully, or error code if any error.
|
||||
*/
|
||||
|
||||
int
|
||||
_vlrec_delete(fcb, recnum)
|
||||
register Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
long rec_position;
|
||||
long tailoff;
|
||||
char tailoffbuf[LONGSIZE];
|
||||
char recnobuf [RECNOSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is within the range of existing record numbers.
|
||||
*/
|
||||
if (recnum < 1 || recnum > fcb->lastrecno)
|
||||
return (EENDFILE);
|
||||
|
||||
rec_position = _vl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
/*
|
||||
* Check that the record is not marked as deleted.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
tailoff = ldlong(tailoffbuf);
|
||||
if (tailoff == VL_RECDELETED) {
|
||||
return (ENOREC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the delete flag to VL_RECDELETED.
|
||||
*/
|
||||
tailoff = VL_RECDELETED;
|
||||
stlong(tailoff, tailoffbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
|
||||
/*
|
||||
* Insert record into chain of deleted records.
|
||||
*/
|
||||
strecno(fcb->freerecno, recnobuf);
|
||||
_cp_tofile(fcb, fcb->datfd, recnobuf, rec_position + LONGSIZE, RECNOSIZE);
|
||||
fcb->freerecno = recnum;
|
||||
|
||||
/*
|
||||
* Delete tail from .var file.
|
||||
*/
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* _vlrec_wrrec(fcb, record, recnum, reclen)
|
||||
*
|
||||
* Write a record by record number.
|
||||
*
|
||||
* Input params:
|
||||
* FCB File Control Block
|
||||
* recnum record number of the record
|
||||
* record record buffer
|
||||
* int reclen (NOT USED)
|
||||
*
|
||||
* Returns 0 if record was written succesfully, or error code if any error.
|
||||
*
|
||||
* Note that _vlrec_wrrec() commits updates and syncs the FCB to avoid
|
||||
* buffer pool overflow.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
_vlrec_wrrec(fcb, record, recnum, reclen)
|
||||
register Fcb *fcb;
|
||||
char *record;
|
||||
Recno recnum;
|
||||
int reclen;
|
||||
{
|
||||
long rec_position;
|
||||
long tailoff;
|
||||
char tailoffbuf[LONGSIZE];
|
||||
Recno recnum2;
|
||||
char recnumbuf [RECNOSIZE];
|
||||
|
||||
/*
|
||||
* Check that recnum is not negative.
|
||||
*/
|
||||
if (recnum < 1)
|
||||
return (EBADARG);
|
||||
|
||||
rec_position = _vl_getpos(fcb, recnum); /* Offset in .rec file */
|
||||
|
||||
if (recnum > fcb->lastrecno) {
|
||||
|
||||
/*
|
||||
* If the recnum is bigger than the highest record number in the .rec
|
||||
* file, extend the .rec file.
|
||||
*/
|
||||
while (_vl_getpos(fcb, recnum + 1) > fcb->datsize * ISPAGESIZE) {
|
||||
fcb->datsize = _extend_file(fcb, fcb->datfd, fcb->datsize);
|
||||
|
||||
/* Sync the updates to avoid buffer pool overflow. */
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark all records in the range <fcb->lastrecno+1, recnum> as
|
||||
* deleted.
|
||||
*/
|
||||
tailoff = VL_RECDELETED;
|
||||
stlong(tailoff, tailoffbuf);
|
||||
for (recnum2 = fcb->lastrecno + 1; recnum2 <= recnum; recnum2++) {
|
||||
_cp_tofile(fcb, fcb->datfd, tailoffbuf, _vl_getpos(fcb, recnum2), LONGSIZE);
|
||||
strecno(fcb->freerecno, recnumbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, recnumbuf,
|
||||
_vl_getpos(fcb, recnum2) + LONGSIZE, RECNOSIZE);
|
||||
fcb->freerecno = recnum2;
|
||||
|
||||
/* Sync the updates to avoid buffer pool overflow. */
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
fcb->lastrecno = recnum;
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the disk structures are in a consistent state now,
|
||||
* the .rec was extended by a few records marked as 'deleted'.
|
||||
* This is important for subsequent rollbacks.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* If recnum specifies a record that has existed, check whether it
|
||||
* has been deleted. _vlrec_wrrec() does not override existing record.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
tailoff = ldlong(tailoffbuf);
|
||||
if (tailoff != VL_RECDELETED) {
|
||||
return (EDUPL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the record from the chain of deleted records.
|
||||
*/
|
||||
remove_from_chain2(fcb, recnum);
|
||||
|
||||
/*
|
||||
* Store variable part of record (the 'tail') in .var file.
|
||||
*/
|
||||
tailoff = _istail_insert(fcb, record + fcb->minreclen, reclen - fcb->minreclen);
|
||||
|
||||
/*
|
||||
* Copy new record to the .rec file.
|
||||
*/
|
||||
stlong(tailoff, tailoffbuf);
|
||||
_cp_tofile(fcb, fcb->datfd, tailoffbuf, rec_position, LONGSIZE);
|
||||
_cp_tofile(fcb, fcb->datfd, record, rec_position + LONGSIZE, fcb->minreclen);
|
||||
|
||||
return (ISOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* remove_from_chain(fcb, recnum)
|
||||
*
|
||||
* Remove record from the chain of deleted records.
|
||||
*/
|
||||
|
||||
static void
|
||||
remove_from_chain2(fcb, recnum)
|
||||
Fcb *fcb;
|
||||
Recno recnum;
|
||||
{
|
||||
char recnobuf1 [RECNOSIZE] , recnobuf2 [RECNOSIZE];
|
||||
long pos1, pos2;
|
||||
Recno recnum2;
|
||||
|
||||
pos1 = _vl_getpos(fcb, recnum);
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf1, pos1 + LONGSIZE, RECNOSIZE);
|
||||
|
||||
if (fcb->freerecno == recnum) {
|
||||
fcb->freerecno = ldrecno(recnobuf1);
|
||||
}
|
||||
else {
|
||||
recnum2 = fcb->freerecno;
|
||||
do {
|
||||
pos2 = _vl_getpos(fcb, recnum2);
|
||||
_cp_fromfile(fcb, fcb->datfd, recnobuf2, pos2 + LONGSIZE, RECNOSIZE);
|
||||
recnum2 = ldrecno(recnobuf2);
|
||||
} while (recnum2 != recnum && recnum2 != NULL_RECNO);
|
||||
|
||||
_cp_tofile(fcb, fcb->datfd, recnobuf1, pos2 + LONGSIZE, RECNOSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following are functions that manipulate the 'tails' of variable
|
||||
* records. The tail is the actual record with the fixed part removed
|
||||
* (fixed part starts at offset zero and its length is minimum record
|
||||
* length. The tails are stored in the .var file.
|
||||
*/
|
||||
|
||||
|
||||
/* Insert tail into .var file. Return offset in .var file */
|
||||
|
||||
long _istail_insert(fcb, tailp, taillen)
|
||||
Fcb *fcb;
|
||||
char *tailp;
|
||||
int taillen;
|
||||
{
|
||||
char frameheadbuf [2 * SHORTSIZE];
|
||||
int framelen;
|
||||
long offset;
|
||||
|
||||
/* printf ("_insert called, taillen %d\n", taillen); */
|
||||
|
||||
if (taillen == 0)
|
||||
return (VL_RECNOTAIL);
|
||||
|
||||
framelen = taillen + 2 * SHORTSIZE;
|
||||
|
||||
/*
|
||||
* Set up frame header.
|
||||
*/
|
||||
stshort((short)taillen, frameheadbuf + VR_FRAMELEN_OFF);
|
||||
stshort((short)taillen, frameheadbuf + VR_TAILLEN_OFF);
|
||||
|
||||
offset = fcb->varend;
|
||||
|
||||
/*
|
||||
* Extend .var file if that is necesary.
|
||||
*/
|
||||
while (offset + framelen > fcb->varsize * ISPAGESIZE)
|
||||
fcb->varsize = _extend_file(fcb, fcb->varfd, fcb->varsize);
|
||||
|
||||
/*
|
||||
* Copy frame head and tail to .var file.
|
||||
*/
|
||||
_cp_tofile(fcb, fcb->varfd, frameheadbuf, offset, 2 * SHORTSIZE);
|
||||
_cp_tofile(fcb, fcb->varfd, tailp, offset + 2 * SHORTSIZE, taillen);
|
||||
|
||||
fcb->varend += taillen + 2 * SHORTSIZE;
|
||||
|
||||
return (offset);
|
||||
}
|
||||
|
||||
/* Remove tail from .var file */
|
||||
|
||||
/* ARGSUSED */
|
||||
Static void _istail_delete(fcb, offset)
|
||||
Fcb *fcb;
|
||||
long offset;
|
||||
{
|
||||
/*
|
||||
* Don't do anything in NetISAM 1.0. The tails are lost, the space
|
||||
* will be re-used after next restructuring: "copy -c file" command
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read tail from .var file */
|
||||
|
||||
Static _istail_read(fcb, offset, buffer)
|
||||
Fcb *fcb;
|
||||
long offset;
|
||||
char *buffer;
|
||||
{
|
||||
char frameheadbuf [2 * SHORTSIZE];
|
||||
int taillen;
|
||||
|
||||
/* printf ("_read called, offset %d\n", offset); */
|
||||
|
||||
if (offset == VL_RECNOTAIL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Read frame header.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->varfd, frameheadbuf, offset, 2 * SHORTSIZE);
|
||||
taillen = ldshort(frameheadbuf + VR_TAILLEN_OFF);
|
||||
_cp_fromfile(fcb, fcb->varfd, buffer, offset + 2 * SHORTSIZE, taillen);
|
||||
|
||||
return (taillen);
|
||||
}
|
||||
|
||||
/* Rewrite tail. Returns -1 if the new tail is longer than the original frame */
|
||||
|
||||
int _istail_modify(fcb, offset, tailp, taillen)
|
||||
Fcb *fcb;
|
||||
long offset;
|
||||
int taillen;
|
||||
char *tailp;
|
||||
{
|
||||
char frameheadbuf [2 * SHORTSIZE];
|
||||
int framelen;
|
||||
|
||||
/*
|
||||
* Trivial case: no old frame, no new tail.
|
||||
*/
|
||||
if (offset == VL_RECNOTAIL && taillen == 0)
|
||||
return (offset);
|
||||
|
||||
if (offset != VL_RECNOTAIL) {
|
||||
/*
|
||||
* Read frame header.
|
||||
*/
|
||||
_cp_fromfile(fcb, fcb->varfd, frameheadbuf, offset, 2 * SHORTSIZE);
|
||||
framelen = ldshort(frameheadbuf + VR_FRAMELEN_OFF);
|
||||
}
|
||||
else
|
||||
framelen = 0;
|
||||
|
||||
if (taillen > framelen) {
|
||||
/*
|
||||
* Delete the old frame if the new tail does not fit.
|
||||
* Insert the new tail at the end of .var file.
|
||||
*/
|
||||
|
||||
_istail_delete(fcb, offset);
|
||||
return (_istail_insert(fcb, tailp, taillen));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* The new tail fits in the existing frame.
|
||||
*/
|
||||
stshort((short)taillen, frameheadbuf + VR_TAILLEN_OFF);
|
||||
_cp_tofile(fcb, fcb->varfd, frameheadbuf, offset, 2 * SHORTSIZE);
|
||||
_cp_tofile(fcb, fcb->varfd, tailp, offset + 2 * SHORTSIZE, taillen);
|
||||
|
||||
return (offset);
|
||||
}
|
||||
}
|
||||
38
cde/lib/tt/mini_isam/isvars.c
Normal file
38
cde/lib/tt/mini_isam/isvars.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isvars.c /main/3 1995/10/23 11:45:48 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isvars.c 1.7 90/08/15 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isvars.c
|
||||
*
|
||||
* Description:
|
||||
* NetISAM gloabl variables
|
||||
*
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
|
||||
int iserrno;
|
||||
int isreclen;
|
||||
long isrecnum;
|
||||
|
||||
char isstat1, isstat2, isstat3, isstat4;
|
||||
|
||||
static struct keydesc _nokey;
|
||||
struct keydesc *nokey = &_nokey;
|
||||
|
||||
/*
|
||||
* isdupl is used internally to indicate that some index contains
|
||||
* a duplicate value. Used only to set up isstat2 Cobol variable.
|
||||
*/
|
||||
|
||||
int isdupl; /* 1 if duplicate found */
|
||||
|
||||
23
cde/lib/tt/mini_isam/isversion.c
Normal file
23
cde/lib/tt/mini_isam/isversion.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: isversion.c /main/3 1995/10/23 11:46:03 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)isversion.c 1.5 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988, 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* isversion.c
|
||||
*
|
||||
* Description:
|
||||
* Keep version for Customer Support benefit
|
||||
* Since this version is considered part of ToolTalk, use the
|
||||
* ToolTalk version number.
|
||||
*
|
||||
*/
|
||||
|
||||
char _isam_version[] = TT_VERSION_STRING;
|
||||
113
cde/lib/tt/mini_isam/iswrite.c
Normal file
113
cde/lib/tt/mini_isam/iswrite.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iswrite.c /main/3 1995/10/23 11:46:15 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iswrite.c 1.8 89/07/17 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iswrite.c
|
||||
*
|
||||
* Description:
|
||||
* Write a record to ISAM file.
|
||||
*/
|
||||
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _am_write();
|
||||
|
||||
/*
|
||||
* err = iswrite(isfd, record)
|
||||
*
|
||||
* Iswrite() adds a new record to an ISAM file. All indexes of the ISAM
|
||||
* file are updated.
|
||||
*
|
||||
* Current record position is not changed.
|
||||
* isrecnum is set to indicate the new record.
|
||||
*
|
||||
* If the ISAM file is for variable length records, the isreclen variable
|
||||
* must be set to indicate the actual length of the record, which must
|
||||
* be between the minimum and maximum length, as specified in isbuild().
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* EDUPL The write woul result in a duplicate on a key that
|
||||
* does not allow duplicates.
|
||||
* ELOCKED The file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was opened with ISINPUT mode.
|
||||
* EBADARG Unacceptable value of isreclen for variable length record.
|
||||
*/
|
||||
|
||||
int
|
||||
iswrite(isfd, record)
|
||||
int isfd;
|
||||
char *record;
|
||||
{
|
||||
int _am_write();
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
Recno recnum;
|
||||
Bytearray curpos;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISOUTPUT, or ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_OUTPUT && fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine record length. Check it against min and max record length.
|
||||
*/
|
||||
reclen = (fab->varlength == TRUE) ? isreclen : fab->minreclen;
|
||||
if (reclen < fab->minreclen || reclen > fab->maxreclen) {
|
||||
_setiserrno2(EBADARG, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the Access Method
|
||||
*/
|
||||
curpos = _bytearr_dup(&fab->curpos);
|
||||
|
||||
if ((ret = _am_write(fab, record, reclen, &curpos, &recnum)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
_bytearr_free(&curpos);
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
|
||||
Static int _am_write(fab, record, reclen, curpos, recnum)
|
||||
register Fab *fab;
|
||||
char *record;
|
||||
int reclen;
|
||||
Bytearray *curpos;
|
||||
Recno *recnum;
|
||||
{
|
||||
return (_amwrite(&fab->isfhandle, record, reclen,
|
||||
curpos, recnum, &fab->errcode));
|
||||
}
|
||||
184
cde/lib/tt/mini_isam/iswrrec.c
Normal file
184
cde/lib/tt/mini_isam/iswrrec.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: iswrrec.c /main/3 1995/10/23 11:46:30 rswiston $ */
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)iswrrec.c 1.7 89/06/07 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iswrrec.c
|
||||
*
|
||||
* Description:
|
||||
* Write a record to ISAM file.
|
||||
*/
|
||||
|
||||
#include "isam_impl.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
static int _amwrrec();
|
||||
|
||||
/*
|
||||
* isfd = iswrrec(isfd, recnum, record)
|
||||
*
|
||||
* Iswrrec() writes a record to ISAM file at specified recno position.
|
||||
* All indexes of the ISAM file are updated.
|
||||
*
|
||||
* Current record position is not changed.
|
||||
* isrecnum is set to recnum.
|
||||
*
|
||||
* If the ISAM file is for variable length records, the isreclen variable
|
||||
* must be set to indicate the actual length of the record, which must
|
||||
* be between the minimum and maximum length, as specified in isbuild().
|
||||
*
|
||||
* Returns 0 if successful, or -1 of any error.
|
||||
*
|
||||
* Errors:
|
||||
* EDUPL The write would result in a duplicate on a key that
|
||||
* does not allow duplicates.
|
||||
* ELOCKED The file has been locked by another process.
|
||||
* ENOTOPEN isfd does not correspond to an open ISAM file, or the
|
||||
* ISAM file was not opened with ISINOUT mode.
|
||||
* EKEXISTS Record with recnum already exists.
|
||||
* EBADARG recnum is negative.
|
||||
*/
|
||||
|
||||
int
|
||||
iswrrec(isfd, recnum, record)
|
||||
int isfd;
|
||||
long recnum;
|
||||
char *record;
|
||||
{
|
||||
register Fab *fab;
|
||||
int reclen;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get File Access Block.
|
||||
*/
|
||||
if ((fab = _isfd_find(isfd)) == NULL) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the open mode was ISINOUT.
|
||||
*/
|
||||
if (fab->openmode != OM_INOUT) {
|
||||
_setiserrno2(ENOTOPEN, '9', '0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine record length. Check it against min and max record length.
|
||||
*/
|
||||
reclen = (fab->varlength == TRUE) ? isreclen : fab->minreclen;
|
||||
if (reclen < fab->minreclen || reclen > fab->maxreclen) {
|
||||
_setiserrno2(EBADARG, '9' ,'0');
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
if ((ret = _amwrrec(&fab->isfhandle, record, reclen,
|
||||
recnum, &fab->errcode)) == ISOK) {
|
||||
isrecnum = recnum; /* Set isrecnum */
|
||||
}
|
||||
|
||||
_seterr_errcode(&fab->errcode);
|
||||
|
||||
return (ret); /* Successful write */
|
||||
}
|
||||
|
||||
/*
|
||||
* _amwrrec(isfhandle, record, reclen, recnum, errcode)
|
||||
*
|
||||
* _amwrrec() rewrites a record in ISAM file.
|
||||
*
|
||||
* Input params:
|
||||
* isfhandle Handle of ISAM file
|
||||
* record record
|
||||
* reclen length of the record
|
||||
* recnum record number of record to be deleted
|
||||
*
|
||||
* Output params:
|
||||
* errcode error status of the operation
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
_amwrrec(isfhandle, record, reclen, recnum, errcode)
|
||||
Bytearray *isfhandle;
|
||||
char *record;
|
||||
int reclen;
|
||||
Recno recnum;
|
||||
struct errcode *errcode;
|
||||
{
|
||||
Fcb *fcb = NULL;
|
||||
int err;
|
||||
int (*rec_wrrec)();
|
||||
|
||||
_isam_entryhook();
|
||||
|
||||
/*
|
||||
* Get FCB corresponding to the isfhandle handle.
|
||||
*/
|
||||
if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
rec_wrrec = (fcb->varflag?_vlrec_wrrec:_flrec_wrrec);
|
||||
|
||||
/*
|
||||
* Update information in FCB from CNTL page on the disk
|
||||
*/
|
||||
(void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
if ((err = rec_wrrec(fcb, record, recnum, reclen)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update all keys.
|
||||
*/
|
||||
if ((err = _addkeys(fcb, record, recnum)) != ISOK) {
|
||||
_amseterrcode(errcode, err);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
fcb->nrecords++;
|
||||
|
||||
_amseterrcode(errcode, ISOK);
|
||||
|
||||
_issignals_mask();
|
||||
_isdisk_commit();
|
||||
_isdisk_sync();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Update CNTL Page from the FCB.
|
||||
*/
|
||||
(void)_isfcb_cntlpg_w2(fcb);
|
||||
_issignals_unmask();
|
||||
|
||||
_isam_exithook();
|
||||
return (ISOK);
|
||||
|
||||
ERROR:
|
||||
_isdisk_rollback();
|
||||
_isdisk_inval();
|
||||
|
||||
/*
|
||||
* Restore FCB from CNTL page.
|
||||
*/
|
||||
if (fcb) (void)_isfcb_cntlpg_r2(fcb);
|
||||
|
||||
_isam_exithook();
|
||||
return (ISERROR);
|
||||
}
|
||||
|
||||
|
||||
19
cde/lib/tt/mini_isam/strdup.ultrix.c
Normal file
19
cde/lib/tt/mini_isam/strdup.ultrix.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: strdup.ultrix.c /main/3 1995/10/23 11:46:57 rswiston $ */
|
||||
/* strdup - make duplicate of string s */
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
char *
|
||||
strdup(char *s)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = (char *)malloc(strlen(s) + 1); /* + 1 for '\0' character */
|
||||
if (p != NULL)
|
||||
strcpy(p,s);
|
||||
return p;
|
||||
}
|
||||
Reference in New Issue
Block a user