diff --git a/include/cisam.c b/include/cisam.c index d5220e7a0..1a23bd4a3 100755 --- a/include/cisam.c +++ b/include/cisam.c @@ -1,1695 +1,1695 @@ -/* -* -@(SH) Funzioni per la gestione dei file ISAM -@(C$) PRIVATE -logname : nome del file di LOG (GIORNALE) -INTTLOCK : costante che indica alla funzione di lettura che e' stata chaimata dalla funzione di scrittura e quindi deve solo controllare lo stato di lock del record -ISLOCKED : costante che indica che il record e' bloccato -@(VG$) PRIVATE -KSv, PosSv : variabili di lavoro -PagSv, IndSv : variabili di lavoro -IndActive : stato indici - TRUE = Aggiornati ad ogni modifica, FALSE = aggiorna solo i dati -isstate : Stato transazione corrente -win,wisfd : variabili di lavoro -isjournal : TRUE scrive il giornale -openf : array di TUTTI i puntatori ai descrittori dei file ISAM aperti -------------------------------------------------------------------------------- -*/ -#include "cisam.h" -#include "libdefs.h" -#include "checks.h" -#ifdef __WATCOMC__ -#include -#else -#include -#endif -#define logname "log.gen" -#define INTTLOCK 0xF000 -#define ISLOCKED 225 -#define NOALLOC (char **) -1 - TKey KSv; - int PosSv; - RecNoType PagSv,IndSv; - BOOLEAN IndActive = TRUE; - int isstate = NOTRANS ; - int wln = -1; - isfdptr wisfd; - extern BOOLEAN isjournal; -/* Guy moved them here from extcdecl.h */ - Str80 cprefix; - isfdptr* openf; - void savekeystat(isdef *); - void restkeystat(isdef *,int ); - int addkeys(isdef *,RecType ,int ,int *); - int delkeys(isdef *,RecType ,int ,int *); - int replkeys(isdef *,RecType ,RecType ,int ,int *); -#ifndef DOS - void writeundo(int ,isdef *,RecType); - void writelog(int ,isdef *,RecType); - char *undoname(void); - void getopenf(int ,RecType *); -#endif -/* -@($) savekeystat ISAM -@(ID) -Salva la chiave corrente. -@(FD) -*/ - void savekeystat(isfd) - isfdptr isfd; /* descrittore del file ISAM */ - { - strcpy(KSv,isfd->i.Key); - IndSv = isfd->i.Ind; - PosSv = isfd->i.Pos; - PagSv = isfd->i.CurPag; - } -/* -@($) restkeystat ISAM -@(ID) -Ripristina la chiave corrente. -@(FD) -*/ - void restkeystat(isfd,knum) - isfdptr isfd; /* descrittore del file ISAM */ - int knum; /* numero della chiave */ - { - isfd->i.PN = knum - 1; - strcpy(isfd->i.Key,KSv); - isfd->i.Ind = IndSv; - isfd->i.Pos = PosSv; - isfd->i.CurPag = PagSv; - } -/* -@($) relisfd ISAM -@(ID) -Vuota il descrittore del file . -@(FD) -*/ - void relisfd(isfd) - isfdptr *isfd; /* descrittore del file ISAM */ - { - free((char *) (*isfd)->d); - free((char *) (*isfd)->r); - free((char *) (*isfd)); - } -/* -@($) getisfd ISAM -@(ID) -Alloca e carica il descrittore del file con numero logico "logicname". -@(FD) -*/ - void getisfd(isfd, logicname) - isdef **isfd; /* descrittore del file ISAM */ - int logicname; /* numero logico del file */ - { - (*isfd) = (isfdptr) malloc(sizeof(**isfd)); - (*isfd)->d = (FileDes *) malloc(sizeof(*((*isfd)->d))); - (*isfd)->r = (RecDes *) malloc(sizeof(*((*isfd)->r))); - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, (*isfd)->d, NoLock, NORDIR); - if ((!(STREMPTY((*isfd)->d->SysName))) && ((*isfd)->d->SysName[0] == '%')) - (*isfd)->ft = COMDIR; - else - (*isfd)->ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, (*isfd)->ft); - COpenFile(logicname, (*isfd)->d, NoLock, (*isfd)->ft); - CCloseDir((*isfd)->ft); - COpenRecDir(ManuLock, (*isfd)->ft); - CGetRec(logicname,(*isfd)->r, (*isfd)->ft); - CCloseRecDir((*isfd)->ft); - } - /*void dump(s,l) - RecType s; - int l; - { - message_box("dump : record: %s ", &s[1]); - }*/ -/* -@(#) cisupdflags ISAM -@(ID) -Aggiorna all'interno del direttorio i campi EOD e Flags. -Ritorna il codice di errore. -@(FD) -@(ISV) -wd = riga relativa al file ISAM in oggetto nel Direttorio. -fdir = identificatore del file direttorio. -- Versione DOS e XENIX -@(FSV) -@(IN) -Il campo Flags viene aggiornato comunque, mentre EOD viene aggiornato solo -se il parametro di input "updateeod" e' TRUE. -@(FN) -*/ - int cisupdflags(isfd,err,updateeod) - isdef *isfd; /* puntatore al descrittore del file ISAM */ - int *err; /* codice di errore */ - BOOLEAN updateeod; /* se TRUE si aggiorna anche EOD */ - - { - FileDes wd; - - *err = NoErr ; - if (isfd->ln <= 0) return(*err) ; - COpenDir( ManuLock, isfd->ft); - COpenFile(isfd->ln, &wd, Lock, isfd->ft); - if ((*err = fdir[isfd->ft].IOR) == NoErr) - { - wd.Flags = isfd->d->Flags; -/* #ifdef DOS - if (updateeod) wd.EOD = isfd->d->EOD; - #else */ - if ((updateeod) && (isfd->f.LockMode == ExclLock)) wd.EOD = isfd->d->EOD; -/* #endif */ - CCloseFile(isfd->ln, &wd, isfd->ft); - } - CCloseDir(isfd->ft); - return(*err); - } - -/* -@(#) cisgeteod ISAM - -@(ID) -Ritorna l' EOD del file. -@(FD) - -@(ISV) - -- Versione DOS e XENIX -@(FSV) - -*/ - - RecNoType cisgeteod(isfd,err) - isfdptr isfd; /* puntatore al descrittore del file ISAM */ - int *err; /* codice di errore */ - - { - - *err = NoErr ; - if (isfd->ln > 0) - { - COpenDir( ManuLock , isfd->ft); - COpenFile(isfd->ln, isfd->d, NoLock, isfd->ft); - CCloseDir(isfd->ft); - } - return(isfd->d->EOD) ; - } - -/* -@(#) cisopen ISAM - -@(ID) -Apre un file ISAM e alloca il buffer per un record a attiva la chiave 1 (uno). -Ritorna il codice di errore. -@(FD) - -@(ISV) -werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. - -s = stringa di lavoro per messaggi di errore. - -- Versione DOS e XENIX -@(FSV) - -@(IN) -@(FN) -*/ - - int cisopen (isfd,logicname,record,mode,err) - isfdptr *isfd; /* puntatore al descrittore del file */ - int logicname; /* numero logico */ - RecType *record; /* buffer per contenere un record */ - unsigned int mode; /* modo di apertura (lock) */ - int *err; /* codice di errore */ - - { - *err = NoErr; - if (openf[logicname - 1] != NULL) - fatal_box("File n. %d already open", logicname); -#ifndef DOS - if ((excllock(CInsPref(glockname, NORDIR), FALSE) == -1) && (errno == EACCES)) - fatal_box("Can't open directory : Error n. %d ", errno); -#endif - getisfd (isfd,logicname); - COpen(&((*isfd)->f), (*isfd)->d->SysName, (*isfd)->d->LenR, 0, mode); - if (*err = (*isfd)->f.IOR) - { - Str80 name; strcpy(name, (*isfd)->d->SysName); - relisfd(isfd); - fatal_box("Can't open file n. %d (%s): error %d ", - logicname, name, *err); - } - if ((*isfd)->r->NKeys) - { - Str80 name; strcpy(name, CGetIdxName((*isfd)->d->SysName)); - CBOpenFile (&((*isfd)->i), name, mode, err); - if (*err) - { - CClose(&((*isfd)->f)); - relisfd(isfd); - fatal_box("Can't open file n. %d (%s): error %d ", - logicname, name, *err); - } -#ifndef DOS - else - if (mode == ExclLock) - { - CBLockFile(&((*isfd)->i), err); - if (*err) - { - int werr; - CClose(&((*isfd)->f)); - CBCloseFile(&((*isfd)->i), &werr); - relisfd(isfd); - fatal_box("Can't open exclusively file n. %d: error %d ", logicname, *err); - } - } -#endif - } - if (record != NOALLOC) - *record = (RecType) malloc((*isfd)->d->LenR); - (*isfd)->ln = logicname; - openf[logicname - 1] = *isfd; - if ((*isfd)->r->NKeys) (*isfd)->i.PN = 0; - return (*err); - } - -/* -@(#) ciscopyrec ISAM - -@(ID) -Copia un record dati da un record ad un altro. -Ritorna il codice di errore. -@(FD) - -@(ISV) -d = riga del direttorio corrispondente al file in esame. -@(FSV) - -@(IN) -@(FN) -*/ - - int ciscopyrec(logicname,recdest, recsrc ,err) - int logicname; /* numero logico del file ISAM */ - RecType recdest; /* buffer destinazione */ - RecType recsrc; /* buffer sorgente */ - int *err; /* codice di errore */ - - { - FileDes d; - int ft; - - *err = NoErr; - if (logicname < 0) logicname = -logicname; - if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); - { - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, &d, NoLock, NORDIR); - if ((!(STREMPTY(d.SysName))) && (d.SysName[0] == '%')) ft = COMDIR; - else ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, ft); - COpenFile(logicname, &d, NoLock, ft); - CCloseDir(ft); - } - memcpy(recdest, recsrc, d.LenR); - return(*err); - } - -/* -@(#) cisallocrec ISAM - -@(ID) -Alloca il buffer per un record. -Ritorna il codice di errore. -@(FD) - -@(ISV) -d = riga del direttorio corrispondente al file in esame. -@(FSV) - -@(IN) -@(FN) -*/ - - int cisallocrec(logicname,record,err) - int logicname; /* numero logico del file ISAM */ - RecType *record; /* buffer per il record */ - int *err; /* codice di errore */ - - { - FileDes d; - int ft; - - *err = NoErr; - if (logicname < 0) logicname = -logicname; - if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); - else - { - COpenDir(ManuLock, NORDIR); - CGetFile(logicname, &d, NoLock, NORDIR); - if ((!(STREMPTY(d.SysName))) && (d.SysName[0] == '%')) ft = COMDIR; - else ft = NORDIR; - CCloseDir(NORDIR); - COpenDir(ManuLock, ft); - COpenFile(logicname, &d, NoLock, ft); - CCloseDir(ft); - } - *record = (RecType) malloc(d.LenR); - if (*record == ((RecType) NULL)) return(ENOMEM); - else return(*err); - } - -/* -@(#) cisclose ISAM - -@(ID) -Chiude un file ISAM e libera il buffer del record. -Ritorna il codice di errore. -@(FD) - -@(ISV) -werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. - -s[20] = stringa di lavoro per messaggi di errore. - -- Versione DOS e XENIX -@(FSV) - -@(IN) -Restituisce il codice di errore -@(FN) -*/ - - int cisclose(isfd,rec,err) - isdef **isfd; /* puntatore al descrittore del file */ - RecType *rec; /* buffer per il record */ - int *err; /* codice di errore */ - - { - int werr = NoErr; - - *err = NoErr; - if (((*isfd)->ln > 0) && ((*isfd == NULL) || (openf[(*isfd)->ln - 1] == NULL))) - { - if (*isfd != NULL) - error_box("File n. % isclose : Error n. %d ", (*isfd)->ln, IsNotOpen); - else - error_box("isclose : errore n. %d ", IsNotOpen); - } - CClose(&((*isfd)->f)); - *err = ((*isfd)->f.IOR); - if ((*isfd)->r->NKeys) - { - CBCloseFile(&((*isfd)->i), &werr); - if (werr != NoErr ) *err = werr; - } - if ((*isfd)->ln > 0) - openf[(*isfd)->ln - 1] = NULL ; - if ((rec != NULL) && (*rec != NULL)) - free(*rec); - relisfd(isfd); -#ifndef DOS - exclunlock(CInsPref(glockname, NORDIR), FALSE); -#endif - if (*err) - fatal_box("isclose : Error n. %d ", *err); - return (*err); - } - -/* -@(#) cisstart ISAM - -@(ID) -Esegue una lettura cambiando il numero di chiave attiva. -Ritorna il codice di errore. -@(FD) - -@(IN) - La variabile record in input contiene i campi necessari per la ricerca, - in output contiene il record letto. - - La variabile mode e' formata da un comando di lock + comando di posizionamento - . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile - record non ha nessuna importanza. -@(FN) -*/ - - int cisstart(isfd,keynum,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - int keynum; /* numero della chiave */ - RecType record; /* buffer per il record */ - unsigned int mode; /* comando di lettura */ - int *err; /* codice di errore */ - - { - if(isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - *err = NoErr; - if(!(keynum >= 1) && (keynum <= isfd->r->NKeys)) - return((*err = BTrPathErr)); - isfd->i.PN = keynum - 1; - *err = cisread(isfd,record,mode,err); - return(*err); - } - -/* -@(#) cisread ISAM - -@(ID) -Esegue una lettura utilizzando la chiave attiva. -Ritorna il codice di errore. -@(FD) - -@(ISV) -rmode = variabile che contiene il tipo lettura utilizzato. - -lmode = varibaile dhe contiene il tipo lock utilizzato. - -knum = numero chiave attiva. - -junk = variabile spazzatura per la chiamata alla funzione "sleep". - -times = variabile di lavoro. - -s = stringa contenente messaggio. - -w = descrittore finestra . - -internaltlock = flag che verifica se la isread e' stata chiamata da iswrite per testare l' esistenza di un record. - -@(FSV) - -@(IN) - La variabile record in input contiene i campi necessari per la ricerca, - in output contiene il record letto. - - La variabile mode e' formata da un comando di lock + comando di posizionamento - . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile - record non ha nessuna importanza. -@(FN) -*/ - - int cisread(isfd,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record;/* buffer per il record */ - unsigned int mode; /* modo di lettura */ - int *err; /* codice di errore */ - - { - unsigned int rmode = (mode & READTYPES), - lmode = (mode & RecLockTypes), - knum = (isfd->i.PN+1); - int junk,times = 1; - TKey key,key1,key2; -/* char s[120]; */ - BOOLEAN internaltlock = (lmode == INTTLOCK); - - if (internaltlock) lmode = ShareLock; - *err = NoErr ; - if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - if (rmode & (IsPrevN + IsNextN)) - { - times = rmode & BYTEMASK; - if (rmode & IsPrevN) rmode = IsPrev; - else rmode = IsNext; - } - if (rmode == IsCurr) - { - if (!isfd->RecNo) return((*err = IsNotCurr)); - } - else - { - if (rmode == IsNext) - { - while ((times--) && (!*err)) - { - CBNext(&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - else - { - if (rmode == IsPrev) - { - while ((times--) && (!*err)) - { - CBPrev(&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - else - { - if (rmode == IsFirst) MinKey(CCalcLenKey(isfd->r,knum),key); - else - if (rmode == IsLast) MaxKey(CCalcLenKey(isfd->r,knum),key); - else - CBuildKey(isfd->r,knum,record,key); - CBRead(&isfd->i,knum,key,key1,&isfd->RecNo,err); - if ((rmode == IsGreat) && (!*err)) - while ((strcmp(key,key1) == 0) && (!*err)) - CBNext (&isfd->i,knum,key1,&isfd->RecNo,err); - } - } - } - do - { - if (((*err) && (rmode == IsEqual)) || - ((*err == BTrEOF) && (rmode == IsGreat))) - CRead(&isfd->f,record,isfd->RecNo,NoLock); - else - CRead(&isfd->f,record,isfd->RecNo,lmode); - if (TESTLOCK(isfd->f.IOR)) - { - if (lmode == ShareLock) - { - if (!*err) *err = ISLOCKED; - break; - } - message_box("Codice %s in uso da parte\ndi un altro utente.", key1); - if (rmode != IsCurr) - { - CBReRead(&isfd->i,knum,key1,key2,isfd->RecNo,&isfd->RecNo,&junk); - if (junk) strcpy(key1, key2) ; - } - } - else - if (!*err) *err = isfd->f.IOR; - } while (TESTLOCK(isfd->f.IOR)) ; - if (((rmode == IsFirst) || (rmode == IsLast)) && (*err != BTrEmptyTree)) - *err = NoErr; - if ((rmode == IsGtEq) && (*err != BTrEOF) && (*err != BTrEmptyTree)) - *err = NoErr ; - if (DEADLOCK(*err)) return(*err = IsDeadLock); - if (rmode == IsCurr) - { - CBuildKey(isfd->r,knum,record,key); - CBReRead(&isfd->i,knum,key,key1,isfd->RecNo,&isfd->RecNo,&junk); - } - if (*err == BTrEmptyTree) CZeroRec(isfd->r, record); - return(*err); - } - -/* -@($) addkeys ISAM - -@(ID) -Aggiunge all'indice le chiavi contenute nel record. -Ritorna il codice di errore. -@(FD) - -@(ISV) -i,j = contatori. - -werr = codice errore restituito dalla CBDelete. - -key = valore delle chiavi. -@(FSV) - -@(IN) -@(FN) -*/ - - int addkeys (isfd,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int knum; /* numero chiave corrente */ - int *err; /* codice errore */ - - { - int i,j,werr; - TKey key; - - for (i = 1;(i <= isfd->r->NKeys) && (!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBWrite(&isfd->i,i,key,isfd->RecNo,err); - if (i == knum) savekeystat(isfd); - } - if (*err) - { - if (i == 2 && *err == BTrDupKeysNotAll) *err = IsReInsert; - for (j = 1; (j < i); j++) - { - CBuildKey(isfd->r,j,record,key); - CBDelete(&isfd->i,j,key,isfd->RecNo,&werr); - } - } - else restkeystat(isfd,knum); - return(*err); - } - -/* -@(#) ciswrite ISAM - -@(ID) -Aggiunge un nuovo record al file ISAM. -Ritorna il codice di errore. -@(FD) - -@(ISV) -werr = codice errore restituito. - -knum = numero chiave attiva. - -junk = variabile di lavoro per la chiamata di varie funzioni. - -wrec = buffer di lavoro. -@(FSV) - -@(IN) - La variabile record in input contiene il record da aggiungere. -@(FN) -*/ - - int ciswrite (isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - - { - int knum = (isfd->i.PN+1), werr, junk; - RecNoType neweox; - - *err = NoErr; - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - if (isfd->ln > 0) - { - COpenDir (ManuLock, isfd->ft); - COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); - } - if (isfd->d->EOD == isfd->d->EOX) - { - neweox = isfd->d->EOX / 20 + 1; - if (neweox < 10) neweox = 10; - if (demoflag) - *err = IsFileFull; - else - { - neweox += isfd->d->EOX; - cisextend(isfd, isfd->ln, neweox, err); - } - if (*err == NoErr) - { - if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); - for (junk = 0; junk < isfd->r->NKeys; junk++) - isfd->i.Base[junk].PEOX = neweox; - } - else - { - isfd->d->EOX = neweox; - if (isfd->f.LockMode == ExclLock) - for (junk = 0; junk < isfd->r->NKeys; junk++) - isfd->i.Base[junk].PEOX = neweox; - } - } - else - { - if (isfd->ln > 0) - CCloseDir(isfd->ft); - isfd->RecNo = 0; - if (DEADLOCK(*err)) *err = IsDeadLock; - return((*err ? *err : (*err = IsFileFull))); - } - } - IRecallRec(record); - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - { - RecType wrec = malloc(isfd->d->LenR); - memcpy(wrec, record, isfd->d->LenR); - savekeystat(isfd); - junk = cisstart(isfd, 1, wrec, NoLock+IsEqual, &junk); - restkeystat(isfd, knum); - free(wrec); - - if ((junk == NoErr) || (junk == ISLOCKED)) - { - *err = IsReInsert; - if (isfd->ln > 0) - CCloseDir(isfd->ft); - isfd->RecNo = 0; - return(*err); - } - } - if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, Lock, isfd->ft); - } - isfd->RecNo = (++isfd->d->EOD); - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err) ; - if (!addkeys(isfd, record, knum, err)) - { - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - isfd->RecNo = 0; - junk = delkeys(isfd, record, knum, &werr); - } -/* else - if (isfd->ln > 0) - CCloseFile(isfd->ln,isfd->d, isfd->ft) ; */ - } - else isfd->d->EOD-- ; - if (isfd->ln > 0) - { - CCloseFile(isfd->ln,isfd->d, isfd->ft) ; - } - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - else - { - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) isfd->RecNo = 0; - else CCloseFile(isfd->ln,isfd->d, isfd->ft) ; - } - if (!(*err)) - { -#ifndef DOS - if (isstate == NOTRANS) writelog(FNWRITE, isfd, record); - else writeundo(FNWRITE, isfd, record); -#endif - } - if (isfd->ln > 0) - CCloseDir(isfd->ft); -// if (test_share()) - { - junk = cisunlock(isfd, &junk); - if (isstate == NOTRANS) - CLockRec(&isfd->f,isfd->RecNo,UnLock); - if (DEADLOCK(*err)) *err = IsDeadLock; - } - return(*err); - } - -/* -@($) delkeys ISAM - -@(ID) -Cancella le chiavi contenute nel record dall'indice. -Ritorna il codice di errore. -@(FD) - -@(ISV) -i,j = contatori. - -werr = codice errore da CBWrite. - -key = valori chiave. -@(FSV) - -@(IN) -@(FN) -*/ - - int delkeys (isfd,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int knum; /* numero della chiave attuale */ - int *err; /* codice di errore */ - - { - int i,j,werr; - TKey key; - - for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBDelete(&isfd->i,i,key,isfd->RecNo,err); - } - if (*err) - { - for (j = 1;(j < i);j++) - { - CBuildKey(isfd->r,j,record,key); - CBWrite(&isfd->i,j,key,isfd->RecNo,&werr); - } - } - else restkeystat(isfd,knum); - return(*err); - } - -/* -@(#) cisdelete ISAM - -@(ID) -Cancella un record da un file ISAM. -Ritorna il codice di errore. -@(FD) - -@(ISV) -knum = numero chiave successiva a quella attiva. - -werr = codice errore da CBUnLockFile. - -key1,key = valori chiave. - -- Versione DOS e XENIX -@(FSV) - -@(IN) - La variabile record in input contiene il record da cancellare. -@(FN) -*/ - - int cisdelete(isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - - { - int knum = (isfd->i.PN+1), werr; - TKey key,key1; - - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - *err = NoErr; - savekeystat(isfd); - CBuildKey(isfd->r,1,record,key); - *err = NoErr ; - CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); - if (*err) - { - restkeystat(isfd,knum); - return(*err); - } - CRead(&isfd->f, record, isfd->RecNo, NoLock); - if ((*err = isfd->f.IOR)) - { - restkeystat(isfd,knum); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if( /* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err) ; - delkeys(isfd, record, knum, err) ; - } - IDeleteRec(record); - CWrite(&isfd->f,record,isfd->RecNo,UnLock); - if((*err = isfd->f.IOR)) - { - IRecallRec(record); - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((isfd->r->NKeys) && IndActive) addkeys(isfd, record, knum, err) ; - restkeystat(isfd,knum); - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNDELETE, isfd, NULL); - CRead(&isfd->f,record,isfd->RecNo,UnLock); - } - else writeundo(FNDELETE, isfd, NULL); - } - if (/* test_share() && */(isfd->r->NKeys) && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -#else -/* if (test_share()) */ - { - CRead(&isfd->f,record,isfd->RecNo,UnLock); - if (isfd->r->NKeys && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; - } -#endif - return(*err); - } - -/* -@($) replkeys ISAM - -@(ID) -Rimpiazza le chiavi all'interno dell'indice. -Ritorna il codice di errore. -@(FD) - -@(ISV) -i,j = contatori. - -werr = codice errore ritornato da CBDelete e CBWrite. - -key,key1 = valori delle chiavi. -@(FSV) -*/ - - int replkeys (isfd,oldrec,record,knum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType oldrec; /* buffer contenente il vecchio record */ - RecType record; /* buffer contenente il nuovo record */ - int knum; /* numero della chiave attuale */ - int *err; /* codice di errore */ - - { - int i,j,werr; - TKey key,key1; - - for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) - { - CBuildKey(isfd->r,i,record,key); - CBuildKey(isfd->r,i,oldrec,key1); - if (strcmp(key,key1) != 0) - { - CBDelete(&isfd->i,i,key1,isfd->RecNo,err); - if (*err) break; - CBWrite(&isfd->i,i,key,isfd->RecNo,err); - if (*err) CBWrite(&isfd->i,i,key1,isfd->RecNo,err); - if (i == knum) savekeystat(isfd); - } - } - if (*err) - { - for (j = 1;(j < i);j++) - { - CBuildKey(isfd->r,j,record,key); - CBuildKey(isfd->r,j,oldrec,key1); - if (strcmp(key,key1) != 0) - { - CBDelete (&isfd->i,j,key,isfd->RecNo,&werr); - CBWrite(&isfd->i,j,key1,isfd->RecNo,&werr); - } - } - } - else restkeystat(isfd,knum); - return(*err); - } - -/* -@(#) cisrewrite ISAM - -@(ID) -Aggiorna un record nel file ISAM. -Ritorna il codice di errore. -@(FD) - -@(ISV) -knum = numero chiave successiva all'attuale. - -werr = codice errore restituito da CBUnLock. - -key, key1 = valori delle chiavi. - -oldrec = buffer di lavoro. - -- Versione DOS e XENIX -@(FSV) - -@(IN) - La variabile record in input contiene il record da aggiornare. -Utilizza la chiave 1 per ritrovare il record da aggiornare. -@(FN) -*/ - - int cisrewrite(isfd,record,err) - isfdptr isfd; /* descrittore del file isam */ - RecType record; /* buffer contenente i record */ - int *err; /* codice di errore */ - - { - int knum = (isfd->i.PN+1), werr; - TKey key,key1; - RecType oldrec; - - *err = NoErr ; - if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - savekeystat(isfd); - IRecallRec(record); - CBuildKey(isfd->r,1,record,key); - CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); - if(*err) - { - restkeystat(isfd,knum); - return(*err); - } - CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - restkeystat(isfd,knum); - free(oldrec); - return(*err); - } - if (memcmp(oldrec,record,isfd->d->LenR) == 0) - { - *err = NoErr; - restkeystat(isfd,knum); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - replkeys(isfd, oldrec, record, knum, err) ; - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - replkeys(isfd, record, oldrec, knum, err) ; - restkeystat(isfd,knum); - } - else -#ifndef DOS - { - if (isstate == NOTRANS) - { - writelog(FNREWRITE, isfd, record); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNREWRITE, isfd, oldrec); - } - -#else -// if (test_share()) - CLockRec(&isfd->f,isfd->RecNo,UnLock); -#endif - free(oldrec); - return(*err); - } - -/* -@(#) cisdelcurr ISAM - -@(ID) -Cancella il record corrente. -Ritorna il codice di errore. -@(FD) -*/ - - int cisdelcurr(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - - { - if(isfd->RecNo) cisdelrec(isfd,isfd->RecNo,err); - else *err = IsNotCurr; - return(*err); - } - -/* -@(#) cisrewcurr ISAM - -@(ID) -Riscrive il record corrente. -Ritorna il codice di errore. -@(FD) - -@(IN) - La variabile record in input contiene il record da aggiornare. -@(FN) -*/ - - int cisrewcurr(isfd,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer contenente il record */ - int *err; /* codice di errore */ - - { - if(isfd->RecNo) cisrewrec(isfd,isfd->RecNo,record,err); - else *err = IsNotCurr; - return (*err); - } - -/* -@(#) cisreadrec ISAM - -@(ID) -Legge un record di numero "recnum". -Ritorna il codice di errore. -@(FD) -*/ - - int cisreadrec(isfd,recnum,record,mode,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero del record */ - RecType record; /* buffer per il record */ - unsigned int mode; /* modo di lock */ - int *err; /* codice di errore */ - - { - isfd->RecNo = recnum; - return(cisread(isfd,record,IsCurr+(mode & RecLockTypes),err)); - } - -/* -@(#) ciswriterec ISAM - -@(ID) -Riscrive un record di numero "recnum". -@(FD) - -@(IN) - La variabile record in input contiene il record da aggiornare. -@(FN) - -@(ISV) -knum = numero chiave attiva. - -werr = codice errore restituito da CBUnLockFile. - -oldrec = buffer di lavoro. - -- Versione DOS e XENIX -@(FSV) -*/ - - int cisrewrec(isfd,recnum,record,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero del record da riscrivere */ - RecType record; /* buffer per il record */ - int *err; /* codice di errore */ - - { - int knum = (isfd->i.PN+1), werr; - RecType oldrec; - - *err = NoErr; - if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - isfd->RecNo = recnum; - IRecallRec(record); - CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - free(oldrec); - return(*err); - } - if (memcmp(oldrec,record,isfd->d->LenR) == 0) - { - *err = NoErr; -// if (test_share()) - CLockRec(&isfd->f,isfd->RecNo,UnLock); - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - replkeys(isfd, oldrec, record, knum, err) ; - if (/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i, &werr) ; - } - if (isstate == NOTRANS) CWrite(&isfd->f,record,isfd->RecNo,UnLock); - else CWrite(&isfd->f,record,isfd->RecNo,NoLock); - if ((*err = isfd->f.IOR)) - { - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - replkeys(isfd, record, oldrec, knum, err) ; - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNREWRITE, isfd, record); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNREWRITE, isfd, oldrec); - } -#else -/* if (test_share()) */ - CLockRec(&isfd->f,isfd->RecNo,UnLock); -#endif - free(oldrec); - return(*err); - } -/* -@(#) cisdelrec ISAM -@(ID) -Cancella un record utilizzando un numero di record. -Ritorna il codice di errore. -@(FD) -@(IN) - La variabile record in input contiene il record da cancellare. -@(FN) -@(ISV) -knum = numero della chiave attiva. -werr = codice di errore restituito da CBUnLockFiles. -oldrec = buffer di lavoro. -key1 = valore della chiave. -- Versione DOS e XENIX -@(FSV) -*/ - int cisdelrec(isfd,recnum,err) - isfdptr isfd; /* descrittore del file ISAM */ - RecNoType recnum; /* numero di record */ - int *err; /* codice di errore */ - { - int knum = (isfd->i.PN+1), werr; - int junk; - RecType oldrec ; - TKey key1 ; - *err = NoErr; - if(isfd == (isfdptr) NULL) return ((*err = IsNotOpen)); - oldrec = (RecType) malloc(isfd->d->LenR); - isfd->RecNo = recnum; - savekeystat(isfd); - CRead(&isfd->f, oldrec, isfd->RecNo, NoLock); - if ((*err = isfd->f.IOR)) - { - free(oldrec); - return(*err); - } - if ((isfd->r->NKeys) && IndActive) - { - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i, err) ; - delkeys(isfd, oldrec, knum, err); - } - IDeleteRec(oldrec); - CWrite(&isfd->f,oldrec,isfd->RecNo,UnLock); - if ((*err = isfd->f.IOR)) - { - IRecallRec(oldrec); - CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); - if ((isfd->r->NKeys) && IndActive) addkeys(isfd, oldrec, knum, err); - } -#ifndef DOS - else - { - if (isstate == NOTRANS) - { - writelog(FNDELETE, isfd, NULL); - CLockRec(&isfd->f,isfd->RecNo,UnLock); - } - else writeundo(FNDELETE, isfd, NULL); - } - if (/* test_share() && */(isfd->r->NKeys) && IndActive && (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; -#else -// if (test_share()) - { - CLockRec(&isfd->f,isfd->RecNo,UnLock); - if (isfd->r->NKeys && IndActive && - (isfd->f.LockMode != ExclLock)) - CBUnLockFile(&isfd->i, &werr) ; - } -#endif - free(oldrec); - isfd->RecNo = 0; - return(*err); - } -/* -@(#) cisgetrecno ISAM -@(ID) -Restituisce il numero del record corrente. -@(FD) -*/ - RecNoType cisgetrecno(isfd, err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - - { - if (!isfd->RecNo) *err = IsNotCurr; - else *err = NoErr; - return(isfd->RecNo); - } -/* -@(#) cislock ISAM -@(ID) -Blocca il file ISAM. -@(FD) -@(ISV) -junk = variabile spazzatura per la chiamata di sleep. -@(FSV) -*/ - int cislock(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - { - int junk; - *err = NoErr ; - if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); -#ifndef DOS - do - { - if (lockf(isfd->f.F,F_TLOCK,0L) == -1) - { - *err = CIOResult() ; - junk = sleep(1) ; - } - } while (TESTLOCK(*err)) ; -#endif - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBLockFile(&isfd->i,err); - return(*err); - } -/* -@(#) cisunlock ISAM -@(ID) -Sblocca un file ISAM. -@(FD) -*/ - int cisunlock(isfd,err) - isfdptr isfd; /* descrittore del file */ - int *err; /* codice di errore */ - { - return(cisrelease(isfd,err)); - } -/* -@(#) cisrelease ISAM -@(ID) -Sblocca un file ISAM. -@(FD) -*/ - int cisrelease(isfd,err) - isfdptr isfd; /* descrittore del file ISAM */ - int *err; /* codice di errore */ - { - *err = NoErr ; -#ifndef DOS - if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); - do - { - if (lockf(isfd->f.F,F_ULOCK,0L) == -1) *err = CIOResult() ; - } while (TESTLOCK(*err)) ; -#endif - if(/* test_share() && */ isfd->f.LockMode != ExclLock) - CBUnLockFile(&isfd->i,err); - return(*err); - } -/* -@(#) IndexOn ISAM -@(ID) -Attiva Aggiornamento Indici. -@(FD) -@(IN) -Di default gli indici sono attivi. -@(FN) -*/ - void IndexOn() - { - IndActive = TRUE ; - } -/* -@(#) IndexOff ISAM -@(ID) -Disattiva l'aggiornamento Indici. -@(FD) -*/ - void IndexOff() - { - IndActive = FALSE ; - } -#ifndef DOS -/* -@($) undoname ISAM -@(ID) -Restituisce il nome del file di Undo. -@(FD) -@(ISV) -path = stringa contenente il nome file. -@(FSV) -*/ - char *undoname() - { - static PathSt path; - TMPFNAME(path, "undo"); - return(path); - } -/* -@($) writeundo ISAM -@(ID) -Scrive una operazione effettuata nel file di Undo. -@(FD) -@(ISV) -fd = puntatore al file. -uname = nome del file di undo. -lgh = variabile di lavoro che contiene l' header del record di undo. -@(FSV) -*/ - void writeundo(fntype,isfd,record) - int fntype; /* operazione da effettuare */ - isfdptr isfd; /* descrittore del file */ - RecType record; /* buffer contenente il record */ - { - int fd; - PathSt uname; - loghead lgh; - - if (isfd->ln <= 0) return ; - strcpy(uname ,undoname()); - if ((fd = open(uname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - lgh.type = fntype; - lgh.time = time(NULL); - lgh.procid = getpid(); - lgh.userid = getuid(); - lgh.filenum = isfd->ln; - lgh.recnum = isfd->RecNo; - lgh.lenrec = isfd->d->LenR; - if (write(fd, &lgh, sizeof(lgh)) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - if (fntype & (FNREWRITE)) - if (write(fd, record, lgh.lenrec) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - if (close(fd) == -1) - fatal_box("Writeundo : Error n. %d ", errno); - } -/* -@($) writelog ISAM -@(ID) -Scrive sul file Giornale l'operazione effettuata. -@(FD) -@(ISV) -junk = variabile spazzatura per la chiamata di execunlock. -lname = nome del file Giornale (LOG). -fd = puntatore al file giornale. -lgh = testata del file giornale. -@(FSV) -*/ - void writelog(fntype,isfd,record) - int fntype; /* operazione effetuata */ - isfdptr isfd; /* descrittore del file ISAM */ - RecType record; /* buffer per il record */ - { - int fd,junk; - PathSt lname; - loghead lgh; - if (!isjournal) return; - if (isfd->ln <= 0) return ; - strcpy(lname, CInsPref(logname, NORDIR)); - while (excllock(lname,TRUE) == -1) sleep(1); - if ((fd = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - lgh.type = fntype + FNSTTRANS; - lgh.time = time(NULL); - lgh.procid = getpid(); - lgh.userid = getuid(); - if (fntype & (FNREWRITE + FNWRITE + FNDELETE)) - { - lgh.filenum = isfd->ln; - lgh.recnum = isfd->RecNo; - lgh.lenrec = isfd->d->LenR; - } - else - { - lgh.filenum = 0; - if (fntype == FNREORG) lgh.recnum = *((RecNoType *) record); - else lgh.recnum = 0L; - if (fntype == FNCHGREC) lgh.lenrec = sizeof(RecDes); - else lgh.lenrec = 0; - } - if (write(fd, &lgh, sizeof(lgh)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - if (fntype & (FNREWRITE + FNWRITE + FNCHGREC)) - if (write(fd, record, lgh.lenrec) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Writelog : Error n. %d ", errno); - } - if (close(fd) == -1) - fatal_box("Writelog : Error n. %d ", errno); - junk = exclunlock(lname,TRUE); - } -#endif -/* -@(#) StTrans ISAM -@(ID) -Inizia una transazione. -@(FD) -*/ - void StTrans() - { -#ifndef DOS - if (isstate == TRANS) EndTrans(); -#endif - isstate = TRANS; - } -#ifndef DOS -/* -@($) getopenf ISAM -@(ID) -Riconfigura il file di lavoro attivo sul file di numero logico "ln". -@(FD) -@(ISV) -junk = variabile spazzatura per la chiamata alla cisclose. -err = codice di errore ritornato dalla cisopen. -@(FSV) -*/ - void getopenf(ln,record) - int ln; /* numero logico del file */ - RecType *record; /* puntatore al buffer per il record */ - { - int err,junk; - if (openf[ln - 1] == NULL) - { - if (wln != ln) - { - if (wln != -1) junk = cisclose(&wisfd ,record ,&err); - cisopen(&wisfd, ln, record, ManuLock, &err); - wln = ln; - } - } - else *record = realloc(*record, openf[ln - 1]->d->LenR); - } -#endif -/* -@(#) EndTrans ISAM -@(ID) -Chiude una transazione. -@(FD) -@(ISV) -fdl, fdu = puntatori ai file di LOG e di Undo. -lname, uname = nomi dei file di LOG e di Undo. -lgh, lgh1 = variabili di lavoro contenenti le testate dei file di log. -nread = variabile di lavoro per la chiamata alla read. -werr = codice di errore ritornato dalla cisclose. -junk = variabile spazzatura per la chiamata di exclunlock. -start = variabile di lavoro. -record = buffer di lavoro. -@(FSV) -*/ - void EndTrans() - { -#ifndef DOS - int fdl, fdu; - PathSt lname, uname; - loghead lgh, lgh1; - int nread, werr, junk, start = FNSTTRANS; - RecType record; - strcpy(lname ,CInsPref(logname, NORDIR)); - while (excllock(lname,TRUE) == -1) sleep(1); - if (((fdl = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) || - ((fdu = open(uname, O_RDONLY, 0666)) == -1)) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - while ((nread = read(fdu, &lgh, sizeof(lgh))) > 0) - { - lgh.type += start; - start = 0; - if (write(fdl, &lgh, sizeof(lgh)) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - if (lgh.type == FNREWRITE) - if (lseek(fdu, (long) lgh.lenrec, 1) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - getopenf(lgh.filenum, &record); - CRead(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - if (write(fdl, record, lgh.lenrec) == -1) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - } - if ((nread <= 0) || (close(fdu) == -1) || (close(fdl) == -1) || - (unlink(uname) == -1)) - { - junk = exclunlock(lname,TRUE); - fatal_box("Endtrans : Error n. %d ", errno); - } - if (wln != -1) - { - junk = cisclose(&wisfd, &record, &werr); - wln = -1; - } - junk = exclunlock(lname,TRUE); -#endif - } -/* -@(#) AbTrans ISAM -@(ID) -Abortisce una transazione. -@(FD) -*/ - void AbTrans() - { -#ifndef DOS - int fd; - PathSt uname; - loghead lgh; - int nread, werr, junk; - RecType record; - RecType oldrec; - strcpy(uname ,undoname()); - if ((fd = open(uname, O_RDONLY, 0666)) == -1) - fatal_box("Abtrans : Error n. %d ", errno); - while ((nread = read(fd, &lgh, sizeof(lgh))) > 0) - { - getopenf(lgh.filenum, &record); - if (oldrec == NULL) oldrec = malloc(lgh.lenrec); - else oldrec = realloc(oldrec, lgh.lenrec); - if (lgh.type & (FNREWRITE)) - { - if ((nread = read(fd, record, lgh.lenrec)) <= 0) - fatal_box("Abtrans : Error n. %d ", errno); - } - if (lgh.lenrec != openf[lgh.filenum - 1]->d->LenR) - fatal_box("Abtrans : Error n. %d ", IsNoMatch); - CRead(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, NoLock); - switch (lgh.type) - { - case FNREWRITE : - junk = replkeys(openf[lgh.filenum - 1], oldrec, record, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - break; - case FNDELETE : - IRecallRec(oldrec); - junk = addkeys(openf[lgh.filenum - 1], oldrec, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, UnLock); - break; - case FNWRITE : - IDeleteRec(oldrec); - junk = delkeys(openf[lgh.filenum - 1], oldrec, - openf[lgh.filenum - 1]->i.PN + 1, &werr); - CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); - break; - } - } - if ((nread == -1) || (close(fd) == -1) || (unlink(uname) == -1)) - fatal_box("Abtrans : Error n. %d ", errno); - if (wln != -1) - { - junk = cisclose(&wisfd, &record, &werr); - wln = -1; - } -#endif - } - +/* +* +@(SH) Funzioni per la gestione dei file ISAM +@(C$) PRIVATE +logname : nome del file di LOG (GIORNALE) +INTTLOCK : costante che indica alla funzione di lettura che e' stata chaimata dalla funzione di scrittura e quindi deve solo controllare lo stato di lock del record +ISLOCKED : costante che indica che il record e' bloccato +@(VG$) PRIVATE +KSv, PosSv : variabili di lavoro +PagSv, IndSv : variabili di lavoro +IndActive : stato indici - TRUE = Aggiornati ad ogni modifica, FALSE = aggiorna solo i dati +isstate : Stato transazione corrente +win,wisfd : variabili di lavoro +isjournal : TRUE scrive il giornale +openf : array di TUTTI i puntatori ai descrittori dei file ISAM aperti +------------------------------------------------------------------------------- +*/ +#include "cisam.h" +#include "libdefs.h" +#include "checks.h" +#ifdef __WATCOMC__ +#include +#else +#include +#endif +#define logname "log.gen" +#define INTTLOCK 0xF000 +#define ISLOCKED 225 +#define NOALLOC (char **) -1 + TKey KSv; + int PosSv; + RecNoType PagSv,IndSv; + BOOLEAN IndActive = TRUE; + int isstate = NOTRANS ; + int wln = -1; + isfdptr wisfd; + extern BOOLEAN isjournal; +/* Guy moved them here from extcdecl.h */ + Str80 cprefix; + isfdptr* openf; + void savekeystat(isdef *); + void restkeystat(isdef *,int ); + int addkeys(isdef *,RecType ,int ,int *); + int delkeys(isdef *,RecType ,int ,int *); + int replkeys(isdef *,RecType ,RecType ,int ,int *); +#ifndef DOS + void writeundo(int ,isdef *,RecType); + void writelog(int ,isdef *,RecType); + char *undoname(void); + void getopenf(int ,RecType *); +#endif +/* +@($) savekeystat ISAM +@(ID) +Salva la chiave corrente. +@(FD) +*/ + void savekeystat(isfd) + isfdptr isfd; /* descrittore del file ISAM */ + { + strcpy(KSv,isfd->i.Key); + IndSv = isfd->i.Ind; + PosSv = isfd->i.Pos; + PagSv = isfd->i.CurPag; + } +/* +@($) restkeystat ISAM +@(ID) +Ripristina la chiave corrente. +@(FD) +*/ + void restkeystat(isfd,knum) + isfdptr isfd; /* descrittore del file ISAM */ + int knum; /* numero della chiave */ + { + isfd->i.PN = knum - 1; + strcpy(isfd->i.Key,KSv); + isfd->i.Ind = IndSv; + isfd->i.Pos = PosSv; + isfd->i.CurPag = PagSv; + } +/* +@($) relisfd ISAM +@(ID) +Vuota il descrittore del file . +@(FD) +*/ + void relisfd(isfd) + isfdptr *isfd; /* descrittore del file ISAM */ + { + free((char *) (*isfd)->d); + free((char *) (*isfd)->r); + free((char *) (*isfd)); + } +/* +@($) getisfd ISAM +@(ID) +Alloca e carica il descrittore del file con numero logico "logicname". +@(FD) +*/ + void getisfd(isfd, logicname) + isdef **isfd; /* descrittore del file ISAM */ + int logicname; /* numero logico del file */ + { + (*isfd) = (isfdptr) malloc(sizeof(**isfd)); + (*isfd)->d = (FileDes *) malloc(sizeof(*((*isfd)->d))); + (*isfd)->r = (RecDes *) malloc(sizeof(*((*isfd)->r))); + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, (*isfd)->d, NoLock, NORDIR); + if ((!(STREMPTY((*isfd)->d->SysName))) && ((*isfd)->d->SysName[0] != '$')) + (*isfd)->ft = COMDIR; + else + (*isfd)->ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, (*isfd)->ft); + COpenFile(logicname, (*isfd)->d, NoLock, (*isfd)->ft); + CCloseDir((*isfd)->ft); + COpenRecDir(ManuLock, (*isfd)->ft); + CGetRec(logicname,(*isfd)->r, (*isfd)->ft); + CCloseRecDir((*isfd)->ft); + } + /*void dump(s,l) + RecType s; + int l; + { + message_box("dump : record: %s ", &s[1]); + }*/ +/* +@(#) cisupdflags ISAM +@(ID) +Aggiorna all'interno del direttorio i campi EOD e Flags. +Ritorna il codice di errore. +@(FD) +@(ISV) +wd = riga relativa al file ISAM in oggetto nel Direttorio. +fdir = identificatore del file direttorio. +- Versione DOS e XENIX +@(FSV) +@(IN) +Il campo Flags viene aggiornato comunque, mentre EOD viene aggiornato solo +se il parametro di input "updateeod" e' TRUE. +@(FN) +*/ + int cisupdflags(isfd,err,updateeod) + isdef *isfd; /* puntatore al descrittore del file ISAM */ + int *err; /* codice di errore */ + BOOLEAN updateeod; /* se TRUE si aggiorna anche EOD */ + + { + FileDes wd; + + *err = NoErr ; + if (isfd->ln <= 0) return(*err) ; + COpenDir( ManuLock, isfd->ft); + COpenFile(isfd->ln, &wd, Lock, isfd->ft); + if ((*err = fdir[isfd->ft].IOR) == NoErr) + { + wd.Flags = isfd->d->Flags; +/* #ifdef DOS + if (updateeod) wd.EOD = isfd->d->EOD; + #else */ + if ((updateeod) && (isfd->f.LockMode == ExclLock)) wd.EOD = isfd->d->EOD; +/* #endif */ + CCloseFile(isfd->ln, &wd, isfd->ft); + } + CCloseDir(isfd->ft); + return(*err); + } + +/* +@(#) cisgeteod ISAM + +@(ID) +Ritorna l' EOD del file. +@(FD) + +@(ISV) + +- Versione DOS e XENIX +@(FSV) + +*/ + + RecNoType cisgeteod(isfd,err) + isfdptr isfd; /* puntatore al descrittore del file ISAM */ + int *err; /* codice di errore */ + + { + + *err = NoErr ; + if (isfd->ln > 0) + { + COpenDir( ManuLock , isfd->ft); + COpenFile(isfd->ln, isfd->d, NoLock, isfd->ft); + CCloseDir(isfd->ft); + } + return(isfd->d->EOD) ; + } + +/* +@(#) cisopen ISAM + +@(ID) +Apre un file ISAM e alloca il buffer per un record a attiva la chiave 1 (uno). +Ritorna il codice di errore. +@(FD) + +@(ISV) +werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. + +s = stringa di lavoro per messaggi di errore. + +- Versione DOS e XENIX +@(FSV) + +@(IN) +@(FN) +*/ + + int cisopen (isfd,logicname,record,mode,err) + isfdptr *isfd; /* puntatore al descrittore del file */ + int logicname; /* numero logico */ + RecType *record; /* buffer per contenere un record */ + unsigned int mode; /* modo di apertura (lock) */ + int *err; /* codice di errore */ + + { + *err = NoErr; + if (openf[logicname - 1] != NULL) + fatal_box("File n. %d already open", logicname); +#ifndef DOS + if ((excllock(CInsPref(glockname, NORDIR), FALSE) == -1) && (errno == EACCES)) + fatal_box("Can't open directory : Error n. %d ", errno); +#endif + getisfd (isfd,logicname); + COpen(&((*isfd)->f), (*isfd)->d->SysName, (*isfd)->d->LenR, 0, mode); + if (*err = (*isfd)->f.IOR) + { + Str80 name; strcpy(name, (*isfd)->d->SysName); + relisfd(isfd); + fatal_box("Can't open file n. %d (%s): error %d ", + logicname, name, *err); + } + if ((*isfd)->r->NKeys) + { + Str80 name; strcpy(name, CGetIdxName((*isfd)->d->SysName)); + CBOpenFile (&((*isfd)->i), name, mode, err); + if (*err) + { + CClose(&((*isfd)->f)); + relisfd(isfd); + fatal_box("Can't open file n. %d (%s): error %d ", + logicname, name, *err); + } +#ifndef DOS + else + if (mode == ExclLock) + { + CBLockFile(&((*isfd)->i), err); + if (*err) + { + int werr; + CClose(&((*isfd)->f)); + CBCloseFile(&((*isfd)->i), &werr); + relisfd(isfd); + fatal_box("Can't open exclusively file n. %d: error %d ", logicname, *err); + } + } +#endif + } + if (record != NOALLOC) + *record = (RecType) malloc((*isfd)->d->LenR); + (*isfd)->ln = logicname; + openf[logicname - 1] = *isfd; + if ((*isfd)->r->NKeys) (*isfd)->i.PN = 0; + return (*err); + } + +/* +@(#) ciscopyrec ISAM + +@(ID) +Copia un record dati da un record ad un altro. +Ritorna il codice di errore. +@(FD) + +@(ISV) +d = riga del direttorio corrispondente al file in esame. +@(FSV) + +@(IN) +@(FN) +*/ + + int ciscopyrec(logicname,recdest, recsrc ,err) + int logicname; /* numero logico del file ISAM */ + RecType recdest; /* buffer destinazione */ + RecType recsrc; /* buffer sorgente */ + int *err; /* codice di errore */ + + { + FileDes d; + int ft; + + *err = NoErr; + if (logicname < 0) logicname = -logicname; + if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); + { + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, &d, NoLock, NORDIR); + if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; + else ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, ft); + COpenFile(logicname, &d, NoLock, ft); + CCloseDir(ft); + } + memcpy(recdest, recsrc, d.LenR); + return(*err); + } + +/* +@(#) cisallocrec ISAM + +@(ID) +Alloca il buffer per un record. +Ritorna il codice di errore. +@(FD) + +@(ISV) +d = riga del direttorio corrispondente al file in esame. +@(FSV) + +@(IN) +@(FN) +*/ + + int cisallocrec(logicname,record,err) + int logicname; /* numero logico del file ISAM */ + RecType *record; /* buffer per il record */ + int *err; /* codice di errore */ + + { + FileDes d; + int ft; + + *err = NoErr; + if (logicname < 0) logicname = -logicname; + if (openf[logicname - 1] != NULL) d = *(openf[logicname - 1]->d); + else + { + COpenDir(ManuLock, NORDIR); + CGetFile(logicname, &d, NoLock, NORDIR); + if ((!(STREMPTY(d.SysName))) && (d.SysName[0] != '$')) ft = COMDIR; + else ft = NORDIR; + CCloseDir(NORDIR); + COpenDir(ManuLock, ft); + COpenFile(logicname, &d, NoLock, ft); + CCloseDir(ft); + } + *record = (RecType) malloc(d.LenR); + if (*record == ((RecType) NULL)) return(ENOMEM); + else return(*err); + } + +/* +@(#) cisclose ISAM + +@(ID) +Chiude un file ISAM e libera il buffer del record. +Ritorna il codice di errore. +@(FD) + +@(ISV) +werr = variabile di lavoro che raccoglie il codice errore proveniente dalla CBCloseFile. + +s[20] = stringa di lavoro per messaggi di errore. + +- Versione DOS e XENIX +@(FSV) + +@(IN) +Restituisce il codice di errore +@(FN) +*/ + + int cisclose(isfd,rec,err) + isdef **isfd; /* puntatore al descrittore del file */ + RecType *rec; /* buffer per il record */ + int *err; /* codice di errore */ + + { + int werr = NoErr; + + *err = NoErr; + if (((*isfd)->ln > 0) && ((*isfd == NULL) || (openf[(*isfd)->ln - 1] == NULL))) + { + if (*isfd != NULL) + error_box("File n. % isclose : Error n. %d ", (*isfd)->ln, IsNotOpen); + else + error_box("isclose : errore n. %d ", IsNotOpen); + } + CClose(&((*isfd)->f)); + *err = ((*isfd)->f.IOR); + if ((*isfd)->r->NKeys) + { + CBCloseFile(&((*isfd)->i), &werr); + if (werr != NoErr ) *err = werr; + } + if ((*isfd)->ln > 0) + openf[(*isfd)->ln - 1] = NULL ; + if ((rec != NULL) && (*rec != NULL)) + free(*rec); + relisfd(isfd); +#ifndef DOS + exclunlock(CInsPref(glockname, NORDIR), FALSE); +#endif + if (*err) + fatal_box("isclose : Error n. %d ", *err); + return (*err); + } + +/* +@(#) cisstart ISAM + +@(ID) +Esegue una lettura cambiando il numero di chiave attiva. +Ritorna il codice di errore. +@(FD) + +@(IN) + La variabile record in input contiene i campi necessari per la ricerca, + in output contiene il record letto. + + La variabile mode e' formata da un comando di lock + comando di posizionamento + . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile + record non ha nessuna importanza. +@(FN) +*/ + + int cisstart(isfd,keynum,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + int keynum; /* numero della chiave */ + RecType record; /* buffer per il record */ + unsigned int mode; /* comando di lettura */ + int *err; /* codice di errore */ + + { + if(isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + *err = NoErr; + if(!(keynum >= 1) && (keynum <= isfd->r->NKeys)) + return((*err = BTrPathErr)); + isfd->i.PN = keynum - 1; + *err = cisread(isfd,record,mode,err); + return(*err); + } + +/* +@(#) cisread ISAM + +@(ID) +Esegue una lettura utilizzando la chiave attiva. +Ritorna il codice di errore. +@(FD) + +@(ISV) +rmode = variabile che contiene il tipo lettura utilizzato. + +lmode = varibaile dhe contiene il tipo lock utilizzato. + +knum = numero chiave attiva. + +junk = variabile spazzatura per la chiamata alla funzione "sleep". + +times = variabile di lavoro. + +s = stringa contenente messaggio. + +w = descrittore finestra . + +internaltlock = flag che verifica se la isread e' stata chiamata da iswrite per testare l' esistenza di un record. + +@(FSV) + +@(IN) + La variabile record in input contiene i campi necessari per la ricerca, + in output contiene il record letto. + + La variabile mode e' formata da un comando di lock + comando di posizionamento + . Se non si utilizza ISEQUAL o ISGREAT o ISGTEQ, il valore della variabile + record non ha nessuna importanza. +@(FN) +*/ + + int cisread(isfd,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record;/* buffer per il record */ + unsigned int mode; /* modo di lettura */ + int *err; /* codice di errore */ + + { + unsigned int rmode = (mode & READTYPES), + lmode = (mode & RecLockTypes), + knum = (isfd->i.PN+1); + int junk,times = 1; + TKey key,key1,key2; +/* char s[120]; */ + BOOLEAN internaltlock = (lmode == INTTLOCK); + + if (internaltlock) lmode = ShareLock; + *err = NoErr ; + if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + if (rmode & (IsPrevN + IsNextN)) + { + times = rmode & BYTEMASK; + if (rmode & IsPrevN) rmode = IsPrev; + else rmode = IsNext; + } + if (rmode == IsCurr) + { + if (!isfd->RecNo) return((*err = IsNotCurr)); + } + else + { + if (rmode == IsNext) + { + while ((times--) && (!*err)) + { + CBNext(&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + else + { + if (rmode == IsPrev) + { + while ((times--) && (!*err)) + { + CBPrev(&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + else + { + if (rmode == IsFirst) MinKey(CCalcLenKey(isfd->r,knum),key); + else + if (rmode == IsLast) MaxKey(CCalcLenKey(isfd->r,knum),key); + else + CBuildKey(isfd->r,knum,record,key); + CBRead(&isfd->i,knum,key,key1,&isfd->RecNo,err); + if ((rmode == IsGreat) && (!*err)) + while ((strcmp(key,key1) == 0) && (!*err)) + CBNext (&isfd->i,knum,key1,&isfd->RecNo,err); + } + } + } + do + { + if (((*err) && (rmode == IsEqual)) || + ((*err == BTrEOF) && (rmode == IsGreat))) + CRead(&isfd->f,record,isfd->RecNo,NoLock); + else + CRead(&isfd->f,record,isfd->RecNo,lmode); + if (TESTLOCK(isfd->f.IOR)) + { + if (lmode == ShareLock) + { + if (!*err) *err = ISLOCKED; + break; + } + message_box("Codice %s in uso da parte\ndi un altro utente.", key1); + if (rmode != IsCurr) + { + CBReRead(&isfd->i,knum,key1,key2,isfd->RecNo,&isfd->RecNo,&junk); + if (junk) strcpy(key1, key2) ; + } + } + else + if (!*err) *err = isfd->f.IOR; + } while (TESTLOCK(isfd->f.IOR)) ; + if (((rmode == IsFirst) || (rmode == IsLast)) && (*err != BTrEmptyTree)) + *err = NoErr; + if ((rmode == IsGtEq) && (*err != BTrEOF) && (*err != BTrEmptyTree)) + *err = NoErr ; + if (DEADLOCK(*err)) return(*err = IsDeadLock); + if (rmode == IsCurr) + { + CBuildKey(isfd->r,knum,record,key); + CBReRead(&isfd->i,knum,key,key1,isfd->RecNo,&isfd->RecNo,&junk); + } + if (*err == BTrEmptyTree) CZeroRec(isfd->r, record); + return(*err); + } + +/* +@($) addkeys ISAM + +@(ID) +Aggiunge all'indice le chiavi contenute nel record. +Ritorna il codice di errore. +@(FD) + +@(ISV) +i,j = contatori. + +werr = codice errore restituito dalla CBDelete. + +key = valore delle chiavi. +@(FSV) + +@(IN) +@(FN) +*/ + + int addkeys (isfd,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int knum; /* numero chiave corrente */ + int *err; /* codice errore */ + + { + int i,j,werr; + TKey key; + + for (i = 1;(i <= isfd->r->NKeys) && (!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBWrite(&isfd->i,i,key,isfd->RecNo,err); + if (i == knum) savekeystat(isfd); + } + if (*err) + { + if (i == 2 && *err == BTrDupKeysNotAll) *err = IsReInsert; + for (j = 1; (j < i); j++) + { + CBuildKey(isfd->r,j,record,key); + CBDelete(&isfd->i,j,key,isfd->RecNo,&werr); + } + } + else restkeystat(isfd,knum); + return(*err); + } + +/* +@(#) ciswrite ISAM + +@(ID) +Aggiunge un nuovo record al file ISAM. +Ritorna il codice di errore. +@(FD) + +@(ISV) +werr = codice errore restituito. + +knum = numero chiave attiva. + +junk = variabile di lavoro per la chiamata di varie funzioni. + +wrec = buffer di lavoro. +@(FSV) + +@(IN) + La variabile record in input contiene il record da aggiungere. +@(FN) +*/ + + int ciswrite (isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + + { + int knum = (isfd->i.PN+1), werr, junk; + RecNoType neweox; + + *err = NoErr; + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + if (isfd->ln > 0) + { + COpenDir (ManuLock, isfd->ft); + COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); + } + if (isfd->d->EOD == isfd->d->EOX) + { + neweox = isfd->d->EOX / 20 + 1; + if (neweox < 10) neweox = 10; + if (demoflag) + *err = IsFileFull; + else + { + neweox += isfd->d->EOX; + cisextend(isfd, isfd->ln, neweox, err); + } + if (*err == NoErr) + { + if (isfd->ln > 0) + { + COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); + for (junk = 0; junk < isfd->r->NKeys; junk++) + isfd->i.Base[junk].PEOX = neweox; + } + else + { + isfd->d->EOX = neweox; + if (isfd->f.LockMode == ExclLock) + for (junk = 0; junk < isfd->r->NKeys; junk++) + isfd->i.Base[junk].PEOX = neweox; + } + } + else + { + if (isfd->ln > 0) + CCloseDir(isfd->ft); + isfd->RecNo = 0; + if (DEADLOCK(*err)) *err = IsDeadLock; + return((*err ? *err : (*err = IsFileFull))); + } + } + IRecallRec(record); + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + { + RecType wrec = malloc(isfd->d->LenR); + memcpy(wrec, record, isfd->d->LenR); + savekeystat(isfd); + junk = cisstart(isfd, 1, wrec, NoLock+IsEqual, &junk); + restkeystat(isfd, knum); + free(wrec); + + if ((junk == NoErr) || (junk == ISLOCKED)) + { + *err = IsReInsert; + if (isfd->ln > 0) + CCloseDir(isfd->ft); + isfd->RecNo = 0; + return(*err); + } + } + if (isfd->ln > 0) + { + COpenFile(isfd->ln,isfd->d, Lock, isfd->ft); + } + isfd->RecNo = (++isfd->d->EOD); + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err) ; + if (!addkeys(isfd, record, knum, err)) + { + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + isfd->RecNo = 0; + junk = delkeys(isfd, record, knum, &werr); + } +/* else + if (isfd->ln > 0) + CCloseFile(isfd->ln,isfd->d, isfd->ft) ; */ + } + else isfd->d->EOD-- ; + if (isfd->ln > 0) + { + CCloseFile(isfd->ln,isfd->d, isfd->ft) ; + } + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + else + { + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) isfd->RecNo = 0; + else CCloseFile(isfd->ln,isfd->d, isfd->ft) ; + } + if (!(*err)) + { +#ifndef DOS + if (isstate == NOTRANS) writelog(FNWRITE, isfd, record); + else writeundo(FNWRITE, isfd, record); +#endif + } + if (isfd->ln > 0) + CCloseDir(isfd->ft); +// if (test_share()) + { + junk = cisunlock(isfd, &junk); + if (isstate == NOTRANS) + CLockRec(&isfd->f,isfd->RecNo,UnLock); + if (DEADLOCK(*err)) *err = IsDeadLock; + } + return(*err); + } + +/* +@($) delkeys ISAM + +@(ID) +Cancella le chiavi contenute nel record dall'indice. +Ritorna il codice di errore. +@(FD) + +@(ISV) +i,j = contatori. + +werr = codice errore da CBWrite. + +key = valori chiave. +@(FSV) + +@(IN) +@(FN) +*/ + + int delkeys (isfd,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int knum; /* numero della chiave attuale */ + int *err; /* codice di errore */ + + { + int i,j,werr; + TKey key; + + for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBDelete(&isfd->i,i,key,isfd->RecNo,err); + } + if (*err) + { + for (j = 1;(j < i);j++) + { + CBuildKey(isfd->r,j,record,key); + CBWrite(&isfd->i,j,key,isfd->RecNo,&werr); + } + } + else restkeystat(isfd,knum); + return(*err); + } + +/* +@(#) cisdelete ISAM + +@(ID) +Cancella un record da un file ISAM. +Ritorna il codice di errore. +@(FD) + +@(ISV) +knum = numero chiave successiva a quella attiva. + +werr = codice errore da CBUnLockFile. + +key1,key = valori chiave. + +- Versione DOS e XENIX +@(FSV) + +@(IN) + La variabile record in input contiene il record da cancellare. +@(FN) +*/ + + int cisdelete(isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + + { + int knum = (isfd->i.PN+1), werr; + TKey key,key1; + + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + *err = NoErr; + savekeystat(isfd); + CBuildKey(isfd->r,1,record,key); + *err = NoErr ; + CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); + if (*err) + { + restkeystat(isfd,knum); + return(*err); + } + CRead(&isfd->f, record, isfd->RecNo, NoLock); + if ((*err = isfd->f.IOR)) + { + restkeystat(isfd,knum); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if( /* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err) ; + delkeys(isfd, record, knum, err) ; + } + IDeleteRec(record); + CWrite(&isfd->f,record,isfd->RecNo,UnLock); + if((*err = isfd->f.IOR)) + { + IRecallRec(record); + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((isfd->r->NKeys) && IndActive) addkeys(isfd, record, knum, err) ; + restkeystat(isfd,knum); + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNDELETE, isfd, NULL); + CRead(&isfd->f,record,isfd->RecNo,UnLock); + } + else writeundo(FNDELETE, isfd, NULL); + } + if (/* test_share() && */(isfd->r->NKeys) && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +#else +/* if (test_share()) */ + { + CRead(&isfd->f,record,isfd->RecNo,UnLock); + if (isfd->r->NKeys && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; + } +#endif + return(*err); + } + +/* +@($) replkeys ISAM + +@(ID) +Rimpiazza le chiavi all'interno dell'indice. +Ritorna il codice di errore. +@(FD) + +@(ISV) +i,j = contatori. + +werr = codice errore ritornato da CBDelete e CBWrite. + +key,key1 = valori delle chiavi. +@(FSV) +*/ + + int replkeys (isfd,oldrec,record,knum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType oldrec; /* buffer contenente il vecchio record */ + RecType record; /* buffer contenente il nuovo record */ + int knum; /* numero della chiave attuale */ + int *err; /* codice di errore */ + + { + int i,j,werr; + TKey key,key1; + + for (i = 1;(i <= isfd->r->NKeys)&&(!*err);i++) + { + CBuildKey(isfd->r,i,record,key); + CBuildKey(isfd->r,i,oldrec,key1); + if (strcmp(key,key1) != 0) + { + CBDelete(&isfd->i,i,key1,isfd->RecNo,err); + if (*err) break; + CBWrite(&isfd->i,i,key,isfd->RecNo,err); + if (*err) CBWrite(&isfd->i,i,key1,isfd->RecNo,err); + if (i == knum) savekeystat(isfd); + } + } + if (*err) + { + for (j = 1;(j < i);j++) + { + CBuildKey(isfd->r,j,record,key); + CBuildKey(isfd->r,j,oldrec,key1); + if (strcmp(key,key1) != 0) + { + CBDelete (&isfd->i,j,key,isfd->RecNo,&werr); + CBWrite(&isfd->i,j,key1,isfd->RecNo,&werr); + } + } + } + else restkeystat(isfd,knum); + return(*err); + } + +/* +@(#) cisrewrite ISAM + +@(ID) +Aggiorna un record nel file ISAM. +Ritorna il codice di errore. +@(FD) + +@(ISV) +knum = numero chiave successiva all'attuale. + +werr = codice errore restituito da CBUnLock. + +key, key1 = valori delle chiavi. + +oldrec = buffer di lavoro. + +- Versione DOS e XENIX +@(FSV) + +@(IN) + La variabile record in input contiene il record da aggiornare. +Utilizza la chiave 1 per ritrovare il record da aggiornare. +@(FN) +*/ + + int cisrewrite(isfd,record,err) + isfdptr isfd; /* descrittore del file isam */ + RecType record; /* buffer contenente i record */ + int *err; /* codice di errore */ + + { + int knum = (isfd->i.PN+1), werr; + TKey key,key1; + RecType oldrec; + + *err = NoErr ; + if(isfd == ((isfdptr) NULL)) return((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + savekeystat(isfd); + IRecallRec(record); + CBuildKey(isfd->r,1,record,key); + CBRead(&isfd->i,1,key,key1,&isfd->RecNo,err); + if(*err) + { + restkeystat(isfd,knum); + return(*err); + } + CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + restkeystat(isfd,knum); + free(oldrec); + return(*err); + } + if (memcmp(oldrec,record,isfd->d->LenR) == 0) + { + *err = NoErr; + restkeystat(isfd,knum); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + replkeys(isfd, oldrec, record, knum, err) ; + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + replkeys(isfd, record, oldrec, knum, err) ; + restkeystat(isfd,knum); + } + else +#ifndef DOS + { + if (isstate == NOTRANS) + { + writelog(FNREWRITE, isfd, record); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNREWRITE, isfd, oldrec); + } + +#else +// if (test_share()) + CLockRec(&isfd->f,isfd->RecNo,UnLock); +#endif + free(oldrec); + return(*err); + } + +/* +@(#) cisdelcurr ISAM + +@(ID) +Cancella il record corrente. +Ritorna il codice di errore. +@(FD) +*/ + + int cisdelcurr(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + + { + if(isfd->RecNo) cisdelrec(isfd,isfd->RecNo,err); + else *err = IsNotCurr; + return(*err); + } + +/* +@(#) cisrewcurr ISAM + +@(ID) +Riscrive il record corrente. +Ritorna il codice di errore. +@(FD) + +@(IN) + La variabile record in input contiene il record da aggiornare. +@(FN) +*/ + + int cisrewcurr(isfd,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer contenente il record */ + int *err; /* codice di errore */ + + { + if(isfd->RecNo) cisrewrec(isfd,isfd->RecNo,record,err); + else *err = IsNotCurr; + return (*err); + } + +/* +@(#) cisreadrec ISAM + +@(ID) +Legge un record di numero "recnum". +Ritorna il codice di errore. +@(FD) +*/ + + int cisreadrec(isfd,recnum,record,mode,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero del record */ + RecType record; /* buffer per il record */ + unsigned int mode; /* modo di lock */ + int *err; /* codice di errore */ + + { + isfd->RecNo = recnum; + return(cisread(isfd,record,IsCurr+(mode & RecLockTypes),err)); + } + +/* +@(#) ciswriterec ISAM + +@(ID) +Riscrive un record di numero "recnum". +@(FD) + +@(IN) + La variabile record in input contiene il record da aggiornare. +@(FN) + +@(ISV) +knum = numero chiave attiva. + +werr = codice errore restituito da CBUnLockFile. + +oldrec = buffer di lavoro. + +- Versione DOS e XENIX +@(FSV) +*/ + + int cisrewrec(isfd,recnum,record,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero del record da riscrivere */ + RecType record; /* buffer per il record */ + int *err; /* codice di errore */ + + { + int knum = (isfd->i.PN+1), werr; + RecType oldrec; + + *err = NoErr; + if (isfd == ((isfdptr) NULL)) return ((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + isfd->RecNo = recnum; + IRecallRec(record); + CRead(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + free(oldrec); + return(*err); + } + if (memcmp(oldrec,record,isfd->d->LenR) == 0) + { + *err = NoErr; +// if (test_share()) + CLockRec(&isfd->f,isfd->RecNo,UnLock); + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + replkeys(isfd, oldrec, record, knum, err) ; + if (/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i, &werr) ; + } + if (isstate == NOTRANS) CWrite(&isfd->f,record,isfd->RecNo,UnLock); + else CWrite(&isfd->f,record,isfd->RecNo,NoLock); + if ((*err = isfd->f.IOR)) + { + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + replkeys(isfd, record, oldrec, knum, err) ; + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNREWRITE, isfd, record); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNREWRITE, isfd, oldrec); + } +#else +/* if (test_share()) */ + CLockRec(&isfd->f,isfd->RecNo,UnLock); +#endif + free(oldrec); + return(*err); + } +/* +@(#) cisdelrec ISAM +@(ID) +Cancella un record utilizzando un numero di record. +Ritorna il codice di errore. +@(FD) +@(IN) + La variabile record in input contiene il record da cancellare. +@(FN) +@(ISV) +knum = numero della chiave attiva. +werr = codice di errore restituito da CBUnLockFiles. +oldrec = buffer di lavoro. +key1 = valore della chiave. +- Versione DOS e XENIX +@(FSV) +*/ + int cisdelrec(isfd,recnum,err) + isfdptr isfd; /* descrittore del file ISAM */ + RecNoType recnum; /* numero di record */ + int *err; /* codice di errore */ + { + int knum = (isfd->i.PN+1), werr; + int junk; + RecType oldrec ; + TKey key1 ; + *err = NoErr; + if(isfd == (isfdptr) NULL) return ((*err = IsNotOpen)); + oldrec = (RecType) malloc(isfd->d->LenR); + isfd->RecNo = recnum; + savekeystat(isfd); + CRead(&isfd->f, oldrec, isfd->RecNo, NoLock); + if ((*err = isfd->f.IOR)) + { + free(oldrec); + return(*err); + } + if ((isfd->r->NKeys) && IndActive) + { + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i, err) ; + delkeys(isfd, oldrec, knum, err); + } + IDeleteRec(oldrec); + CWrite(&isfd->f,oldrec,isfd->RecNo,UnLock); + if ((*err = isfd->f.IOR)) + { + IRecallRec(oldrec); + CWrite(&isfd->f,oldrec,isfd->RecNo,NoLock); + if ((isfd->r->NKeys) && IndActive) addkeys(isfd, oldrec, knum, err); + } +#ifndef DOS + else + { + if (isstate == NOTRANS) + { + writelog(FNDELETE, isfd, NULL); + CLockRec(&isfd->f,isfd->RecNo,UnLock); + } + else writeundo(FNDELETE, isfd, NULL); + } + if (/* test_share() && */(isfd->r->NKeys) && IndActive && (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; +#else +// if (test_share()) + { + CLockRec(&isfd->f,isfd->RecNo,UnLock); + if (isfd->r->NKeys && IndActive && + (isfd->f.LockMode != ExclLock)) + CBUnLockFile(&isfd->i, &werr) ; + } +#endif + free(oldrec); + isfd->RecNo = 0; + return(*err); + } +/* +@(#) cisgetrecno ISAM +@(ID) +Restituisce il numero del record corrente. +@(FD) +*/ + RecNoType cisgetrecno(isfd, err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + + { + if (!isfd->RecNo) *err = IsNotCurr; + else *err = NoErr; + return(isfd->RecNo); + } +/* +@(#) cislock ISAM +@(ID) +Blocca il file ISAM. +@(FD) +@(ISV) +junk = variabile spazzatura per la chiamata di sleep. +@(FSV) +*/ + int cislock(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + { + int junk; + *err = NoErr ; + if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); +#ifndef DOS + do + { + if (lockf(isfd->f.F,F_TLOCK,0L) == -1) + { + *err = CIOResult() ; + junk = sleep(1) ; + } + } while (TESTLOCK(*err)) ; +#endif + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBLockFile(&isfd->i,err); + return(*err); + } +/* +@(#) cisunlock ISAM +@(ID) +Sblocca un file ISAM. +@(FD) +*/ + int cisunlock(isfd,err) + isfdptr isfd; /* descrittore del file */ + int *err; /* codice di errore */ + { + return(cisrelease(isfd,err)); + } +/* +@(#) cisrelease ISAM +@(ID) +Sblocca un file ISAM. +@(FD) +*/ + int cisrelease(isfd,err) + isfdptr isfd; /* descrittore del file ISAM */ + int *err; /* codice di errore */ + { + *err = NoErr ; +#ifndef DOS + if (lseek(isfd->f.F, 0L, 0) == -1) return ((*err = CIOResult())); + do + { + if (lockf(isfd->f.F,F_ULOCK,0L) == -1) *err = CIOResult() ; + } while (TESTLOCK(*err)) ; +#endif + if(/* test_share() && */ isfd->f.LockMode != ExclLock) + CBUnLockFile(&isfd->i,err); + return(*err); + } +/* +@(#) IndexOn ISAM +@(ID) +Attiva Aggiornamento Indici. +@(FD) +@(IN) +Di default gli indici sono attivi. +@(FN) +*/ + void IndexOn() + { + IndActive = TRUE ; + } +/* +@(#) IndexOff ISAM +@(ID) +Disattiva l'aggiornamento Indici. +@(FD) +*/ + void IndexOff() + { + IndActive = FALSE ; + } +#ifndef DOS +/* +@($) undoname ISAM +@(ID) +Restituisce il nome del file di Undo. +@(FD) +@(ISV) +path = stringa contenente il nome file. +@(FSV) +*/ + char *undoname() + { + static PathSt path; + TMPFNAME(path, "undo"); + return(path); + } +/* +@($) writeundo ISAM +@(ID) +Scrive una operazione effettuata nel file di Undo. +@(FD) +@(ISV) +fd = puntatore al file. +uname = nome del file di undo. +lgh = variabile di lavoro che contiene l' header del record di undo. +@(FSV) +*/ + void writeundo(fntype,isfd,record) + int fntype; /* operazione da effettuare */ + isfdptr isfd; /* descrittore del file */ + RecType record; /* buffer contenente il record */ + { + int fd; + PathSt uname; + loghead lgh; + + if (isfd->ln <= 0) return ; + strcpy(uname ,undoname()); + if ((fd = open(uname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + lgh.type = fntype; + lgh.time = time(NULL); + lgh.procid = getpid(); + lgh.userid = getuid(); + lgh.filenum = isfd->ln; + lgh.recnum = isfd->RecNo; + lgh.lenrec = isfd->d->LenR; + if (write(fd, &lgh, sizeof(lgh)) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + if (fntype & (FNREWRITE)) + if (write(fd, record, lgh.lenrec) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + if (close(fd) == -1) + fatal_box("Writeundo : Error n. %d ", errno); + } +/* +@($) writelog ISAM +@(ID) +Scrive sul file Giornale l'operazione effettuata. +@(FD) +@(ISV) +junk = variabile spazzatura per la chiamata di execunlock. +lname = nome del file Giornale (LOG). +fd = puntatore al file giornale. +lgh = testata del file giornale. +@(FSV) +*/ + void writelog(fntype,isfd,record) + int fntype; /* operazione effetuata */ + isfdptr isfd; /* descrittore del file ISAM */ + RecType record; /* buffer per il record */ + { + int fd,junk; + PathSt lname; + loghead lgh; + if (!isjournal) return; + if (isfd->ln <= 0) return ; + strcpy(lname, CInsPref(logname, NORDIR)); + while (excllock(lname,TRUE) == -1) sleep(1); + if ((fd = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + lgh.type = fntype + FNSTTRANS; + lgh.time = time(NULL); + lgh.procid = getpid(); + lgh.userid = getuid(); + if (fntype & (FNREWRITE + FNWRITE + FNDELETE)) + { + lgh.filenum = isfd->ln; + lgh.recnum = isfd->RecNo; + lgh.lenrec = isfd->d->LenR; + } + else + { + lgh.filenum = 0; + if (fntype == FNREORG) lgh.recnum = *((RecNoType *) record); + else lgh.recnum = 0L; + if (fntype == FNCHGREC) lgh.lenrec = sizeof(RecDes); + else lgh.lenrec = 0; + } + if (write(fd, &lgh, sizeof(lgh)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + if (fntype & (FNREWRITE + FNWRITE + FNCHGREC)) + if (write(fd, record, lgh.lenrec) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Writelog : Error n. %d ", errno); + } + if (close(fd) == -1) + fatal_box("Writelog : Error n. %d ", errno); + junk = exclunlock(lname,TRUE); + } +#endif +/* +@(#) StTrans ISAM +@(ID) +Inizia una transazione. +@(FD) +*/ + void StTrans() + { +#ifndef DOS + if (isstate == TRANS) EndTrans(); +#endif + isstate = TRANS; + } +#ifndef DOS +/* +@($) getopenf ISAM +@(ID) +Riconfigura il file di lavoro attivo sul file di numero logico "ln". +@(FD) +@(ISV) +junk = variabile spazzatura per la chiamata alla cisclose. +err = codice di errore ritornato dalla cisopen. +@(FSV) +*/ + void getopenf(ln,record) + int ln; /* numero logico del file */ + RecType *record; /* puntatore al buffer per il record */ + { + int err,junk; + if (openf[ln - 1] == NULL) + { + if (wln != ln) + { + if (wln != -1) junk = cisclose(&wisfd ,record ,&err); + cisopen(&wisfd, ln, record, ManuLock, &err); + wln = ln; + } + } + else *record = realloc(*record, openf[ln - 1]->d->LenR); + } +#endif +/* +@(#) EndTrans ISAM +@(ID) +Chiude una transazione. +@(FD) +@(ISV) +fdl, fdu = puntatori ai file di LOG e di Undo. +lname, uname = nomi dei file di LOG e di Undo. +lgh, lgh1 = variabili di lavoro contenenti le testate dei file di log. +nread = variabile di lavoro per la chiamata alla read. +werr = codice di errore ritornato dalla cisclose. +junk = variabile spazzatura per la chiamata di exclunlock. +start = variabile di lavoro. +record = buffer di lavoro. +@(FSV) +*/ + void EndTrans() + { +#ifndef DOS + int fdl, fdu; + PathSt lname, uname; + loghead lgh, lgh1; + int nread, werr, junk, start = FNSTTRANS; + RecType record; + strcpy(lname ,CInsPref(logname, NORDIR)); + while (excllock(lname,TRUE) == -1) sleep(1); + if (((fdl = open(lname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) || + ((fdu = open(uname, O_RDONLY, 0666)) == -1)) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + while ((nread = read(fdu, &lgh, sizeof(lgh))) > 0) + { + lgh.type += start; + start = 0; + if (write(fdl, &lgh, sizeof(lgh)) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + if (lgh.type == FNREWRITE) + if (lseek(fdu, (long) lgh.lenrec, 1) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + getopenf(lgh.filenum, &record); + CRead(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + if (write(fdl, record, lgh.lenrec) == -1) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + } + if ((nread <= 0) || (close(fdu) == -1) || (close(fdl) == -1) || + (unlink(uname) == -1)) + { + junk = exclunlock(lname,TRUE); + fatal_box("Endtrans : Error n. %d ", errno); + } + if (wln != -1) + { + junk = cisclose(&wisfd, &record, &werr); + wln = -1; + } + junk = exclunlock(lname,TRUE); +#endif + } +/* +@(#) AbTrans ISAM +@(ID) +Abortisce una transazione. +@(FD) +*/ + void AbTrans() + { +#ifndef DOS + int fd; + PathSt uname; + loghead lgh; + int nread, werr, junk; + RecType record; + RecType oldrec; + strcpy(uname ,undoname()); + if ((fd = open(uname, O_RDONLY, 0666)) == -1) + fatal_box("Abtrans : Error n. %d ", errno); + while ((nread = read(fd, &lgh, sizeof(lgh))) > 0) + { + getopenf(lgh.filenum, &record); + if (oldrec == NULL) oldrec = malloc(lgh.lenrec); + else oldrec = realloc(oldrec, lgh.lenrec); + if (lgh.type & (FNREWRITE)) + { + if ((nread = read(fd, record, lgh.lenrec)) <= 0) + fatal_box("Abtrans : Error n. %d ", errno); + } + if (lgh.lenrec != openf[lgh.filenum - 1]->d->LenR) + fatal_box("Abtrans : Error n. %d ", IsNoMatch); + CRead(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, NoLock); + switch (lgh.type) + { + case FNREWRITE : + junk = replkeys(openf[lgh.filenum - 1], oldrec, record, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + break; + case FNDELETE : + IRecallRec(oldrec); + junk = addkeys(openf[lgh.filenum - 1], oldrec, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), oldrec, lgh.recnum, UnLock); + break; + case FNWRITE : + IDeleteRec(oldrec); + junk = delkeys(openf[lgh.filenum - 1], oldrec, + openf[lgh.filenum - 1]->i.PN + 1, &werr); + CWrite(&(openf[lgh.filenum - 1]->f), record, lgh.recnum, UnLock); + break; + } + } + if ((nread == -1) || (close(fd) == -1) || (unlink(uname) == -1)) + fatal_box("Abtrans : Error n. %d ", errno); + if (wln != -1) + { + junk = cisclose(&wisfd, &record, &werr); + wln = -1; + } +#endif + } +