home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c004 / 3.ddi / NOVELL / CTSMSGC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-18  |  9.0 KB  |  427 lines

  1. /*
  2.  *    System Dependent Server Message Handler
  3.  *    Novell Advanced NetWare 2.1
  4.  *
  5.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  6.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  7.  *    transfer of this program is strictly prohibited.
  8.  *
  9.  *      Copyright (c) 1987, 1988, 1989 FairCom Corporation
  10.  *    (Subject to limited distribution and
  11.  *     restricted disclosure only.)
  12.  *    *** ALL RIGHTS RESERVED ***
  13.  *
  14.  *    4006 West Broadway
  15.  *    Columbia, MO 65203
  16.  *
  17.  *
  18.  *    c-tree(R)    Version 4.3
  19.  *            Release C
  20.  *            February 7, 1989 17:30
  21.  *
  22.  */
  23.  
  24. #include "ctstdr.h"
  25. #include "ctoptn.h"
  26. #include "ctstrc.h"
  27. #include "cterrc.h"
  28. #include "ctcomm.h"
  29. #include "ctmssg.h"
  30.  
  31. LOCAL UCOUNT msgsiz;
  32. LOCAL LONG  *ausrmid;
  33. LOCAL COUNT  nusr,nbuf,nrcv;
  34. LOCAL TEXT  *savdat;
  35. LOCAL COUNT *ecbtyp;
  36. LOCAL UCOUNT idle = 0;
  37. #define STRETCH    1000
  38. #define ACKBUF    10
  39.  
  40. extern COUNT uerr_cod,cts_mxusr;
  41. TEXT        *mballc();
  42.  
  43. /* elapsed time before unread user queue declared inactive */
  44. #define INDEFINITE 5    /* seconds */
  45.  
  46. /* LTYPE is defined in ctmsgg.h */
  47.  
  48. ECB *getECB(n)
  49. int n;
  50. {
  51.     int i;
  52.     SPXHDR *spxptr;
  53.     char *tp;
  54.     ECB *ecbptr,*savptr;
  55.  
  56.     if ((spxptr = (SPXHDR *) mballc(n,
  57.         sizeof(SPXHDR))) == NULL ||
  58.         (ecbptr = (ECB *) mballc(n,sizeof(ECB))) == NULL ||
  59.         (ecbtyp = (COUNT *) mballc(n,sizeof(COUNT))) == NULL ||
  60.         (savdat = tp = (TEXT *) mballc(1,n * DATA_SIZE)) == NULL) {
  61.         uerr_cod = SSPC_ERR;
  62.         return(NULL);
  63.     }
  64.  
  65.     for (i = 0, savptr = ecbptr; i < n; i++,spxptr++,ecbptr++) {
  66.         IPXdatadr(spxptr,ecbptr->fragmentDescriptor[0].address);
  67.         ecbptr->fragmentDescriptor[0].size = SPXHDR_SIZE;
  68.         IPXdatadr(tp,ecbptr->fragmentDescriptor[1].address);
  69.         ecbptr->fragmentDescriptor[1].size = DATA_SIZE;
  70.         tp += DATA_SIZE;
  71.     }
  72.  
  73.     return(savptr);
  74. }
  75.  
  76. SetUpRcvECB(n)
  77. int n;
  78. {
  79.     FAST ECB *ecbptr;
  80.     int i;
  81.  
  82.     ecbptr = savecb;
  83.     for (i = 0; i < n; i++, ecbptr++) {
  84.         ecbptr->fragmentCount = 2;
  85.         ecbptr->socketNumber  = soknum;
  86. /*
  87.         mp.mpf = RcvESR;
  88.         ecbptr->ESRAddress[0] = mp.mpw[0];
  89.         ecbptr->ESRAddress[1] = mp.mpw[1];
  90. */
  91.         ecbptr->ESRAddress[0] = 0;
  92.         ecbptr->ESRAddress[1] = 0;
  93. #ifdef SPXDEBUG
  94. display("\rSetUpRcvECB before Listen\n");
  95. #endif
  96.         SPXlisten(ecbptr);
  97.     }
  98.     return(0);
  99. }
  100.  
  101. VOID retlst(ecbptr)
  102. PFAST ECB  *ecbptr;
  103. {
  104.     ecbptr->fragmentCount = 1;
  105.     ecbptr->socketNumber  = soknum;
  106.     ecbptr->ESRAddress[0] = 0;
  107.     ecbptr->ESRAddress[1] = 0;
  108.     SPXlsncon(0,1,ecbptr);
  109. #ifdef SPXDEBUG
  110. display(":: Listen set for ECB");numdis(ecbptr - savecb);
  111. #endif
  112. }
  113.  
  114. SetUpIntECB(n)
  115. int n;
  116. {
  117.     FAST ECB *ecbptr;
  118.     int i;
  119.  
  120.     ecbptr = savecb + nrcv;
  121.     for (i = 0; i < n; i++, ecbptr++)
  122.         retlst(ecbptr);
  123.     return(0);
  124. }
  125.  
  126. TEXT *getmid(sizmsg,maxusr)
  127. UCOUNT         sizmsg;
  128. COUNT            maxusr;
  129. {
  130.     TEXT    majrev,minrev;
  131.     UCOUNT  maxcon,avlcon;
  132.     ECB    *getECB();
  133.  
  134. #ifdef SPXDEBUG
  135. display("\rbeginning of getmid\n");
  136. #endif
  137.     nusr = maxusr;
  138.     nbuf = 2 * nusr;
  139.     if (nbuf > (nusr + ACKBUF)) nbuf = nusr + ACKBUF;
  140.     nrcv = nbuf - nusr;
  141.  
  142.     /* allocate an array for message ids: assumes long is OK */
  143.     if ((ausrmid = (LONG *) mballc(maxusr + 1,sizeof(LONG))) == NULL) {
  144.         uerr_cod = SSCB_ERR;
  145.         return(NULL);
  146.     }
  147.  
  148.     /* get message id for server */
  149.     uerr_cod = xerr = 0;
  150.  
  151.     if ((0x00ff & (xerr = SPXinit(&majrev,&minrev,&maxcon,&avlcon)))
  152.         == (0x00ff & SPX_NOT_INSTALLED))
  153.         uerr_cod = SSKY_ERR;
  154.     else if (xerr = IPXopen(&soknum,0))
  155.         uerr_cod = SSID_ERR;
  156.     else
  157.         msgsiz          = DATA_SIZE;
  158.  
  159.     if (uerr_cod)
  160.         return(NULL);
  161. #ifdef SPXDEBUG
  162. display("\rSPX init complete\n");
  163. #endif
  164.  
  165. /*
  166.  * Is there a need for 2*(maxusr+1) message blocks to allow
  167.  * for communications when the server is full?
  168.  */
  169.     if ((savecb = getECB(nbuf)) == NULL) {
  170.         uerr_cod = ASPC_ERR;
  171.         return(NULL);
  172.     } else if (SetUpRcvECB(nrcv))
  173.         return(NULL);
  174.     else if (SetUpIntECB(nusr))
  175.         return(NULL);
  176.  
  177. #ifdef SPXDEBUG
  178. display("\rgetmid complete\n");
  179. #endif
  180.  
  181.     return(savdat);
  182. }
  183.  
  184. LONG getumsg(pmsg,usrn,msgptr)
  185. MESSAGE        *pmsg;
  186. COUNT          usrn;
  187. TEXT              *msgptr;
  188. {
  189.     UCOUNT locmid;
  190.     FAST ECB *ecbptr;
  191.     SPXHDR *spxptr;
  192.  
  193.     locmid = (msgptr - savdat) / DATA_SIZE;
  194.     ecbptr = savecb + locmid;
  195.     cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
  196.     locmid = spxptr->destConnectionID;
  197.  
  198.     /* save message id: assumes that a long is sufficient */
  199.     if (usrn >= 0)
  200.         ausrmid[usrn] = locmid;
  201.  
  202.     return((LONG) locmid);
  203. }
  204.  
  205. COUNT ridmid()
  206. {
  207.     int i;
  208.  
  209.     /* delay */
  210.     for (i = 0; i < 10000; i++)
  211.         IPXrelq();
  212.  
  213.     /* remove application message handling */
  214.         return(NO_ERROR);
  215. }
  216.  
  217. VOID retecb(ecbptr)
  218. PFAST ECB  *ecbptr;
  219. {
  220.     ecbtyp[ecbptr - savecb] = 0;
  221.     ecbptr->fragmentCount   = 2;
  222.     ecbptr->fragmentDescriptor[1].size = DATA_SIZE;
  223.     SPXlisten(ecbptr);
  224. }
  225.  
  226. COUNT dedusr(msgid)
  227. LONG         msgid;
  228. {
  229.     COUNT usrn;
  230.  
  231.     for (usrn = 0; usrn < cts_mxusr; usrn++)
  232.         if (msgid == ausrmid[usrn]) {
  233.             ausrmid[usrn] = 0;
  234.             return(usrn);
  235.         }
  236.     return(-1);
  237. }
  238.  
  239. COUNT ctrqst(msgadr,pmsg)
  240. PFAST TEXT **msgadr;
  241. MESSAGE           *pmsg;
  242. {
  243.     SPXHDR *spxptr;
  244.     COUNT          ecbflg;
  245.     UCOUNT          locmid;
  246.     FAST COUNT      i;
  247.     FAST ECB     *ecbptr;
  248.  
  249. wait_loop:
  250.     ecbflg = NO;
  251.     for (i = ecbpos, ecbptr = savecb + i; i < nbuf; i++, ecbptr++) 
  252.         if (ecbptr->inUseFlag == 0) {
  253.             if (ecbtyp[i])
  254.                 retecb(ecbptr);
  255.             else {
  256.                 ecbflg = YES;
  257.                 break;
  258.             }
  259.         }
  260.     if (!ecbflg) for (i = 0, ecbptr = savecb; i < ecbpos; i++, ecbptr++)
  261.         if (ecbptr->inUseFlag == 0) {
  262.             if (ecbtyp[i])
  263.                 retecb(ecbptr);
  264.             else {
  265.                 ecbflg = YES;
  266.                 break;
  267.             }
  268.         }
  269.  
  270.     if (!ecbflg) {
  271.         if (++idle > STRETCH)
  272.             dlayvap();
  273.         else
  274.             IPXrelq();
  275.         goto wait_loop;
  276.     } else {
  277.         idle   = 0;
  278.         ecbpos = (i + 1) % nbuf;
  279.     }
  280.  
  281.     /* check if message is administrative (established connection / 
  282.        terminate connection) / a regular msg / or a failed msg
  283.     */
  284.  
  285.     /* get address of SPX header fragment */
  286.     cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
  287.  
  288.     ecbflg = RCV;
  289.     /* if only one fragment, then administrative */
  290.     if (ecbptr->fragmentCount == 1) {
  291.         if ((0x00ff & spxptr->dataStreamType) ==
  292.            (0x00ff & SPX_CLEAN_TERMINATION)) {
  293.             display("\n\rc-tree Unexpected Connection Terminate");
  294.             retlst(ecbptr);
  295.         } else if ((0x00ff & ecbptr->completionCode) ==
  296.             (0x00ff & SPX_CONNECTION_TERMINATED)) {
  297.             /* IPXWorkspace contains conid. call routine to stpusr*/
  298.             cpybuf(&locmid,ecbptr->IPXWorkspace,sizeof(UCOUNT));
  299.             if ((i = dedusr((LONG) locmid)) > -1)
  300.                 stpusr(i);
  301.             retlst(ecbptr);
  302.         } else if (ecbptr->completionCode == 0) {
  303.             ecbflg = LSN;
  304.             retecb(ecbptr);
  305.         } else {
  306.             display("\n\rc-tree Unknown Admin Message: ");
  307.             numdis(ecbptr->completionCode);
  308.             retlst(ecbptr);
  309.         }
  310.         goto wait_loop;
  311.     } else if ((0x00ff & ecbptr->completionCode) ==
  312.         (0x00ff & SPX_CONNECTION_TERMINATED)) {
  313.         /* IPXWorkspace contains conid. call routine to stpusr */
  314.         cpybuf(&locmid,ecbptr->IPXWorkspace,sizeof(UCOUNT));
  315.         if ((i = dedusr((LONG) locmid)) > -1) {
  316.             stpusr(i);
  317.             retlst(ecbptr);
  318.         } else
  319.             retecb(ecbptr);
  320.         goto wait_loop;
  321.     }
  322.  
  323.     cpybuf(msgadr,ecbptr->fragmentDescriptor[1].address,
  324.         sizeof(char *));
  325.  
  326.     /* copy message header */
  327.     cpybuf(pmsg,*msgadr,sizeof(MESSAGE));
  328.  
  329.     return(NO_ERROR);
  330. }
  331.  
  332. COUNT ctrspn(msgadr,pmsg,sizmsg,usrn)
  333. PFAST TEXT  *msgadr;
  334. MESSAGE           *pmsg;
  335. UCOUNT             sizmsg;
  336. COUNT                usrn;
  337. {
  338.     /* local copy of message id with correct type */
  339.     UCOUNT locmid;
  340.  
  341.     FAST ECB *ecbptr;
  342.     SPXHDR *spxptr;
  343.  
  344.     /* copy message header */
  345.     cpybuf(msgadr,pmsg,sizeof(MESSAGE));
  346.  
  347.     locmid = (msgadr - savdat) / DATA_SIZE;
  348.     if (usrn >= 0)
  349.         ecbtyp[locmid] = YES;
  350.     ecbptr = savecb + locmid;
  351.     cpybuf(&spxptr,ecbptr->fragmentDescriptor[0].address,sizeof(char *));
  352.  
  353.     spxptr->dataStreamType = 0;
  354.     spxptr->connectionControl = 0x10;
  355.     ecbptr->fragmentCount = 2;
  356.     ecbptr->fragmentDescriptor[1].size = sizmsg;
  357.     
  358.     if (usrn >= 0) {
  359.         locmid = ausrmid[usrn];
  360.         SPXsend(locmid,ecbptr);
  361.     } else {
  362.         usrn    = - (usrn + 1);
  363. #ifdef SPXDEBUG
  364. display(":: Attempt to logout");numdis(usrn);
  365. #endif
  366.         locmid    = ausrmid[usrn];
  367.         SPXsend(locmid,ecbptr);
  368.         while (ecbptr->inUseFlag)
  369.             IPXrelq();
  370.         retlst(ecbptr);
  371.         ausrmid[usrn] = 0;
  372.     }
  373.     return(NO_ERROR);
  374. }
  375.  
  376. COUNT norspn(usrn)
  377. COUNT         usrn;
  378. {
  379.     return(NO);
  380. }
  381.  
  382. chkusrtim(usrtim,usrmap,usrtrn)
  383. LONG     *usrtim;
  384. COUNT        *usrmap;
  385. LONG               *usrtrn;
  386. {
  387.     TEXT      retmsg[48];
  388.     UCOUNT      locmid;
  389.     COUNT      i,j;
  390.     FAST ECB *ecbptr;
  391.  
  392. #ifdef SPXDEBUG
  393. display("\n\rchkusrtim ");
  394. #endif
  395.     for (i = 0; i < cts_mxusr; i++) {
  396.         if (usrmap[i]) {
  397.         locmid = ausrmid[i];
  398. #ifdef SPXDEBUG
  399. numdis(i);numdis(locmid);
  400. #endif
  401.         if (SPXstatus(locmid,retmsg)) {
  402.             stpusr(i);
  403.             ausrmid[i] = 0;
  404. #ifdef SPXDEBUG
  405. display("\n\rFound disconnection\n");
  406. #endif
  407.             for (j = 0, ecbptr = savecb; j < nbuf; j++, ecbptr++) 
  408.                 if (ecbptr->inUseFlag && ecbptr->fragmentCount
  409.                     == 2 && IPXcancel(ecbptr) == 0) {
  410.                     retlst(ecbptr);
  411.                     break;
  412.                 }
  413. #ifdef SPXDEBUG
  414.             if (j >= nbuf) display("\n\rCould not relisten\n");
  415. #endif
  416.             break; /* only free up one disconnection per login */
  417.         }
  418. #ifdef SPXDEBUG
  419. else numdis(retmsg[0]);
  420. #endif
  421.         }
  422.     }
  423.     return(NO_ERROR);
  424. }
  425.  
  426. /* end of ctsmsg.nov */
  427.