diff --git a/include/ccustio.c b/include/ccustio.c index 479276fdf..20b1ab8fe 100755 --- a/include/ccustio.c +++ b/include/ccustio.c @@ -1,921 +1,922 @@ -/* -@(SH) Funzioni per la gestione dei file a record. - -@(M$) PRIVATE - -CalcPos(Rec,Len,Base) : Calcola la posizione del record nel file - -@(C$) PRIVATE - -LOCKSEM : 'locksem' ; nome del semaforo utilizzato per il lock - -@(VG$) PRIVATE - -ld : struttura su disco che contien i dati per i lock sui file -sizeld : numero di byte occupati dalla struttura ld -semres : flag per l'ok delle operazioni sui semafori -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -*/ - -#include "ccustio.h" -#include "checks.h" -#ifdef DOS -#include -#endif -#include -#ifndef DOS -#include -#include -#include -#else -#include -#include -#include -#include -#include "modaut.h" -#endif - -#define CalcPos(Rec, Len, Base) (((Rec) - 1) * ((RecNoType) (Len)) + ((RecNoType) (Base))) -#define LOCK_OFF 1200000000L - -#ifndef DOS - #define LOCKSEM "locksem" - - /* extern long lseek(int, long, int);*/ - extern int chsize(int, long); - extern int lockf(int, int, long); -#endif - - unsigned setlock(unsigned); - int seeklk(SecDef *, long, unsigned, unsigned, long); -#ifndef DOS - int semtran(char *); - static void semcall(int, int); - void PS(int); - void VS(int); -#endif - -BOOLEAN test_share() - -{ -#ifdef DOS - static BOOLEAN share_active = 2; - - if (share_active == 2) - { - share_active = CGetAut(MUAUT); - if (share_active) - { - int f = open("net.ini", O_RDONLY, SH_DENYNO, S_IREAD); - - share_active = f != -1; - if (f != -1) close(f); - } - } - return share_active; -#else - return TRUE; -#endif -} - - -/* -@($) setlock CUSTIO - -@(ID) -Trasforma il modo di lock utente in modo lock XENIX. -@(FD) - -@(ISV) -Nella versione XENIX : - -lm = numero lock xenix. -@(FSV) - -@(IN) -Restituisce il comando XENIX. -@(FN) -*/ - - unsigned setlock(LockMode) - unsigned LockMode; /* Tipo di lock */ - - { - - int lm; - - LockMode &= RecLockTypes ; -#ifdef DOS - if (LockMode == ShareLock) lm = _LK_NBRLCK ; - else - if (LockMode == Lock) lm = _LK_NBRLCK ; - else lm = _LK_UNLCK ; -#else - if (LockMode == ShareLock) lm = F_TLOCK ; - else - if (LockMode == Lock) lm = F_TLOCK ; - else lm = F_ULOCK ; -#endif - return(lm) ; - } - -/* -@($) seeklk CUSTIO - -@(ID) -Effettua una seek. -@(FD) - -@(ISV) -junk = variabile di lavoro. - -lock = variabile per eseguire comandi di lock. -@(FSV) -*/ - - int seeklk(S, pos, lm, LockMode, rec) - SecDef *S ; /* Descrittore file */ - long pos ; /* posizione all'interno del file */ - unsigned lm ; /* comando di lock per XENIX */ - unsigned LockMode; /* comando di lock utente */ - long rec; /* n.ro di record */ - - { - if (LockMode != NoLock && S->LockMode != ExclLock) - { -#ifdef DOS - if (test_share()) - { - if (_lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L) - if ((S->IOR = CIOResult()) != NoErr) return(-1) ; - if ( _locking(S->F,lm, 1L) == -1) - { - S->IOR = CIOResult(); - if (S->IOR == EACCES) S->IOR = EAGAIN; - if (LockMode == UnLock || LockMode == NoLock) S->IOR = NoErr; - if (S->IOR != NoErr) return(-1); - } - } -#else - if (lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L) - if ((S->IOR = CIOResult()) != NoErr) return(-1) ; - if (lockf(S->F,lm, 1L) == -1) - if ((S->IOR = CIOResult()) != NoErr) return(-1) ; -#endif - } -#ifdef DOS - if (_lseek(S->F, pos, SEEK_SET) == -1L) -#else - if (lseek(S->F, pos, SEEK_SET) == -1L) -#endif - if ((S->IOR = CIOResult()) != NoErr) return(-1) ; - return(0) ; - } - -/* -@(#) CLockRec CUSTIO - -@(ID) -Esegue un comando lock sul record nro. "rec" del file descritto da "s". -@(FD) - -@(ISV) -Solo versione XENIX. -@(FSV) -*/ - - void CLockRec(s, rec, lockmode) - SecDef *s ; /* descrittore del file */ - RecNoType rec ; /* numero record su cui effettuare il lock */ - unsigned lockmode;/* operazione lock da effettuare */ - - { - seeklk(s, CalcPos(rec, s->LenRec, s->BaseFil), setlock(lockmode), lockmode, rec); - } - -/* -@(#) CVerify CUSTIO - -@(ID) -Verifica che il file "name" esista. -@(FD) - -@(ISV) -junk = variabile di lavoro. -@(FSV) -*/ - - void CVerify(S, Name) - SecDef *S; /* descrittore File */ - FileName Name; /* nome file */ - - { - int junk ; - - S->IOR = NoErr; -#ifdef DOS - if ((S->F = sopen(Name, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) -#else - if ((S->F = open(Name, O_RDONLY, 0666)) == -1) -#endif - S->IOR = CIOResult(); - else - if (close(S->F) == -1) - { - junk = CIOResult(); - if (!S->IOR) S->IOR = junk; - } - } - -/* -@(#) COpen CUSTIO - -@(ID) -Apre un file di record. -@(FD) - -@(ISV) -junk = variabile di lavoro. -@(FSV) -*/ - - void COpen(S, Name, Len, Base, LockMode) - SecDef *S; /* descrittore file */ - FileName Name; /* nome del file */ - unsigned Len; /* lunghezza record */ - unsigned Base; /* offset dall'inizio del file fisico; e' sempre 0 per i file dati */ - unsigned LockMode;/* lock di apertura del file */ - - { - int junk; - - S->IOR = NoErr; -#ifdef DOS - if ((S->F = sopen(Name, O_RDWR|O_BINARY, - test_share() && LockMode == ExclLock ? SH_DENYRW : - SH_DENYNO, S_IREAD|S_IWRITE)) == -1) -#else - if ((S->F = open(Name, O_RDWR , 0666)) == -1) -#endif - if ((S->IOR = CIOResult()) != NoErr) return ; - S->LenRec = Len; - S->BaseFil = Base * BlockLenIO ; - S->LockMode = LockMode ; - S->lpos = -1; - strcpy(S->name, Name); - if (lseek(S->F, 0L, SEEK_SET) == -1L) - if ((S->IOR = CIOResult()) != NoErr) return ; - if (excllock(Name, (S->LockMode == ExclLock)) == -1) - { - S->IOR = CIOResult(); - if (close(S->F) == -1) junk = CIOResult(); - } - } -/* -@(#) CCreate CUSTIO - -@(ID) -Crea un nuovo file di record. -@(FD) - -@(ISV) -junk = variabile di lavoro. -@(FSV) -*/ - - void CCreate(S, Name, Len, Base, MaxSec) - SecDef *S; /* descrittore del file */ - FileName Name; /* nome del file */ - unsigned Len; /* lunghezza del record */ - unsigned Base; /* offset dall'inizio del file fisico */ - RecNoType MaxSec; /* Numero di blocchi di disco da allocare */ - - { - int junk; - - S->IOR = NoErr; -#ifdef DOS - if ((S->F = sopen(Name, O_RDWR | O_CREAT, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) -#else - if ((S->F = open(Name, O_RDWR | O_CREAT, 0666)) == -1) -#endif - if ((S->IOR = CIOResult()) != NoErr) return ; - if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1) - S->IOR = CIOResult(); - if (close(S->F) == -1) - { - junk = CIOResult(); - if (!S->IOR) S->IOR = junk; - } - } - -/* -@(#) CChsize CUSTIO - -@(ID) -Cambia la dimensione di un file di record. -@(FD) - -@(ISV) -junk = variabile di lavoro. -@(FSV) -*/ - - void CChsize(S, Name, Len, Base, MaxSec) - SecDef *S; /* descrittore del file */ - FileName Name; /* nome del file */ - unsigned Len; /* lunghezza del record */ - unsigned Base; /* offset dall'inizio del file fisico */ - RecNoType MaxSec; /* numero di blocchi del file modificati */ - - { - int junk; - - S->IOR = NoErr; -#ifdef DOS - if ((S->F = sopen(Name, O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) -#else - if ((S->F = open(Name, O_RDWR, 0666)) == -1) -#endif - if ((S->IOR = CIOResult()) != NoErr) return ; - if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1) - S->IOR = CIOResult(); - if (close(S->F) == -1) - { - junk = CIOResult(); - if (!S->IOR) S->IOR = junk; - } - } - -/* -@(#) CClose CUSTIO - -@(ID) -Chiude un file di record. -@(FD) - -*/ - - void CClose(S) - SecDef *S; /* descrittore del file da chiudere */ - - { - S->IOR = NoErr; -#ifdef DOS - if (close(S->F) == -1) S->IOR = CIOResult(); -#else - if (S->LockMode == AutoLock) - { - if (S->lpos != -1) - { - if (lseek(S->F, S->lpos, SEEK_SET) == -1L) - if ((S->IOR = CIOResult()) != NoErr) return ; - if (lockf(S->F,F_ULOCK,(long) S->LenRec) == -1) - if ((S->IOR = CIOResult()) != NoErr) return ; - } - } - if (close(S->F) == -1) S->IOR = CIOResult(); - if (exclunlock(S->name, (S->LockMode == ExclLock)) == -1) - S->IOR = CIOResult(); -#endif - } - -/* -@(#) CDelete CUSTIO - -@(ID) -Cancella un file di record. -@(FD) -*/ - - - void CDelete(S, Name) - SecDef *S; /* descrittore del file */ - FileName Name; /* Nome del file */ - - { - if (unlink(Name) == -1) - S->IOR = CIOResult(); - else - S->IOR = NoErr; - } - -/* -@(#) CRead CUSTIO - -@(ID) -Legge un record del file. -@(FD) - -@(ISV) -junk = variabile di lavoro. - -fpos = contiene la posizione del record all'interno del file. -@(FSV) - -@(IN) -Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza. -@(FN) -*/ - - void CRead(S, RecBuf, Rec, LockMode) - SecDef *S; /* descrittore del file */ - RecType RecBuf; /* spazio per contenere il record */ - RecNoType Rec; /* Record da leggere */ - unsigned LockMode; /* lock sul record */ - - { - int junk; - register RecNoType fpos; - - if (Rec) - { - S->IOR = NoErr; - fpos = CalcPos(Rec, S->LenRec, S->BaseFil); -#ifndef DOS - if (S->LockMode == AutoLock) - { - if (S->lpos != -1) - if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ; - if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ; - S->lpos = fpos ; - } - else -#endif - if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ; - if (read(S->F, RecBuf, (unsigned) S->LenRec) == -1) - { - S->IOR = CIOResult(); - junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1; - } - } - else S->IOR = 3; - } - -/* -@(#) CWrite CUSTIO - -@(ID) -Scrive un record nel file. -@(FD) - -@(ISV) -junk = variabile di lavoro. - -fpos = contiene la posizione del record all'interno del file. -@(FSV) - -@(IN) -Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza. -@(FN) -*/ - - void CWrite(S, RecBuf, Rec, LockMode) - SecDef *S; /* descrittore del file */ - RecType RecBuf; /* spazio che contiene il record da scrivere */ - RecNoType Rec; /* numero del record da scrivere */ - unsigned LockMode; /* lock sul record */ - - { - int junk; - register RecNoType fpos; - - if (Rec) - { - S->IOR = NoErr; - fpos = CalcPos(Rec, S->LenRec, S->BaseFil); -#ifndef DOS - if (S->LockMode == AutoLock) - { - if (S->lpos != -1) - if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ; - if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ; - S->lpos = fpos ; - } - else -#endif - if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ; - if (write(S->F, RecBuf, (unsigned) S->LenRec) == -1) - { - S->IOR = CIOResult(); - junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1; - } - } - else S->IOR = 3; - } - -/* -@(#) IDeleteRec CUSTIO - -@(ID) -Cancellazione logica di un record. -@(FD) -*/ - - void IDeleteRec(RecBuf) - RecType RecBuf; /* record da cancellare */ - - { - RecBuf[0] = Deleted; - } - -/* -@(#) IRecallRec CUSTIO - -@(ID) -Recupero logico di un record. -@(FD) -*/ - - void IRecallRec(RecBuf) - RecType RecBuf; /* record da recuperare logicamente */ - - { - RecBuf[0] = Valid; - } - -/* -@(#) IRecIsDeleted CUSTIO - -@(ID) -Controlla se il record in "RecBuf" e' cancellato oppure no. -@(FD) -*/ - - BOOLEAN IRecIsDeleted(RecBuf) - RecType RecBuf; /* record da controllare */ - - { - return (RecBuf[0] == Deleted); - } - -/* -@(#) ITestLock CUSTIO - -@(ID) -Controlla se l'errore "err" e' dovuto ad un lock. -@(FD) - -@(ISV) -Versione DOS e XENIX. -@(FSV) -*/ - - -BOOLEAN ITestLock(err) -int err; /* codice di errore */ - -{ - return(TESTLOCK(err)) ; -} - -#ifndef DOS -struct lockdata - { - int users; - int excl; - } ld; - -int sizeld = sizeof(struct lockdata); - -/* -@($) lockpath CUSTIO - -@(ID) -Restituisce il nome del file di lock per il file "name". -@(FD) - -@(ISV) -path = percorso per il file (/usr/tmp/....). - -s1,s,s2 = stringhe di lavoro (nomi file). - -Solo versione XENIX. -@(FSV) -*/ - -char *lockpath(name) -char *name; /* stringa nome file */ - - { - static char path[200]; - char *s1 = name, *s = name, *s2 = name; - - while ((s1 = strchr(s, DIRSEP)) != NULL) - { - s2 = s; - s = s1 + 1; - } - sprintf(path, "/usr/tmp/%s", s2); - return(path); - } - -/* -@($) dirname CUSTIO - -@(ID) -Estrae dal path il nome del direttorio. -@(FD) - -@(ISV) -path = percorso per il file . - -s = stringa di lavoro. - -Solo versione XENIX. -@(FSV) -*/ - -char *dirname(name) -char *name; /* stringa contenente il path */ - - { - static char path[200]; - char *s; - - strcpy(path,name); - if ((s = strrchr(path, DIRSEP)) == NULL) strcpy(path, "."); - else *s = '\0'; - return(path); - } - -static int semres = 0; - -/* -@($) semtran CUSTIO - -@(ID) -Trasforma il nome di un semaforo in un identificatore poi lo crea o lo apre. -@(FD) - -@(ISV) -key = chiave corrispondente al nome semaforo. - -id = identificatore del semaforo. - -Solo versione XENIX. -La semget fa una open sul semaforo; se non lo trova lo crea e poi lo libera. -@(FSV) -*/ - -int semtran(s) -char *s; /* stringa nome del semaforo */ - - { - register int key = 0, sid; - - semres = 0 ; - while (*s) key += *s++; - if ((sid = semget((key_t) key, 1, 0666)) == -1) - { - if ((sid = semget((key_t) key, 1, 0666 | IPC_CREAT)) == -1) - semres = -1; - VS(sid); - } - return(sid); - } - -/* -@($) semcall CUSTIO - -@(ID) -Chiama il semaforo "sid" e su di esso svolge "op". -@(FD) - -@(ISV) -sb = struttura necessaria per la chiamata a "semop". - -Solo versione XENIX. -@(FSV) - -@(IN) -se op = -1 il semaforo viene occupato. - -se op = +1 il semaforo viene liberato. -@(FN) -*/ - -static void semcall(sid, op) -int sid; /* identificatore semaforo */ -int op; /* operazione da effettuare sul semaforo: libero/occupato */ - - { - struct sembuf sb; - - semres = 0 ; - sb.sem_num = 0; - sb.sem_op = op; - sb.sem_flg = 0; - if (semop(sid, &sb, 1) == -1) - semres = -1; - } - -/* -@($) PS CUSTIO - -@(ID) -Acquisisce il semaforo "sid". -@(FD) - -@(ISV) -Solo versione XENIX. -@(FSV) -*/ - -void PS(sid) -int sid; /* identificatore semaforo */ - - { - semcall(sid, -1); - } - -/* -@($) VS CUSTIO - -@(ID) -Rilascia il semaforo "sid". -@(FD) - -@(ISV) -Solo versione XENIX. -@(FSV) -*/ - -void VS(sid) -int sid; - - { - semcall(sid, 1); - } -#endif - -/* -@(#) excllock CUSTIO - -@(ID) -Funzione per la gestione di un lock esclusivo su tutto il file. -@(FD) - -@(ISV) -Nella versione XENIX: - -path = contiene il file di lock. - -dir = contiene la directory. - -fd = identificatore restituito dalla "open". - -junk = variabile di lavoro. - -sid = identificatore del semaforo su locksem. - -errno = numero errore. - -sb = struttura che contiene informazioni sullo stato del file (vedi "stat"). - -@(FSV) -*/ - -int excllock(name,excl) -char *name; /* nome del file */ -BOOLEAN excl; /* se true deve fare il lock ex. altrimenti no */ - - { -#ifndef DOS - char path[200], dir[200]; - int fd, junk, sid; - extern int errno; - struct stat sb; - - strcpy(path, lockpath(name)); - strcpy(dir, dirname(path)); - sid = semtran(LOCKSEM); - if (semres == -1) return(-1); - PS(sid); - if (semres == -1) return(-1); - if ((stat(dir, &sb) == -1) && (errno == ENOENT)) CMkDir(dir); - if (((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) == -1) && - errno == EEXIST) - { - errno = 0; - if ((fd = open(path, O_RDWR, 0666)) == -1) - { - VS(sid); - return(-1); - } - if ((read(fd, &ld, sizeld) <= 0) || - (lseek(fd, 0L, SEEK_SET) == -1L)) - { - junk = close(fd); - VS(sid); - return(-1) ; - } - if (((ld.excl) && (ld.excl != getpid())) || excl) - { - junk = close(fd); - errno = EACCES ; - VS(sid); - return(-1); - } - ld.users++; - } - else - { - if (fd == -1) - { - VS(sid); - return(-1); - } - errno = 0; - ld.users = 1; - if (excl) ld.excl = getpid(); - else ld.excl = 0; - } - if (write(fd, &ld, sizeld) == -1) - { - junk = close(fd); - VS(sid); - return(-1); - } - if (close(fd) == -1) - { - VS(sid); - return(-1); - } - VS(sid); - if (semres == -1) return(-1); -#endif - return(0); - } - -/* -@(#) exclunlock CUSTIO - -@(ID) -Gestisce un unlock esclusivo su tutto il file. -@(FD) - -@(ISV) -Nella versione XENIX: - -path = contiene il file di lock. - -fd = identificatore restituito dalla "open". - -junk = variabile di lavoro. - -sid = identificatore del semaforo su locksem. -@(FSV) -*/ - -int exclunlock(name,excl) -char *name; /* nome file */ -BOOLEAN excl; /* se true esegue un unlock sul file */ - - { -#ifndef DOS - int fd, junk, sid; - char path[200]; - - strcpy(path, lockpath(name)); - sid = semtran(LOCKSEM); - if (semres == -1) return(-1); - PS(sid); - if (semres == -1) return(-1); - if (((fd = open(path, O_RDWR , 0666)) == -1) || - (read(fd, &ld, sizeld) <= 0) || - (lseek(fd, 0L, SEEK_SET) == -1L)) - { - junk = close(fd); - VS(sid); - return(-1); - } - if (excl) ld.excl = 0; - if (--ld.users == 0) - { - if ((close(fd) == -1) || (unlink(path) == -1)) - { - VS(sid); - return(-1); - } - VS(sid); - if (semres == -1) return(-1); - return(0); - } - if (write(fd, &ld, sizeld) == -1) - { - junk = close(fd); - VS(sid); - return(-1); - } - if (close(fd) == -1) - { - VS(sid); - return(-1); - } - VS(sid); - if (semres == -1) return(-1); -#endif - return(0); - } +/* +@(SH) Funzioni per la gestione dei file a record. + +@(M$) PRIVATE + +CalcPos(Rec,Len,Base) : Calcola la posizione del record nel file + +@(C$) PRIVATE + +LOCKSEM : 'locksem' ; nome del semaforo utilizzato per il lock + +@(VG$) PRIVATE + +ld : struttura su disco che contien i dati per i lock sui file +sizeld : numero di byte occupati dalla struttura ld +semres : flag per l'ok delle operazioni sui semafori +------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +*/ + +#include "ccustio.h" +#include "checks.h" +#ifdef DOS +#include +#endif +#include +#ifndef DOS +#include +#include +#include +#else +#include +#include +#include +#include +#include "modaut.h" +#endif + +#define CalcPos(Rec, Len, Base) (((Rec) - 1) * ((RecNoType) (Len)) + ((RecNoType) (Base))) +#define LOCK_OFF 1200000000L + +#ifndef DOS + #define LOCKSEM "locksem" + + /* extern long lseek(int, long, int);*/ + extern int chsize(int, long); + extern int lockf(int, int, long); +#endif + + unsigned setlock(unsigned); + int seeklk(SecDef *, long, unsigned, unsigned, long); +#ifndef DOS + int semtran(char *); + static void semcall(int, int); + void PS(int); + void VS(int); +#endif + +BOOLEAN test_share() + +{ +#ifdef DOS + static BOOLEAN share_active = 2; + + if (share_active == 2) + { + share_active = CGetAut(MUAUT); + if (share_active) + { + int f = open("net.ini", O_RDONLY, SH_DENYNO, S_IREAD); + + share_active = f != -1; + if (f != -1) close(f); + } + } + return share_active; +#else + return TRUE; +#endif +} + + +/* +@($) setlock CUSTIO + +@(ID) +Trasforma il modo di lock utente in modo lock XENIX. +@(FD) + +@(ISV) +Nella versione XENIX : + +lm = numero lock xenix. +@(FSV) + +@(IN) +Restituisce il comando XENIX. +@(FN) +*/ + + unsigned setlock(LockMode) + unsigned LockMode; /* Tipo di lock */ + + { + + int lm; + + LockMode &= RecLockTypes ; +#ifdef DOS + if (LockMode == ShareLock) lm = _LK_NBRLCK ; + else + if (LockMode == Lock) lm = _LK_NBRLCK ; + else lm = _LK_UNLCK ; +#else + if (LockMode == ShareLock) lm = F_TLOCK ; + else + if (LockMode == Lock) lm = F_TLOCK ; + else lm = F_ULOCK ; +#endif + return(lm) ; + } + +/* +@($) seeklk CUSTIO + +@(ID) +Effettua una seek. +@(FD) + +@(ISV) +junk = variabile di lavoro. + +lock = variabile per eseguire comandi di lock. +@(FSV) +*/ + + int seeklk(S, pos, lm, LockMode, rec) + SecDef *S ; /* Descrittore file */ + long pos ; /* posizione all'interno del file */ + unsigned lm ; /* comando di lock per XENIX */ + unsigned LockMode; /* comando di lock utente */ + long rec; /* n.ro di record */ + + { + if (LockMode != NoLock && S->LockMode != ExclLock) + { +#ifdef DOS + if (test_share()) + { + if (_lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L) + if ((S->IOR = CIOResult()) != NoErr) return(-1) ; + if ( _locking(S->F,lm, 1L) == -1) + { + S->IOR = CIOResult(); + + if (S->IOR == EACCES) S->IOR = EAGAIN; + if (LockMode == UnLock || LockMode == NoLock) S->IOR = NoErr; + if (S->IOR != NoErr) return(-1); + } + } +#else + if (lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L) + if ((S->IOR = CIOResult()) != NoErr) return(-1) ; + if (lockf(S->F,lm, 1L) == -1) + if ((S->IOR = CIOResult()) != NoErr) return(-1) ; +#endif + } +#ifdef DOS + if (_lseek(S->F, pos, SEEK_SET) == -1L) +#else + if (lseek(S->F, pos, SEEK_SET) == -1L) +#endif + if ((S->IOR = CIOResult()) != NoErr) return(-1) ; + return(0) ; + } + +/* +@(#) CLockRec CUSTIO + +@(ID) +Esegue un comando lock sul record nro. "rec" del file descritto da "s". +@(FD) + +@(ISV) +Solo versione XENIX. +@(FSV) +*/ + + void CLockRec(s, rec, lockmode) + SecDef *s ; /* descrittore del file */ + RecNoType rec ; /* numero record su cui effettuare il lock */ + unsigned lockmode;/* operazione lock da effettuare */ + + { + seeklk(s, CalcPos(rec, s->LenRec, s->BaseFil), setlock(lockmode), lockmode, rec); + } + +/* +@(#) CVerify CUSTIO + +@(ID) +Verifica che il file "name" esista. +@(FD) + +@(ISV) +junk = variabile di lavoro. +@(FSV) +*/ + + void CVerify(S, Name) + SecDef *S; /* descrittore File */ + FileName Name; /* nome file */ + + { + int junk ; + + S->IOR = NoErr; +#ifdef DOS + if ((S->F = sopen(Name, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) +#else + if ((S->F = open(Name, O_RDONLY, 0666)) == -1) +#endif + S->IOR = CIOResult(); + else + if (close(S->F) == -1) + { + junk = CIOResult(); + if (!S->IOR) S->IOR = junk; + } + } + +/* +@(#) COpen CUSTIO + +@(ID) +Apre un file di record. +@(FD) + +@(ISV) +junk = variabile di lavoro. +@(FSV) +*/ + + void COpen(S, Name, Len, Base, LockMode) + SecDef *S; /* descrittore file */ + FileName Name; /* nome del file */ + unsigned Len; /* lunghezza record */ + unsigned Base; /* offset dall'inizio del file fisico; e' sempre 0 per i file dati */ + unsigned LockMode;/* lock di apertura del file */ + + { + int junk; + + S->IOR = NoErr; +#ifdef DOS + if ((S->F = sopen(Name, O_RDWR|O_BINARY, + test_share() && LockMode == ExclLock ? SH_DENYRW : + SH_DENYNO, S_IREAD|S_IWRITE)) == -1) +#else + if ((S->F = open(Name, O_RDWR , 0666)) == -1) +#endif + if ((S->IOR = CIOResult()) != NoErr) return ; + S->LenRec = Len; + S->BaseFil = Base * BlockLenIO ; + S->LockMode = LockMode ; + S->lpos = -1; + strcpy(S->name, Name); + if (lseek(S->F, 0L, SEEK_SET) == -1L) + if ((S->IOR = CIOResult()) != NoErr) return ; + if (excllock(Name, (S->LockMode == ExclLock)) == -1) + { + S->IOR = CIOResult(); + if (close(S->F) == -1) junk = CIOResult(); + } + } +/* +@(#) CCreate CUSTIO + +@(ID) +Crea un nuovo file di record. +@(FD) + +@(ISV) +junk = variabile di lavoro. +@(FSV) +*/ + + void CCreate(S, Name, Len, Base, MaxSec) + SecDef *S; /* descrittore del file */ + FileName Name; /* nome del file */ + unsigned Len; /* lunghezza del record */ + unsigned Base; /* offset dall'inizio del file fisico */ + RecNoType MaxSec; /* Numero di blocchi di disco da allocare */ + + { + int junk; + + S->IOR = NoErr; +#ifdef DOS + if ((S->F = sopen(Name, O_RDWR | O_CREAT, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) +#else + if ((S->F = open(Name, O_RDWR | O_CREAT, 0666)) == -1) +#endif + if ((S->IOR = CIOResult()) != NoErr) return ; + if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1) + S->IOR = CIOResult(); + if (close(S->F) == -1) + { + junk = CIOResult(); + if (!S->IOR) S->IOR = junk; + } + } + +/* +@(#) CChsize CUSTIO + +@(ID) +Cambia la dimensione di un file di record. +@(FD) + +@(ISV) +junk = variabile di lavoro. +@(FSV) +*/ + + void CChsize(S, Name, Len, Base, MaxSec) + SecDef *S; /* descrittore del file */ + FileName Name; /* nome del file */ + unsigned Len; /* lunghezza del record */ + unsigned Base; /* offset dall'inizio del file fisico */ + RecNoType MaxSec; /* numero di blocchi del file modificati */ + + { + int junk; + + S->IOR = NoErr; +#ifdef DOS + if ((S->F = sopen(Name, O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1) +#else + if ((S->F = open(Name, O_RDWR, 0666)) == -1) +#endif + if ((S->IOR = CIOResult()) != NoErr) return ; + if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1) + S->IOR = CIOResult(); + if (close(S->F) == -1) + { + junk = CIOResult(); + if (!S->IOR) S->IOR = junk; + } + } + +/* +@(#) CClose CUSTIO + +@(ID) +Chiude un file di record. +@(FD) + +*/ + + void CClose(S) + SecDef *S; /* descrittore del file da chiudere */ + + { + S->IOR = NoErr; +#ifdef DOS + if (close(S->F) == -1) S->IOR = CIOResult(); +#else + if (S->LockMode == AutoLock) + { + if (S->lpos != -1) + { + if (lseek(S->F, S->lpos, SEEK_SET) == -1L) + if ((S->IOR = CIOResult()) != NoErr) return ; + if (lockf(S->F,F_ULOCK,(long) S->LenRec) == -1) + if ((S->IOR = CIOResult()) != NoErr) return ; + } + } + if (close(S->F) == -1) S->IOR = CIOResult(); + if (exclunlock(S->name, (S->LockMode == ExclLock)) == -1) + S->IOR = CIOResult(); +#endif + } + +/* +@(#) CDelete CUSTIO + +@(ID) +Cancella un file di record. +@(FD) +*/ + + + void CDelete(S, Name) + SecDef *S; /* descrittore del file */ + FileName Name; /* Nome del file */ + + { + if (unlink(Name) == -1) + S->IOR = CIOResult(); + else + S->IOR = NoErr; + } + +/* +@(#) CRead CUSTIO + +@(ID) +Legge un record del file. +@(FD) + +@(ISV) +junk = variabile di lavoro. + +fpos = contiene la posizione del record all'interno del file. +@(FSV) + +@(IN) +Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza. +@(FN) +*/ + + void CRead(S, RecBuf, Rec, LockMode) + SecDef *S; /* descrittore del file */ + RecType RecBuf; /* spazio per contenere il record */ + RecNoType Rec; /* Record da leggere */ + unsigned LockMode; /* lock sul record */ + + { + int junk; + register RecNoType fpos; + + if (Rec) + { + S->IOR = NoErr; + fpos = CalcPos(Rec, S->LenRec, S->BaseFil); +#ifndef DOS + if (S->LockMode == AutoLock) + { + if (S->lpos != -1) + if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ; + if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ; + S->lpos = fpos ; + } + else +#endif + if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ; + if (read(S->F, RecBuf, (unsigned) S->LenRec) == -1) + { + S->IOR = CIOResult(); + junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1; + } + } + else S->IOR = 3; + } + +/* +@(#) CWrite CUSTIO + +@(ID) +Scrive un record nel file. +@(FD) + +@(ISV) +junk = variabile di lavoro. + +fpos = contiene la posizione del record all'interno del file. +@(FSV) + +@(IN) +Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza. +@(FN) +*/ + + void CWrite(S, RecBuf, Rec, LockMode) + SecDef *S; /* descrittore del file */ + RecType RecBuf; /* spazio che contiene il record da scrivere */ + RecNoType Rec; /* numero del record da scrivere */ + unsigned LockMode; /* lock sul record */ + + { + int junk; + register RecNoType fpos; + + if (Rec) + { + S->IOR = NoErr; + fpos = CalcPos(Rec, S->LenRec, S->BaseFil); +#ifndef DOS + if (S->LockMode == AutoLock) + { + if (S->lpos != -1) + if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ; + if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ; + S->lpos = fpos ; + } + else +#endif + if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ; + if (write(S->F, RecBuf, (unsigned) S->LenRec) == -1) + { + S->IOR = CIOResult(); + junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1; + } + } + else S->IOR = 3; + } + +/* +@(#) IDeleteRec CUSTIO + +@(ID) +Cancellazione logica di un record. +@(FD) +*/ + + void IDeleteRec(RecBuf) + RecType RecBuf; /* record da cancellare */ + + { + RecBuf[0] = Deleted; + } + +/* +@(#) IRecallRec CUSTIO + +@(ID) +Recupero logico di un record. +@(FD) +*/ + + void IRecallRec(RecBuf) + RecType RecBuf; /* record da recuperare logicamente */ + + { + RecBuf[0] = Valid; + } + +/* +@(#) IRecIsDeleted CUSTIO + +@(ID) +Controlla se il record in "RecBuf" e' cancellato oppure no. +@(FD) +*/ + + BOOLEAN IRecIsDeleted(RecBuf) + RecType RecBuf; /* record da controllare */ + + { + return (RecBuf[0] == Deleted); + } + +/* +@(#) ITestLock CUSTIO + +@(ID) +Controlla se l'errore "err" e' dovuto ad un lock. +@(FD) + +@(ISV) +Versione DOS e XENIX. +@(FSV) +*/ + + +BOOLEAN ITestLock(err) +int err; /* codice di errore */ + +{ + return(TESTLOCK(err)) ; +} + +#ifndef DOS +struct lockdata + { + int users; + int excl; + } ld; + +int sizeld = sizeof(struct lockdata); + +/* +@($) lockpath CUSTIO + +@(ID) +Restituisce il nome del file di lock per il file "name". +@(FD) + +@(ISV) +path = percorso per il file (/usr/tmp/....). + +s1,s,s2 = stringhe di lavoro (nomi file). + +Solo versione XENIX. +@(FSV) +*/ + +char *lockpath(name) +char *name; /* stringa nome file */ + + { + static char path[200]; + char *s1 = name, *s = name, *s2 = name; + + while ((s1 = strchr(s, DIRSEP)) != NULL) + { + s2 = s; + s = s1 + 1; + } + sprintf(path, "/usr/tmp/%s", s2); + return(path); + } + +/* +@($) dirname CUSTIO + +@(ID) +Estrae dal path il nome del direttorio. +@(FD) + +@(ISV) +path = percorso per il file . + +s = stringa di lavoro. + +Solo versione XENIX. +@(FSV) +*/ + +char *dirname(name) +char *name; /* stringa contenente il path */ + + { + static char path[200]; + char *s; + + strcpy(path,name); + if ((s = strrchr(path, DIRSEP)) == NULL) strcpy(path, "."); + else *s = '\0'; + return(path); + } + +static int semres = 0; + +/* +@($) semtran CUSTIO + +@(ID) +Trasforma il nome di un semaforo in un identificatore poi lo crea o lo apre. +@(FD) + +@(ISV) +key = chiave corrispondente al nome semaforo. + +id = identificatore del semaforo. + +Solo versione XENIX. +La semget fa una open sul semaforo; se non lo trova lo crea e poi lo libera. +@(FSV) +*/ + +int semtran(s) +char *s; /* stringa nome del semaforo */ + + { + register int key = 0, sid; + + semres = 0 ; + while (*s) key += *s++; + if ((sid = semget((key_t) key, 1, 0666)) == -1) + { + if ((sid = semget((key_t) key, 1, 0666 | IPC_CREAT)) == -1) + semres = -1; + VS(sid); + } + return(sid); + } + +/* +@($) semcall CUSTIO + +@(ID) +Chiama il semaforo "sid" e su di esso svolge "op". +@(FD) + +@(ISV) +sb = struttura necessaria per la chiamata a "semop". + +Solo versione XENIX. +@(FSV) + +@(IN) +se op = -1 il semaforo viene occupato. + +se op = +1 il semaforo viene liberato. +@(FN) +*/ + +static void semcall(sid, op) +int sid; /* identificatore semaforo */ +int op; /* operazione da effettuare sul semaforo: libero/occupato */ + + { + struct sembuf sb; + + semres = 0 ; + sb.sem_num = 0; + sb.sem_op = op; + sb.sem_flg = 0; + if (semop(sid, &sb, 1) == -1) + semres = -1; + } + +/* +@($) PS CUSTIO + +@(ID) +Acquisisce il semaforo "sid". +@(FD) + +@(ISV) +Solo versione XENIX. +@(FSV) +*/ + +void PS(sid) +int sid; /* identificatore semaforo */ + + { + semcall(sid, -1); + } + +/* +@($) VS CUSTIO + +@(ID) +Rilascia il semaforo "sid". +@(FD) + +@(ISV) +Solo versione XENIX. +@(FSV) +*/ + +void VS(sid) +int sid; + + { + semcall(sid, 1); + } +#endif + +/* +@(#) excllock CUSTIO + +@(ID) +Funzione per la gestione di un lock esclusivo su tutto il file. +@(FD) + +@(ISV) +Nella versione XENIX: + +path = contiene il file di lock. + +dir = contiene la directory. + +fd = identificatore restituito dalla "open". + +junk = variabile di lavoro. + +sid = identificatore del semaforo su locksem. + +errno = numero errore. + +sb = struttura che contiene informazioni sullo stato del file (vedi "stat"). + +@(FSV) +*/ + +int excllock(name,excl) +char *name; /* nome del file */ +BOOLEAN excl; /* se true deve fare il lock ex. altrimenti no */ + + { +#ifndef DOS + char path[200], dir[200]; + int fd, junk, sid; + extern int errno; + struct stat sb; + + strcpy(path, lockpath(name)); + strcpy(dir, dirname(path)); + sid = semtran(LOCKSEM); + if (semres == -1) return(-1); + PS(sid); + if (semres == -1) return(-1); + if ((stat(dir, &sb) == -1) && (errno == ENOENT)) CMkDir(dir); + if (((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) == -1) && + errno == EEXIST) + { + errno = 0; + if ((fd = open(path, O_RDWR, 0666)) == -1) + { + VS(sid); + return(-1); + } + if ((read(fd, &ld, sizeld) <= 0) || + (lseek(fd, 0L, SEEK_SET) == -1L)) + { + junk = close(fd); + VS(sid); + return(-1) ; + } + if (((ld.excl) && (ld.excl != getpid())) || excl) + { + junk = close(fd); + errno = EACCES ; + VS(sid); + return(-1); + } + ld.users++; + } + else + { + if (fd == -1) + { + VS(sid); + return(-1); + } + errno = 0; + ld.users = 1; + if (excl) ld.excl = getpid(); + else ld.excl = 0; + } + if (write(fd, &ld, sizeld) == -1) + { + junk = close(fd); + VS(sid); + return(-1); + } + if (close(fd) == -1) + { + VS(sid); + return(-1); + } + VS(sid); + if (semres == -1) return(-1); +#endif + return(0); + } + +/* +@(#) exclunlock CUSTIO + +@(ID) +Gestisce un unlock esclusivo su tutto il file. +@(FD) + +@(ISV) +Nella versione XENIX: + +path = contiene il file di lock. + +fd = identificatore restituito dalla "open". + +junk = variabile di lavoro. + +sid = identificatore del semaforo su locksem. +@(FSV) +*/ + +int exclunlock(name,excl) +char *name; /* nome file */ +BOOLEAN excl; /* se true esegue un unlock sul file */ + + { +#ifndef DOS + int fd, junk, sid; + char path[200]; + + strcpy(path, lockpath(name)); + sid = semtran(LOCKSEM); + if (semres == -1) return(-1); + PS(sid); + if (semres == -1) return(-1); + if (((fd = open(path, O_RDWR , 0666)) == -1) || + (read(fd, &ld, sizeld) <= 0) || + (lseek(fd, 0L, SEEK_SET) == -1L)) + { + junk = close(fd); + VS(sid); + return(-1); + } + if (excl) ld.excl = 0; + if (--ld.users == 0) + { + if ((close(fd) == -1) || (unlink(path) == -1)) + { + VS(sid); + return(-1); + } + VS(sid); + if (semres == -1) return(-1); + return(0); + } + if (write(fd, &ld, sizeld) == -1) + { + junk = close(fd); + VS(sid); + return(-1); + } + if (close(fd) == -1) + { + VS(sid); + return(-1); + } + VS(sid); + if (semres == -1) return(-1); +#endif + return(0); + } diff --git a/include/cfiles.c b/include/cfiles.c index 0301129f4..2fa0cc3e7 100755 --- a/include/cfiles.c +++ b/include/cfiles.c @@ -1,1622 +1,1623 @@ -/* -@(SH) Funzioni per la manipolazione dei files in direttorio ------------------------------------------------------------------------------- -@(VG$) PRIVATE - -fdir : identificatori per il direttori -rdir : identificatori per i tracciati record -dispferr : flag che attiva segnalazione errore per campo inesistente -dirfl : flags che permettono aperture e chiusure multiple per i direttori -recfl : flags che permettono aperture e chiusure multiple per i Tr. record ------------------------------------------------------------------------------- -*/ - -#define __CFILES_C /* fv */ - -#include "cfiles.h" -#include "fldtypes.h" -#include "lffilesc.h" - - int hashfun(char *); - void setdec(char *, int); - char *prefname(void); - - HIDDEN BOOLEAN pathpread = FALSE; - - BOOLEAN dispferr = TRUE; - int dirfl[2] = {0, 0}, recfl[2] = {0, 0} ; - char __ptprf[80] = ""; - -/* -@(#) COpenDir FILES - -@(ID) -Apre il file directory di una ditta. -@(FD) - -@(ISV) -name = percorso per il file di direttorio. - -Versione DOS e XENIX. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegare dettagliatamente il motivo. -@(FN) -*/ - - void COpenDir(lockmode, dirflg) - int lockmode; /* modo di apertura */ - int dirflg; /* flag per file comuni */ - - { - PathSt name; - - if (dirfl[dirflg]++) return; -#ifndef DOS - if ((excllock(CInsPref(glockname, dirflg), (lockmode == ExclLock)) == -1) - && (errno == EACCES)) - fatal_box("Locked Directory. Error number : %d ", errno); -#endif - strcpy(name, CInsPref(directory, dirflg)) ; - COpen(&fdir[dirflg], name, sizeof(FileDes), 0, lockmode) ; - if (fdir[dirflg].IOR != NoErr) - fatal_box("Can't open Directory. Error number : %d ", fdir[dirflg].IOR); - } - -/* -@(#) CCloseDir FILES - -@(ID) -Chiude il file di direttorio di una ditta. -@(FD) - -@(ISV) -Versione DOS e XENIX. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CCloseDir(dirflg) - int dirflg; /* flag per file comuni */ - - { -#ifndef DOS - exclunlock(CInsPref(glockname, dirflg), (fdir[dirflg].LockMode == ExclLock)); -#endif - if (dirfl[dirflg]) dirfl[dirflg]--; - if (!dirfl[dirflg]) CClose(&fdir[dirflg]) ; - } - -/* -@(#) COpenFile FILES - -@(ID) -Legge i dati di un archivio dal Direttorio. -@(FD) - -@(ISV) -junk = variabile spazzatura per la chiamata della funzione "sleep". - -s = stringa contenente messaggio di attesa. - -w = descrittore finestra di attesa. - -Versione DOS e XENIX. -@(FSV) - -@(IN) -Sostituisce l'eventuale simbolo "$" con il prefisso corrente. - -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void COpenFile(logicname,filed,lockmode,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore alla struttura che contiene i dati letti dal direttorio */ - int lockmode; /* tipo di lock effettuato sul record */ - int dirflg; /* flag per file comuni */ - - { - - do - { - CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); - if (TESTLOCK(fdir[dirflg].IOR)) - message_box("Sono in attesa della directory n.ro %d", logicname); - } - while TESTLOCK(fdir[dirflg].IOR) ; - strcpy(filed->SysName, CAddPref(filed->SysName)) ; - } ; - -/* -@(#) CCloseFile FILES - -@(ID) -Chiude e Riscrive i dati di un file sul direttorio. -@(FD) - -@(ISV) -wd = descrittore di una riga di direttorio. - -junk = variabile spazzatura per la chiamata della funzione "sleep". - -s = messaggio di attesa. - -w = descrittore della finestra di attesa. -@(FSV) - -@(IN) -ATTENZIONE : questa funzione aggiorna esclusivamente i campi EOD e Flags . - -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CCloseFile(logicname,filed,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore di un archivio */ - int dirflg; /* flag per file comuni */ - - { - FileDes wd; - - CRead(&fdir[dirflg],(RecType) &wd,(long) logicname, NoLock); - wd.EOD = filed->EOD; - wd.Flags = filed->Flags; - CWrite(&fdir[dirflg],(RecType) &wd,(long) logicname, UnLock); - } -/* -@($) CGetFile FILES - -@(ID) -Legge i dati relativi ad un archivio nel direttorio. -Non sostituisce con il prefisso l'eventuale carattere "$". -@(FD) - -@(ISV) -junk = variabile spazzatura per la chiamata della funzione "sleep". - -s = messaggio di attesa. - -w = descrittore finestra di attesa. - -Versione DOS e XENIX. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CGetFile(logicname,filed,lockmode,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore archivio nel direttorio */ - int lockmode; /* tipo di lock sul record */ - int dirflg; /* flag per file comuni */ - { - - do - { - CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); - if (TESTLOCK(fdir[dirflg].IOR)) - message_box("Sono in attesa della directory n.ro %d", logicname); - } - while TESTLOCK(fdir[dirflg].IOR) ; - } - -/* -@($) CPutFile FILES - -@(ID) -Chiude il direttorio e Riscrive i dati relativi ad un archivo. -Aggiorna tutti i campi. -@(FD) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CPutFile(logicname,filed,dirflg) - int logicname; /* numero logico file */ - FileDes *filed; /* puntatore al descrittore dell'archivio */ - int dirflg; /* flag per file comuni */ - - { - CWrite(&fdir[dirflg],(RecType) filed,(long) logicname, UnLock); - } - -/* -@($) zerofdes FILES - -@(ID) -Azzera un descrittore di directory. -@(FD) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - - void zerofdes(d) - FileDes *d; /* puntatore al descrittore di un archivio nella direttorio */ - - { - strcpy(d->SysName, ""); - d->EOD = 0; - d->EOX = 0; - d->LenR = 0; - d->Flags = 0; - strcpy(d->Des, ""); - strcpy(d->FCalc, ""); - strcpy(d->GenPrompt, ""); - } - -/* -@(#) COpenRecDir FILES - -@(ID) -Apre l'Archivio dei Tracciati Record. -@(FD) - -@(ISV) -name = nome dell'archivio dei Tracciati Record. - -Versione DOS e XENIX. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void COpenRecDir(lockmode,dirflg) - int lockmode; /* modo di apertura */ - int dirflg; /* flag per file comuni */ - - { - PathSt name; - - if (recfl[dirflg]++) return; - strcpy(name, CInsPref(ntrrec, dirflg)) ; - COpen(&rdir[dirflg], name, sizeof(RecDes), 0, lockmode) ; - if (rdir[dirflg].IOR != NoErr) - fatal_box("Can't open record description file. Error number : %d ", rdir[dirflg].IOR); - - } - -/* -@(#) CCloseRecDir FILES - -@(ID) -Chiude l'Archivio dei Tracciati Record -@(FD) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo -@(FN) -*/ - - void CCloseRecDir(dirflg) - int dirflg; /* flag per file comuni */ - - { - if (recfl[dirflg]) recfl[dirflg]--; - if (!recfl[dirflg]) CClose(&rdir[dirflg]) ; - } - -/* -@(#) CGetRec FILES - -@(ID) -Legge il tracciato record del file "logicname" e lo mette in "recd". -@(FD) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CGetRec(logicname,recd,dirflg) - int logicname; /* numero file */ - RecDes *recd; /* descrittore record */ - int dirflg; /* flag per file comuni */ - - { - CRead(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); - } - - -/* -@($) CPutRec FILES - -@(ID) -Aggiorna il file dei Tracciati Record. -@(FD) - -*/ - - void CPutRec(logicname,recd,dirflg) - int logicname; /* numero file */ - RecDes *recd; /* descrittore record */ - int dirflg; /* flag per file comuni */ - - { - CWrite(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); - } - -/* -@($) zerodes FILES - -@(ID) -Azzera il Tracciato Record "r". -@(FD) - -@(ISV) -i,j = contatori. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void zerordes(r) - RecDes *r; /* descrittore record */ - - { - int i,j ; - - r->NFields = 0; - for (i = 0; i < MaxFields; i++) - { - strcpy(r->Fd[i].Name, ""); - r->Fd[i].TypeF = NullF; - r->Fd[i].Len = 0; - r->Fd[i].Dec = 0; - r->Fd[i].RecOff = 0; - } - for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; - r->NKeys = 0; - for (i = 1; i < MaxKeys; i++) - { - r->Ky[i].DupKeys = FALSE; - r->Ky[i].NkFields = 0; - for (j = 0; j < MKFields; j++) r->Ky[i].FieldSeq[j] = INVFLD; - for (j = 0; j < MKFields; j++) r->Ky[i].FromCh[j] = INVFLD; - for (j = 0; j < MKFields; j++) r->Ky[i].ToCh[j] = INVFLD; - } - } - -/* -@($) setrdes FILES - -@(ID) -Dato il tracciato record crea la struttura HASH (sortFd) per l'accesso veloce -ai campi. -@(FD) - -@(ISV) -pos = indirizzo Hash. - -i = contatore. - -nf = variabile di lavoro. - -tmppos = indirizzo hash per l'accesso ai campi. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - word setrdes(r) - RecDes *r; /* descrittore record */ - - { - int pos, tmppos, nf, i; - - for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; - if (r->NFields) - { - for (i = 0; i < r->NFields; i++) - { - nf = i; - pos = hashfun(r->Fd[nf].Name); - while (TRUE) - { - if (r->SortFd[pos] == INVFLD) - { - r->SortFd[pos] = (byte) nf; - break; - } - else - { - if (strcmp(r->Fd[r->SortFd[pos]].Name, r->Fd[nf].Name) <= 0) - { - pos++; - if (pos >= MaxFields) - pos = 0; - } - else - { - tmppos = r->SortFd[pos]; - r->SortFd[pos] = (byte) nf; - nf = tmppos; - } - } - } - } - r->Fd[0].RecOff = 1; - for (i = 1; i < r->NFields; i++) - r->Fd[i].RecOff = r->Fd[i - 1].RecOff + r->Fd[i - 1].Len; - return(r->Fd[r->NFields - 1].RecOff + r->Fd[r->NFields - 1].Len); - } - return(0); - } - -/* -@(SHF) Funzioni per la gestione dei campi dei record -@($) setdec FILES - -@(ID) -Data la stringa "s" (contenente un numero) Aggiusta il numero dei decimali in -base a "dec". -@(FD) - -@(ISV) -s1 = stringa di lavoro. - -i = contatore. - -l = lunghezza stringa s1. - -carry = eventuale riporto approssimazione. - -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void setdec(s,dec) - char *s; /* stringa che deve contenere un numero */ - int dec; /* numero di decimali che deve avere il numero */ - - { - char *s1; - int i, l, carry; - - if (LENGTH(s) == 0) strcpy(s, "0"); - if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; - s1 = strchr(s, '.'); - if ((dec) && (s1 == NULL)) - { - strcat(s, "."); - s1 = strchr(s, '.'); - } - else - if (!dec) - { - if (s1 == NULL) return ; - l = LENGTH(s1); /* occhio verificare */ - carry = (s1[1] >= '5'); - *s1 = '\0'; - while (carry) - { - s1--; - if (*s1 == '-') break; - if (*s1 == '9') - { - *s1 = '0'; - if (s == s1) break; - } - else - { - (*s1)++; - carry = FALSE; - } - } - if (carry) - { - for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; - s[(*s1 == '-')] = '1'; - } - return; - } - s1++; - l = LENGTH(s1); - if (l > dec) - { - carry = (s1[dec] >= '5'); - s1[dec] = '\0'; - while (carry) - { - dec--; - if (s1[dec] == '9') - { - s1[dec] = '0'; - if (!dec) break; - } - else - { - s1[dec]++; - carry = FALSE; - } - } - s1--; - while (carry) - { - s1--; - if (*s1 == '-') break; - if (*s1 == '9') - { - *s1 = '0'; - if (s == s1) break; - } - else - { - (*s1)++; - carry = FALSE; - } - } - if (carry) - { - for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; - s[(*s1 == '-')] = '1'; - } - } - else - while (l++ < dec) strcat(s1, "0"); - } - -/* -@($) hashfun FILES - -@(ID) -Data la stringa "s" costruisce la chiave Hash. -@(FD) - -@(ISV) -l = lunghezza della stringa "s". - -w[82] = copia di lavoro della stringa "s". - -temp = variabile di lavoro. - -pw = puntatore ai caratteri della stringa. - -Utilizza l'operatore OR Esclusivo. -@(FSV) - -@(IN) -Restituisce l'indirizzo HASH. -@(FN) -*/ - - int hashfun(s) - char *s; /* stringa da eleborare */ - - { - int l; - char w[82]; - unsigned short temp = 0, *pw = (unsigned short *) w; - - strcpy(w, s); - if (ODD(LENGTH(s))) strcat(w, " "); - l = LENGTH(s); - while ((char *) pw < w + l) - { - temp ^= *pw; - pw++; - } - l = (short) (temp % (MaxFields - 3)); - if (l < 0) l = -l; - return(l); - } - -/* -@($) findfld FILES - -@(ID) -Ricerca all'interno di un record il campo di nome "s". -@(FD) - -@(ISV) -i= variabile di lavoro. -startp = variabile di lavoro. -cmp = variabile di lavoro. -@(FSV) -*/ - - int findfld(recd,s) - RecDes *recd; /* Descrittore record Tracciato Record */ - char *s; /* stringa contenente il nome del campo */ - - { - int i, cmp, startp; - - i = hashfun(s); - startp = i; - if (recd->SortFd[i] == INVFLD) return(-1); - do - { - if (!(cmp = strcmp(recd->Fd[recd->SortFd[i]].Name, s))) - return((int) (recd->SortFd[i])); - else - if (cmp > 0) return(-1); - else - if (++i >= MaxFields) i = 0; - if (recd->SortFd[i] == INVFLD) return(-1); - } - while (i != startp) ; - return(-1); - } - -/* -@(#) CFieldSize FILES - -@(ID) -Restituisce la lunghezza del campo. -@(FD) - -@(ISV) -p = puntatore al campo. -@(FSV) -*/ - - unsigned int CFieldSize(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - - { - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len); - else return(0); - } - -/* -@(#) CFieldDec FILES - -@(ID) -Restituisce il numero di decimali presenti nel campo. -@(FD) - -@(ISV) -p = puntatore al campo. -@(FSV) -*/ - - unsigned int CFieldDec(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - - { - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec); - else return(0); - } - -/* -@(#) CFieldType FILES - -@(ID) -Restituisce un intero rappresentante il tipo del campo. -@(FD) - -@(ISV) -p = posizione all'interno del record del campo. -@(FSV) -*/ - - int CFieldType(fieldname,recd) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - - { - int p; - - if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].TypeF); - else return(NullF); - } - -/* -@($) getfrmt FILES - -@(ID) -Prepara il il formato per dsprintf per il campo "nf" del tracciato record "recd". -@(FD) - -@(ISV) -len = lunghezza del campo. - -dec = numero di decimali presenti nel campo. -@(FSV) -*/ - - void getfrmt(recd,nf,frm) - RecDes *recd; /* descrittore record */ - int nf; /* numero campo */ - char *frm; /* stringa in formato per dsprintf */ - - { - int len, dec; - - strcpy(frm, ""); - len = recd->Fd[nf].Len; - dec = recd->Fd[nf].Dec; - if (recd->Fd[nf].TypeF == IntF) sprintf(frm, "%%%dd", len); - else - if (recd->Fd[nf].TypeF == Int4F) sprintf(frm, "%%%dld", len); - else - if (recd->Fd[nf].TypeF == RealF) sprintf(frm, "%%%d.%dt",len, dec); - /*cambiare */ - else - if (recd->Fd[nf].TypeF == WordF) sprintf(frm, "%%%du", len); - else - if (recd->Fd[nf].TypeF == ZeroF) sprintf(frm, "%%0%dd", len); - else - if (recd->Fd[nf].TypeF == EZeroF) sprintf(frm, "%%0%dld", len); - } - -/* -@(#) CGetField FILES - -@(ID) -Estrae il valore di un campo dal record e lo pone in "fout". - -Restituisce un eventuale codice errore. -@(FD) - -@(ISV) -r = variabile che contiene l'eventuale codice errore. - -p = variabile per la chiamata di "findfld". - -s = puntatore alla zona di memoria allocata. - -frm= stringa per contenere un formato per la dsprintf. -@(FSV) - -@(IN) -Si osservi che "fout" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. -@(FN) -*/ - -#ifndef FOXPRO - - int CGetField(fieldname,recd,recin,fout) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - RecType recin; /* buffer contenente il record */ - void *fout; /* contenuto del campo in output */ - - { - int r,p; - char *s, frm[30], *wp = (char *) fout; - - s = malloc(256); - p = findfld(recd, fieldname); - getfrmt(recd, p, frm); - if ((r = CGetFieldBuff(fieldname, recd, recin, s)) != -1) - if (recd->Fd[p].TypeF == AlfaF) strcpy((char *) fout, s); - else - if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) - { - if (LENGTH(s)) *((int *) fout) = CCONVINT(s); - else *((int *) fout) = 0; - } - else - if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) - { - if (LENGTH(s)) *((long *) fout) = CONVLONG(s); - else *((long *) fout) = 0L; - } - else - if (recd->Fd[p].TypeF == RealF) atod((DEC *) fout, s); - else - if (recd->Fd[p].TypeF == DateF) *((TrDate *) fout) = cpackdata(s); - else - if (recd->Fd[p].TypeF == WordF) - { - if (LENGTH(s)) *((unsigned *) fout) = (unsigned)CONVLONG(s); - else *((unsigned *) fout) = 0; - } - else - if (recd->Fd[p].TypeF == CharF) - *wp = *s; - else - if (recd->Fd[p].TypeF == BoolF) - *((BOOLEAN *) fout) = (*s == 'X'); - free(s); - return(r); - } - -/* -@(#) CPutField FILES - -@(ID) -Scrive il contenuto della variabile puntata da "fin" nel campo "fieldname" del record. - -Restituisce un eventuale codice errore. -@(FD) - -@(ISV) -r = variabile che contiene l'eventuale codice errore. - -p = variabile per la chiamata di "findfld". - -s = puntatore alla zona di memoria allocata. - -frm= stringa per contenere un formato per la dsprintf. -@(FSV) - -@(IN) -Si osservi che "fin" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. -@(FN) -*/ - - int CPutField(fieldname,recd,fin,recout) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - void *fin; /* puntatore al valore da scrivere */ - RecType recout; /* buffer contenetnte il record */ - - { - int p; - char s[256], frm[30]; - - strcpy(s, ""); - p = findfld(recd, fieldname); - getfrmt(recd, p, frm); - if (recd->Fd[p].TypeF == AlfaF) strcpy(s, (char *) fin); - else - if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) - sprintf(s, frm, *((int *) fin)); - else - if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) - sprintf(s, frm, *((long *) fin)) ; - else - if (recd->Fd[p].TypeF == RealF) dsprintf(s, frm, (DEC *) fin); - else - if (recd->Fd[p].TypeF == DateF) ceditdata(*((TrDate *) fin), s); - else - if (recd->Fd[p].TypeF == WordF) sprintf(s, frm, *((unsigned *) fin)) ; - else - if (recd->Fd[p].TypeF == CharF) - { - s[0] = *((char *) fin); - s[1] = '\0'; - } - else - if (recd->Fd[p].TypeF == BoolF) - { - s[0] = *((BOOLEAN*) fin) ? 'X' : ' '; - s[1] = '\0'; - } - return CPutFieldBuff(fieldname, recd, s, recout); - } - -#endif /* FOXPRO */ - -/* -@(#) CGetFieldBuff FILES - -@(ID) -Estrae il valore di un campo dal record e lo pone nella stringa "s". - -Restituisce un eventuale codice errore. -@(FD) - -@(ISV) -p = puntatore al campo. - -i = contatore. - -Off = offest in byte all'interno del record per il campo in oggetto. - -len = lunghezza campo. - -s1 = stringa di lavoro. - -d = data in formato stringa. -@(FSV) - -@(IN) -Utilizzato per il Data Entry. -@(FN) -*/ - - int CGetFieldBuff(fieldname,recd,recin,s) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - RecType recin; /* buffer contenente il record */ - char *s; /* stringa per l'output */ - - { - int p, i; - unsigned int off; - byte len; - char *s1; - TrDate d; - - if ((p = findfld(recd, fieldname)) != -1) - { - off = recd->Fd[p].RecOff; - len = recd->Fd[p].Len; - if ((recd->Fd[p].TypeF != AlfaF) && - (recd->Fd[p].TypeF != DateF) && - (recd->Fd[p].TypeF != ZeroF) && - (recd->Fd[p].TypeF != EZeroF)) - { - while ((recin[off] == ' ') && (len)) - { - off++; - len--; - } - if ((recd->Fd[p].TypeF != RealF) && (recd->Fd[p].TypeF != CharF)) - { - while ((recin[off] == '0') && (len)) - { - off++; - len--; - } - } - } - else - if ((recd->Fd[p].TypeF == ZeroF) || - (recd->Fd[p].TypeF == EZeroF)) - { - int i = 0, pos = 0; - while (i < len) - { - if (recin[off + i] != '0') break; - i++; - pos = i; - } - if (pos == len) - { - off += len; - len = 0; - } - } - if (len) - { - s1 = recin + off; - for (i = 0; i < len; i++) s[i] = s1[i]; - s[len] = '\0'; - while ((len) && (s[len - 1] == ' ')) s[--len] = '\0'; - } - else strcpy(s, ""); - if ((recd->Fd[p].TypeF == DateF)) - { - if (LENGTH(s)) d = atol(s); /* sscanf(s, "%ld", &d); */ - else d = 0 ; - ceditdata(d, s); - } - if ((recd->Fd[p].TypeF == RealF)) - if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; - return(0); - } - else - { - strcpy(s, ""); - return(-1); - } - } - -/* -@(#) CPutFieldBuff FILES - -@(ID) -Scrive il contenuto della stringa "s" nel campo "fieldname" del record. - -Restituisce un eventuale codice errore. -@(FD) - -@(ISV) -p = puntatore al campo. - -i = contatore. - -l = variabile di lavoro. - -off = offest in byte all'interno del record per il campo in oggetto. - -len = lunghezza campo. - -s1,s2 = stringa di lavoro. - -d = data in formato stringa. -@(FSV) - -@(IN) -Utilizzato per il Data Entry -@(FN) -*/ - - int CPutFieldBuff(fieldname,recd,s,recout) - char *fieldname; /* nome del campo */ - RecDes *recd; /* descrittore record */ - char *s; /* stringa contenente il valore da scrivere nel campo */ - RecType recout; /* buffer contenente il record */ - - { - int p, off, len, l, i; - char *s1; - char *s2; - TrDate d; - - s2 = malloc(256); - strcpy(s2, s); - if ((p = findfld(recd, fieldname)) != -1) - { - off = recd->Fd[p].RecOff; - len = recd->Fd[p].Len; - if (recd->Fd[p].TypeF == DateF) - { - d = cpackdata(s2); - sprintf(s2,"%06ld", d); - } - if (recd->Fd[p].TypeF == RealF) setdec(s2, recd->Fd[p].Dec); - l = LENGTH(s2); - if (l > len) - { - free(s2); - return(-1); - } - s1 = recout + off ; - for (i = 0; i < l ; i++) s1[i] = s2[i] ; - if ((recd->Fd[p].TypeF == IntF) || - (recd->Fd[p].TypeF == Int4F) || - (recd->Fd[p].TypeF == WordF) || - (recd->Fd[p].TypeF == RealF) || - (recd->Fd[p].TypeF == ZeroF) || - (recd->Fd[p].TypeF == EZeroF)) - { - char c; - if ((recd->Fd[p].TypeF == ZeroF) || - (recd->Fd[p].TypeF == EZeroF)) - c = '0'; - else c = ' '; - if (l == 0) s1[l++] = '0'; - while (l < len) - { - for (i = l; i > 0; i--) s1[i] = s1[i - 1]; - s1[0] = c; - l++; - } - } - else - while (l < len) s1[l++] = ' '; - free(s2); - return(0); - } - else - { - strcpy(s, ""); - free(s2); - return(-1); - } - } - - -/* -@(#) CZeroField FILES - -@(ID) -Azzera un campo. -@(FD) - -@(ISV) -p = puntatore al campo. - -s = stringa messaggio. -@(FSV) -*/ - - int CZeroField(fieldname,recd,recout) - char *fieldname; /* nonme del campo */ - RecDes *recd; /* descrittore record */ - RecType recout; /* buffer contenente il record */ - - { - int p; - - if ((p = findfld(recd, fieldname)) != -1) - { - if (recd->Fd[p].TypeF == DateF) - memset(recout + recd->Fd[p].RecOff, '0', recd->Fd[p].Len); - else - { - memset(recout + recd->Fd[p].RecOff, Blank, recd->Fd[p].Len); - if ((recd->Fd[p].TypeF == IntF) || - (recd->Fd[p].TypeF == Int4F) || - (recd->Fd[p].TypeF == WordF)) - { - *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; - } - else - if (recd->Fd[p].TypeF == RealF) - { - if (recd->Fd[p].Dec) - { - memset(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - - recd->Fd[p].Dec - 2, '0', recd->Fd[p].Dec + 2); - *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - - recd->Fd[p].Dec - 1) = '.'; - } - else *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; - } - return(NoErr); - } - } - else return(-1); - return(NoErr); - } - -/* -@(#) CZeroRec FILES - -@(ID) -Azzera tutto il record. -@(FD) - -@(ISV) -i = contatore. - -junk = variabile spazzatura per la chiamata di CZeroField. -@(FSV) -*/ - - void CZeroRec(recd,recout) - RecDes *recd; /* descrittore record */ - RecType recout; /* buffer contenente il record */ - - { - int i, junk; - - IRecallRec(recout) ; - for (i = 0; i < recd->NFields; i++) junk = CZeroField(recd->Fd[i].Name, - recd, recout); - } - -/* -@($) CBuildKey FILES - -@(ID) -Costruisce la chiave corrispondente al numero chiave. -@(FD) - -@(ISV) -i = contatore. - -nf = numero campi che compongono la chiave. - -len = lunghezza del campo. - -off = offest in byte all'interno del record per il campo in oggetto. - -l = variabile di lavoro. - -up = variabile di lavoro per rendere maiuscola la stringa. - -wd = variabile per la data. - -s1 = stringa di lavoro. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - int CBuildKey(recd,numkey,recin,key) - RecDes *recd; /* descrittore record */ - int numkey; /* numero chiave */ - RecType recin; /* buffer contenente il record */ - char *key; /* valore della chiave */ - - { - int i, nf, l = 0, len, off; - TrDate wd ; - char s1[10]; - BOOLEAN upp = FALSE; - - strcpy(key, ""); - if (numkey-- <= recd->NKeys) - { - for (i = 0; i < recd->Ky[numkey].NkFields; i++) - { - if ((upp = (recd->Ky[numkey].FieldSeq[i] > MaxFields)) == TRUE) - nf = recd->Ky[numkey].FieldSeq[i] - MaxFields; - else - nf = recd->Ky[numkey].FieldSeq[i]; - if (recd->Ky[numkey].FromCh[i] == INVFLD) - { - off = recd->Fd[nf].RecOff; - len = recd->Fd[nf].Len; - } - else - { - if (recd->Fd[nf].TypeF == DateF) - { - off = recd->Fd[nf].RecOff; - len = recd->Fd[nf].Len; - strncpy(s1, (recin + off), len); - s1[len] = '\0'; - wd = 0; - for(len = 0; len < LENGTH(s1); len++) - if (isdigit(s1[len])) wd = (wd * 10) + (s1[len] - '0'); - ceditdata(wd, s1); - s1[2] = s1[3]; - s1[3] = s1[4]; - s1[4] = s1[6]; - s1[5] = s1[7]; - s1[6] = '\0'; - off = recd->Ky[numkey].FromCh[i]; - len = recd->Ky[numkey].ToCh[i] - - recd->Ky[numkey].FromCh[i] + 1; - } - else - { - off = recd->Fd[nf].RecOff + recd->Ky[numkey].FromCh[i]; - len = recd->Ky[numkey].ToCh[i] - - recd->Ky[numkey].FromCh[i] + 1; - } - } - if ((l + len) > 80) - { - strcpy(key, ""); - return(BTrKeyLenErr); - } - if ((recd->Fd[nf].TypeF == DateF) && (recd->Ky[numkey].FromCh[i] != INVFLD)) - strncpy((key + l), &s1[off], len); - else - { - strncpy((key + l), (recin + off), len); - if (recin[off] == '\0') memset(key + l, ' ', len); - else - if ((recd->Fd[nf].TypeF == IntF) || - (recd->Fd[nf].TypeF == Int4F) || - (recd->Fd[nf].TypeF == WordF)) - { - int w = l, j = l + len; - while (w < j && key[w] == ' ') w++; - while (w < j && key[w] == '0') - key[w++] = ' '; - } - } - l += len; - } - key[l] = '\0'; - crtrim(key); - if (upp) CUpString(key) ; - return(NoErr); - } - return(BTrPathErr); - } - -/* -@($) CCalcLenKey FILES - -@(ID) -Ritorna la lunghezza della chiave. -@(FD) - -@(ISV) -nf = numero campi chiave. - -i = contatore. - -l = variabile di lavoro. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - int CCalcLenKey(recd,numkey) - RecDes *recd; /* descrittore record */ - int numkey; /* numero della chiave */ - - { - register int l = 0, i, nf; - - if (numkey-- <= recd->NKeys) - { - for (i = 0; i < recd->Ky[numkey].NkFields; i++) - { - if (recd->Ky[numkey].FieldSeq[i] > MaxFields) - nf = (int) recd->Ky[numkey].FieldSeq[i] - MaxFields; - else - nf = (int) recd->Ky[numkey].FieldSeq[i]; - if (recd->Ky[numkey].FromCh[i] == INVFLD) l += (int) recd->Fd[nf].Len; - else l += (int) (recd->Ky[numkey].ToCh[i] - recd->Ky[numkey].FromCh[i] + 1); - } - return(l); - } - return(-1); - } - -/* -@($) prefname FILES - -@(ID) -Restituisce il nome del file che contiene il prefisso corrente. -@(FD) - -@(ISV) -s,s1 = stringhe di lavoro. - -Versione DOS e XENIX. -@(FSV) -*/ - char *prefname() - - { - static PathSt s; -#ifdef DOS - char *s1 = getenv("PREFPATH"); - if (s1 == NULL) s1 = "prefix.txt"; - strcpy(s, s1); -#else - sprintf(s, "prefix.%-d", getuid()); -#endif - return(s) ; - } - -/* -@(#) CGetPref FILES - -@(ID) -Legge dal file prefisso il prefisso dati corrente. -@(FD) - -@(ISV) -f = puntatore al file. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - char *CGetPref() - - { - const char* p = prefname(); - FILE *f = fopen(p, "r"); - - if (f == NULL) - { - strcpy(cprefix, ""); - } - else - { - if (fgets(cprefix, 42, f) != NULL) - { - const int len = LENGTH(cprefix)-1; - if (len >= 0 && cprefix[len] <= ' ') cprefix[len] = '\0'; - } - else - *cprefix = '\0'; - fclose(f); - } - if (!pathpread) - { - const char* p = "pathpref.ini"; - FILE* f = fopen(p, "r"); - pathpread = TRUE; - if (f != NULL) - { - if (fgets(__ptprf, 42, f) != NULL) - { - const int len = LENGTH(__ptprf)-1; - if (len >= 0 && __ptprf[len] <= ' ') - { - __ptprf[len] = '\0'; - if (len > 0) strcat(__ptprf, "/"); - } - } - else - *__ptprf = '\0'; - fclose(f); - } - } - if (*__ptprf) - { - char ws[200]; - sprintf(ws, "%s%s", __ptprf, cprefix); - strcpy(cprefix, ws); - } - return(cprefix); - } - -/* -@($) CPutPref FILES - -@(ID) -Aggiorna sul file prefisso il prefisso dati corrente. -@(FD) - -@(ISV) -f = puntatore a file. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - void CPutPref(pref) - char *pref; /* stringa contenente il nuovo prefisso */ - - { - FILE *f; - const int l = strlen(__ptprf); - - if (l && strncmp(pref, __ptprf, l) == 0) pref += l; - if ((f = fopen(prefname(), "w")) == NULL) - fatal_box("Put prefix. Error number : %d ", errno); - fprintf(f, "%s\n", pref); - fclose(f); - } - -/* -@($) CAddPref FILES - -@(ID) -Cerca il carattere "$" nel nome file e lo sostituisce con il prefisso corrente. -@(FD) - -@(ISV) -s = stringa che contiene il nome. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - char *CAddPref(name) - char *name; /* nome file */ - - { - static PathSt s; - - if (*name == '$') - { - name++; - return(CInsPref(name, NORDIR)) ; - } - else - if (*name == '%') - { - name++; - return(CInsPref(name, COMDIR)) ; - } - else - { - strcpy(s, name); - return(s); - } - } - -/* -@($) CInsPref FILES - -@(ID) -Aggiunge (a sinistra) il prefisso corrente. -@(FD) - -@(ISV) -s = stringa di lavoro. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. -@(FN) -*/ - - char *CInsPref(name,dirflg) - char *name; /* nome del file cui aggiungere il prefisso */ - int dirflg; /* flag per file comuni */ - - { - static PathSt s; - - if (dirflg == NORDIR) - { - if (LENGTH(cprefix) == 0) sprintf(s,"%s", name); - else sprintf(s,"%s%c%s",cprefix, DIRSEP, name); - } - else sprintf(s,"%scom%c%s", __ptprf, DIRSEP, name); - return(s); - } - -/* -@(#) CGetIdxName FILES - -@(ID) -Dato un nome file costruisce il nome del file indice corrispondente. -@(FD) - -@(ISV) -fdst,s1,s2 = stringhe di lavoro. -@(FSV) - -@(IN) -NON UTILIZZARE !!. - -Se si utilizza spiegarne dettagliatamente il motivo. - -L' estensione dei file indice e' ndx; e' quindi vietato utilizzare un nome -di file che abbia tale estensione. L' estensione dei file dati e' dta. -@(FN) -*/ - - char *CGetIdxName(s) - char *s; /* stringa contenente il nome file */ - - { - static PathSt fdst; - char *s1, *s2; - - strcpy(fdst, s) ; - s1 = strrchr(fdst,DIRSEP) ; - if (s1 == NULL) s1 = fdst; - s2 = strchr(s1,'.') ; - if (s2 != NULL) s2[0] = '\0' ; - s1 = strcat(fdst, ".ndx") ; - return(fdst) ; - } +/* +@(SH) Funzioni per la manipolazione dei files in direttorio +------------------------------------------------------------------------------ +@(VG$) PRIVATE + +fdir : identificatori per il direttori +rdir : identificatori per i tracciati record +dispferr : flag che attiva segnalazione errore per campo inesistente +dirfl : flags che permettono aperture e chiusure multiple per i direttori +recfl : flags che permettono aperture e chiusure multiple per i Tr. record +------------------------------------------------------------------------------ +*/ + +#define __CFILES_C /* fv */ + +#include "cfiles.h" +#include "fldtypes.h" +#include "lffilesc.h" + + int hashfun(char *); + void setdec(char *, int); + char *prefname(void); + + HIDDEN BOOLEAN pathpread = FALSE; + + BOOLEAN dispferr = TRUE; + int dirfl[2] = {0, 0}, recfl[2] = {0, 0} ; + char __ptprf[80] = ""; + +/* +@(#) COpenDir FILES + +@(ID) +Apre il file directory di una ditta. +@(FD) + +@(ISV) +name = percorso per il file di direttorio. + +Versione DOS e XENIX. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegare dettagliatamente il motivo. +@(FN) +*/ + + void COpenDir(lockmode, dirflg) + int lockmode; /* modo di apertura */ + int dirflg; /* flag per file comuni */ + + { + PathSt name; + + if (dirfl[dirflg]++) return; +#ifndef DOS + if ((excllock(CInsPref(glockname, dirflg), (lockmode == ExclLock)) == -1) + && (errno == EACCES)) + fatal_box("Locked Directory. Error number : %d ", errno); +#endif + strcpy(name, CInsPref(directory, dirflg)) ; + COpen(&fdir[dirflg], name, sizeof(FileDes), 0, lockmode) ; + if (fdir[dirflg].IOR != NoErr) + fatal_box("Can't open Directory. Error number : %d ", fdir[dirflg].IOR); + } + +/* +@(#) CCloseDir FILES + +@(ID) +Chiude il file di direttorio di una ditta. +@(FD) + +@(ISV) +Versione DOS e XENIX. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CCloseDir(dirflg) + int dirflg; /* flag per file comuni */ + + { +#ifndef DOS + exclunlock(CInsPref(glockname, dirflg), (fdir[dirflg].LockMode == ExclLock)); +#endif + if (dirfl[dirflg]) dirfl[dirflg]--; + if (!dirfl[dirflg]) CClose(&fdir[dirflg]) ; + } + +/* +@(#) COpenFile FILES + +@(ID) +Legge i dati di un archivio dal Direttorio. +@(FD) + +@(ISV) +junk = variabile spazzatura per la chiamata della funzione "sleep". + +s = stringa contenente messaggio di attesa. + +w = descrittore finestra di attesa. + +Versione DOS e XENIX. +@(FSV) + +@(IN) +Sostituisce l'eventuale simbolo "$" con il prefisso corrente. + +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void COpenFile(logicname,filed,lockmode,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore alla struttura che contiene i dati letti dal direttorio */ + int lockmode; /* tipo di lock effettuato sul record */ + int dirflg; /* flag per file comuni */ + + { + + do + { + CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); + + if (TESTLOCK(fdir[dirflg].IOR)) + message_box("Sono in attesa della directory n.ro %d", logicname); + } + while TESTLOCK(fdir[dirflg].IOR) ; + strcpy(filed->SysName, CAddPref(filed->SysName)) ; + } ; + +/* +@(#) CCloseFile FILES + +@(ID) +Chiude e Riscrive i dati di un file sul direttorio. +@(FD) + +@(ISV) +wd = descrittore di una riga di direttorio. + +junk = variabile spazzatura per la chiamata della funzione "sleep". + +s = messaggio di attesa. + +w = descrittore della finestra di attesa. +@(FSV) + +@(IN) +ATTENZIONE : questa funzione aggiorna esclusivamente i campi EOD e Flags . + +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CCloseFile(logicname,filed,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore di un archivio */ + int dirflg; /* flag per file comuni */ + + { + FileDes wd; + + CRead(&fdir[dirflg],(RecType) &wd,(long) logicname, NoLock); + wd.EOD = filed->EOD; + wd.Flags = filed->Flags; + CWrite(&fdir[dirflg],(RecType) &wd,(long) logicname, UnLock); + } +/* +@($) CGetFile FILES + +@(ID) +Legge i dati relativi ad un archivio nel direttorio. +Non sostituisce con il prefisso l'eventuale carattere "$". +@(FD) + +@(ISV) +junk = variabile spazzatura per la chiamata della funzione "sleep". + +s = messaggio di attesa. + +w = descrittore finestra di attesa. + +Versione DOS e XENIX. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CGetFile(logicname,filed,lockmode,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore archivio nel direttorio */ + int lockmode; /* tipo di lock sul record */ + int dirflg; /* flag per file comuni */ + { + + do + { + CRead(&fdir[dirflg],(RecType) filed,(long) logicname, lockmode); + if (TESTLOCK(fdir[dirflg].IOR)) + message_box("Sono in attesa della directory n.ro %d", logicname); + } + while TESTLOCK(fdir[dirflg].IOR) ; + } + +/* +@($) CPutFile FILES + +@(ID) +Chiude il direttorio e Riscrive i dati relativi ad un archivo. +Aggiorna tutti i campi. +@(FD) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CPutFile(logicname,filed,dirflg) + int logicname; /* numero logico file */ + FileDes *filed; /* puntatore al descrittore dell'archivio */ + int dirflg; /* flag per file comuni */ + + { + CWrite(&fdir[dirflg],(RecType) filed,(long) logicname, UnLock); + } + +/* +@($) zerofdes FILES + +@(ID) +Azzera un descrittore di directory. +@(FD) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + + void zerofdes(d) + FileDes *d; /* puntatore al descrittore di un archivio nella direttorio */ + + { + strcpy(d->SysName, ""); + d->EOD = 0; + d->EOX = 0; + d->LenR = 0; + d->Flags = 0; + strcpy(d->Des, ""); + strcpy(d->FCalc, ""); + strcpy(d->GenPrompt, ""); + } + +/* +@(#) COpenRecDir FILES + +@(ID) +Apre l'Archivio dei Tracciati Record. +@(FD) + +@(ISV) +name = nome dell'archivio dei Tracciati Record. + +Versione DOS e XENIX. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void COpenRecDir(lockmode,dirflg) + int lockmode; /* modo di apertura */ + int dirflg; /* flag per file comuni */ + + { + PathSt name; + + if (recfl[dirflg]++) return; + strcpy(name, CInsPref(ntrrec, dirflg)) ; + COpen(&rdir[dirflg], name, sizeof(RecDes), 0, lockmode) ; + if (rdir[dirflg].IOR != NoErr) + fatal_box("Can't open record description file. Error number : %d ", rdir[dirflg].IOR); + + } + +/* +@(#) CCloseRecDir FILES + +@(ID) +Chiude l'Archivio dei Tracciati Record +@(FD) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo +@(FN) +*/ + + void CCloseRecDir(dirflg) + int dirflg; /* flag per file comuni */ + + { + if (recfl[dirflg]) recfl[dirflg]--; + if (!recfl[dirflg]) CClose(&rdir[dirflg]) ; + } + +/* +@(#) CGetRec FILES + +@(ID) +Legge il tracciato record del file "logicname" e lo mette in "recd". +@(FD) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CGetRec(logicname,recd,dirflg) + int logicname; /* numero file */ + RecDes *recd; /* descrittore record */ + int dirflg; /* flag per file comuni */ + + { + CRead(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); + } + + +/* +@($) CPutRec FILES + +@(ID) +Aggiorna il file dei Tracciati Record. +@(FD) + +*/ + + void CPutRec(logicname,recd,dirflg) + int logicname; /* numero file */ + RecDes *recd; /* descrittore record */ + int dirflg; /* flag per file comuni */ + + { + CWrite(&rdir[dirflg],(RecType) recd,(long) logicname, NoLock); + } + +/* +@($) zerodes FILES + +@(ID) +Azzera il Tracciato Record "r". +@(FD) + +@(ISV) +i,j = contatori. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void zerordes(r) + RecDes *r; /* descrittore record */ + + { + int i,j ; + + r->NFields = 0; + for (i = 0; i < MaxFields; i++) + { + strcpy(r->Fd[i].Name, ""); + r->Fd[i].TypeF = NullF; + r->Fd[i].Len = 0; + r->Fd[i].Dec = 0; + r->Fd[i].RecOff = 0; + } + for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; + r->NKeys = 0; + for (i = 1; i < MaxKeys; i++) + { + r->Ky[i].DupKeys = FALSE; + r->Ky[i].NkFields = 0; + for (j = 0; j < MKFields; j++) r->Ky[i].FieldSeq[j] = INVFLD; + for (j = 0; j < MKFields; j++) r->Ky[i].FromCh[j] = INVFLD; + for (j = 0; j < MKFields; j++) r->Ky[i].ToCh[j] = INVFLD; + } + } + +/* +@($) setrdes FILES + +@(ID) +Dato il tracciato record crea la struttura HASH (sortFd) per l'accesso veloce +ai campi. +@(FD) + +@(ISV) +pos = indirizzo Hash. + +i = contatore. + +nf = variabile di lavoro. + +tmppos = indirizzo hash per l'accesso ai campi. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + word setrdes(r) + RecDes *r; /* descrittore record */ + + { + int pos, tmppos, nf, i; + + for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD; + if (r->NFields) + { + for (i = 0; i < r->NFields; i++) + { + nf = i; + pos = hashfun(r->Fd[nf].Name); + while (TRUE) + { + if (r->SortFd[pos] == INVFLD) + { + r->SortFd[pos] = (byte) nf; + break; + } + else + { + if (strcmp(r->Fd[r->SortFd[pos]].Name, r->Fd[nf].Name) <= 0) + { + pos++; + if (pos >= MaxFields) + pos = 0; + } + else + { + tmppos = r->SortFd[pos]; + r->SortFd[pos] = (byte) nf; + nf = tmppos; + } + } + } + } + r->Fd[0].RecOff = 1; + for (i = 1; i < r->NFields; i++) + r->Fd[i].RecOff = r->Fd[i - 1].RecOff + r->Fd[i - 1].Len; + return(r->Fd[r->NFields - 1].RecOff + r->Fd[r->NFields - 1].Len); + } + return(0); + } + +/* +@(SHF) Funzioni per la gestione dei campi dei record +@($) setdec FILES + +@(ID) +Data la stringa "s" (contenente un numero) Aggiusta il numero dei decimali in +base a "dec". +@(FD) + +@(ISV) +s1 = stringa di lavoro. + +i = contatore. + +l = lunghezza stringa s1. + +carry = eventuale riporto approssimazione. + +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void setdec(s,dec) + char *s; /* stringa che deve contenere un numero */ + int dec; /* numero di decimali che deve avere il numero */ + + { + char *s1; + int i, l, carry; + + if (LENGTH(s) == 0) strcpy(s, "0"); + if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; + s1 = strchr(s, '.'); + if ((dec) && (s1 == NULL)) + { + strcat(s, "."); + s1 = strchr(s, '.'); + } + else + if (!dec) + { + if (s1 == NULL) return ; + l = LENGTH(s1); /* occhio verificare */ + carry = (s1[1] >= '5'); + *s1 = '\0'; + while (carry) + { + s1--; + if (*s1 == '-') break; + if (*s1 == '9') + { + *s1 = '0'; + if (s == s1) break; + } + else + { + (*s1)++; + carry = FALSE; + } + } + if (carry) + { + for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; + s[(*s1 == '-')] = '1'; + } + return; + } + s1++; + l = LENGTH(s1); + if (l > dec) + { + carry = (s1[dec] >= '5'); + s1[dec] = '\0'; + while (carry) + { + dec--; + if (s1[dec] == '9') + { + s1[dec] = '0'; + if (!dec) break; + } + else + { + s1[dec]++; + carry = FALSE; + } + } + s1--; + while (carry) + { + s1--; + if (*s1 == '-') break; + if (*s1 == '9') + { + *s1 = '0'; + if (s == s1) break; + } + else + { + (*s1)++; + carry = FALSE; + } + } + if (carry) + { + for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1]; + s[(*s1 == '-')] = '1'; + } + } + else + while (l++ < dec) strcat(s1, "0"); + } + +/* +@($) hashfun FILES + +@(ID) +Data la stringa "s" costruisce la chiave Hash. +@(FD) + +@(ISV) +l = lunghezza della stringa "s". + +w[82] = copia di lavoro della stringa "s". + +temp = variabile di lavoro. + +pw = puntatore ai caratteri della stringa. + +Utilizza l'operatore OR Esclusivo. +@(FSV) + +@(IN) +Restituisce l'indirizzo HASH. +@(FN) +*/ + + int hashfun(s) + char *s; /* stringa da eleborare */ + + { + int l; + char w[82]; + unsigned short temp = 0, *pw = (unsigned short *) w; + + strcpy(w, s); + if (ODD(LENGTH(s))) strcat(w, " "); + l = LENGTH(s); + while ((char *) pw < w + l) + { + temp ^= *pw; + pw++; + } + l = (short) (temp % (MaxFields - 3)); + if (l < 0) l = -l; + return(l); + } + +/* +@($) findfld FILES + +@(ID) +Ricerca all'interno di un record il campo di nome "s". +@(FD) + +@(ISV) +i= variabile di lavoro. +startp = variabile di lavoro. +cmp = variabile di lavoro. +@(FSV) +*/ + + int findfld(recd,s) + RecDes *recd; /* Descrittore record Tracciato Record */ + char *s; /* stringa contenente il nome del campo */ + + { + int i, cmp, startp; + + i = hashfun(s); + startp = i; + if (recd->SortFd[i] == INVFLD) return(-1); + do + { + if (!(cmp = strcmp(recd->Fd[recd->SortFd[i]].Name, s))) + return((int) (recd->SortFd[i])); + else + if (cmp > 0) return(-1); + else + if (++i >= MaxFields) i = 0; + if (recd->SortFd[i] == INVFLD) return(-1); + } + while (i != startp) ; + return(-1); + } + +/* +@(#) CFieldSize FILES + +@(ID) +Restituisce la lunghezza del campo. +@(FD) + +@(ISV) +p = puntatore al campo. +@(FSV) +*/ + + unsigned int CFieldSize(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + + { + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len); + else return(0); + } + +/* +@(#) CFieldDec FILES + +@(ID) +Restituisce il numero di decimali presenti nel campo. +@(FD) + +@(ISV) +p = puntatore al campo. +@(FSV) +*/ + + unsigned int CFieldDec(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + + { + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec); + else return(0); + } + +/* +@(#) CFieldType FILES + +@(ID) +Restituisce un intero rappresentante il tipo del campo. +@(FD) + +@(ISV) +p = posizione all'interno del record del campo. +@(FSV) +*/ + + int CFieldType(fieldname,recd) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + + { + int p; + + if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].TypeF); + else return(NullF); + } + +/* +@($) getfrmt FILES + +@(ID) +Prepara il il formato per dsprintf per il campo "nf" del tracciato record "recd". +@(FD) + +@(ISV) +len = lunghezza del campo. + +dec = numero di decimali presenti nel campo. +@(FSV) +*/ + + void getfrmt(recd,nf,frm) + RecDes *recd; /* descrittore record */ + int nf; /* numero campo */ + char *frm; /* stringa in formato per dsprintf */ + + { + int len, dec; + + strcpy(frm, ""); + len = recd->Fd[nf].Len; + dec = recd->Fd[nf].Dec; + if (recd->Fd[nf].TypeF == IntF) sprintf(frm, "%%%dd", len); + else + if (recd->Fd[nf].TypeF == Int4F) sprintf(frm, "%%%dld", len); + else + if (recd->Fd[nf].TypeF == RealF) sprintf(frm, "%%%d.%dt",len, dec); + /*cambiare */ + else + if (recd->Fd[nf].TypeF == WordF) sprintf(frm, "%%%du", len); + else + if (recd->Fd[nf].TypeF == ZeroF) sprintf(frm, "%%0%dd", len); + else + if (recd->Fd[nf].TypeF == EZeroF) sprintf(frm, "%%0%dld", len); + } + +/* +@(#) CGetField FILES + +@(ID) +Estrae il valore di un campo dal record e lo pone in "fout". + +Restituisce un eventuale codice errore. +@(FD) + +@(ISV) +r = variabile che contiene l'eventuale codice errore. + +p = variabile per la chiamata di "findfld". + +s = puntatore alla zona di memoria allocata. + +frm= stringa per contenere un formato per la dsprintf. +@(FSV) + +@(IN) +Si osservi che "fout" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. +@(FN) +*/ + +#ifndef FOXPRO + + int CGetField(fieldname,recd,recin,fout) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + RecType recin; /* buffer contenente il record */ + void *fout; /* contenuto del campo in output */ + + { + int r,p; + char *s, frm[30], *wp = (char *) fout; + + s = malloc(256); + p = findfld(recd, fieldname); + getfrmt(recd, p, frm); + if ((r = CGetFieldBuff(fieldname, recd, recin, s)) != -1) + if (recd->Fd[p].TypeF == AlfaF) strcpy((char *) fout, s); + else + if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) + { + if (LENGTH(s)) *((int *) fout) = CCONVINT(s); + else *((int *) fout) = 0; + } + else + if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) + { + if (LENGTH(s)) *((long *) fout) = CONVLONG(s); + else *((long *) fout) = 0L; + } + else + if (recd->Fd[p].TypeF == RealF) atod((DEC *) fout, s); + else + if (recd->Fd[p].TypeF == DateF) *((TrDate *) fout) = cpackdata(s); + else + if (recd->Fd[p].TypeF == WordF) + { + if (LENGTH(s)) *((unsigned *) fout) = (unsigned)CONVLONG(s); + else *((unsigned *) fout) = 0; + } + else + if (recd->Fd[p].TypeF == CharF) + *wp = *s; + else + if (recd->Fd[p].TypeF == BoolF) + *((BOOLEAN *) fout) = (*s == 'X'); + free(s); + return(r); + } + +/* +@(#) CPutField FILES + +@(ID) +Scrive il contenuto della variabile puntata da "fin" nel campo "fieldname" del record. + +Restituisce un eventuale codice errore. +@(FD) + +@(ISV) +r = variabile che contiene l'eventuale codice errore. + +p = variabile per la chiamata di "findfld". + +s = puntatore alla zona di memoria allocata. + +frm= stringa per contenere un formato per la dsprintf. +@(FSV) + +@(IN) +Si osservi che "fin" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere. +@(FN) +*/ + + int CPutField(fieldname,recd,fin,recout) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + void *fin; /* puntatore al valore da scrivere */ + RecType recout; /* buffer contenetnte il record */ + + { + int p; + char s[256], frm[30]; + + strcpy(s, ""); + p = findfld(recd, fieldname); + getfrmt(recd, p, frm); + if (recd->Fd[p].TypeF == AlfaF) strcpy(s, (char *) fin); + else + if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF)) + sprintf(s, frm, *((int *) fin)); + else + if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF)) + sprintf(s, frm, *((long *) fin)) ; + else + if (recd->Fd[p].TypeF == RealF) dsprintf(s, frm, (DEC *) fin); + else + if (recd->Fd[p].TypeF == DateF) ceditdata(*((TrDate *) fin), s); + else + if (recd->Fd[p].TypeF == WordF) sprintf(s, frm, *((unsigned *) fin)) ; + else + if (recd->Fd[p].TypeF == CharF) + { + s[0] = *((char *) fin); + s[1] = '\0'; + } + else + if (recd->Fd[p].TypeF == BoolF) + { + s[0] = *((BOOLEAN*) fin) ? 'X' : ' '; + s[1] = '\0'; + } + return CPutFieldBuff(fieldname, recd, s, recout); + } + +#endif /* FOXPRO */ + +/* +@(#) CGetFieldBuff FILES + +@(ID) +Estrae il valore di un campo dal record e lo pone nella stringa "s". + +Restituisce un eventuale codice errore. +@(FD) + +@(ISV) +p = puntatore al campo. + +i = contatore. + +Off = offest in byte all'interno del record per il campo in oggetto. + +len = lunghezza campo. + +s1 = stringa di lavoro. + +d = data in formato stringa. +@(FSV) + +@(IN) +Utilizzato per il Data Entry. +@(FN) +*/ + + int CGetFieldBuff(fieldname,recd,recin,s) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + RecType recin; /* buffer contenente il record */ + char *s; /* stringa per l'output */ + + { + int p, i; + unsigned int off; + byte len; + char *s1; + TrDate d; + + if ((p = findfld(recd, fieldname)) != -1) + { + off = recd->Fd[p].RecOff; + len = recd->Fd[p].Len; + if ((recd->Fd[p].TypeF != AlfaF) && + (recd->Fd[p].TypeF != DateF) && + (recd->Fd[p].TypeF != ZeroF) && + (recd->Fd[p].TypeF != EZeroF)) + { + while ((recin[off] == ' ') && (len)) + { + off++; + len--; + } + if ((recd->Fd[p].TypeF != RealF) && (recd->Fd[p].TypeF != CharF)) + { + while ((recin[off] == '0') && (len)) + { + off++; + len--; + } + } + } + else + if ((recd->Fd[p].TypeF == ZeroF) || + (recd->Fd[p].TypeF == EZeroF)) + { + int i = 0, pos = 0; + while (i < len) + { + if (recin[off + i] != '0') break; + i++; + pos = i; + } + if (pos == len) + { + off += len; + len = 0; + } + } + if (len) + { + s1 = recin + off; + for (i = 0; i < len; i++) s[i] = s1[i]; + s[len] = '\0'; + while ((len) && (s[len - 1] == ' ')) s[--len] = '\0'; + } + else strcpy(s, ""); + if ((recd->Fd[p].TypeF == DateF)) + { + if (LENGTH(s)) d = atol(s); /* sscanf(s, "%ld", &d); */ + else d = 0 ; + ceditdata(d, s); + } + if ((recd->Fd[p].TypeF == RealF)) + if ((s1 = strchr(s, ',')) != NULL) *s1 = '.'; + return(0); + } + else + { + strcpy(s, ""); + return(-1); + } + } + +/* +@(#) CPutFieldBuff FILES + +@(ID) +Scrive il contenuto della stringa "s" nel campo "fieldname" del record. + +Restituisce un eventuale codice errore. +@(FD) + +@(ISV) +p = puntatore al campo. + +i = contatore. + +l = variabile di lavoro. + +off = offest in byte all'interno del record per il campo in oggetto. + +len = lunghezza campo. + +s1,s2 = stringa di lavoro. + +d = data in formato stringa. +@(FSV) + +@(IN) +Utilizzato per il Data Entry +@(FN) +*/ + + int CPutFieldBuff(fieldname,recd,s,recout) + char *fieldname; /* nome del campo */ + RecDes *recd; /* descrittore record */ + char *s; /* stringa contenente il valore da scrivere nel campo */ + RecType recout; /* buffer contenente il record */ + + { + int p, off, len, l, i; + char *s1; + char *s2; + TrDate d; + + s2 = malloc(256); + strcpy(s2, s); + if ((p = findfld(recd, fieldname)) != -1) + { + off = recd->Fd[p].RecOff; + len = recd->Fd[p].Len; + if (recd->Fd[p].TypeF == DateF) + { + d = cpackdata(s2); + sprintf(s2,"%06ld", d); + } + if (recd->Fd[p].TypeF == RealF) setdec(s2, recd->Fd[p].Dec); + l = LENGTH(s2); + if (l > len) + { + free(s2); + return(-1); + } + s1 = recout + off ; + for (i = 0; i < l ; i++) s1[i] = s2[i] ; + if ((recd->Fd[p].TypeF == IntF) || + (recd->Fd[p].TypeF == Int4F) || + (recd->Fd[p].TypeF == WordF) || + (recd->Fd[p].TypeF == RealF) || + (recd->Fd[p].TypeF == ZeroF) || + (recd->Fd[p].TypeF == EZeroF)) + { + char c; + if ((recd->Fd[p].TypeF == ZeroF) || + (recd->Fd[p].TypeF == EZeroF)) + c = '0'; + else c = ' '; + if (l == 0) s1[l++] = '0'; + while (l < len) + { + for (i = l; i > 0; i--) s1[i] = s1[i - 1]; + s1[0] = c; + l++; + } + } + else + while (l < len) s1[l++] = ' '; + free(s2); + return(0); + } + else + { + strcpy(s, ""); + free(s2); + return(-1); + } + } + + +/* +@(#) CZeroField FILES + +@(ID) +Azzera un campo. +@(FD) + +@(ISV) +p = puntatore al campo. + +s = stringa messaggio. +@(FSV) +*/ + + int CZeroField(fieldname,recd,recout) + char *fieldname; /* nonme del campo */ + RecDes *recd; /* descrittore record */ + RecType recout; /* buffer contenente il record */ + + { + int p; + + if ((p = findfld(recd, fieldname)) != -1) + { + if (recd->Fd[p].TypeF == DateF) + memset(recout + recd->Fd[p].RecOff, '0', recd->Fd[p].Len); + else + { + memset(recout + recd->Fd[p].RecOff, Blank, recd->Fd[p].Len); + if ((recd->Fd[p].TypeF == IntF) || + (recd->Fd[p].TypeF == Int4F) || + (recd->Fd[p].TypeF == WordF)) + { + *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; + } + else + if (recd->Fd[p].TypeF == RealF) + { + if (recd->Fd[p].Dec) + { + memset(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - + recd->Fd[p].Dec - 2, '0', recd->Fd[p].Dec + 2); + *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - + recd->Fd[p].Dec - 1) = '.'; + } + else *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0'; + } + return(NoErr); + } + } + else return(-1); + return(NoErr); + } + +/* +@(#) CZeroRec FILES + +@(ID) +Azzera tutto il record. +@(FD) + +@(ISV) +i = contatore. + +junk = variabile spazzatura per la chiamata di CZeroField. +@(FSV) +*/ + + void CZeroRec(recd,recout) + RecDes *recd; /* descrittore record */ + RecType recout; /* buffer contenente il record */ + + { + int i, junk; + + IRecallRec(recout) ; + for (i = 0; i < recd->NFields; i++) junk = CZeroField(recd->Fd[i].Name, + recd, recout); + } + +/* +@($) CBuildKey FILES + +@(ID) +Costruisce la chiave corrispondente al numero chiave. +@(FD) + +@(ISV) +i = contatore. + +nf = numero campi che compongono la chiave. + +len = lunghezza del campo. + +off = offest in byte all'interno del record per il campo in oggetto. + +l = variabile di lavoro. + +up = variabile di lavoro per rendere maiuscola la stringa. + +wd = variabile per la data. + +s1 = stringa di lavoro. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + int CBuildKey(recd,numkey,recin,key) + RecDes *recd; /* descrittore record */ + int numkey; /* numero chiave */ + RecType recin; /* buffer contenente il record */ + char *key; /* valore della chiave */ + + { + int i, nf, l = 0, len, off; + TrDate wd ; + char s1[10]; + BOOLEAN upp = FALSE; + + strcpy(key, ""); + if (numkey-- <= recd->NKeys) + { + for (i = 0; i < recd->Ky[numkey].NkFields; i++) + { + if ((upp = (recd->Ky[numkey].FieldSeq[i] > MaxFields)) == TRUE) + nf = recd->Ky[numkey].FieldSeq[i] - MaxFields; + else + nf = recd->Ky[numkey].FieldSeq[i]; + if (recd->Ky[numkey].FromCh[i] == INVFLD) + { + off = recd->Fd[nf].RecOff; + len = recd->Fd[nf].Len; + } + else + { + if (recd->Fd[nf].TypeF == DateF) + { + off = recd->Fd[nf].RecOff; + len = recd->Fd[nf].Len; + strncpy(s1, (recin + off), len); + s1[len] = '\0'; + wd = 0; + for(len = 0; len < LENGTH(s1); len++) + if (isdigit(s1[len])) wd = (wd * 10) + (s1[len] - '0'); + ceditdata(wd, s1); + s1[2] = s1[3]; + s1[3] = s1[4]; + s1[4] = s1[6]; + s1[5] = s1[7]; + s1[6] = '\0'; + off = recd->Ky[numkey].FromCh[i]; + len = recd->Ky[numkey].ToCh[i] - + recd->Ky[numkey].FromCh[i] + 1; + } + else + { + off = recd->Fd[nf].RecOff + recd->Ky[numkey].FromCh[i]; + len = recd->Ky[numkey].ToCh[i] - + recd->Ky[numkey].FromCh[i] + 1; + } + } + if ((l + len) > 80) + { + strcpy(key, ""); + return(BTrKeyLenErr); + } + if ((recd->Fd[nf].TypeF == DateF) && (recd->Ky[numkey].FromCh[i] != INVFLD)) + strncpy((key + l), &s1[off], len); + else + { + strncpy((key + l), (recin + off), len); + if (recin[off] == '\0') memset(key + l, ' ', len); + else + if ((recd->Fd[nf].TypeF == IntF) || + (recd->Fd[nf].TypeF == Int4F) || + (recd->Fd[nf].TypeF == WordF)) + { + int w = l, j = l + len; + while (w < j && key[w] == ' ') w++; + while (w < j && key[w] == '0') + key[w++] = ' '; + } + } + l += len; + } + key[l] = '\0'; + crtrim(key); + if (upp) CUpString(key) ; + return(NoErr); + } + return(BTrPathErr); + } + +/* +@($) CCalcLenKey FILES + +@(ID) +Ritorna la lunghezza della chiave. +@(FD) + +@(ISV) +nf = numero campi chiave. + +i = contatore. + +l = variabile di lavoro. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + int CCalcLenKey(recd,numkey) + RecDes *recd; /* descrittore record */ + int numkey; /* numero della chiave */ + + { + register int l = 0, i, nf; + + if (numkey-- <= recd->NKeys) + { + for (i = 0; i < recd->Ky[numkey].NkFields; i++) + { + if (recd->Ky[numkey].FieldSeq[i] > MaxFields) + nf = (int) recd->Ky[numkey].FieldSeq[i] - MaxFields; + else + nf = (int) recd->Ky[numkey].FieldSeq[i]; + if (recd->Ky[numkey].FromCh[i] == INVFLD) l += (int) recd->Fd[nf].Len; + else l += (int) (recd->Ky[numkey].ToCh[i] - recd->Ky[numkey].FromCh[i] + 1); + } + return(l); + } + return(-1); + } + +/* +@($) prefname FILES + +@(ID) +Restituisce il nome del file che contiene il prefisso corrente. +@(FD) + +@(ISV) +s,s1 = stringhe di lavoro. + +Versione DOS e XENIX. +@(FSV) +*/ + char *prefname() + + { + static PathSt s; +#ifdef DOS + char *s1 = getenv("PREFPATH"); + if (s1 == NULL) s1 = "prefix.txt"; + strcpy(s, s1); +#else + sprintf(s, "prefix.%-d", getuid()); +#endif + return(s) ; + } + +/* +@(#) CGetPref FILES + +@(ID) +Legge dal file prefisso il prefisso dati corrente. +@(FD) + +@(ISV) +f = puntatore al file. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + char *CGetPref() + + { + const char* p = prefname(); + FILE *f = fopen(p, "r"); + + if (f == NULL) + { + strcpy(cprefix, ""); + } + else + { + if (fgets(cprefix, 42, f) != NULL) + { + const int len = LENGTH(cprefix)-1; + if (len >= 0 && cprefix[len] <= ' ') cprefix[len] = '\0'; + } + else + *cprefix = '\0'; + fclose(f); + } + if (!pathpread) + { + const char* p = "pathpref.ini"; + FILE* f = fopen(p, "r"); + pathpread = TRUE; + if (f != NULL) + { + if (fgets(__ptprf, 42, f) != NULL) + { + const int len = LENGTH(__ptprf)-1; + if (len >= 0 && __ptprf[len] <= ' ') + { + __ptprf[len] = '\0'; + if (len > 0) strcat(__ptprf, "/"); + } + } + else + *__ptprf = '\0'; + fclose(f); + } + } + if (*__ptprf) + { + char ws[200]; + sprintf(ws, "%s%s", __ptprf, cprefix); + strcpy(cprefix, ws); + } + return(cprefix); + } + +/* +@($) CPutPref FILES + +@(ID) +Aggiorna sul file prefisso il prefisso dati corrente. +@(FD) + +@(ISV) +f = puntatore a file. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + void CPutPref(pref) + char *pref; /* stringa contenente il nuovo prefisso */ + + { + FILE *f; + const int l = strlen(__ptprf); + + if (l && strncmp(pref, __ptprf, l) == 0) pref += l; + if ((f = fopen(prefname(), "w")) == NULL) + fatal_box("Put prefix. Error number : %d ", errno); + fprintf(f, "%s\n", pref); + fclose(f); + } + +/* +@($) CAddPref FILES + +@(ID) +Cerca il carattere "$" nel nome file e lo sostituisce con il prefisso corrente. +@(FD) + +@(ISV) +s = stringa che contiene il nome. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + char *CAddPref(name) + char *name; /* nome file */ + + { + static PathSt s; + + if (*name == '$') + { + name++; + return(CInsPref(name, NORDIR)) ; + } + else + if (*name == '%') + { + name++; + return(CInsPref(name, COMDIR)) ; + } + else + { + strcpy(s, name); + return(s); + } + } + +/* +@($) CInsPref FILES + +@(ID) +Aggiunge (a sinistra) il prefisso corrente. +@(FD) + +@(ISV) +s = stringa di lavoro. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. +@(FN) +*/ + + char *CInsPref(name,dirflg) + char *name; /* nome del file cui aggiungere il prefisso */ + int dirflg; /* flag per file comuni */ + + { + static PathSt s; + + if (dirflg == NORDIR) + { + if (LENGTH(cprefix) == 0) sprintf(s,"%s", name); + else sprintf(s,"%s%c%s",cprefix, DIRSEP, name); + } + else sprintf(s,"%scom%c%s", __ptprf, DIRSEP, name); + return(s); + } + +/* +@(#) CGetIdxName FILES + +@(ID) +Dato un nome file costruisce il nome del file indice corrispondente. +@(FD) + +@(ISV) +fdst,s1,s2 = stringhe di lavoro. +@(FSV) + +@(IN) +NON UTILIZZARE !!. + +Se si utilizza spiegarne dettagliatamente il motivo. + +L' estensione dei file indice e' ndx; e' quindi vietato utilizzare un nome +di file che abbia tale estensione. L' estensione dei file dati e' dta. +@(FN) +*/ + + char *CGetIdxName(s) + char *s; /* stringa contenente il nome file */ + + { + static PathSt fdst; + char *s1, *s2; + + strcpy(fdst, s) ; + s1 = strrchr(fdst,DIRSEP) ; + if (s1 == NULL) s1 = fdst; + s2 = strchr(s1,'.') ; + if (s2 != NULL) s2[0] = '\0' ; + s1 = strcat(fdst, ".ndx") ; + return(fdst) ; + } diff --git a/include/cisam.c b/include/cisam.c index 0e7b67559..cd911966d 100755 --- a/include/cisam.c +++ b/include/cisam.c @@ -672,7 +672,7 @@ wrec = buffer di lavoro. if (isfd->ln > 0) { COpenDir (ManuLock, isfd->ft); - COpenFile(isfd->ln,isfd->d, Lock, isfd->ft); + COpenFile(isfd->ln,isfd->d, NoLock, isfd->ft); } if (isfd->d->EOD == isfd->d->EOX) { @@ -704,10 +704,7 @@ wrec = buffer di lavoro. else { if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, UnLock, isfd->ft); CCloseDir(isfd->ft); - } isfd->RecNo = 0; if (DEADLOCK(*err)) *err = IsDeadLock; return((*err ? *err : (*err = IsFileFull))); @@ -727,14 +724,15 @@ wrec = buffer di lavoro. { *err = IsReInsert; if (isfd->ln > 0) - { - COpenFile(isfd->ln,isfd->d, UnLock, isfd->ft); 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) { @@ -748,11 +746,15 @@ wrec = buffer di lavoro. isfd->RecNo = 0; junk = delkeys(isfd, record, knum, &werr); } - else +/* else if (isfd->ln > 0) - CCloseFile(isfd->ln,isfd->d, isfd->ft) ; + 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) ; } diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 37363d2a2..b23f02490 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -116,10 +116,6 @@ void TSpreadsheet::init() xi_init(); xi_set_pref(XI_PREF_3D_LOOK, TRUE); - // xi_set_pref(XI_PREF_COLOR_LIGHT, COLOR_CYAN); - // xi_set_pref(XI_PREF_COLOR_CTRL, MASK_BACK_COLOR); - // xi_set_pref(XI_PREF_COLOR_DARK, COLOR_GRAY); - first = FALSE; } @@ -222,7 +218,7 @@ TSpreadsheet::TSpreadsheet(short x, short y, short dx, short dy, listdef->v.list->width = rct.right-rct.left; listdef->v.list->min_cell_height = CHARY; listdef->v.list->min_heading_height = CHARY; - listdef->v.list->white_space_color = COLOR_GRAY; + listdef->v.list->white_space_color = MASK_DARK_COLOR; XI_OBJ_DEF* coldef = xi_add_column_def(listdef, 0, XI_ATR_RJUST, 0, NUMBER_WIDTH, NUMBER_WIDTH, ""); @@ -514,7 +510,7 @@ break; xiev->v.cell_request.button_on_focus = TRUE; } if (cell_disabled(rec, col)) - xiev->v.cell_request.back_color = MASK_BACK_COLOR; + xiev->v.cell_request.back_color = DISABLED_BACK_COLOR; } } } else src = format("%d", rec+1); diff --git a/include/sheet.cpp b/include/sheet.cpp index d6090acc1..2b65dd0fa 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -753,7 +753,7 @@ void TBrowse_sheet::repos_buttons() const int left = CHARX; // left coord of next control to draw - for (int i = 0; i < 1; i++) + for (int i = 0; i < 2; i++) { const short id = i ? DLG_EDIT : DLG_FINDREC; const WINDOW w = get_ctl_window(win(), id);