cdesktopenv/cde/lib/DtSearch/raima/dblfcns.c

493 lines
14 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* COMPONENT_NAME: austext
*
* FUNCTIONS: FL_LIST_ACCESS
* FL_LIST_DEACCESS
* Pi
* alloc_table
* bld_lock_tables
* d_close
* d_freeall
* d_keyfree
* d_keylock
* d_keylstat
* d_lock
* d_open
* d_recfree
* d_reclock
* d_reclstat
* d_retries
* d_rlbclr
* d_rlbset
* d_rlbtst
* d_setfree
* d_setlock
* d_setlstat
* d_timeout
* d_trabort
* d_trbegin
* d_trend
* free_files
* initdbt
* initses
* keep_locks
* lock_files
* neterr
* pr_lock_descr
* process_lock
* recovery_check
* reset_locks
* send_free
* send_lock
* taskinit
* termfree
* termses
*
* ORIGINS: 27,157
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
*
* OBJECT CODE ONLY SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1995, 1996
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*-----------------------------------------------------------------------=
$XConsortium: dblfcns.c /main/6 1996/11/25 18:48:05 drk $
dblfcns -- Database Access & Locking Functions
This file contains functions which open/close a
db_VISTA database and manage multiuser access
to the db_VISTA database files
(C) Copyright 1985, 1986, 1987 by Raima Corp.
-----------------------------------------------------------------------*/
/* ********************** EDIT HISTORY *******************************
SCR DATE INI DESCRIPTION
----- --------- --- -----------------------------------------------------
76 16-Jun-88 RSC Make dblfcns consistent when SINGLE_USER defined
240 17-Jun-88 RSC Make dblfcns consistent when NO_TRANS defined
103 24-Jun-88 RSC Improve generation of single user version
237 29-Jun-88 RSC Do not permit recfree/setfree/keyfree inside transaction
272 29-Jun-88 RSC make sure log entry is added to taf after lockmgr, and
deleted before lockmgr
305 01-Jul-88 RSC clear cache_ovfl flag after d_trend and d_trabort
??? 06-Jul_88 WLW include GENERAL lockmgr changes
353 14-Jul-88 RSC place dio_clear outside ifndef SINGLE_USER in d_trabort
367 14-Jul-88 RSC initialize prev lock to 'f' in bld_lock_tables
115 18-Jul-88 RSC Integrate VAX/VMS changes into master source
76 27-Jul-88 RSC More work making dblfcns work with SINGLE_USER
03-AUG-88 RTK MULTI_TASKing changes
310 10-Aug-88 RSC Cleanup of function prototypes
11-Aug-88 RTK Incremental database open/multi-tasking changes
18-Aug-88 RSC Moved rn_type/dba to separate table
423 10-Sep-88 RSC Allocated wrong size for rec_locks
423 12-Sep-88 RSC Moved o_free above termfree
423 15-Sep-88 RSC Initialized no_of_dbs to 1 in d_close
424 21-Sep-88 RSC Integrated International Character Set (ESM)
04-Oct-88 WLW Removed taskinit call from d_close, replaced with init's
425 05-Oct-88 RSC d_trabort was not completely clearing page zero
05-Oct-88 RSC must also init no_of_dbs = 1 in d_close (cf 04-Oct above)
420 07-Oct-88 RSC Unoptimized usage of fl_list - was full of bugs.
11-Oct-88 RSC Fix for clean compile under Lattice 3.3
441 08-Dec-88 RSC Place call to netbios_chk within ifndef GENERAL
Placed setting of inode/device within ifndef GENERAL
Removed undef UNIX / define MSC inside GENERAL
440 13-Dec-88 RSC Removed LR_LOCK lock_reply from db_global to scalar
440 22-Dec-88 RSC More modifications for General Lockmgr
539 18-Jan-89 RSC General Lockmgr was broke when open mode = one user
420 24-Jan-89 WLW Added ifdef's for SINGLE_USER in lock sets
571 27-Jan-89 RSC Remove defn of taf_close - General lockmgr lattice port issue
420 14-Feb-89 WLW Corrected KEYMARK handling in d_lock and lock_files
637 08-Mar-89 RSC Should not alloc file_refs in exclusive access, wasn't
Freeing fl_list of key_locks
713 08-May-89 WLW Make external recovery work for single-user and one-user
656 08-May-89 WLW Eliminate assignment to unallocated memory with gen lm.
$Log$
* Revision 1.2 1995/10/13 18:44:53 miker
* Change hardcoded dbfile[] size from 48 to DtSrFILENMLEN.
* Remove call to initenv()--disregard environment variables.
*/
/* To work with the General Lock Manager, the Unix case of using inode
number and device to identify a file is not used.
*/
#ifdef GENERAL
#define IS_UNIX_REALLY
#endif
#define DEBUG_DBLF
int debugging_dopen = 0; /* 1 = TRUE */
#include <stdio.h>
#include "vista.h"
#include "dbtype.h"
#ifdef IS_UNIX_REALLY
#undef DIRCHAR
#define DIRCHAR '/'
#endif
#define KEYMARK 30000
#define send_pkt (Send_pkt.ptr)
#define recv_pkt (Recv_pkt.ptr)
TASK db_global = { 0 };
int db_glob_init = 0;
/* As a quick fix to the General Lockmgr, the structure lock_reply was
removed from db_global. However, this assumes that db_VISTA would
never be preempted in the multi-tasking version, and that all function
calls would complete before a new task is run. If this assumption is
ever "broken" then lock_reply will need to be placed back within db_global
again */
extern CHAR_P Dbpgbuff; /* allocated by dio_init used by o_update */
extern LOOKUP_ENTRY_P Db_lookup; /* database page lookup table */
extern PAGE_ENTRY_P Dbpg_table; /* database page table */
extern LOOKUP_ENTRY_P Ix_lookup; /* index page lookup table */
extern PAGE_ENTRY_P Ixpg_table; /* index page table */
extern INT_P Used_files;
#define lsn (db_global.Lsn)
BOOLEAN trcommit = FALSE;
int db_txtest = 0; /* transaction commit failure testing flag */
#define FL_LIST_ACCESS(ld_ptr) (FILE_NO *)(ld_ptr)->fl_list.ptr
#define FL_LIST_DEACCESS(ld_ptr) /**/
/* Internal function prototypes */
static int bld_lock_tables(void);
static int initses(void);
static int lock_files(int, LOCK_REQUEST *);
static int send_lock(void);
static int send_free(void);
static void reset_locks(void);
static int recovery_check(void);
/* Open db_VISTA database
*/
int
d_open(const char *dbnames, const char *opentype)
{
DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_ALL));
#ifdef DEBUG_DBLF
if (debugging_dopen) {
puts (__FILE__"265 d_open");
fflush(stdout);
}
#endif
if ( dbopen ) d_close();
#ifdef MIKER /**@@@***/
/* initialize the country table if "vista.ctb" exists */
if ( ctb_init() != S_OKAY )
RETURN( db_status );
#endif
/* initialize multi-db tables */
if ( initdbt(dbnames) != S_OKAY ) RETURN( db_status );
/* read in schema tables */
if ( inittab() != S_OKAY ) RETURN( db_status );
#ifdef DEBUG_DBLF
if (debugging_dopen) {
puts(__FILE__"324 d_open calling renfiles");
fflush(stdout);
}
#endif
if ( renfiles() != S_OKAY ) RETURN( db_status );
dbopen = 2;
#ifdef DEBUG_DBLF
if (debugging_dopen) {
printf(__FILE__"392 d_open before key_open. pgsz=%hd lrgst=%hd\n",
page_size,largest_page);
fflush(stdout);
}
#endif
if ( key_open() == S_OKAY ) {
if ( dio_init() == S_OKAY ) {
RETURN( db_status );
}
}
dbopen = 0;
#ifdef DEBUG_DBLF
if (debugging_dopen) {
printf(__FILE__"404 d_open after dio_init. pgsz=%hd lrgst=%hd\n",
page_size,largest_page);
fflush(stdout);
}
#endif
RETURN( db_status );
} /* d_open() */
/* Initialize a task structure
*/
int taskinit(TASK *tsk)
{
byteset(tsk, '\0', sizeof(TASK));
tsk->No_of_dbs = 1;
tsk->Dboptions = DCHAINUSE;
return( db_status );
}
/* Initialize multiple database table entries
*/
int
initdbt(const char *dbnames)
{
int dbt_lc; /* loop control */
char dbfile [DtSrFILENMLEN];
char *ptr;
const char *cp;
int i;
/* compute number of databases to be opened */
old_no_of_dbs = (( no_of_dbs == 1 ) ? 0 : no_of_dbs);
for ( cp = dbnames; *cp; ++cp )
if ( *cp == ';' ) ++no_of_dbs;
#ifdef DEBUG_DBLF
if (debugging_dopen) {
printf(__FILE__"457 initdbt: new#dbs=%d\n", (int)no_of_dbs);
fflush(stdout);
}
#endif
/* Now make sure there are the right # of elements in dbd/dbfpath */
if (dbdpath[0]) {
if (get_element(dbdpath,no_of_dbs-1) == NULL) /* Not enuf? */
return( dberr(S_BADBDPATH) );
if (strrchr(dbdpath,';') != NULL) /* Is dbdpath single element */
if (get_element(dbdpath,no_of_dbs) != NULL) /* Too many? */
return( dberr(S_BADBDPATH) );
}
if (dbfpath[0]) {
if (get_element(dbfpath,no_of_dbs-1) == NULL) /* Not enuf? */
return( dberr(S_BADBFPATH) );
if (strrchr(dbfpath,';') != NULL) { /* Is dbfpath single element */
if (get_element(dbfpath,no_of_dbs) != NULL) /* Too many? */
return( dberr(S_BADBFPATH) );
}
}
/* allocate db_table space */
/* Macro references must be on one line for some compilers */
if ((ALLOC_TABLE(&db_global.Db_table, no_of_dbs*sizeof(DB_ENTRY),
old_no_of_dbs*sizeof(DB_ENTRY), "db_table") != S_OKAY) ||
(ALLOC_TABLE(&db_global.Rn_table, no_of_dbs*sizeof(RN_ENTRY),
old_no_of_dbs*sizeof(RN_ENTRY), "rn_table") != S_OKAY)) {
return( db_status );
}
/* initialize db_table entries */
for (dbt_lc = no_of_dbs, cp = dbnames,
curr_db_table = &db_table[old_no_of_dbs];
--dbt_lc >= 0;
++cp, ++curr_db_table) {
/* extract database name */
for ( i = 0; *cp && *cp != ';'; ++cp, ++i )
dbfile[i] = *cp;
dbfile[i] = '\0';
if ( (ptr = strrchr(dbfile, DIRCHAR)) == NULL )
ptr = strrchr(dbfile, ':');
if ( ptr ) {
if ( strlen(ptr+1) >= DBNMLEN ) RETURN( dberr(S_NAMELEN) );
strcpy(DB_REF(db_name), ptr+1);
*(ptr+1) = '\0';
if ( strlen(dbfile) >= PATHLEN ) RETURN( dberr(S_NAMELEN) );
strcpy(DB_REF(db_path), dbfile);
}
else {
strcpy(DB_REF(db_path), "");
strcpy(DB_REF(db_name), dbfile);
}
}
return( db_status = S_OKAY );
} /* initdbt() */
/****************************************/
/* */
/* d_close */
/* */
/****************************************/
/* Close database
*/
int
d_close(void)
{
int i;
DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_ALL));
if ( dbopen ) {
db_status = S_OKAY;
dio_flush();
for (i = 0; i < size_ft; ++i) {
/* close all files */
dio_close(i);
}
#ifdef MIKER /**@@@***/
/* free the country table */
if ( db_global.ctbl_activ )
ctbl_free();
#endif
/* termfree();
key_close();
sk_free();
dio_free(); */
}
if ( dbopen ) {
setdb_on = FALSE;
curr_db = 0;
no_of_dbs = 1;
db_status = S_OKAY;
curr_rec = NULL_DBA;
size_ft = 0;
size_rt = 0;
size_fd = 0;
size_st = 0;
size_mt = 0;
size_srt = 0;
size_kt = 0;
no_of_keys = 0;
dbopen = 0;
}
RETURN( db_status );
} /* d_close() */
/* Free all allocated memory upon termination
*/
void termfree(void)
{
/* free all allocated memory */
if ( curr_mem ) {
MEM_UNLOCK(&db_global.Curr_mem);
FREE(&db_global.Curr_mem);
}
if ( curr_own ) {
MEM_UNLOCK(&db_global.Curr_own);
FREE(&db_global.Curr_own);
}
if ( sort_table ) {
MEM_UNLOCK(&db_global.Sort_table);
FREE(&db_global.Sort_table);
}
if ( member_table ) {
MEM_UNLOCK(&db_global.Member_table);
FREE(&db_global.Member_table);
}
if ( set_table ) {
MEM_UNLOCK(&db_global.Set_table);
FREE(&db_global.Set_table);
}
if ( field_table ) {
MEM_UNLOCK(&db_global.Field_table);
FREE(&db_global.Field_table);
}
if ( key_table ) {
MEM_UNLOCK(&db_global.Key_table);
FREE(&db_global.Key_table);
}
if ( record_table ) {
MEM_UNLOCK(&db_global.Record_table);
FREE(&db_global.Record_table);
}
if ( file_table ) {
MEM_UNLOCK(&db_global.File_table);
FREE(&db_global.File_table);
}
if ( db_table ) {
MEM_UNLOCK(&db_global.Db_table);
FREE(&db_global.Db_table);
}
if ( rn_table ) {
MEM_UNLOCK(&db_global.Rn_table);
FREE(&db_global.Rn_table);
}
}
int alloc_table(
CHAR_P *Table,
#define table Table->ptr
unsigned new_size,
unsigned old_size
)
{
CHAR_P Temp_table;
Temp_table.ptr = ALLOC(&Temp_table, new_size, varname);
if ( Temp_table.ptr == NULL ) {
return( dberr(S_NOMEMORY) );
}
byteset(&Temp_table.ptr[old_size], 0, new_size - old_size);
if ( old_size ) {
bytecpy(Temp_table.ptr, table, old_size);
MEM_UNLOCK(Table);
FREE(Table);
}
*Table = Temp_table;
return( db_status );
}
/* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin dblfcns.c */