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