home *** CD-ROM | disk | FTP | other *** search
- /* ==( bench/iogen.c )== */
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written VvA Aug-89 */
- /* Modified VvA 11-Apr-90 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 11-Apr-90 VvA - addrec=appendrec, delrec=removerec
- * 28-Mar-90 VvA - adjustments for locking modes, transactions
- * 13-Mar-90 VvA - allow for database name, user id, passwords
- * 01-Feb-90 VvA - adj open_file, selectinx, replace "" with NULLs
- */
-
- /* I/O Library - General Functions
- * This module will provide the interface between generic I/O calls from
- * generated PRO-C applications and the specific I/O managers supported.
- * The calls are macro definitions, defined for the I/O manager chosen.
- *
- * Original I/O library modules by: AMcDonald, BZigon, NAttwell
- * Generalized I/O library concept: GLong
- */
-
-
- # include <stdio.h>
- # include <proc.io>
- # include <bench.h>
- # include <iodef.h>
- # include <iomsg.h>
- # include <passwd.h>
-
-
- #ifdef ANSI
- static int skiprec(int, char *, int);
- #else
- static int skiprec();
- #endif
-
-
- #define DB_INIT(dbnum, buffer) (*Fntab[dbnum-1][1])(-1, buffer)
- #define DB_LOGIN(dbnum, buffer) (*Fntab[dbnum-1][15])(-1, buffer)
-
- #define DB_OPEN(n, buffer) (*Fntab[fd[n].dbnum-1][2])(n, buffer)
- #define DB_CLOSE(n, buffer) (*Fntab[fd[n].dbnum-1][3])(n, buffer)
- #define DB_ADD(n, buffer) (*Fntab[fd[n].dbnum-1][4])(n, buffer)
- #define DB_DEL(n, buffer) (*Fntab[fd[n].dbnum-1][5])(n, buffer)
- #define DB_FIND(n, buffer) (*Fntab[fd[n].dbnum-1][6])(n, buffer)
- #define DB_FIRST(n, buffer) (*Fntab[fd[n].dbnum-1][7])(n, buffer)
- #define DB_LAST(n, buffer) (*Fntab[fd[n].dbnum-1][8])(n, buffer)
- #define DB_LOCK(n, buffer) (*Fntab[fd[n].dbnum-1][9])(n, buffer)
- #define DB_NEXT(n, buffer) (*Fntab[fd[n].dbnum-1][10])(n, buffer)
- #define DB_PREV(n, buffer) (*Fntab[fd[n].dbnum-1][11])(n, buffer)
- #define DB_ULOCK(n, buffer) (*Fntab[fd[n].dbnum-1][12])(n, buffer)
- #define DB_UPD(n, buffer) (*Fntab[fd[n].dbnum-1][13])(n, buffer)
- #define DB_COMMIT(n, buffer) (*Fntab[fd[n].dbnum-1][14])(n, buffer)
- #define DB_LOGOFF(n, buffer) (*Fntab[fd[n].dbnum-1][16])(n, buffer)
- #define DB_ROLLBACK(n, buffer) (*Fntab[fd[n].dbnum-1][17])(n, buffer)
- #define DB_TRANSACT(n, buffer) (*Fntab[fd[n].dbnum-1][18])(n, buffer)
- #define DB_SELINX(n, buffer) (*Fntab[fd[n].dbnum-1][19])(n, buffer)
- #define DB_REREAD(n, buffer) (*Fntab[fd[n].dbnum-1][20])(n, buffer)
- #define DB_NAME(n, buffer) (*Fntab[fd[n].dbnum-1][21])(n, buffer)
-
-
- struct fd_def fd[MAX_FILES];
- static int first_time = 1;
- static int ForEver; /* for file locking modes */
-
- extern char userid[];
- extern char password[];
-
-
- /*
- * General database and structure initialization
- * - database name, user id, password should be NULLs if not used
- */
- int init_file(dbname, uid, psw, dbnum)
- char *dbname, *uid, *psw;
- int dbnum;
- {
- int iostat, i;
-
- /* If table is not set up - go home */
- if (Fntab[dbnum-1][1] == (int(*)())0) /* Added by Geo 30-Nov-89 */
- abort_mess("Database indirection tables not loaded");
-
- if (first_time)
- {
- /* password check if reqd */
- if (iostat = login(uid, psw, dbnum))
- return(io_error(-1, iostat, "INIT1", NULL));
-
- /* database initialization if reqd */
- if (iostat = DB_INIT(dbnum, dbname))
- return(io_error(-1, iostat, "INIT2", NULL));
-
- first_time = 0;
- for (i = 0; i < MAX_FILES; i++)
- fd[i].active = NO;
- }
-
- return(IOGOOD);
- }
-
-
- /*
- * Generic open_file: calls I/O specific init_file and open_file
- * - fd structure should contain everything required by I/O mgr's open call
- * - I/O mgr interface function should take care of create, if needed
- */
- int open_file(fname, fsize, keys, flds, mode, dbnum)
- char *fname;
- int fsize;
- struct keyinfo *keys;
- struct fldinfx *flds;
- int mode, dbnum;
- {
- int fd_sys; /* file id value, also index into fd table */
- int iostat, i;
- char filename[PATHNAME_LEN];
- char *buffer = NULL; /* not actually used here but dummy for open */
-
- /* If table is not set up - go home */
- if (Fntab[dbnum-1][1] == (int(*)())0) /* Added by Geo 30-Nov-89 */
- abort_mess("Database indirection tables not loaded");
-
- for (fd_sys = UNUSED, i = 0; i < MAX_FILES; ++i)
- if (! fd[i].active) /* found first unused file defn */
- {
- fd[fd_sys = i].dbnum = dbnum;
- break;
- }
-
- if (fd_sys == UNUSED) /* if fd_sys still UNUSED, table is full */
- {
- errmsg(FileMaxOpen);
- return(IOERROR);
- }
-
- strcpy(filename, fname);
- DB_NAME(fd_sys, filename); /* set up file name as reqd by I/O manager */
-
- fd[fd_sys].active = YES;
- fd[fd_sys].cur_key = 0; /* default current index */
- fd[fd_sys].got_rec = NO;
- fd[fd_sys].rec_len = fsize; /* in case we create a dummy buffer */
- fd[fd_sys].openmode = mode;
- fd[fd_sys].lockmode = 0; /* assigned in each selectinx call */
- strcpy(fd[fd_sys].filname, filename); /* for error reporting */
- fd[fd_sys].flds = flds;
- fd[fd_sys].keys = keys;
-
- /* find field count */
- for (i = 0; fd[fd_sys].flds[i].fldname; i++)
- ;
- fd[fd_sys].fld_cnt = i;
-
- /* find key count */
- for (i = 0; fd[fd_sys].keys[i].segcount >= 0; i++)
- ;
- fd[fd_sys].key_cnt = i;
-
- if (iostat = DB_OPEN(fd_sys, buffer))
- return(io_error(fd_sys, iostat, "OPEN", NULL));
-
- return(fd_sys);
- }
-
-
- /*
- * Generic close_file - includes setting first_time if all files closed
- */
- int close_file(fd_sys)
- int fd_sys;
- {
- int iostat, n;
-
- if (iostat = DB_CLOSE(fd_sys, NULL))
- return(io_error(fd_sys, iostat, "CLOSE", NULL));
-
- if (fd_sys > -1) /* trap in case this is called with fd_sys = -1 */
- fd[fd_sys].active = NO;
-
- first_time = 1;
- for (n = 0; n < MAX_FILES; n++) /* first time set only if all closed */
- if (fd[n].active == YES)
- first_time = 0;
-
- return(IOGOOD);
- }
-
-
- /*
- * Generic select index:
- */
- void selectinx(fd_sys, keyno, match, retry)
- int fd_sys, keyno, match, retry;
- {
- fd[fd_sys].cur_key = --keyno;
- fd[fd_sys].exact = match; /* should be 1 for exact, 0 for GTE */
- fd[fd_sys].lockmode = retry;
- ForEver = (retry == -1);
- DB_SELINX(fd_sys, NULL);
- }
-
-
- /*
- * Generic key locate:
- */
- int findkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat, tries;
-
- tries = fd[fd_sys].lockmode;
- do
- {
- iostat = DB_FIND(fd_sys, buffer);
- if (iostat != IOLOCKED)
- break;
- }
- while ((--tries > 0) || ForEver);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "FIND", NULL));
-
- return(IOGOOD);
- }
-
-
- /*
- * Duplicate key check for record to be added:
- */
- int checkrec(fd_sys, buffer, inx)
- int fd_sys;
- char *buffer;
- int inx;
- {
- int iostat, oldexact;
- char tmpbuf[MAX_RECLEN];
- struct fd_def *fptr = &fd[fd_sys];
-
- memcpy(tmpbuf, buffer, fptr->rec_len);
- oldexact = fptr->exact;
-
- selectinx(fd_sys, inx, EXACT, 0);
-
- if (!(iostat = DB_FIND(fd_sys, tmpbuf))) /* direct call bypasses message */
- {
- ulock_rec(fd_sys, tmpbuf);
- fptr->exact = oldexact;
- return(IODUP);
- }
-
- fptr->exact = oldexact;
- return(IOGOOD);
- }
-
-
- /*
- * Generic top of file by current key:
- */
- int firstkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat, tries;
-
- tries = fd[fd_sys].lockmode;
- do
- {
- iostat = DB_FIRST(fd_sys, buffer);
- if (iostat != IOLOCKED)
- break;
- }
- while ((--tries > 0) || ForEver);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "FRST", NULL));
-
- return(IOGOOD);
- }
-
-
- /*
- * Generic end of file by current key:
- */
- int lastkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat, tries;
-
- tries = fd[fd_sys].lockmode;
- do
- {
- iostat = DB_LAST(fd_sys, buffer);
- if (iostat != IOLOCKED)
- break;
- }
- while ((--tries > 0) || ForEver);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "LAST", NULL));
-
- return(IOGOOD);
- }
-
-
- /*
- * Generic next record by current key:
- */
- int nextrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(skiprec(fd_sys, buffer, NEXT));
- }
-
-
- /*
- * Generic previous record by current key:
- */
- int prevrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(skiprec(fd_sys, buffer, PREV));
- }
-
-
- /*
- * General next/previous file traversal:
- * - next and previous record moves are identical except for actual call
- * and return condition from the I/O manager
- */
- static int skiprec(fd_sys, buffer, direction)
- int fd_sys, direction;
- char *buffer;
- {
- int klen, iostat, tries;
- char tmpbuf[MAX_RECLEN], oldkey[MAX_RECLEN], newkey[MAX_RECLEN];
- struct fd_def *fptr = &fd[fd_sys];
-
- if (fptr->exact) /* if exact match used, keep copy of starting key */
- {
- memcpy(tmpbuf, buffer, fptr->rec_len);
- extract_key(fd_sys, buffer, oldkey);
- }
-
- tries = fd[fd_sys].lockmode;
- do
- {
- if (direction == NEXT)
- iostat = DB_NEXT(fd_sys, buffer);
- else
- iostat = DB_PREV(fd_sys, buffer);
- if (iostat != IOLOCKED)
- break;
- }
- while ((--tries > 0) || ForEver);
-
- if (iostat != IOGOOD)
- {
- if (direction == NEXT)
- return(io_error(fd_sys, iostat, "NEXT", NULL));
- else
- return(io_error(fd_sys, iostat, "PREV", NULL));
- }
-
- if (fptr->exact) /* for exact "next", check if new key still matches */
- {
- klen = extract_key(fd_sys, buffer, newkey);
- if (memcmp(oldkey, newkey, klen))
- {
- DB_ULOCK(fd_sys, buffer);
- memcpy(buffer, tmpbuf, fptr->rec_len); /* restore old buffer */
- if (iostat = DB_REREAD(fd_sys, buffer)) /* restore old recpointer */
- return(io_error(fd_sys, iostat, "REREAD", NULL));
- return(IONONEXT); /* keys don't match for exact "next" */
- }
- }
- return(IOGOOD);
- }
-
-
- /*
- * Extracts all segments of a key into a temporary buffer
- * (DEC 89 - used to be static)
- */
- int extract_key(fd_sys, buffer, keybuf) /* returns total key length */
- int fd_sys;
- char *buffer, *keybuf;
- {
- int m, ko;
- struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
-
- struct fd_def *fptr = &fd[fd_sys]; /* ANDRE */
-
- for (m = 0, ko = 0; m < kptr->segcount; m++)
- {
- memcpy(&keybuf[ko], &buffer[kptr->segstart[m]], kptr->seglen[m]);
- ko += kptr->seglen[m];
-
- /*
- * 99 is a special key match, which allows the search
- * to inquire on n-1 of the segments, whilst still
- * ordering by all of the segments. Really only for
- * Oracle (ie. for Special Projects - NIG)
- */
- if (fptr->exact == 99 && (m + 2) == kptr->segcount)
- break;
- }
- return(ko);
- }
-
-
- /*
- * Generic add_rec:
- */
- int appendrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat;
-
- iostat = DB_ADD(fd_sys, buffer);
- DB_ULOCK(fd_sys, buffer);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "ADD", NULL));
- return(IOGOOD);
- }
-
-
- /*
- * Generic upd_rec:
- */
- int updrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat;
-
- iostat = DB_UPD(fd_sys, buffer);
- DB_ULOCK(fd_sys, buffer);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "UPD", NULL));
- return(IOGOOD);
- }
-
-
- /*
- * Generic del_rec:
- */
- int removerec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat;
-
- iostat = DB_DEL(fd_sys, buffer);
- DB_ULOCK(fd_sys, buffer);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "DEL", NULL));
- return(IOGOOD);
- }
-
-
- /*
- * Lock record - may be a dummy call for some I/O managers
- * - value in lockmode determines if lock tried, and how often
- * - because some file managers, ie Btrieve, use the lock function to do
- * repositioning, the onus will be on specific I/O modules to bounce
- * NOLOCK instances back with IOGOOD
- */
- int lock_rec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int iostat, tries;
-
- tries = fd[fd_sys].lockmode;
- do
- {
- if ((iostat = DB_LOCK(fd_sys, buffer)) != IOLOCKED)
- break;
- }
- while ((--tries > 0) || ForEver);
-
- if (iostat != IOGOOD)
- return(io_error(fd_sys, iostat, "LOCK", NULL));
-
- return(IOGOOD);
- }
-
-
- /*
- * Unlock record - may be a dummy call for some I/O managers
- */
- int ulock_rec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(DB_ULOCK(fd_sys, buffer));
- }
-
-
- /*
- * Login - may be a dummy call for some I/O managers
- * (if uid and psw are NULL, file manager itself can call for these)
- * - loginstr contains user id at offset 0, decrypted password at
- * offset 20 and is a static char array to avoid encrypt/decrypt
- * problems if files are closed and later reopened using this function
- */
- int login(uid, psw, dbnum)
- char *uid, *psw;
- int dbnum;
- {
- static char loginstr[41], *loginptr;
-
- if (uid && psw && !loginptr)
- {
- loginptr = loginstr;
- strcpy(loginptr, uid);
- strcpy(loginptr + 20, psw);
- }
-
- return(DB_LOGIN(dbnum, loginptr));
- }
-
-
- /*
- * Logoff - may be a dummy call for some I/O managers
- */
- int logoff(fd_sys)
- int fd_sys;
- {
- return(DB_LOGOFF(fd_sys, NULL));
- }
-
-
- /*
- * Start transaction - may be a dummy call for some I/O managers
- */
- int transact(fd_sys)
- int fd_sys;
- {
- return(DB_TRANSACT(fd_sys, NULL));
- }
-
-
- /*
- * Commit transaction - may be a dummy call for some I/O managers
- */
- int commit(fd_sys)
- int fd_sys;
- {
- return(DB_COMMIT(fd_sys, NULL));
- }
-
-
- /*
- * Rollback transaction - may be a dummy call for some I/O managers
- */
- int rollback(fd_sys)
- int fd_sys;
- {
- return(DB_ROLLBACK(fd_sys, NULL));
- }
-
-
- /*
- * General error handling routine
- * (pass -1 in fd_sys to close all files and exit)
- */
- int io_error(fd_sys, ernum, errcode, nextpgm)
- int fd_sys, ernum;
- char *errcode;
- char *nextpgm;
- {
- int n;
- extern int no_msg; /* suppresses error messages */
-
- if (!no_msg && (ernum != IOERROR))
- {
- switch(ernum)
- {
- case IONOTRANS :
- errmsg(FileNoTrans_s, fd[fd_sys].filname);
- break;
- case IONONEXT :
- errmsg(FileNoMoreMatch_ss, "target key", fd[fd_sys].filname);
- break;
- case IONOLOCK :
- errmsg(FileNotLocked_s, fd[fd_sys].filname);
- break;
- case IOLOCKED :
- errmsg(FileLocked_s, fd[fd_sys].filname);
- break;
- case IOEOF :
- errmsg(FileEnd_s, fd[fd_sys].filname);
- break;
- case IOTOF :
- errmsg(FileTop_s, fd[fd_sys].filname);
- break;
- case IODUP :
- errmsg(FileDuplKey_ss, "of target", fd[fd_sys].filname);
- break;
- case IONOKEY :
- errmsg(FileNoKey_ss, "of target", fd[fd_sys].filname);
- break;
- case IOINDEXPOSN :
- errmsg(FileDiffKey_s, fd[fd_sys].filname);
- break;
- case IOBADOPEN :
- errmsg(FileNotOpened_s, fd[fd_sys].filname);
- break;
- case IONOFILE :
- errmsg(FileNotFound_s, fd[fd_sys].filname);
- break;
- default :
- errmsg(FileDbgError_sds, fd[fd_sys].filname, ernum, errcode);
- }
- }
-
- if (fd_sys == -1)
- {
- for (n = 0; n < MAX_FILES; n++)
- if (fd[n].active == YES)
- close_file(n++);
- /*close_help();*/
- chain(nextpgm, NULL);
- }
-
- return(ernum);
- }
-