289 lines
7.5 KiB
C
289 lines
7.5 KiB
C
// CLOCK.C - set read and write locks in the cookie file
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
#include "messages.h"
|
|
EnableAssert
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Name: cookie_free
|
|
* Purpose: free any and ALL locks for current locker
|
|
* Assumes:
|
|
* Returns: OP_OK for success, or OP_SYSERR
|
|
* NOTE: This may be called during aborting, so shouldn't call FatalError
|
|
*/
|
|
int cookie_free(F fAutotype)
|
|
{
|
|
char *Cookiebuf;
|
|
char *NewCookiebuf;
|
|
int hfCookieFile, bufbytes;
|
|
int Totread = 0;
|
|
int TotLocks = 0;
|
|
USHORT Rcount, Wcount, RBcount;
|
|
char *tp;
|
|
char *cp;
|
|
char Lname[CMAXNAME];
|
|
char Llock[CMAXLOCK];
|
|
char Lcomm[CMAXDATE*2];
|
|
int wMon, wDay, wHour, wMin;
|
|
int cbLockName = strlen(szLockName);
|
|
int cbWrite, cbWritten;
|
|
char *pbWrite;
|
|
|
|
// set all lock counts to zero, free at most one of each lock type
|
|
|
|
Rcount = Wcount = RBcount = 0;
|
|
|
|
if ((hfCookieFile = open_cookie()) == -1)
|
|
{
|
|
Error(szCookieOpen, pszCookieFile, SzForEn(_doserrno));
|
|
return (OP_SYSERR);
|
|
}
|
|
|
|
Cookiebuf = malloc(cbCookieMax);
|
|
|
|
if ((char *)NULL == Cookiebuf)
|
|
{
|
|
_close(hfCookieFile);
|
|
Error(szOutOfMem);
|
|
return (OP_SYSERR);
|
|
}
|
|
|
|
NewCookiebuf = malloc(cbCookieMax);
|
|
|
|
if ((char *)NULL == NewCookiebuf)
|
|
{
|
|
free(Cookiebuf);
|
|
_close(hfCookieFile);
|
|
Error(szOutOfMem);
|
|
return (OP_SYSERR);
|
|
}
|
|
|
|
Cookiebuf[0] = '\0';
|
|
NewCookiebuf[0] = '\0';
|
|
|
|
while ((bufbytes=_read(hfCookieFile, NewCookiebuf, cbCookieMax)) > 0)
|
|
{
|
|
Totread += bufbytes;
|
|
if (Totread >= cbCookieMax)
|
|
{
|
|
FatalError(szCookieTooBig, pszCookieFile);
|
|
_close(hfCookieFile);
|
|
free(Cookiebuf);
|
|
free(NewCookiebuf);
|
|
return (OP_SYSERR);
|
|
}
|
|
NewCookiebuf[bufbytes] = '\0';
|
|
strcat(Cookiebuf, NewCookiebuf);
|
|
}
|
|
cp = Cookiebuf;
|
|
tp = NewCookiebuf;
|
|
|
|
while (*cp != '\0')
|
|
{
|
|
if ((strncmp(cp, szLockName, cbLockName) == 0) &&
|
|
*(cp + cbLockName) == ' ')
|
|
{
|
|
if (sscanf(cp,"%s %s %d/%d @ %d:%d %s", Lname, Llock,
|
|
&wMon, &wDay, &wHour, &wMin, Lcomm) != 7)
|
|
{
|
|
Error(szCookieCorrupt, pszCookieFile);
|
|
_close(hfCookieFile);
|
|
free(Cookiebuf);
|
|
free(NewCookiebuf);
|
|
return (OP_SYSERR);
|
|
}
|
|
if (strcmp(Llock, "READ")==0)
|
|
{
|
|
if (fAutotype)
|
|
{
|
|
if (strncmp(Lcomm, "autolock", 8) != 0 ||
|
|
wLockMin != wMin || wLockHour != wHour ||
|
|
wLockDay != wDay || wLockMon != wMon)
|
|
goto passlock;
|
|
}
|
|
if (++Rcount > 1)
|
|
goto passlock;
|
|
}
|
|
else if (strcmp(Llock, "WRITE")==0)
|
|
{
|
|
if (++Wcount > 1)
|
|
goto passlock;
|
|
}
|
|
else if (strcmp(Llock, "READ-BLOCK")==0)
|
|
{
|
|
if (fAutotype)
|
|
goto passlock;
|
|
if (++RBcount > 1)
|
|
goto passlock;
|
|
}
|
|
|
|
while (*cp++ != '\n')
|
|
; // increment past current line
|
|
*(cp-1) = '\0';
|
|
if (fVerbose)
|
|
PrErr("lock released.\n");
|
|
TotLocks++;
|
|
}
|
|
else
|
|
{
|
|
passlock: /* do not free this lock, just move into next buffer and loop */
|
|
while ((*tp++ = *cp++) != '\n')
|
|
;
|
|
}
|
|
}
|
|
|
|
*tp = '\0';
|
|
|
|
free(Cookiebuf); /* only the new buffer needed now */
|
|
|
|
if (_chsize(hfCookieFile, 0) != 0)
|
|
{
|
|
Error(szCookieTrunc, pszCookieFile, SzForEn(errno));
|
|
_close(hfCookieFile);
|
|
free(NewCookiebuf);
|
|
return (OP_SYSERR);
|
|
}
|
|
|
|
if (_lseek(hfCookieFile, 0, SEEK_SET) == -1)
|
|
{
|
|
Error(szCookieSeek, pszCookieFile, SzForEn(errno));
|
|
_close(hfCookieFile);
|
|
free(NewCookiebuf);
|
|
return (OP_SYSERR);
|
|
}
|
|
|
|
cbWrite = strlen(NewCookiebuf);
|
|
pbWrite = NewCookiebuf;
|
|
while (cbWrite)
|
|
{
|
|
cbWritten = _write(hfCookieFile, pbWrite, cbWrite);
|
|
if (-1 == cbWritten || 0 == cbWritten)
|
|
{
|
|
if (WRetryError(eoWrite, "writing", 0, pszCookieFile) != 0)
|
|
continue;
|
|
else
|
|
{
|
|
_close(hfCookieFile);
|
|
free(NewCookiebuf);
|
|
return (OP_SYSERR);
|
|
}
|
|
}
|
|
ClearPreviousError();
|
|
cbWrite -= cbWritten;
|
|
pbWrite += cbWritten;
|
|
}
|
|
|
|
free(NewCookiebuf);
|
|
_close(hfCookieFile);
|
|
if (TotLocks == 0)
|
|
{
|
|
if (fAutotype)
|
|
Error("not found; lock file may have been corrupted\n");
|
|
else
|
|
PrErr("no locks.\n");
|
|
}
|
|
return (OP_OK);
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
//
|
|
// cookie_lock_RB
|
|
//
|
|
// obtain a read-block lock for given workstation name
|
|
//
|
|
//============================================================================
|
|
int cookie_lock_RB(AD *pad, char *szComment)
|
|
{
|
|
char *TargBuf;
|
|
int lock_res;
|
|
|
|
TargBuf = malloc(LINE_LEN);
|
|
if ((char *)NULL == TargBuf)
|
|
FatalError(szOutOfMem);
|
|
|
|
LockFill(pad, TargBuf, RB_LOCK);
|
|
|
|
strcat(TargBuf, szComment);
|
|
strcat(TargBuf, "\r\n");
|
|
lock_res = add_cookie_lock(pad, TargBuf, RB_LOCK, fFalse);
|
|
free(TargBuf);
|
|
if (lock_res != OP_OK)
|
|
{
|
|
Error("Read lock DENIED\n");
|
|
return (lock_res);
|
|
}
|
|
|
|
if (fVerbose)
|
|
PrErr(szCookieGrant, "Read", szLockName);
|
|
return (OP_OK);
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
//
|
|
// cookie_lock_read
|
|
//
|
|
// obtain a read lock for given workstation name
|
|
//
|
|
//============================================================================
|
|
int cookie_lock_read(AD *pad, char *szComment, int fAutotype)
|
|
{
|
|
char *TargBuf;
|
|
int lock_res;
|
|
|
|
TargBuf = malloc(LINE_LEN);
|
|
if ((char *)NULL == TargBuf)
|
|
FatalError(szOutOfMem);
|
|
LockFill(pad, TargBuf, READ_LOCK);
|
|
|
|
strcat(TargBuf, szComment);
|
|
strcat(TargBuf, "\r\n");
|
|
lock_res = add_cookie_lock(pad, TargBuf, READ_LOCK, fAutotype);
|
|
free(TargBuf);
|
|
if (lock_res != OP_OK)
|
|
{
|
|
Error("Read lock DENIED\n");
|
|
return (lock_res);
|
|
}
|
|
|
|
if (fVerbose)
|
|
PrErr(szCookieGrant, "Read", szLockName);
|
|
return (OP_OK);
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
//
|
|
// cookie_lock_write
|
|
//
|
|
// obtain a write lock for current project
|
|
//
|
|
//============================================================================
|
|
int cookie_lock_write(AD *pad, char *szComment, F fAutotype)
|
|
{
|
|
char *TargBuf;
|
|
int lock_res;
|
|
|
|
TargBuf = malloc(LINE_LEN);
|
|
if ((char *)NULL == TargBuf)
|
|
FatalError(szOutOfMem);
|
|
|
|
LockFill(pad, TargBuf, WRITE_LOCK);
|
|
|
|
strcat(TargBuf, szComment);
|
|
strcat(TargBuf, "\r\n");
|
|
lock_res = add_cookie_lock(pad, TargBuf, WRITE_LOCK, fAutotype);
|
|
free(TargBuf);
|
|
if (lock_res != OP_OK)
|
|
{
|
|
Error("Write lock DENIED\n");
|
|
return (lock_res);
|
|
}
|
|
|
|
if (fVerbose)
|
|
PrErr(szCookieGrant, "Write", szLockName);
|
|
return (OP_OK);
|
|
}
|