MOdificata gestione chiave 1 della relapp git-svn-id: svn://10.65.10.50/trunk@1333 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1711 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1711 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|  *
 | |
|  @(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 <malloc.h>
 | |
| #else
 | |
| #include                                <memory.h>
 | |
| #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); 
 | |
|     isfd = NULL;
 | |
|     if (*err == 13)
 | |
|     {              
 | |
|       if (mode == ExclLock)
 | |
|         fatal_box("L'archivio n. %d (%s) non puo' essere aperto in modo esclusivo", logicname, name);    
 | |
|       else
 | |
|         fatal_box("L'archivio n. %d (%s) e' stato aperto in modo esclusivo da un altro programma", logicname, name);    
 | |
|     }  
 | |
|     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);
 | |
|       isfd = NULL;
 | |
|       if (*err == 13)
 | |
|       {              
 | |
|         if (mode == ExclLock)
 | |
|           fatal_box("L'indice n. %d (%s) non puo' essere aperto in modo esclusivo", logicname, name);    
 | |
|         else
 | |
|           fatal_box("L'indice n. %d (%s) e' stato aperto in modo esclusivo da un altro programma", logicname, name);    
 | |
|       }  
 | |
|       fatal_box("Can't open index 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
 | |
| }
 | |
| 
 |