Files
cdesktop/cde/lib/tt/mini_isam/isamopen.c
Jon Trulson c0388656dc tt/mini_isam: add new isam_prototypes.h include file and fix up problems
There were a variety of potential 64b problems due to the complete
lack of prototype declarations.  So, we add a file, isam_prototypes.h,
generated mostly by the 'cproto' tool.

We also fixed up some errors that having proper prototypes pointed
out, mainly in passing ints where pointers were expected and vice
versa.  The iserase() function was supposed to accept a char *, but
was defined as only accepting a char.  Fun stuff like that.
2018-06-30 20:13:39 -06:00

309 lines
7.3 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
*/
/*%% (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 $ */
/*
* 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(char *isfname, enum openmode openmode, Bool *varflag,
int *minlen, int *maxlen, Bytearray *isfhandle,
Bytearray *curpos, struct errcode *errcode)
{
Fcb *fcb;
Bytearray isfhandle0;
Crp *crp;
_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(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(Bytearray *isfhandle)
{
return (isfhandle->data);
}
/*
* isfhandle = _makeisfhandle(isfname)
*
* Make ISAM file handle.
*/
Bytearray
_makeisfhandle(char *isfname)
{
return (_bytearr_new((u_short)(strlen(isfname) + 1), isfname));
}