home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / spxdos.exe / SUPPORT.C < prev   
Text File  |  1995-01-27  |  12KB  |  480 lines

  1. /****************************************************************************
  2. **    File:    Support.C    
  3. **
  4. **    Desc:    Sample SPX chat program.    
  5. **
  6. **            This Sample code demonstrates how to set up and use SPX
  7. **            communications to communicate between 2 nodes.
  8. **        
  9. **        
  10. **        
  11. **
  12. **        DISCLAIMER  
  13. **  
  14. **    Novell, Inc. makes no representations or warranties with respect to
  15. **    any NetWare software, and specifically disclaims any express or
  16. **    implied warranties of merchantability, title, or fitness for a
  17. **    particular purpose.  
  18. **
  19. **    Distribution of any NetWare software is forbidden without the
  20. **    express written consent of Novell, Inc.  Further, Novell reserves
  21. **    the right to discontinue distribution of any NetWare software.
  22. **    
  23. **    Novell is not responsible for lost profits or revenue, loss of use
  24. **    of the software, loss of data, costs of re-creating lost data, the
  25. **    cost of any substitute equipment or program, or claims by any party
  26. **    other than you.  Novell strongly recommends a backup be made before
  27. **    any software is installed.   Technical support for this software
  28. **    may be provided at the discretion of Novell.
  29. **
  30. **    Programmers:
  31. **
  32. **        Ini    Who                        Firm
  33. **        -----------------------------------------------------------------------
  34. **        TDOC  Technical Documentation Team
  35. **        KLB    Karl Bunnell                Novell Developer Support.
  36. **
  37. **    History:
  38. **
  39. **        When        Who    What
  40. **        -----------------------------------------------------------------------
  41. **        10-25-88    TDOC    First code.
  42. **        01-27-95 KLB   Ported this example to the NetWare Client SDK
  43. */
  44.  
  45. /****************************************************************************
  46. **    Include headers, macros, function prototypes, etc.
  47. */
  48.     /*------------------------------------------------------------------------
  49.     **    MACROS
  50.     */
  51.     #define NWDOS
  52.  
  53.  
  54.     /*------------------------------------------------------------------------
  55.     **    ANSI
  56.     */
  57.     #include <stdio.h>
  58.     #include <string.h>
  59.     #include <malloc.h>
  60.  
  61.  
  62.     /*------------------------------------------------------------------------
  63.     **    NetWare
  64.     */
  65.     #include <nwcalls.h>
  66.     #include <nwipxspx.h>
  67.  
  68.     #include <ctype.h>
  69.     #include "chat.h"
  70.  
  71.     /*------------------------------------------------------------------------
  72.     **    GLOBALS
  73.     */
  74.  
  75.  
  76.  
  77.     ECB            sendECB[NUM_SEND_ECBS],    *ECBqueue[NUM_RECEIVE_ECBS];
  78.     SPXHeader    sendHeader[NUM_SEND_ECBS];
  79.     WORD        SPXConnectionNumber, Socket = SESSION_SOCKET, connectionID,
  80.                 preferredConnectionID = 0, listeningConnection;
  81.     BYTE        immediateAddress[6], networkNumber[4];
  82.     CONNECTION_INFO connectionInfo[44];
  83.     char        OutChars[NUM_SEND_ECBS],    character,
  84.                 hello[] = " wants to CHAT.  To answer, type HELLO ";
  85.     int            RECEIVE_FLAG = FALSE, ACTIVE_CONNECTION = 1;
  86.     extern int    sendRow, sendCol, receiveRow, receiveCol;
  87.     NETWORK_NODE    destNode, callNode;
  88.  
  89.     void       SetUpSendECB();
  90.     void    SetUpReceiveECBs();
  91.     void    SendPacket();
  92.     void    TearDownConnection();
  93.     ECB        *SetUpInitialECB();
  94.     void    SendMessage();
  95.     void    PrintCharacter();
  96.     int        PollForMessage();
  97.     void    ListenESR();
  98.  
  99.     extern    void far ESRHandler();
  100.     extern    void Update();
  101.     extern    void ScrollUp();
  102.     extern    void SetCursor();
  103.     extern    DeleteChar();
  104.  
  105.     extern NWCONN_HANDLE connHandle;
  106.  
  107. ECB *SetUpInitialECB()
  108. {
  109.     static     ECB            initialECB;
  110.     static    SPXHeader    initialHeader;
  111.     unsigned    transportTime;
  112.     NETWORK_ADDR    iNetAddress;
  113.     BYTE         immediateAddress[6];
  114.     WORD        mysocket;
  115.     NWGetInternetAddress (connHandle, listeningConnection, (BYTE *)&iNetAddress);
  116.     
  117.     memcpy(&destNode, iNetAddress.node, 6);
  118.     memcpy(&networkNumber, iNetAddress.network, 4);
  119.  
  120.  /* Put the destination header in the address */
  121.      memcpy(initialHeader.destination.network, networkNumber, 4);
  122.     memcpy(initialHeader.destination.node, &destNode, 6);
  123.     memcpy(&initialHeader.destination.socket, &Socket, 2);
  124.     initialHeader.packetType = 5;
  125.     initialHeader.length = IntSwap(sizeof(SPXHeader));
  126.  
  127.  /* Now initialzie your initial ECB */
  128.     initialECB.socketNumber = Socket;
  129.     initialECB.inUseFlag = 0;
  130.     initialECB.ESRAddress = 0; /* no event service routine, just poll */
  131.     initialECB.fragmentCount = 1;
  132.     initialECB.fragmentDescriptor[0].address = &initialHeader;
  133.     initialECB.fragmentDescriptor[0].size = sizeof(initialHeader);
  134.  
  135.     return( (ECB *)&initialECB );
  136. }
  137.  
  138.  
  139. void SetUpReceiveECBs()
  140. {
  141.     int        i;
  142.     char    *inChar;
  143.     ECB            *receiveECB;
  144.     SPXHeader    *receiveHeader;
  145.  
  146.     for ( i = 0; i < NUM_RECEIVE_ECBS; i++ )
  147.     {
  148.         if( (receiveECB = (ECB *)calloc(1,sizeof(ECB)) ) == (ECB *)NULL )
  149.             Error("Out of memory during packet allocation",0);
  150.  
  151.         if( (receiveHeader = (SPXHeader *)calloc(1,sizeof(SPXHeader)) ) == (ECB *)NULL)
  152.             Error("Out of memory during packet allocation",0);
  153.  
  154.         if ( (inChar = (char *)calloc(1,sizeof(char)) ) == (ECB *)NULL)
  155.             Error("Out of memory during packet allocation",0);
  156.  
  157.         receiveHeader->packetType = (char)5;
  158.         receiveHeader->length = IntSwap(sizeof(SPXHeader));
  159.  
  160.         receiveECB->ESRAddress = (void (far *)())ESRHandler;
  161.         receiveECB->socketNumber = Socket;
  162. //        memcpy(receiveECB->immediateAddress, &destNode, 6);
  163.         receiveECB->fragmentCount = 2;
  164.         receiveECB->fragmentDescriptor[0].address = receiveHeader;
  165.         receiveECB->fragmentDescriptor[0].size = sizeof(SPXHeader);
  166.         receiveECB->fragmentDescriptor[1].address = inChar;
  167.         receiveECB->fragmentDescriptor[1].size = sizeof(char);
  168.         SPXListenForSequencedPacket (receiveECB);
  169.     }
  170. }
  171.  
  172. void SetUpSendECB()
  173. {
  174.     int     i;
  175.  
  176.     for (i = 0; i < NUM_SEND_ECBS; i++)
  177.     {
  178.      /* Fill in your address */
  179.         IPXGetInternetworkAddress(sendHeader[i].source.network); /* includes the source node */
  180.         memcpy( &sendHeader[i].source.socket, &Socket, 2);
  181.  
  182.      /* Fill in the destination address */
  183.         memcpy(sendHeader[i].destination.network, networkNumber, 4);
  184.         memcpy(sendHeader[i].destination.node, &destNode, 6);
  185.         memcpy(&sendHeader[i].destination.socket, &Socket, 2);
  186.         sendHeader[i].length = IntSwap(sizeof(SPXHeader));
  187.         sendHeader[i].packetType = 5;
  188.  
  189.      /* Now initialize the Send ECBs */
  190.         sendECB[i].ESRAddress = 0;     /* no routine, just polling */
  191.         sendECB[i].inUseFlag = 0;
  192.         sendECB[i].fragmentCount = 2;
  193.         sendECB[i].socketNumber = Socket;
  194. //        memcpy(sendECB[i].immediateAddress, &destNode, 6);
  195.         sendECB[i].fragmentDescriptor[0].address = (sendHeader + i);
  196.         sendECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
  197.         sendECB[i].fragmentDescriptor[1].address = (OutChars + i);
  198.         sendECB[i].fragmentDescriptor[1].size = sizeof(char);
  199.     }
  200. }
  201.  
  202. int    PollForPacket()
  203. {
  204.     BYTE    dataType;
  205.     char    ch, *charPtr;
  206.     static int     out;
  207.  
  208.     if (RECEIVE_FLAG > 0)
  209.     {
  210.      /* Set the queue pointer */
  211.         if (++out >= 20)
  212.             out = 0;
  213.  
  214.      /* Get the data type */
  215.         dataType = (BYTE)( ((SPXHeader *)ECBqueue[out]->fragmentDescriptor[0].address)->dataStreamType);
  216.  
  217.         if (dataType == TERMINATING_PACKET ) 
  218.         {
  219.             Update("Connection has been terminated");    
  220.             return(0);
  221.         }    
  222.  
  223.      /* Get the character */
  224.          charPtr = (char *)(ECBqueue[out]->fragmentDescriptor[1].address);
  225.         memcpy (&character, charPtr, 1);
  226.     
  227.       /* Release the ECB and print the character */
  228.          SPXListenForSequencedPacket (ECBqueue[out]); 
  229.         --RECEIVE_FLAG;
  230.         PrintCharacter();
  231.     }
  232.     return(1);
  233. }
  234.  
  235.  
  236.  
  237. void PrintCharacter()
  238. {
  239.     int        i;
  240.     char    ch;
  241.  
  242.     CursorOff();
  243.      switch (character)
  244.     {
  245.         case TAB:
  246.             ClearReceiveBox();
  247.             break;
  248.           case ENTER:
  249.             receiveRow++;
  250.             if (receiveRow > LAST_RECEIVE_ROW) 
  251.             {
  252.                 receiveRow = LAST_RECEIVE_ROW;
  253.                 ScrollUp (1, TOP_RECEIVE_ROW, LAST_RECEIVE_ROW, FIRST_TEXT_COL, LAST_TEXT_COL);
  254.             }
  255.             receiveCol = FIRST_TEXT_COL;
  256.             break;
  257.         case BACKSPACE:
  258.             if (receiveCol > FIRST_TEXT_COL)
  259.                 DeleteChar (&receiveCol, &receiveRow);
  260.             break;
  261.         default:
  262.             if (receiveCol >= LAST_TEXT_COL)
  263.             {
  264.                 receiveCol = FIRST_TEXT_COL;
  265.                 receiveRow++;
  266.             }
  267.  
  268.             if (receiveRow > LAST_RECEIVE_ROW) 
  269.             {
  270.                 receiveRow = LAST_RECEIVE_ROW;
  271.                 ScrollUp(1,TOP_RECEIVE_ROW,LAST_RECEIVE_ROW,FIRST_TEXT_COL,LAST_TEXT_COL);
  272.             }
  273.             SetCursor(receiveRow, receiveCol++);
  274.             putchar(character);
  275.             break;
  276.     }
  277.     SetCursor(sendRow, sendCol);
  278.     CursorOn();
  279. }
  280.  
  281.  
  282. void ListenESR(receiveECBptr)
  283. ECB *receiveECBptr;
  284. {
  285.     SPXHeader    *header;
  286.     static int    in; 
  287.  
  288.     if (++in >= 20)
  289.         in = 0;
  290.  
  291.     ECBqueue[in] = receiveECBptr;        
  292.     ++RECEIVE_FLAG;
  293.     return;
  294. }
  295.  
  296.  
  297. void SendPacket(charBuffer)
  298. char *charBuffer;
  299. {
  300.     int     ccode = 0, i;
  301.  
  302.     i = FindECB();
  303.  
  304.  /* Check for a valid connection */
  305.     ccode = SPXGetConnectionStatus(SPXConnectionNumber, connectionInfo);
  306.      if (ccode)
  307.          Error("Invalid connection.");
  308.  
  309.  /* Send character */
  310.      memcpy( (OutChars + i), charBuffer, 1);
  311.     SPXSendSequencedPacket (SPXConnectionNumber, (sendECB + i) );
  312.  
  313.      if(sendECB[i].completionCode != 0)
  314.         ACTIVE_CONNECTION = 0;
  315.     else
  316.         Update ("Connection is active.");
  317. }
  318.  
  319.  
  320.  
  321. void TearDownConnection()
  322. {
  323.     int     i;
  324.  
  325.     i = FindECB();
  326.  
  327.     sendECB[i].ESRAddress = 0;
  328.     sendECB[i].fragmentCount = 1;
  329.     sendECB[i].fragmentDescriptor[0].size = 42;
  330.  
  331.     SPXTerminateConnection( SPXConnectionNumber, (sendECB + i) );
  332.  
  333.  /* Wait until the Terminate has completed */
  334.     while ( sendECB[i].inUseFlag )
  335.         /* wait */;
  336.     
  337.     IPXCloseSocket(Socket);
  338.  
  339.     ClearScreen();
  340. }
  341.  
  342.  
  343. FindECB()
  344. {
  345.     int        ALL_ECBS_ARE_BUSY = 1, ECBnumber;
  346.  
  347.     while (ALL_ECBS_ARE_BUSY)
  348.     {
  349.         for (ECBnumber = 0; ECBnumber < NUM_SEND_ECBS; ECBnumber++)
  350.         {
  351.             if (!sendECB[ECBnumber].inUseFlag)
  352.             {
  353.                 ALL_ECBS_ARE_BUSY = FALSE;
  354.                 break;
  355.             }
  356.             else if (ECBnumber == (NUM_SEND_ECBS - 1) )
  357.                 Update ("Your partner has suspended the connection.  Please wait.");
  358.         }
  359.     }
  360.     return (ECBnumber);
  361. }
  362.  
  363. ParseDestination(server, user, command)
  364. char    *server, *user, *command;
  365. {
  366.     int        ch,    i = 0, j = 0;
  367.  
  368.     while ( (ch = *(command + i)) != '/' )
  369.     {
  370.         ch = toupper (ch);
  371.         *(server + i++) = (char)ch;
  372.         if (ch == '\0')
  373.         {
  374.             printf ("CHAT.EXE v1.01\n");
  375.             printf ("by Novell Technical Documentation\n\n");
  376.             printf ("Format: Chat fileserver/username\n");
  377.             printf ("Example: Chat Server_1/Rasputin\n");
  378.             exit (); 
  379.         }
  380.     }
  381.     *(server + i++) = '\0';
  382.  
  383.     while( (ch = *(command + i++)) != '\0' )
  384.     {
  385.         ch = toupper(ch);
  386.         *(user + j++) = (char)ch;
  387.     }
  388.     *(user + j) = '\0';
  389.  
  390. }
  391.  
  392.  
  393. GetConnectionAndNode(preferredServer, userName, connection)
  394. char    *preferredServer, *userName;
  395. WORD    *connection;
  396.  
  397. {
  398.     WORD    *count, max = 100, mysocket;
  399.     int        ccode;
  400.     char    networkNumber[4];
  401.     BYTE    address[6];
  402.     NETWORK_ADDR    iNetAddress;
  403.  
  404.  /* Get the connection number of listening side */
  405.     ccode = NWGetObjectConnectionNumbers(connHandle, userName, OT_USER, count,
  406.                 connection, max);
  407.  
  408.  /* Get the node address of the listening side */
  409.  
  410.     NWGetInternetAddress (connHandle, listeningConnection, (BYTE *)&iNetAddress);
  411.     
  412.     memcpy(&destNode, iNetAddress.node, 6);
  413.     memcpy(&networkNumber, iNetAddress.network, 4);
  414.  
  415. /*     destNode.hiNode = IntSwap(destNode.hiNode);
  416.     destNode.loNode = LongSwap(destNode.loNode); */
  417. }
  418.  
  419.  
  420. SayHello(listeningConnection)
  421. WORD    *listeningConnection;
  422. {
  423.     BYTE    time[7], address[6];
  424.     NWFLAGS    result;
  425.     WORD    callingConnection;
  426.     char    callerName[48], networkNumber[4], connString[3];
  427.     int        type, ccode;
  428.     long    IDNumber;
  429.  
  430.  /* Get connection number of calling side */
  431.     NWGetConnectionNumber(connHandle, &callingConnection);
  432.  
  433.  /* Use the connection number to get the name of the caller */
  434.     NWGetConnectionInformation(connHandle, callingConnection, callerName, &type,
  435.             &IDNumber, time);
  436.  
  437.  /* Create broadcast message */
  438.       ConvertToString(&callingConnection, connString, 1); 
  439.     strncat(callerName, hello, sizeof(hello) );
  440.     strncat(callerName, connString, sizeof(connString));
  441.     ccode = NWSendBroadcastMessage(connHandle, callerName, 1, listeningConnection, &result);
  442.     return( ccode );
  443. }
  444.  
  445. ConvertToString(number, string, size)
  446. char    *number,*string,size;
  447. {
  448.     char        i, j, k;
  449.     int            left = 1;
  450.  
  451.     for (i = j = k = 0; i < size; i++)
  452.     {
  453.         if (left)
  454.         {
  455.             j = *(number + i--);
  456.             j = j & 0x00F0;
  457.             j = j >> 4;
  458.             left--;
  459.         }
  460.  
  461.         else
  462.         {
  463.             j = *(number + i);
  464.             j = j & 0x000F;
  465.             left++;
  466.         }
  467.  
  468.         if (j < 10)
  469.              *(string + k++) = j + 0x30;
  470.         else
  471.              *(string + k++) = j + 0x37;
  472.  
  473.     }
  474.    *(string + k) = '\0';
  475.  
  476. }
  477.  
  478.  
  479.  
  480.