home *** CD-ROM | disk | FTP | other *** search
- /*
- * c-tree Server System Independent Code
- *
- * This program is the CONFIDENTIAL and PROPRIETARY property
- * of FairCom(R) Corporation. Any unauthorized use, reproduction or
- * transfer of this program is strictly prohibited.
- *
- * Copyright (c) 1987, 1988, 1989 FairCom Corporation
- * (Subject to limited distribution and
- * restricted disclosure only.)
- * *** ALL RIGHTS RESERVED ***
- *
- * 4006 West Broadway
- * Columbia, MO 65203
- *
- *
- * c-tree(R) Version 4.3
- * Release C
- * February 7, 1989 17:30
- *
- */
-
- #include "ctstdr.h"
- #include "ctoptn.h"
- #include "ctstrc.h"
- #include "ctvrec.h"
- #include "cterrc.h"
- #include "ctcomm.h"
- #include "ctdecl.h"
-
- /*
- * Define CHECK_LOCK if you wish the server to make sure no conflicting
- * lock is held during data file updates.
- *
- * Define MUST_LOCK if you wish the server to make sure that the user
- * issuing a data file update holds a write-lock.
- *
- * Otherwise, the server assumes that the application programs are well
- * behaved; i.e., they have acquired necessary locks.
- *
- #define CHECK_LOCK or #define MUST_LOCK
- *
- * If either of the options are defined, then a lock conflict or missing lock
- * results in an error 57 (DADV_ERR) on writes, rewrites or deletes.
- */
-
- #define cts_nodsec srvprm.spns
- #define cts_buffer srvprm.spbf
- #define cts_maxsmsg srvprm.spsz
- #define cts_maxlok srvprm.splk
- #define cts_keyops srvprm.spky
- #define rqsts cts_stat.srqsts
- #define redo cts_stat.sredo
- #define sets cts_stat.ssets
- #define waks cts_stat.swaks
- #define uwaks cts_stat.suwaks
- #define retry cts_stat.sretry
-
- MESSAGE *rmsg;
- LONG *usrtim;
- SRVPRM srvprm;
-
- COUNT cur_usrid;
- MESSAGE omsg;
- UCOUNT srvsiz;
- KEYOPS *cts_kops;
- TEXT *srvmsg,*srvdat;
- COUNT cts_mxusr = CTS_MAXUSR;
- COUNT cts_mxfil = CTS_MAXFIL;
- SSTATUS cts_stat = {0};
- LOCAL LONG ffrq[MAX_FUNC] = {0};
- LOCAL MESSAGE imsg,*umsg;
- LOCAL UCOUNT *ausrsiz;
- LOCAL UCOUNT *akopsiz,cts_zkop;
- LOCAL COUNT **afilmap;
- LOCAL USRCON *ausrcon;
- LOCAL COUNT *ausrmap;
- LOCAL LONG *ausrtrn;
-
-
- TEXT *getmid(),*mballc();
- LONG getumsg();
- COUNT getctf(),norspn(),dedusr();
- #ifdef VARLDATA
- COUNT getvhdr(),putvhdr();
- #endif
-
- CTFILE *tstfnm();
- LONG time();
-
- extern CTFILE *ct_key;
- extern COUNT uerr_cod,avlfil,ct_mxfil;
- extern RECLOK *ct_loklst,*ct_frelst;
- extern LONG ct_gsrl;
-
- /* DO NOT MODIFY THESE #defines. Your locking protocol is specified above */
- #ifdef LOCK_TEST
- #undef LOCK_TEST
- #endif
- #ifdef CHECK_LOCK
- #define LOCK_TEST CHK_LOCK
- #endif
- #ifdef MUST_LOCK
- #define LOCK_TEST MST_LOCK
- #endif
- #ifdef LOCK_TEST
- COUNT cts_lok();
- #endif
-
- LOCAL VOID setsrlpos(msgp)
- MESSAGE *msgp;
- {
- cpybuf(&msgp->mfiln,&ct_gsrl,sizeof(ct_gsrl));
- }
-
- LOCAL UCOUNT min(a,b)
- UCOUNT a,b;
- {
- if (b < a)
- return(b);
- else
- return(a);
- }
-
- COUNT chkopn(fn)
- PFAST TEXT *fn;
- {
- FAST CTFILE *ctnum;
-
- for (ctnum = ct_key; ctnum < ct_key + ct_mxfil; ctnum++)
- if ((ctnum->chnacs == 'y' || ctnum->chnacs == 'v') &&
- #ifdef CT_ANSI
- ctnum->fd != (RNDFILE) NULL &&
- #else
- ctnum->fd >= 0 &&
- #endif
- strcmp(fn,ctnum->flname) == 0)
- return(ctnum->filnum);
- return(-1);
- }
-
- LOCAL trycls(usrn,filno)
- COUNT usrn,filno;
- {
- FAST CTFILE *ctnum;
- FAST RECLOK *cp;
- RECLOK *np;
- COUNT temp,afil;
-
- VOID pshlst();
-
- afil = afilmap[usrn][filno];
- if ((ctnum = tstfnm(afil)) == NULL)
- return;
- afilmap[usrn][filno] = -1;
- if (ctnum->kmem > 0) /* a member is not closed directly */
- return;
- for (temp = ctnum->nmem + filno; temp > filno; temp--)
- afilmap[usrn][temp] = -1;
-
- if (--ctnum->usrcnt > 0) {
- cp = ctnum->rlokh;
- while (cp != NULL) {
- np = cp->rllink;
- if (cp->rlusrn == usrn)
- pshlst(cp,ctnum);
- cp = np;
- }
- } else {
- if (ctnum->rlokt != NULL) {
- ctnum->rlokt->rllink = ct_frelst;
- ct_frelst = ctnum->rlokh;
- ctnum->rlokh = ctnum->rlokt = NULL;
- }
- temp = ctnum->nmem + 1;
- CLSFIL(afil,0);
- avlfil += temp;
- }
- }
-
- LOCAL COUNT chkcon(usrn,filno,segop)
- COUNT usrn,filno,segop;
- {
- FAST USRCON *u;
- COUNT blocker;
-
- for (u = ausrcon; u < ausrcon + cts_mxusr; u++)
- if (u->ucfiln == filno && u->ucsgop == segop) {
- if (segop == CTXTND || (segop != CTXTND &&
- imsg.mpntr >= u->ucbpos && imsg.mpntr < u->ucepos)) {
- blocker = (COUNT) (u - ausrcon);
- #ifndef CTS_CPLD
- (ausrcon + usrn)->ucslep = blocker;
- #endif
- if (usrn == blocker) terr(979);
- return(blocker);
- }
- }
-
- return(-2);
- }
-
- LOCAL COUNT wakcon(usrn,filno,segop)
- COUNT usrn,filno,segop;
- {
- FAST USRCON *u;
- COUNT awake;
- FAST CTFILE *ctnum;
- TEXT *usrmsg;
-
- ctnum = ct_key + filno;
- u = ausrcon + usrn;
- usrmsg = u->ucmsgp;
-
- if (u->ucsgop == segop) {
- waks++;
- u->ucsgop = CTNONE;
- if (segop == CTREAD) {
- if (--ctnum->ucred < 0)
- terr(978);
- } else if (segop == CTWRITE) {
- if (--ctnum->ucwrt < 0)
- terr(977);
- } else if (segop == CTXTND) {
- if (ctnum->ucext != YES)
- terr(976);
- else
- ctnum->ucext = NO;
- } else
- terr(974);
-
- #ifndef CTS_CPLD
- for (u = ausrcon; u < ausrcon + cts_mxusr; u++)
- if (u->ucslep == usrn) {
- awake = (COUNT) (u - ausrcon);
- u->ucslep = -2;
- uwaks++;
- ctrspn(usrmsg,umsg + awake,
- sizeof(MESSAGE),awake);
- }
- #endif
- }
- return(NO_ERROR);
- }
-
- LOCAL COUNT setcon(usrn,filno,segop,len,msgptr)
- COUNT usrn,filno,segop;
- UCOUNT len;
- TEXT *msgptr;
- {
- FAST USRCON *u;
- FAST CTFILE *ctnum;
-
- ctnum = ct_key + filno;
- u = ausrcon + usrn;
- u->ucfiln = filno;
-
- if (u->ucsgop == segop)
- return(NO_ERROR);
- else if (u->ucsgop != CTNONE)
- terr(970);
- u->ucsgop = segop;
- u->ucmsgp = msgptr;
- sets++;
-
- if (segop == CTREAD)
- ctnum->ucred++;
- else if (segop == CTWRITE)
- ctnum->ucwrt++;
- else if (segop == CTXTND) {
- ctnum->ucext = YES;
- return(NO_ERROR);
- } else
- terr(975);
-
- u->ucbpos = imsg.mpntr;
- u->ucepos = imsg.mpntr + len;
-
- return(NO_ERROR);
- }
-
- VOID stpusr(usrn)
- COUNT usrn;
- {
- FAST COUNT i;
- FAST USRCON *u;
-
- if (usrn >= 0 && usrn < cts_mxusr && ausrmap[usrn] != NO) {
- if (ausrtrn[usrn])
- transact(ABRTRAN,usrn,ausrtrn);
- (u = ausrcon + usrn)->ucslep = -2;
- if (u->ucsgop != CTNONE)
- wakcon(usrn,u->ucfiln,u->ucsgop);
- u->ucsgop = CTNONE;
- for (i = 0; i < cts_mxfil; i++)
- if (afilmap[usrn][i] > -1) {
- trycls(usrn,i);
- }
- ausrmap[usrn] = NO;
- }
- }
-
- #ifdef CTS_ISAM
- LOCAL COUNT MLTKEY(usrn,nops,tp)
- COUNT usrn,nops;
- PFAST TEXT *tp;
- {
- FAST KEYOPS *k;
- COUNT i,keyno;
-
- for (i = 1, k = cts_kops; i++ <= nops; k++, tp += cts_zkop) {
- cpybuf(k,tp,cts_zkop);
- keyno = afilmap[usrn][k->kokeyn];
- if ((ct_key + keyno)->ucext && k->komode == FN_ADDKEY &&
- chkcon(usrn,keyno,CTXTND) > -1)
- return(-1);
- }
-
- for (i = 1, k = cts_kops; i <= nops; i++, k++) {
- keyno = afilmap[usrn][k->kokeyn];
- if (k->komode == FN_ADDKEY && ADDKEY(keyno,k->kobufr,
- k->kopntr,REGADD))
- return(i);
- if (k->komode == FN_DELCHK && DELCHK(keyno,k->kobufr,
- k->kopntr))
- return(i);
- }
- return(0);
- }
- #endif
-
- stpsrv(try,lmt,usrflg)
- LONG try;
- int lmt;
- COUNT usrflg;
- {
- COUNT usrn;
- CTFILE *ctnum;
-
- for (usrn = 0; usrn < cts_mxusr; usrn++)
- if (ausrtrn[usrn]) {
- if (try < lmt)
- return(usrn + 1);
- else
- transact(ABRTRAN,usrn,ausrtrn);
- }
- for (ctnum = ct_key; ctnum < ct_key + ct_mxfil; ctnum++)
- if (ctnum->chnacs == 'y')
- CLSFIL(ctnum->filnum,0);
-
- if (usrflg < 0)
- signoff(ffrq,ausrcon,ausrmap,ausrtrn);
- return(0);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- COUNT *ctp;
- RECLOK *curlst,*prvlst;
- USRCON *ucon;
- UCOUNT temp;
-
- VOID mainloop();
-
- getsenv(&srvprm,argc,argv);
-
- if (INTREE(cts_buffer,cts_mxfil,cts_nodsec))
- srvexit("Could not allocate dynamic space for server",
- uerr_cod,0);
- rmsg = &omsg;
- if ((afilmap = (COUNT **) mballc(cts_mxusr,sizeof(COUNT *))) ==
- NULL ||
- (ctp = (COUNT *) mballc(cts_mxusr * cts_mxfil,sizeof(COUNT))) ==
- NULL ||
- (umsg = (MESSAGE *) mballc(cts_mxusr,sizeof(MESSAGE))) == NULL ||
- (cts_keyops > 1 && (cts_kops = (KEYOPS *) mballc(cts_keyops,
- sizeof(KEYOPS))) == NULL) ||
- (ct_loklst = (RECLOK *) mballc(cts_maxlok,sizeof(RECLOK))) == NULL ||
- (ausrcon = (USRCON *) mballc(cts_mxusr,sizeof(USRCON))) == NULL ||
- (ausrmap = (COUNT *) mballc(cts_mxusr,sizeof(COUNT))) == NULL ||
- (ausrtrn = (LONG *) mballc(cts_mxusr,sizeof(LONG))) == NULL ||
- (akopsiz = (UCOUNT *) mballc(cts_mxusr,sizeof(UCOUNT))) == NULL ||
- (usrtim = (LONG *) mballc(cts_mxusr,sizeof(LONG))) == NULL ||
- (ausrsiz = (UCOUNT *) mballc(cts_mxusr + 1,sizeof(UCOUNT))) ==
- NULL)
- srvexit(
- "Could not allocate dynamic space for control structures",uerr_cod = SSCB_ERR,
- 0);
-
- ausrsiz[cts_mxusr] = sizeof(MESSAGE);
- for (temp = 0, ucon = ausrcon; temp < cts_mxusr; temp++, ucon++) {
- ucon->ucslep = -2;
- ucon->ucsgop = CTNONE;
- afilmap[temp] = ctp;
- ctp += cts_mxfil;
- }
- for (prvlst = NULL, curlst = ct_loklst; curlst < ct_loklst + cts_maxlok;
- prvlst = curlst, curlst++)
- curlst->rllink = prvlst;
- ct_frelst = prvlst;
-
- if ((srvmsg = getmid(srvsiz = cts_maxsmsg,cts_mxusr)) == NULL)
- srvexit("Could not open server message area.",uerr_cod,0);
- else
- srvdat = srvmsg + sizeof(MESSAGE);
-
- /* prepare for main loop. prploop in ctsrve.c */
- prploop();
-
- /* execute main server loop */
- for(;;)
- mainloop();
- }
-
- VOID mainloop() {
- USRCON *ucon;
- TEXT outval[MAXLEN];
- TEXT *cp;
- TEXT *usrmsg,*usrdat;
- COUNT ufilno,filno,prmchk;
- UCOUNT usrsiz,temp,savext;
- FILEPARM fpm;
- FAST CTFILE *ctnum,*ltnum;
- POINTER recbyt;
- VRLEN unused;
- #ifdef VARLDATA
- VHDR tvhdr;
- #endif
-
- /* main SERVER loop */
- rqsts++;
- if (prmchk = ctrqst(&srvmsg,&imsg)) {
- if (prmchk == NO_RQST)
- return;
- srvexit("Could not read request",0,0);
- } else
- srvdat = srvmsg + sizeof(MESSAGE);
-
- cmbloop:
-
- /* setup output message pointers */
- cpybuf(rmsg,&imsg,sizeof(MESSAGE));
- cur_usrid = rmsg->musrn;
- ucon = ausrcon + cur_usrid;
- usrmsg = srvmsg;
- usrdat = usrmsg + sizeof(MESSAGE);
- if (imsg.mfunc < TST_MESSAGE) {
- usrsiz = ausrsiz[cur_usrid];
- cts_zkop = akopsiz[cur_usrid];
- ffrq[imsg.mfunc]++;
- } else if (imsg.mfunc < MAX_FUNC) {
- usrsiz = sizeof(MESSAGE);
- ffrq[imsg.mfunc]++;
- }
-
- /* perform function */
- uerr_cod = NO_ERROR;
-
- ufilno = imsg.mfiln;
- if (imsg.mfunc < TST_MLTOPS) {
- if (ufilno >= 0 && ufilno < cts_mxfil)
- filno = afilmap[cur_usrid][ufilno];
- else {
- filno = 0;
- imsg.mfunc = TST_BADFIL;
- }
- } else
- filno = ufilno;
-
-
- /* test for legal filno range before computing ctnum */
- if ((imsg.mfunc < FN_FOPNCRE || imsg.mfunc > FN_LOPNCRE) &&
- imsg.mfunc < TST_MLTOPS)
- ctnum = tstfnm(filno);
-
- if (imsg.mretc != CMBREDAT)
- rmsg->mdlen = 0;
-
- if (uerr_cod == NO_ERROR) switch (imsg.mfunc) {
- case FN_ADDKEY:
- if (ctnum->ucext && chkcon(cur_usrid,filno,CTXTND) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
- temp = imsg.mseqn;
- rmsg->mseqn = 0;
- ADDKEY(filno,srvdat,imsg.mpntr,temp);
- break;
- case FN_DELBLD:
- rmsg->mpntr = DELBLD(filno,srvdat);
- break;
- case FN_DELCHK:
- DELCHK(filno,srvdat,imsg.mpntr);
- break;
- #ifdef CTS_ISAM
- case FN_MLTKEY:
- rmsg->mseqn = MLTKEY(imsg.musrn,imsg.mseqn,srvdat);
- if (rmsg->mseqn < 0) {
- uerr_cod = STRY_ERR;
- rmsg->mseqn = imsg.mseqn;
- }
- break;
- #endif
- case FN_EQLKEY:
- rmsg->mpntr = EQLKEY(filno,srvdat);
- break;
- case FN_FRSKEY:
- rmsg->mpntr = FRSKEY(filno,usrdat);
- break;
- case FN_LSTKEY:
- rmsg->mpntr = LSTKEY(filno,usrdat);
- break;
- case FN_NXTKEY:
- rmsg->mpntr = NXTKEY(filno,usrdat);
- break;
- case FN_PRVKEY:
- rmsg->mpntr = PRVKEY(filno,usrdat);
- break;
- case FN_FRCKEY:
- rmsg->mpntr = FRCKEY(filno,usrdat,imsg.mseqn);
- break;
- case FN_GTEKEY:
- rmsg->mpntr = GTEKEY(filno,srvdat,outval);
- break;
- case FN_GTKEY:
- rmsg->mpntr = GTKEY(filno,srvdat,outval);
- break;
- case FN_LTEKEY:
- rmsg->mpntr = LTEKEY(filno,srvdat,outval);
- break;
- case FN_LTKEY:
- rmsg->mpntr = LTKEY(filno,srvdat,outval);
- break;
-
- case FN_OPNFIL:
- cpybuf(&fpm,srvdat,sizeof(FILEPARM));
- if ((fpm.fpmod & NONEXCLUSIVE) == NONEXCLUSIVE)
- /* only set READFIL flag if SHARED & READFIL both on */
- fpm.fpmod &= ~SHARED;
- if ((filno = chkopn(fpm.fpnam)) < 0) {
- if ((filno = getctf()) < 0) {
- uerr_cod = SNFB_ERR;
- break;
- } else if (OPNFIL(filno,fpm.fpnam,
- fpm.fpmod & ~PERMANENT)) {
- retctf(filno);
- break;
- } else {
- ctnum = ct_key + filno;
- ctnum->usrcnt = 0;
- ctnum->ucext = ctnum->ucred = ctnum->ucwrt = 0;
- }
- } else { /* check for conflicts */
- ctnum = ct_key + filno;
- /* check for exclusive rqst */
- if (!(NONEXCLUSIVE & fpm.fpmod) ||
- (ctnum->flmode & NONEXCLUSIVE) != (fpm.fpmod &
- NONEXCLUSIVE)) {
- uerr_cod = FNOP_ERR;
- break;
- }
- if (ctnum->ucext &&
- chkcon(cur_usrid,filno,CTXTND) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
- }
- temp = 0;
- ltnum = ctnum;
- cp = usrdat;
- ctnum->usrcnt++;
-
- do {
- temp += HDRSIZ;
- if (temp <= usrsiz - sizeof(MESSAGE)) {
- cpybuf(cp,ltnum,HDRSIZ);
- rmsg->mdlen = temp;
- cp += HDRSIZ;
- }
- afilmap[cur_usrid][ufilno++] = ltnum - ct_key;
- ltnum = ltnum->xmem;
- } while (ltnum != (CTFILE *) NULL);
-
- if (ctnum->usrcnt == 1 && rmsg->mdlen < ((ctnum->nmem + 1) *
- HDRSIZ))
- setcon(cur_usrid,filno,CTXTND,(UCOUNT) 0,usrmsg);
- break;
-
- case FN_CREDAT:
- cpybuf(&fpm,srvdat,sizeof(FILEPARM));
- if (chkopn(fpm.fpnam) >= 0)
- uerr_cod = DOPN_ERR;
- else if ((filno = getctf()) < 0)
- uerr_cod = SNFB_ERR;
- else if (CREDAT(filno,fpm.fpnam,fpm.fplen,fpm.fpxtd,
- fpm.fpmod & ~PERMANENT) == NO_ERROR) {
- ctnum = ct_key + filno;
- cpybuf(usrdat,ctnum,rmsg->mdlen = HDRSIZ);
- ctnum->usrcnt = 1;
- afilmap[cur_usrid][ufilno] = filno;
- } else
- retctf(filno);
- break;
-
- case FN_CREIDX:
- cpybuf(&fpm,srvdat,sizeof(FILEPARM));
- if (chkopn(fpm.fpnam) >= 0)
- uerr_cod = KOPN_ERR;
- else if ((filno = getctf()) < 0)
- uerr_cod = SNFB_ERR;
- else if (getctm(fpm.fpmem,ct_key + filno) < 0) {
- retctf(filno);
- uerr_cod = SNFB_ERR;
- } else if (CREIDX(filno,fpm.fpnam,fpm.fplen,fpm.fptyp,fpm.fpdup,
- fpm.fpmem,fpm.fpxtd,fpm.fpmod & ~PERMANENT) == NO_ERROR) {
- ctnum = ct_key + filno;
- cpybuf(usrdat,ctnum,rmsg->mdlen = HDRSIZ);
- ctnum->usrcnt = 1;
- while (ctnum != (CTFILE *) NULL) {
- afilmap[cur_usrid][ufilno++] = ctnum - ct_key;
- ctnum = ctnum->xmem;
- }
- } else
- retctf(filno);
- break;
-
- case FN_CREMEM:
- cpybuf(&fpm,srvdat,sizeof(FILEPARM));
- if (CREMEM(filno,fpm.fplen,fpm.fptyp,fpm.fpdup,fpm.fpmem) ==
- NO_ERROR) {
- ctnum = ct_key + filno;
- while (fpm.fpmem-- > 0)
- ctnum = ctnum->xmem;
- cpybuf(usrdat,ctnum,rmsg->mdlen = HDRSIZ);
- }
- break;
-
- case FN_DATENT:
- rmsg->mpntr = DATENT(filno);
- break;
- case FN_SERIALNUM:
- rmsg->mpntr = SERIALNUM(filno);
- break;
- case FN_IDXENT:
- rmsg->mpntr = IDXENT(filno);
- break;
- case FN_FLUSHDOS:
- flushdos(filno);
- break;
- case FN_LOKREC:
- LOKREC(filno,imsg.mseqn,imsg.mpntr);
- break;
- case FN_DLOCK:
- DLOCK(imsg.mpntr,ctnum);
- break;
- case FN_UDLOCK:
- UDLOCK(imsg.mpntr,ctnum);
- break;
- case FN_RLOCK:
- RLOCK(imsg.mpntr,ctnum);
- break;
- #ifdef CTS_ISAM
- case FN_MLTULK:
- if (imsg.mvlen == 0)
- terr(968);
- UDLOCK(imsg.mpntr,ctnum);
- temp = 0;
- while (--imsg.mvlen != 0) {
- cpybuf(&recbyt,srvdat + temp,sizeof(POINTER));
- cpybuf(&ufilno,srvdat + temp + sizeof(POINTER),
- sizeof(COUNT));
- filno = afilmap[cur_usrid][ufilno];
- ctnum = ct_key + filno;
- UDLOCK(recbyt,ctnum);
- temp += (sizeof(POINTER) + sizeof(COUNT));
- }
- break;
- #endif
- case FN_NEWREC:
- if (ctnum->ucext && chkcon(cur_usrid,filno,CTXTND) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
- if ((rmsg->mpntr = NEWREC(filno)) != DRNZERO)
- setsrlpos(rmsg);
- break;
- #ifdef CTS_ISAM
- case FN_MLTWRT:
- temp = imsg.mvlen;
- if (imsg.mpntr == DRNZERO) {
- if (ctnum->ucext && chkcon(cur_usrid,filno,CTXTND) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
- imsg.mseqn = 0;
- if ((rmsg->mpntr = NEWREC(filno)) == DRNZERO) {
- rmsg->mseqn = 1;
- break;
- } else
- imsg.mpntr = rmsg->mpntr;
- }
- if (temp) {
- cpybuf(srvdat + temp - 1,&ct_gsrl,sizeof(ct_gsrl));
- #ifndef NATURAL_SERIAL
- #ifdef LOW_HIGH
- revobj(srvdat + temp - 1,sizeof(ct_gsrl));
- #endif
- #endif
- }
- #ifdef LOCK_TEST
- if ((ctnum->flmode & NONEXCLUSIVE) &&
- (uerr_cod = cts_lok(imsg.musrn,filno,0,LOCK_TEST,
- imsg.mpntr))) {
- rmsg->mseqn = 2;
- break;
- }
- #endif
- if (WRTREC(filno,imsg.mpntr,srvdat))
- rmsg->mseqn = 2;
- else
- rmsg->mseqn = 0;
- if (rmsg->mseqn == 0)
- setsrlpos(rmsg);
- break;
- #endif
-
- #ifdef VARLDATA
- case FN_GTVLEN:
- rmsg->mvlen = GTVLEN(filno,imsg.mpntr);
- break;
-
- case FN_NEWVREC:
- if (ctnum->ucext && chkcon(cur_usrid,filno,CTXTND) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
- if ((rmsg->mpntr = NEWVREC(filno,imsg.mvlen)) != DRNZERO)
- setsrlpos(rmsg);
- break;
-
- case FN_RETVREC:
- #ifdef LOCK_TEST
- if ((ctnum->flmode & NONEXCLUSIVE) &&
- (uerr_cod = cts_lok(imsg.musrn,filno,0,LOCK_TEST,
- imsg.mpntr)))
- break;
- #endif
- RETVREC(filno,imsg.mpntr);
- break;
- #endif
-
- case FN_RETREC:
- #ifdef LOCK_TEST
- if ((ctnum->flmode & NONEXCLUSIVE) &&
- (uerr_cod = cts_lok(imsg.musrn,filno,0,LOCK_TEST,
- imsg.mpntr)))
- break;
- #endif
- RETREC(filno,imsg.mpntr);
- break;
-
- case FN_CLSFIL:
- trycls(cur_usrid,ufilno);
- break;
-
- case FN_DELFIL:
- DELFIL(filno);
- break;
-
- case FN_TSTREC:
- if (imsg.mpntr > ctnum->numrec) {
- rmsg->mpntr = DRNZERO;
- uerr_cod = LEOF_ERR;
- } else
- rmsg->mpntr = ctnum->numrec;
- break;
-
- case CNT_HDROUT:
- temp = HDRSIZ;
- ltnum = ctnum;
- cp = usrdat;
- while (imsg.mseqn-- > 0)
- ltnum = ltnum->xmem;
- do {
- cpybuf(cp,ltnum,HDRSIZ);
- rmsg->mdlen = temp;
- temp += HDRSIZ;
- cp += HDRSIZ;
- ltnum = ltnum->xmem;
- } while (temp <= usrsiz - sizeof(MESSAGE) &&
- ltnum != (CTFILE *) NULL);
-
- if (ltnum == (CTFILE *) NULL)
- wakcon(cur_usrid,filno,CTXTND);
- break;
-
- case TST_MSGSIZ:
- case TST_SPCLOG:
- /* check for dead users */
- chkusrtim(usrtim,ausrmap,ausrtrn);
-
- /* assign user number */
- imsg.musrn = cur_usrid = cts_mxusr;
-
- /* test for shut down in progress */
- if (cts_stat.shtdwn && imsg.mfunc == TST_MSGSIZ) {
- rmsg->musrn = cts_mxusr;
- uerr_cod = SHUT_ERR;
- } else {
- for (temp = 0; temp < cts_mxusr; temp++)
- if (ausrmap[temp] == NO) {
- ausrmap[temp] = YES;
- imsg.musrn = rmsg->musrn = cur_usrid =
- temp;
- ausrsiz[cur_usrid] = imsg.mvlen;
- akopsiz[cur_usrid] = imsg.mretc;
- ucon = ausrcon + cur_usrid;
- ucon->ucslep = -2;
- ucon->ucsgop = CTNONE;
- rmsg->mseqn = cts_keyops;
- for (filno = 0; filno < cts_mxfil; filno++)
- afilmap[cur_usrid][filno] = -1;
- break;
- }
- if (cur_usrid == cts_mxusr) {
- rmsg->musrn = imsg.musrn = cts_mxusr;
- uerr_cod = SOUT_ERR;
- } else if (imsg.mvlen > srvsiz)
- uerr_cod = SMSG_ERR;
- else if (imsg.mseqn > MAXLEN)
- uerr_cod = SMXL_ERR;
- }
-
- /* save message id */
- getumsg(&imsg,cur_usrid,usrmsg);
- break;
-
- case FN_STATUS:
- cp = srvdat;
- rmsg->mvlen = rmsg->mdlen = 0;
- if (imsg.mseqn < 0) {
- cts_stat.susers = cts_stat.strans = 0;
- for (temp = 0; temp < cts_mxusr; temp++) {
- if (ausrmap[temp] != NO) cts_stat.susers++;
- if (ausrtrn[temp] != 0L) cts_stat.strans++;
- }
- cpybuf(srvdat,(TEXT *) &cts_stat,
- rmsg->mdlen = sizeof(SSTATUS));
- cp += sizeof(SSTATUS);
- rmsg->mseqn = 0;
- }
- temp = sizeof(COUNT) + sizeof(LONG);
- while (rmsg->mseqn < MAX_FUNC) {
- if (ffrq[rmsg->mseqn]) {
- if ((rmsg->mdlen + temp) > (usrsiz - sizeof(MESSAGE)))
- break;
- cpybuf(cp,&rmsg->mseqn,sizeof(COUNT));
- cp += sizeof(COUNT);
- cpybuf(cp,&ffrq[rmsg->mseqn],sizeof(LONG));
- cp += sizeof(LONG);
- rmsg->mdlen += temp;
- rmsg->mvlen++;
- }
- rmsg->mseqn++;
- }
- if (rmsg->mseqn >= MAX_FUNC)
- rmsg->mseqn = 0;
- uerr_cod = NO_ERROR;
- break;
-
- case FN_STFILE:
- rmsg->mvlen = rmsg->mdlen = 0;
- cp = srvdat;
- while (rmsg->mseqn < cts_mxfil) {
- ctnum = ct_key + rmsg->mseqn;
- if ((ctnum->chnacs == 'y' || ctnum->chnacs == 'v') &&
- #ifdef CT_ANSI
- ctnum->fd != (RNDFILE) NULL) {
- #else
- ctnum->fd > -1) {
- #endif
- temp = strlen(ctnum->flname) + 1;
- if ((temp + rmsg->mdlen + sizeof(COUNT)) >
- (usrsiz - sizeof(MESSAGE)))
- break;
- rmsg->mvlen++;
- rmsg->mdlen += (temp + sizeof(COUNT));
- strcpy(cp,ctnum->flname);
- cp += temp;
- cpybuf(cp,&ctnum->usrcnt,sizeof(COUNT));
- cp += sizeof(COUNT);
- }
- rmsg->mseqn++;
- }
- if (rmsg->mseqn >= cts_mxfil)
- rmsg->mseqn = 0;
- uerr_cod = NO_ERROR;
- break;
-
- case TST_STPSRV:
- imsg.musrn = cur_usrid = cts_mxusr;
- cts_stat.shtdwn++;
- getumsg(&imsg,cur_usrid,usrmsg);
- if (stpsrv(cts_stat.shtdwn,CTS_DOWN,cur_usrid)) {
- rmsg->merrn = STRN_ERR;
- rmsg->mpntr = cts_stat.shtdwn;
- rmsg->mseqn = CTS_DOWN;
- ctrspn(usrmsg,rmsg,usrsiz,cur_usrid);
- return;
- }
- rmsg->merrn = 0;
- signoff(ffrq,ausrcon,ausrmap,ausrtrn);
- ctrspn(usrmsg,rmsg,usrsiz,cur_usrid);
- ridmid();
- srvexit("Successful c-tree Termination",0,0);
-
- case TST_DEDUSR:
- if ((cur_usrid = dedusr(imsg.mpntr)) > -1)
- stpusr(cur_usrid);
- /* no response is sent back to requester */
- return;
-
- case TST_STPUSR:
- stpusr(cur_usrid);
- ctrspn(usrmsg,rmsg,usrsiz,-(cur_usrid + 1));
- /* negative user id signals end of user connection */
- return;
-
- case TST_BADFIL:
- uerr_cod = SFIL_ERR;
- break;
-
- case TST_EXISTS:
- usrtim[imsg.mseqn] = time();
- uerr_cod = NO_ERROR;
- return;
-
- case TST_TRAN:
- if (imsg.mfiln == BEGTRAN && cts_stat.shtdwn)
- uerr_cod = SHUT_ERR;
- else
- uerr_cod = transact(imsg.mfiln,imsg.musrn,ausrtrn);
- break;
-
- case CNT_RECIN:
- if (ctnum->ucred > 0 && chkcon(cur_usrid,filno,CTREAD) > -1) {
- uerr_cod = STRY_ERR;
- break;
- }
-
- #ifdef VARLDATA
- if (imsg.mretc == VAR1st) { /* 1st seg of variable length */
- #ifdef LOCK_TEST
- if ((ctnum->flmode & NONEXCLUSIVE) &&
- (uerr_cod = cts_lok(imsg.musrn,filno,0,LOCK_TEST,
- imsg.mpntr)))
- break;
- #endif
- if (getvhdr(ctnum,imsg.mpntr,&tvhdr))
- break;
- if (tvhdr.trclen < imsg.mvlen) {
- uerr_cod = VLEN_ERR;
- break;
- }
- tvhdr.urclen = imsg.mvlen;
- tvhdr.recmrk = VACT_FLAG;
-
- unused = tvhdr.trclen - imsg.mvlen;
- if (unused > (ctnum->reclen + SIZVHDR) && unused > 64)
- tvhdr.trclen = imsg.mvlen;
- else
- unused = 0;
- if (putvhdr(ctnum,imsg.mpntr,&tvhdr))
- break;
-
- if (unused) { /* reclaim space */
- recbyt = imsg.mpntr + imsg.mvlen +
- SIZVHDR;
- tvhdr.recmrk = VDEL_FLAG;
- tvhdr.trclen = unused - SIZVHDR;
- tvhdr.urclen = 0;
- if (putvhdr(ctnum,recbyt,&tvhdr))
- break;
- savext = ctnum->extsiz;
- ctnum->extsiz = 0;
- RETVREC(filno,recbyt);
- ctnum->extsiz = savext;
- if (uerr_cod)
- break;
- }
- }
- #endif
-
- #ifdef LOCK_TEST
- if (imsg.mretc != VAR1st && (ctnum->flmode & NONEXCLUSIVE))
- if (imsg.mseqn == ((imsg.mvlen + imsg.mdlen - 1) /
- imsg.mdlen) - 1)
- if (uerr_cod = cts_lok(imsg.musrn,filno,0,
- LOCK_TEST,imsg.mpntr))
- break;
- #endif
- ctio(CTWRITE,ctnum,imsg.mpntr,srvdat,imsg.mdlen);
-
- if (imsg.mseqn == 0 && ucon->ucsgop == CTWRITE)
- wakcon(cur_usrid,filno,CTWRITE);
- else if (imsg.mseqn > 0)
- setcon(cur_usrid,filno,CTWRITE,imsg.mvlen,usrmsg);
- break;
-
- case CNT_RECOUT:
- if (ctnum->ucwrt > 0 && chkcon(cur_usrid,filno,CTWRITE) > -1) {
- if (imsg.mretc == CMBREDAT) {
- (ausrcon + cur_usrid)->ucslep = -2;
- rmsg->mretc = CMBREDCN;
- uerr_cod = NO_ERROR;
- break;
- } else {
- uerr_cod = STRY_ERR;
- break;
- }
- }
-
- if (imsg.mseqn == 0) { /* 1st request: must determine len */
- if (ctnum->clstyp == DAT_CLOSE || imsg.mvlen == 0)
- temp = ctnum->reclen;
- #ifdef VARLDATA
- else {
- if (getvhdr(ctnum,imsg.mpntr,&tvhdr))
- break;
- if ((temp = tvhdr.urclen) > imsg.mvlen) {
- uerr_cod = VBSZ_ERR;
- break;
- }
- }
- #endif
- rmsg->mvlen = temp;
- } else
- rmsg->mvlen = temp = imsg.mvlen;
-
- if (imsg.mretc == CMBREDAT) {
- if (temp > (usrsiz - sizeof(MESSAGE) - rmsg->mdlen))
- terr(969);
- ctio(CTREAD,ctnum,rmsg->mpntr,usrdat + rmsg->mdlen,
- temp);
- rmsg->mdlen += temp;
- break;
- }
-
- ctio(CTREAD,ctnum,imsg.mpntr,usrdat,rmsg->mdlen =
- min(temp,usrsiz - sizeof(MESSAGE)));
-
- if (rmsg->mdlen == temp && ucon->ucsgop == CTREAD)
- wakcon(cur_usrid,filno,CTREAD);
- else if (rmsg->mdlen < temp)
- setcon(cur_usrid,filno,CTREAD,temp,usrmsg);
- break;
-
- default:
- srvmesg("Illegal function number at server:",
- imsg.mfunc,uerr_cod = SFUN_ERR);
- }
-
- /* set error return code */
- rmsg->merrn = uerr_cod;
-
- /* for output keys, get key length */
- if (imsg.mfunc >= FN_FLOWKEY && imsg.mfunc <= FN_LLOWKEY) {
- rmsg->mdlen = ctnum->length;
- if (imsg.mfunc >= FN_FTWOKEY)
- cpybuf(usrdat,outval,rmsg->mdlen);
- }
-
- if (rmsg->merrn == ARDO_ERR) {
- usrsiz = sizeof(MESSAGE);
- rmsg->mdlen = imsg.mdlen;
- redo++;
- } else if (rmsg->merrn == STRY_ERR) {
- retry++;
- #ifndef CTS_CPLD
- imsg.merrn = STRY_ERR;
- cpybuf(umsg + cur_usrid,&imsg,sizeof(MESSAGE));
- return;
- #else
- usrsiz = sizeof(MESSAGE);
- rmsg->mdlen = imsg.mdlen;
- #endif
- }
-
- if (rmsg->mretc == CMBREDLK || rmsg->mretc == (CMBREDLK + 1)) {
- prmchk = ENABLE + (rmsg->mretc - CMBREDLK) * (READREC - ENABLE);
- rmsg->mretc = CMBREDWO;
- if (rmsg->merrn == 0 && rmsg->mpntr != DRNZERO)
- rmsg->merrn = LOKREC(afilmap[cur_usrid][imsg.mseqn],
- prmchk,rmsg->mpntr);
- }
- if (rmsg->mretc == CMBREDWO) {
- rmsg->mretc = imsg.mretc = CMBREDAT;
- if (rmsg->merrn == 0) {
- imsg.mfunc = CNT_RECOUT;
- imsg.mfiln = imsg.mseqn;
- imsg.mdlen = rmsg->mdlen;
- imsg.mseqn = 0;
- imsg.mvlen = 0;
- if ((imsg.mpntr = rmsg->mpntr) == DRNZERO)
- rmsg->merrn = INOT_ERR;
- else
- goto cmbloop;
- }
- }
-
- if (usrsiz > sizeof(MESSAGE))
- usrsiz = sizeof(MESSAGE) + rmsg->mdlen;
-
- if (ctrspn(usrmsg,rmsg,usrsiz,cur_usrid))
- srvmesg("Could not send response:",cur_usrid,uerr_cod);
-
- return;
- }
-
- /* end of ctsrvr.c */
-
-