home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / xsap1a.exe / CLIENT.C next >
Text File  |  1994-09-14  |  15KB  |  562 lines

  1. /****************************************************************************
  2. **    File:    CLIENT.C
  3. **
  4. **    Desc:
  5. **
  6. **        Example of a DOS client which enlists the help of a SAPing server
  7. **        process.  
  8. **
  9. **    Disclaimer:
  10. **
  11. **        Novell, Inc. makes no representations or warranties with respect to
  12. **        any NetWare software, and specifically disclaims any express or
  13. **        implied warranties of merchantability, title, or fitness for a
  14. **        particular purpose.  
  15. **
  16. **        Distribution of any NetWare software is forbidden without the
  17. **        express written consent of Novell, Inc.  Further, Novell reserves
  18. **        the right to discontinue distribution of any NetWare software.
  19. **
  20. **        Novell is not responsible for lost profits or revenue, loss of use
  21. **        of the software, loss of data, costs of re-creating lost data, the
  22. **        cost of any substitute equipment or program, or claims by any party
  23. **        other than you.  Novell strongly recommends a backup be made before
  24. **        any software is installed.   Technical support for this software
  25. **        may be provided at the discretion of Novell.
  26. **
  27. **
  28. **    Programmers:
  29. **
  30. **        Ini    Who                        Firm
  31. **        -----------------------------------------------------------------------
  32. **        ABJ    Adam B. Jerome            Novell Developer Support.
  33. **
  34. **    History:
  35. **
  36. **        When        Who    What
  37. **        -----------------------------------------------------------------------
  38. **        08-19-94    ABJ    First code.
  39. **        09-14-94 ABJ    Fixed the LocateScanID() function so that it works.
  40. **                            (See header to LocateScanID() for details.)
  41. */
  42.  
  43. /****************************************************************************
  44. **    Include headers, macros, function prototypes, etc.
  45. */
  46.     /*------------------------------------------------------------------------
  47.     **    ANSI
  48.     */
  49.     #include <stdlib.h>    /*    exit()    */
  50.     #include <stdio.h>    /* printf() */
  51.     #include <string.h>    
  52.     #include <conio.h>      
  53.     #include <time.h>
  54.  
  55.     /*------------------------------------------------------------------------
  56.     **    NetWare
  57.     */
  58.     #define NWDOS
  59.     #include <nwcalls.h>
  60.     #include <nwipxspx.h>
  61.  
  62.     /*------------------------------------------------------------------------
  63.     **    CLIENT
  64.     */
  65.     #include "common.h"
  66.  
  67. /****************************************************************************
  68. ** Communicate with server.
  69. */
  70. int ComReq(IPXAddress *addr, COM_DATA_PACKET *txData, COM_DATA_PACKET *rxData, int retryCount, double timeOut)
  71.     {
  72.     WORD             listenSocket = 0x0000;  /* zero value causes NetWare to allocate a socket dynamicly */
  73.     time_t        dTime = 0L;
  74.  
  75.     int             cCode;
  76.     int            transportTime;
  77.  
  78.     ECB            rxEcb;
  79.     IPXHeader    rxIpxHeader;
  80.     
  81.     ECB            txEcb;
  82.     IPXHeader    txIpxHeader;
  83.  
  84.     /*------------------------------------------------------------------------
  85.     ** Initialize storage.
  86.     */
  87.     memset(&rxEcb, 0x00, sizeof(rxEcb));
  88.     memset(&rxIpxHeader, 0x00, sizeof(rxIpxHeader));
  89.  
  90.     memset(&txEcb, 0x00, sizeof(txEcb));
  91.     memset(&txIpxHeader, 0x00, sizeof(txIpxHeader));
  92.     
  93.     /*------------------------------------------------------------------------
  94.     ** Get NetWare to assign us a dynamic socket number to listen on.
  95.     */
  96.     cCode=IPXOpenSocket((BYTE *)&listenSocket, 0x00);
  97.     switch(cCode)
  98.         {
  99.         case 0x0000:
  100.             break;
  101.  
  102.         case 0x00F0:
  103.             printf("ERROR:  IPX is not installed.\n");
  104.             goto END;
  105.  
  106.         case 0x00FF:
  107.             printf("ERROR:  IPX socket 0x%04hX is already in use on this node.\n", listenSocket);
  108.             goto END;
  109.  
  110.         case 0x00FE:
  111.             printf("ERROR:  IPX socket table is full on this node.\n");
  112.             goto END;
  113.  
  114.         default:
  115.             printf("ERROR:  IPXOpenSocket() returned an unknown error: %d\n", cCode);
  116.             goto END;
  117.         }
  118.  
  119.     /*------------------------------------------------------------------------
  120.     ** Set up a listen ECB.
  121.     */
  122.     rxEcb.ESRAddress     = NULL;
  123.     rxEcb.socketNumber     = listenSocket;
  124.     rxEcb.fragmentCount = 2;
  125.     rxEcb.fragmentDescriptor[0].address        = &rxIpxHeader;
  126.     rxEcb.fragmentDescriptor[0].size         =    sizeof(rxIpxHeader);
  127.  
  128.     rxEcb.fragmentDescriptor[1].address        =    rxData;
  129.     rxEcb.fragmentDescriptor[1].size         =    sizeof(COM_DATA_PACKET);
  130.     IPXListenForPacket(&rxEcb);
  131.  
  132.     /*------------------------------------------------------------------------
  133.     ** Setup send ECB.
  134.     */
  135.     txEcb.ESRAddress     = NULL;
  136.     txEcb.socketNumber     = listenSocket;
  137.     
  138.     cCode=IPXGetLocalTarget(
  139.         /* I-    networkAddress        */    (BYTE *)addr,
  140.         /*    -O    immediateAddress    */    txEcb.immediateAddress,
  141.         /* -O    transportTime        */    &transportTime
  142.         );
  143.     switch(cCode)
  144.         {
  145.         case 0x0000:
  146.             break;
  147.  
  148.         case 0xFA:
  149.             printf("ERROR:  No local target identified.\n");
  150.             goto END;
  151.  
  152.         default:
  153.             printf("ERROR:  IPXGetLocalTarget() returned unknown error: %d.\n", cCode);
  154.             goto END;
  155.         }
  156.  
  157.     txEcb.fragmentCount = 2;
  158.     txEcb.fragmentDescriptor[0].address        = &txIpxHeader;
  159.     txEcb.fragmentDescriptor[0].size         =    sizeof(txIpxHeader);
  160.  
  161.     txEcb.fragmentDescriptor[1].address        =    txData;
  162.     txEcb.fragmentDescriptor[1].size         =    sizeof(COM_DATA_PACKET);
  163.     
  164.     txIpxHeader.packetType    = 0x04;     /* IPX packet type. */
  165.     memcpy(&txIpxHeader.destination, addr, sizeof(IPXAddress));
  166.     
  167.     /*------------------------------------------------------------------------
  168.     ** Wait for recieve ECB to happen.
  169.     */
  170.     while(rxEcb.inUseFlag != 0x00)
  171.         {
  172.         /*---------------------------------------------------------------------
  173.         ** First time in or Timeout/re-send?
  174.         ** 
  175.         ** time is initialized to 0, therfore, packet will be sent first time
  176.         **    in.
  177.         */
  178.         if(difftime(time(NULL), dTime) > timeOut)
  179.             {
  180.  
  181.             /*------------------------------------------------------------------------
  182.             **    Send packet.
  183.             */
  184.             time(&dTime);
  185.             --retryCount;
  186.             IPXSendPacket(&txEcb);
  187.  
  188.             /*------------------------------------------------------------------------
  189.             ** Wait for send to happen.
  190.             */
  191.             while(txEcb.inUseFlag != 0x00)
  192.                 {
  193.                 if(kbhit())
  194.                     {
  195.                     printf("NOTE: TX aborted by user request.\n");
  196.                     cCode=IPXCancelEvent(&txEcb);
  197.                     switch(cCode)
  198.                         {
  199.                         case 0x0000:
  200.                             break;
  201.  
  202.                         case 0xF9:
  203.                             printf("WARNING-tx: ECB cannot be canceled.\n");
  204.                             break;
  205.  
  206.                         case 0xFF:
  207.                             printf("NOTE-tx: ECB not in use.\n");
  208.                             break;
  209.  
  210.                         default:
  211.                             printf("ERROR-tx:  IPXCancelEvent() returned unknown error: %d\n", cCode);
  212.                             break;
  213.                         }
  214.                     }
  215.  
  216.                 IPXRelinquishControl();
  217.                 }
  218.     
  219.             switch(txEcb.completionCode)
  220.                 {
  221.                 case 0x00:
  222.                     break;
  223.  
  224.                 case 0xFC:
  225.                     printf("NOTE-tx: Request canceled.\n");
  226.                     break;
  227.  
  228.                 case 0xFD:
  229.                     printf("ERROR-tx: Packet did not have a 30 byte header as the first fragment,\n"
  230.                              "          or its total length exceeded 576 bytes.\n");
  231.                     goto END;
  232.  
  233.                 case 0xFE:
  234.                     printf("ERROR-tx: Packet not deliverable.\n");
  235.                     goto END;
  236.  
  237.                 case 0xFF:
  238.                     printf("ERROR-tx: Hardware failure.\n");
  239.                     goto END;
  240.  
  241.                 default:
  242.                     printf("ERROR-tx:  Unknown ECB completion code on send: %d.\n", 0x000000FF & txEcb.completionCode);
  243.                     goto END;            
  244.                 }
  245.  
  246.             }
  247.  
  248.         /*---------------------------------------------------------------------
  249.         **    User or retry abort?
  250.         */
  251.         if(kbhit() || (retryCount == 0))
  252.             {
  253.             if(kbhit())
  254.                 {
  255.                 if(!getch()) getch();
  256.                 printf("NOTE: TX aborted by user request.\n");
  257.                 }
  258.             else
  259.                 printf("NOTE: Retry count limmit reached.\n");
  260.  
  261.             cCode=IPXCancelEvent(&rxEcb);
  262.             switch(cCode)
  263.                 {
  264.                 case 0x0000:
  265.                     break;
  266.  
  267.                 case 0xF9:
  268.                     printf("WARNING-rx: ECB cannot be canceled.\n");
  269.                     break;
  270.  
  271.                 case 0xFF:
  272.                     printf("NOTE-rx: ECB not in use.\n");
  273.                     break;
  274.  
  275.                 default:
  276.                     printf("ERROR-rx:  IPXCancelEvent() returned unknown error: %d\n", cCode);
  277.                     break;
  278.                 }
  279.             }
  280.         
  281.         IPXRelinquishControl();
  282.         }
  283.  
  284.     /*------------------------------------------------------------------------
  285.     ** Did we get something?
  286.     */
  287.     switch(rxEcb.completionCode)
  288.         {
  289.         case 0x00:
  290.             break;
  291.  
  292.         case 0xFC:
  293.             printf("NOTE-rx: Request canceled.\n");
  294.             break;
  295.  
  296.         case 0xFD:
  297.             printf("ERROR-rx: Bad packet\n");
  298.             goto END;
  299.  
  300.         case 0xFF:
  301.             printf("ERROR-rx: Hardware failure.\n");
  302.             goto END;
  303.  
  304.         default:
  305.             printf("ERROR-rx:  Unknown ECB completion code: %d.\n", 0x000000FF & rxEcb.completionCode);
  306.             goto END;            
  307.         }
  308.     cCode=rxEcb.completionCode;
  309.  
  310. END:
  311.  
  312.     /*------------------------------------------------------------------------
  313.     ** Give our socket back to NetWare.
  314.     */
  315.     if(listenSocket != 0x0000)
  316.         IPXCloseSocket(listenSocket);
  317.     
  318.     return(cCode);
  319.     }
  320.  
  321. /****************************************************************************
  322. ** Locate server using ScanID method.
  323. **
  324. **    When        Who    What
  325. **    --------------------------------------------------------------------------
  326. **    08-19-94    ABJ    First code.
  327. **    09-14-94 ABJ    Again, I was brain dead when I flipped out the first rev
  328. **                        of this code.
  329. **
  330. **                        -The function NWScanObject() was not needed and was 
  331. **                        removed.
  332. **
  333. **                        -The COM_SERVER_TYPE must be swapped in order for the older
  334. **                        NWReadPropertyValue() function to operate correctly.
  335. **
  336. **                        -fgets() leaves a <CR> on the end of the string.  It is now
  337. **                        removed.
  338. */
  339. int LocateScanID(IPXAddress *addr, char *serverName)
  340.     {
  341.     NWCCODE        cCode;
  342.     NWOBJ_ID        objectID = -1;
  343.     BYTE            propValue[128];
  344.     
  345.     /*------------------------------------------------------------------------
  346.     **    Get the name of the server.
  347.     */
  348.     if(serverName[0] == '\0')
  349.         {
  350.         printf("Server name: ");
  351.         fgets(serverName, 47, stdin);
  352.         serverName[strlen(serverName)-1] = '\0';  /* rid the nasty <CR> */
  353.         }
  354.  
  355.     /*------------------------------------------------------------------------
  356.     **    Read the address property
  357.     */
  358.     cCode = NWReadPropertyValue(
  359.         /* I- connHandle      */ 0,             /* 0 = default server connection */
  360.         /* I- objectName      */ serverName,
  361.         /* I- objectType      */ NWWordSwap(COM_SERVER_TYPE),
  362.         /* I- propertyName    */ "NET_ADDRESS",
  363.         /* I- dataSetIndx     */ 1,
  364.         /* -O dataBuffer      */ propValue,
  365.         /* -O moreFlag        */ NULL,
  366.         /* -O propertyFlags   */ NULL
  367.         );
  368.  
  369.     switch(cCode)
  370.         {
  371.         case 0x0000:
  372.             break;
  373.  
  374.         case 0x89F0:
  375.             printf("ERROR:  NWReadPropertyValue()     reports and invalid serverName or type.\n");
  376.             goto END;
  377.  
  378.         case 0x89FC:
  379.             printf("ERROR:  NWReadPropertyValue()  reports \"No such object.\"\n");
  380.             goto END;
  381.  
  382.         default:
  383.             printf("ERROR:  NWReadPropertyValue() returned 0x%04X\n", cCode);
  384.             goto END;
  385.         }
  386.  
  387.     /*------------------------------------------------------------------------
  388.     **    Copy network address
  389.     */
  390.     memcpy(addr, propValue, sizeof(IPXAddress));
  391.  
  392. END:
  393.  
  394.     return(cCode);
  395.     }
  396.  
  397. /****************************************************************************
  398. ** Locate server using Get Nearest method.
  399. */
  400. int LocateGetNearest(IPXAddress *addr)
  401.     {
  402.     SAP sap;
  403.     int cCode;
  404.     
  405.     memset(&sap, 0x00, sizeof(SAP));
  406.     cCode=QueryServices(
  407.         /* I- queryType        */    3,
  408.         /* I- serverType        */    COM_SERVER_TYPE,
  409.         /* I- returnSize        */    sizeof(SAP),
  410.         /*    -O serviceBuffer    */    &sap
  411.         );
  412.     switch(cCode)
  413.         {
  414.         case 0x0000:
  415.             printf("ERROR: ??? Cant find server ???\n");
  416.             cCode = 1;
  417.             goto END;
  418.  
  419.         case 0x0001:
  420.             printf("Server: %s\n", sap.ServerName);
  421.             cCode = 0;
  422.             break;
  423.  
  424.         default:
  425.             printf("ERROR: QueryServices() returned unknown error: %d.\n", cCode);
  426.             goto END;
  427.         }
  428.  
  429.     /*------------------------------------------------------------------------
  430.     **    Copy network address
  431.     */
  432.     memcpy(addr, sap.Network, sizeof(IPXAddress));
  433.  
  434. END:
  435.  
  436.     return(cCode);
  437.     }
  438.  
  439. /****************************************************************************
  440. ** Select method to locate server.
  441. */
  442. int LocateServer(IPXAddress *addr, int method, char *serverName)
  443.     {
  444.     int cCode;
  445.  
  446.     if(!method)
  447.         {
  448.         printf("Specify method to locate server:\n");
  449.         printf("\n");
  450.         printf("  0  Exit program.\n");
  451.         printf("\n");
  452.         printf("  1  Get Nearest\n");
  453.         printf("     This method assumes one of the following:\n");
  454.         printf("       A.  There is only one server of type 0x%04X\n", COM_SERVER_TYPE);
  455.         printf("       B.  All servers of type 0x%04X, provide exactly the same services.\n", COM_SERVER_TYPE);
  456.         printf("\n");
  457.         printf("  2  Scan Bindery or Directory services\n");
  458.         printf("     This method assumes that you are attached to a NetWare fileserver\n");
  459.         printf("     and the fileserver name must be discovered by the application, \n");
  460.         printf("     (ie, user specified, config file, OS environmental variable, etc).\n");
  461.         printf("\n");
  462.         printf("Enter choice: ");
  463.         do    {
  464.             method = getch() - '0';
  465.             } while((method < 0) || (method > 2));
  466.         
  467.         printf("%d\n", method);
  468.         }
  469.  
  470.     switch(method)
  471.         {
  472.         case 0:
  473.             cCode = (-1);
  474.             break;
  475.  
  476.         case 1:
  477.             cCode=LocateGetNearest(addr);
  478.             break;
  479.  
  480.         case 2:
  481.             cCode=LocateScanID(addr, serverName);
  482.             break;
  483.         }
  484.  
  485.     return(cCode);
  486.     }
  487.  
  488. /****************************************************************************
  489. ** Program start.
  490. */
  491. void main(int argc, char *argv[])
  492.     {
  493.     COM_DATA_PACKET     rxData;
  494.     COM_DATA_PACKET     txData;
  495.     IPXAddress              addr;
  496.     LONG                       cCode;
  497.     int                     method = 0;
  498.     char                     serverName[47+1];
  499.  
  500.     /*------------------------------------------------------------------------
  501.     ** Process command line.
  502.     */
  503.     if(argc > 1) method = atoi(argv[1]);
  504.     memset(serverName, 0x00, sizeof(serverName));
  505.     if(argc > 2) memcpy(serverName, argv[2], sizeof(serverName)-1);
  506.  
  507.     /*------------------------------------------------------------------------
  508.     ** Say hello to IPX.
  509.     */
  510.     cCode=IPXInitialize();
  511.     switch(cCode)
  512.         {
  513.         case 0x00:
  514.             break;
  515.  
  516.         case 0xF0:
  517.             printf("ERROR: IPX is not installed on this node.\n");
  518.             goto END;
  519.  
  520.         default:
  521.             printf("ERROR: IPXInitialize() returned unknown error: %d.\n", cCode);
  522.             goto END;
  523.         }
  524.  
  525.     /*------------------------------------------------------------------------
  526.     ** Get the servers IPX network address.
  527.     */
  528.     cCode=LocateServer(&addr, method, serverName);
  529.     if(cCode) goto END;
  530.  
  531.     /*------------------------------------------------------------------------
  532.     ** Communicate with server.
  533.     */
  534.     txData.type = COM_REQ_PING;
  535.     cCode=ComReq(&addr, &txData, &rxData, 10, 2.0);
  536.     if(cCode) goto END;
  537.  
  538.     /*------------------------------------------------------------------------
  539.     **    Print out rx packet data.
  540.     */
  541.     switch(rxData.status)
  542.         {
  543.         case COM_SUCCESS:
  544.             printf("%s\n", rxData.data);
  545.             break;
  546.  
  547.         case COM_ERR_UNKNOWN_TYPE:
  548.             printf("ERROR:  Server indicates unknown request type.\n");
  549.             goto END;
  550.  
  551.         default:
  552.             printf("ERROR:  Unknown error returned from server: %d.\n", rxData.status);
  553.             goto END;
  554.         }
  555.  
  556. END:
  557.  
  558.     exit(0);
  559.     }
  560.  
  561.  
  562.