923 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			923 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
| @(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	<sys/types.h>
 | |
| #endif
 | |
| #include	<sys/stat.h>
 | |
| #ifndef DOS
 | |
| #include <sys/ipc.h>
 | |
| #include <sys/sem.h>
 | |
| #include <unistd.h>
 | |
| #else
 | |
| #include <io.h>
 | |
| #include <share.h>
 | |
| #include <sys/locking.h>           
 | |
| #include <dos.h>
 | |
| #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);
 | |
| 	}
 |