home *** CD-ROM | disk | FTP | other *** search
- /*
- * System Dependent Server Message Handler
- * Novell Advanced NetWare 2.1
- *
- * 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(TM) Version 4.3
- * Release C
- * February 7, 1989 17:30
- *
- */
-
- #include "ctstdr.h"
- #include "ctoptn.h"
- #include "ctstrc.h"
- #include "cterrc.h"
- #include "ctcomm.h"
- #include "ctmssg.h"
-
- LOCAL UCOUNT msgsiz;
- LOCAL LONG *ausrmid;
- LOCAL COUNT nusr;
- LOCAL TEXT *savdat;
- LOCAL COUNT *ecbtyp;
- LOCAL UCOUNT idle = 0;
- #define STRETCH 1000
-
- extern COUNT uerr_cod,cts_mxusr;
- TEXT *mballc();
-
- /* elapsed time before unread user queue declared inactive */
- #define INDEFINITE 5 /* seconds */
-
- /* LTYPE is defined in ctmsgg.h */
-
- ECB *getECB(n)
- int n;
- {
- int i;
- SPXHDR *spxptr;
- char *tp;
- ECB *ecbptr,*savptr;
-
- if ((spxptr = (SPXHDR *) mballc(n,
- sizeof(SPXHDR))) == NULL ||
- (ecbptr = (ECB *) mballc(n,sizeof(ECB))) == NULL ||
- (ecbtyp = (COUNT *) mballc(n,sizeof(COUNT))) == NULL ||
- (savdat = tp = (TEXT *) mballc(1,n * DATA_SIZE)) == NULL) {
- uerr_cod = SSPC_ERR;
- return(NULL);
- }
-
- for (i = 0, savptr = ecbptr; i < n; i++,spxptr++,ecbptr++) {
- IPXdatadr(spxptr,ecbptr->fragmentDescriptor[0].address);
- ecbptr->fragmentDescriptor[0].size = SPXHDR_SIZE;
- IPXdatadr(tp,ecbptr->fragmentDescriptor[1].address);
- ecbptr->fragmentDescriptor[1].size = DATA_SIZE;
- tp += DATA_SIZE;
- }
-
- return(savptr);
- }
-
- SetUpRcvECB(n)
- int n;
- {
- FAST ECB *ecbptr;
- int i;
-
- ecbptr = savecb;
- for (i = 0; i < n; i++, ecbptr++) {
- ecbptr->fragmentCount = 2;
- ecbptr->socketNumber = soknum;
- /*
- mp.mpf = RcvESR;
- ecbptr->ESRAddress[0] = mp.mpw[0];
- ecbptr->ESRAddress[1] = mp.mpw[1];
- */
- ecbptr->ESRAddress[0] = 0;
- ecbptr->ESRAddress[1] = 0;
- #ifdef SPXDEBUG
- display("\rSetUpRcvECB before Listen\n");
- #endif
- SPXlisten(ecbptr);
- }
- return(0);
- }
-
- VOID retlst(ecbptr)
- PFAST ECB *ecbptr;
- {
- ecbptr->fragmentCount = 1;
- ecbptr->socketNumber = soknum;
- ecbptr->ESRAddress[0] = 0;
- ecbptr->ESRAddress[1] = 0;
- SPXlsncon(0,1,ecbptr);
- #ifdef SPXDEBUG
- display(":: Listen set for ECB");numdis(ecbptr - savecb);
- #endif
- }
-
- SetUpIntECB(n)
- int n;
- {
- FAST ECB *ecbptr;
- int i;
-
- ecbptr = savecb + n;
- for (i = 0; i < n; i++, ecbptr++)
- retlst(ecbptr);
- return(0);
- }
-
- TEXT *getmid(sizmsg,maxusr)
- UCOUNT sizmsg;
- COUNT maxusr;
- {
- TEXT majrev,minrev;
- UCOUNT maxcon,avlcon;
- ECB *getECB();
-
- #ifdef SPXDEBUG
- display("\rbeginning of getmid\n");
- #endif
- nusr = maxusr;
-
- /* allocate an array for message ids: assumes long is OK */
- if ((ausrmid = (LONG *) mballc(maxusr + 1,sizeof(LONG))) == NULL) {
- uerr_cod = SSCB_ERR;
- return(NULL);
- }
-
- /* get message id for server */
- uerr_cod = xerr = 0;
-
- if ((0x00ff & (xerr = SPXinit(&majrev,&minrev,&maxcon,&avlcon)))
- == (0x00ff & SPX_NOT_INSTALLED))
- uerr_cod = SSKY_ERR;
- else if (xerr = IPXopen(&soknum,0))
- uerr_cod = SSID_ERR;
- else
- msgsiz = DATA_SIZE;
-
- if (uerr_cod)
- return(NULL);
- #ifdef SPXDEBUG
- display("\rSPX init complete\n");
- #endif
-
- /*
- * Is there a need for 2*(maxusr+1) message blocks to allow
- * for communications when the server is full?
- */
- if ((savecb = getECB(2 * maxusr)) == NULL) {
- uerr_cod = ASPC_ERR;
- return(NULL);
- } else if (SetUpRcvECB(maxusr))
- return(NULL);
- else if (SetUpIntECB(maxusr))
- return(NULL);
-
- #ifdef SPXDEBUG
- display("\rgetmid complete\n");
- #endif
-
- return(savdat);
- }
-
- LONG getumsg(pmsg,usrn,msgptr)
- MESSAGE *pmsg;
- COUNT usrn;
- TEXT *msgptr;
- {
- UCOUNT locmid;
- FAST ECB *ecbptr;
- SPXHDR *spxptr;
-
- locmid = (msgptr - savdat) / DATA_SIZE;
- ecbptr = savecb + locmid;
- cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
- locmid = spxptr->destConnectionID;
-
- /* save message id: assumes that a long is sufficient */
- if (usrn >= 0)
- ausrmid[usrn] = locmid;
-
- return((LONG) locmid);
- }
-
- COUNT ridmid()
- {
- int i;
-
- /* delay */
- for (i = 0; i < 10000; i++)
- IPXrelq();
-
- /* remove application message handling */
- return(NO_ERROR);
- }
-
- VOID retecb(ecbptr)
- PFAST ECB *ecbptr;
- {
- ecbtyp[ecbptr - savecb] = 0;
- ecbptr->fragmentCount = 2;
- ecbptr->fragmentDescriptor[1].size = DATA_SIZE;
- SPXlisten(ecbptr);
- }
-
- COUNT dedusr(msgid)
- LONG msgid;
- {
- COUNT usrn;
-
- for (usrn = 0; usrn < cts_mxusr; usrn++)
- if (msgid == ausrmid[usrn]) {
- ausrmid[usrn] = 0;
- return(usrn);
- }
- return(-1);
- }
-
- COUNT ctrqst(msgadr,pmsg)
- PFAST TEXT **msgadr;
- MESSAGE *pmsg;
- {
- SPXHDR *spxptr;
- COUNT ecbflg;
- UCOUNT locmid;
- FAST COUNT i;
- FAST ECB *ecbptr;
-
- wait_loop:
- ecbflg = NO;
- for (i = ecbpos, ecbptr = savecb + i; i < 2 * nusr; i++, ecbptr++)
- if (ecbptr->inUseFlag == 0) {
- if (ecbtyp[i])
- retecb(ecbptr);
- else {
- ecbflg = YES;
- break;
- }
- }
- if (!ecbflg) for (i = 0, ecbptr = savecb; i < ecbpos; i++, ecbptr++)
- if (ecbptr->inUseFlag == 0) {
- if (ecbtyp[i])
- retecb(ecbptr);
- else {
- ecbflg = YES;
- break;
- }
- }
-
- if (!ecbflg) {
- if (++idle > STRETCH)
- dlayvap();
- else
- IPXrelq();
- goto wait_loop;
- } else {
- idle = 0;
- ecbpos = (i + 1) % (2 * nusr);
- }
-
- /* check if message is administrative (established connection /
- terminate connection) / a regular msg / or a failed msg
- */
-
- /* get address of SPX header fragment */
- cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
-
- ecbflg = RCV;
- /* if only one fragment, then administrative */
- if (ecbptr->fragmentCount == 1) {
- if ((0x00ff & spxptr->dataStreamType) ==
- (0x00ff & SPX_CLEAN_TERMINATION)) {
- display("\n\rc-tree Unexpected Connection Terminate");
- retlst(ecbptr);
- } else if ((0x00ff & ecbptr->completionCode) ==
- (0x00ff & SPX_CONNECTION_TERMINATED)) {
- /* IPXWorkspace contains conid. call routine to stpusr*/
- cpybuf(&locmid,ecbptr->IPXWorkspace,sizeof(UCOUNT));
- if ((i = dedusr((LONG) locmid)) > -1)
- stpusr(i);
- retlst(ecbptr);
- } else if (ecbptr->completionCode == 0) {
- ecbflg = LSN;
- retecb(ecbptr);
- } else {
- display("\n\rc-tree Unknown Admin Message: ");
- numdis(ecbptr->completionCode);
- retlst(ecbptr);
- }
- goto wait_loop;
- } else if ((0x00ff & ecbptr->completionCode) ==
- (0x00ff & SPX_CONNECTION_TERMINATED)) {
- /* IPXWorkspace contains conid. call routine to stpusr */
- cpybuf(&locmid,ecbptr->IPXWorkspace,sizeof(UCOUNT));
- if ((i = dedusr((LONG) locmid)) > -1) {
- stpusr(i);
- retlst(ecbptr);
- } else
- retecb(ecbptr);
- goto wait_loop;
- }
-
- cpybuf(msgadr,ecbptr->fragmentDescriptor[1].address,
- sizeof(char *));
-
- /* copy message header */
- cpybuf(pmsg,*msgadr,sizeof(MESSAGE));
-
- return(NO_ERROR);
- }
-
- COUNT ctrspn(msgadr,pmsg,sizmsg,usrn)
- PFAST TEXT *msgadr;
- MESSAGE *pmsg;
- UCOUNT sizmsg;
- COUNT usrn;
- {
- /* local copy of message id with correct type */
- UCOUNT locmid;
-
- FAST ECB *ecbptr;
- SPXHDR *spxptr;
-
- /* copy message header */
- cpybuf(msgadr,pmsg,sizeof(MESSAGE));
-
- locmid = (msgadr - savdat) / DATA_SIZE;
- if (usrn >= 0)
- ecbtyp[locmid] = YES;
- ecbptr = savecb + locmid;
- cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
-
- spxptr->dataStreamType = 0;
- spxptr->connectionControl = 0x10;
- ecbptr->fragmentCount = 2;
- ecbptr->fragmentDescriptor[1].size = sizmsg;
-
- if (usrn >= 0) {
- locmid = ausrmid[usrn];
- SPXsend(locmid,ecbptr);
- } else {
- usrn = - (usrn + 1);
- #ifdef SPXDEBUG
- display(":: Attempt to logout");numdis(usrn);
- #endif
- locmid = ausrmid[usrn];
- SPXsend(locmid,ecbptr);
- while (ecbptr->inUseFlag)
- IPXrelq();
- retlst(ecbptr);
- ausrmid[usrn] = 0;
- }
- return(NO_ERROR);
- }
-
- COUNT norspn(usrn)
- COUNT usrn;
- {
- return(NO);
- }
-
- chkusrtim(usrtim,usrmap,usrtrn)
- LONG *usrtim;
- COUNT *usrmap;
- LONG *usrtrn;
- {
- TEXT retmsg[48];
- UCOUNT locmid;
- COUNT i,j;
- FAST ECB *ecbptr;
-
- #ifdef SPXDEBUG
- display("\n\rchkusrtim ");
- #endif
- for (i = 0; i < cts_mxusr; i++) {
- if (usrmap[i]) {
- locmid = ausrmid[i];
- #ifdef SPXDEBUG
- numdis(i);numdis(locmid);
- #endif
- if (SPXstatus(locmid,retmsg)) {
- stpusr(i);
- ausrmid[i] = 0;
- #ifdef SPXDEBUG
- display("\n\rFound disconnection\n");
- #endif
- for (j = 0, ecbptr = savecb; j < 2*nusr; j++, ecbptr++)
- if (ecbptr->inUseFlag && ecbptr->fragmentCount
- == 2 && IPXcancel(ecbptr) == 0) {
- retlst(ecbptr);
- break;
- }
- #ifdef SPXDEBUG
- if (j >= 2 * nusr) display("\n\rCould not relisten\n");
- #endif
- break; /* only free up one disconnection per login */
- }
- #ifdef SPXDEBUG
- else numdis(retmsg[0]);
- #endif
- }
- }
- return(NO_ERROR);
- }
-
- /* end of ctsmsg.nov */
-