home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / NETBIO.ZIP / NETBIOS / NETSAMPO.C < prev    next >
Text File  |  1991-12-02  |  20KB  |  567 lines

  1. /*
  2. *   Module name :     NETSAMPL
  3. *
  4. *   Function :        Demo program for NETBIOS
  5. *
  6. *   Usage :           NETSAMPL   {SEND|RECV} [Adapter={0|1}]
  7. *                                            [Lclname=aaaaaaaaaaaaaaa]
  8. *                                            [Netname=bbbbbbbbbbbbbbb]
  9. *
  10. *                                where the two names can have up to
  11. *                                      fifteen characters.
  12. *
  13. *                                defaults: SEND
  14. *                                          Adapter=0
  15. *                                          Lclname=NETSAMPLSEND
  16. *                                          Netname=NETSAMPLRECV
  17. *                     NETSAMPL   ?
  18. *
  19. *   External modules: none
  20. *
  21. *   Return codes :    0    if successful
  22. *                     1    if a parameter was bad and/or Help was given
  23. *                     x    if an NCB fails the ncb.retcode is returned
  24. *
  25. *
  26. *
  27. */
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. /* if you are 32 bit applications, then add the following statement
  32. #define  E32TO16                    */
  33.  
  34.  
  35. #include "lan_7_c.h"       /* general typedefs */
  36. #include "netb_1_c.h"      /* NCB defines      */
  37. #include "netb_2_c.h"      /* NCB structures   */
  38. #include "netb_4_c.h"      /* NETBIOS external definition */
  39.  
  40. #include "netgblv.h"
  41. #include "neterror.h"
  42.  
  43. /**********************************************************************/
  44. /*
  45. **  main        Accepts the arguments and provides help if requested
  46. **              RESETs the specified PC Network Adapter
  47. **              ADDs the localname to the network
  48. **              Initiates a CALL of the remotename over the network
  49. **              When the CALL is answered, a message is SENT to the
  50. **                answering network station over the new session
  51. **              HANGs UP the session with the remote station
  52. **              RESETs the specified adapter
  53. **
  54. **              Error conditions:
  55. **                      First parameter not SEND or RECV
  56. **                      Incorrect Lana number specified
  57. **                      NAME already exists on the network
  58. **                      Fatal NETBIOS error 0x..
  59. **
  60. */
  61. main ( argc, argv )
  62. int argc;
  63. char *argv[];
  64. {
  65.         /*------------------------------------------------------------+
  66.         |  Set the default parameters and initial values              |
  67.         +------------------------------------------------------------*/
  68.  
  69.         Mode = SEND;
  70.         Lana = 0;
  71.         memset( LclName, 0, 16);
  72.         memset( NetName, 0, 16);
  73.  
  74.         if ( GrabArgs( argc, argv ) )  {
  75.                 Help();
  76.                 exit(1);
  77.         }
  78.  
  79.         /*------------------------------------------------------------+
  80.         |  If a name wasn't given, use the defaults                   |
  81.         +------------------------------------------------------------*/
  82.  
  83.         if ( ! LclName[0] )
  84.                 strncpy(LclName,(Mode==SEND ?"NETSAMPLSEND":"NETSAMPLRECV"),15);
  85.         if ( ! NetName[0] )
  86.                 strncpy(NetName,(Mode==SEND ?"NETSAMPLRECV":"NETSAMPLSEND"),15);
  87.  
  88.         /*------------------------------------------------------------+
  89.         |  To make sure we start with a clean adapter, we reset it.   |
  90.         +------------------------------------------------------------*/
  91.  
  92.         retcode = NetReset( Lana, NET_LSN, NET_NUM );
  93.         if (retcode)
  94.                 Terminate( "Reset", retcode );
  95.  
  96.         /*------------------------------------------------------------+
  97.         |  Add the name by which we wish to be known to the network   |
  98.         +------------------------------------------------------------*/
  99.  
  100.         retcode = NetAddName( Lana, LclName );
  101.         if (retcode)
  102.                 Terminate( "AddName", retcode );
  103.  
  104.         /*------------------------------------------------------------+
  105.         |  If we are acting as the SENDing station, we next do:       |
  106.         |     a CALL to the other station, and if it is answered,     |
  107.         |     a SEND of our message to the other station.             |
  108.         |  Otherwise, we are the RECEIVing station and we next do:    |
  109.         |     a LISTEN for a CALL from the other station, and when    |
  110.         |       it occurs,                                            |
  111.         |     a RECEIVE to accept one message from the other station. |
  112.         +------------------------------------------------------------*/
  113.  
  114.         if ( Mode == SEND )  {
  115.                 retcode = NetCall( Lana, LclName, NetName );
  116.                 if (retcode)
  117.                         Terminate( "Call", retcode );
  118.  
  119.                 strcpy( Message, "Hello there!" );
  120.  
  121.                 retcode = NetSend( Lana, Ncb.basic_ncb.ncb_lsn, Message, strlen(Message) );
  122.                 if (retcode)
  123.                         Terminate( "Send", retcode );
  124.         }
  125.         else  {
  126.                 retcode = NetListen( Lana, LclName, NetName );
  127.                 if (retcode)
  128.                         Terminate( "Listen", retcode );
  129.  
  130.                 retcode = NetReceive( Lana, Ncb.basic_ncb.ncb_lsn, Message, sizeof Message );
  131.                 if (retcode)
  132.                         Terminate( "Receive", retcode );
  133.  
  134.                 printf( "Received Message:\n" );
  135.                 printf( "  \"%s\"\n", Message);
  136.         }
  137.  
  138.         /*------------------------------------------------------------+
  139.         |  We terminate the session made above with the CALL/LISTEN   |
  140.         |  by doing a HANGUP of the session.                          |
  141.         +------------------------------------------------------------*/
  142.  
  143.         retcode = NetHangup( Lana, Ncb.basic_ncb.ncb_lsn );
  144.         if (retcode && retcode != NB_SESSION_CLOSED)
  145.                 Terminate( "Hangup", retcode );
  146.  
  147.         /*------------------------------------------------------------+
  148.         |  Finally, we reset the adapter to remove all traces of our  |
  149.         |  ever using the adapter.                                    |
  150.         +------------------------------------------------------------*/
  151.  
  152.         retcode = NetReset( Lana, NET_LSN, NET_NUM );
  153.         if (retcode)
  154.                 Terminate( "Reset", retcode );
  155.  
  156.         exit(0);
  157. }
  158.  
  159.  
  160. /**********************************************************************/
  161. /*
  162. ** NetReset     Resets the NETBIOS interface status, clears the name
  163. **              and session tables, and aborts all sessions.
  164. **
  165. **              Accepts the adapter number, max sessions, and max
  166. **              pending NCBs.
  167. **
  168. **              Returns the NCB return code.
  169. */
  170.  
  171. byte NetReset( lana, sessions, commands )
  172. byte lana, sessions, commands;
  173. {
  174.         printf( "Resetting lan adapter %u ... ", lana);
  175.  
  176.         memset( &Ncb, 0, sizeof(union ncb_types) );
  177.         Ncb.reset.ncb_command  = NB_RESET_WAIT;
  178.         Ncb.reset.ncb_lana_num = lana;
  179.         Ncb.reset.req_sessions = sessions;
  180.         Ncb.reset.req_commands = commands;
  181.  
  182.         TRNcmd( &Ncb.reset );
  183.  
  184.         if ( ! Ncb.reset.ncb_retcode )
  185.                 puts( "Ok");
  186.  
  187.         return (Ncb.reset.ncb_retcode);
  188. }
  189.  
  190. /**********************************************************************/
  191. /*
  192. ** NetAddName   Adds a 16-character name to the table of names.  The
  193. **              name must be unique across the network.  This is a
  194. **              name that this station will be known by.
  195. **
  196. **              Accepts the adapter number and the char array holding
  197. **              the name.
  198. **
  199. **              Returns the NCB return code.
  200. */
  201.  
  202. byte NetAddName( lana, name )
  203. byte lana;
  204. byte *name;
  205. {
  206.         printf( "Adding the local name \"%s\" to the network ... ", name);
  207.  
  208.         memset( &Ncb, 0, sizeof(union ncb_types) );
  209.         Ncb.basic_ncb.ncb_command  = NB_ADD_NAME_WAIT;
  210.         Ncb.basic_ncb.ncb_lana_num = lana;
  211.         strncpy( Ncb.basic_ncb.ncb_name, name, 16 );
  212.  
  213.         TRNcmd( &Ncb.basic_ncb );
  214.  
  215.         if ( ! Ncb.basic_ncb.ncb_retcode )
  216.                 puts( "Ok");
  217.  
  218.         return (Ncb.basic_ncb.ncb_retcode);
  219. }
  220.  
  221. /**********************************************************************/
  222. /*
  223. ** NetCall      Opens a session with another name specified in the
  224. **              NCB.CALLNAME field using the local name specified in
  225. **              the NCB.NAME field.
  226. **
  227. **              Accepts the adapter number and the char arrays holding
  228. **              the local and remote names.
  229. **
  230. **              Returns the NCB return code.  If successful, the session
  231. **              number is returned in the NCB.LSN field.
  232. */
  233.  
  234. #define RECV_TIMEOUT    10
  235. #define SEND_TIMEOUT    10
  236.  
  237. byte NetCall( lana, lclname, rmtname)
  238. byte lana;
  239. byte *lclname, *rmtname;
  240. {
  241.         printf( "Calling the remote station \"%s\" ... ", rmtname);
  242.  
  243.         memset( &Ncb, 0, sizeof(union ncb_types) );
  244.         Ncb.basic_ncb.ncb_command  = NB_CALL_WAIT;
  245.         Ncb.basic_ncb.ncb_lana_num = lana;
  246.         Ncb.basic_ncb.ncb_rto      = RECV_TIMEOUT<<1;  /* times 2 since in   */
  247.         Ncb.basic_ncb.ncb_sto      = SEND_TIMEOUT<<1;  /* steps of 500 msecs */
  248.         strncpy( Ncb.basic_ncb.ncb_name, lclname, 16 );
  249.         strncpy( Ncb.basic_ncb.ncb_callname, rmtname, 16 );
  250.  
  251.         TRNcmd( &Ncb.basic_ncb );
  252.  
  253.         if ( ! Ncb.basic_ncb.ncb_retcode )
  254.                 puts( "Ok");
  255.  
  256.         return (Ncb.basic_ncb.ncb_retcode);
  257. }
  258.  
  259. /**********************************************************************/
  260. /*
  261. ** NetListen    Enables a session to be opened with the name specified
  262. **              in the NCB.CALLNAME field, using the name specified in
  263. **              the NCB.NAME field.
  264. **
  265. **              Accepts the adapter number and the char arrays holding
  266. **              the local and remote names.
  267. **
  268. **              Returns the NCB return code.  If successful, the session
  269. **              number is returned in the NCB.LSN field.
  270. **
  271. **              Note: A Listen command will NOT timeout, but it occupies
  272. **              a session entry and is considered a pending session in the
  273. **              information returned by a NCB.STATUS command.
  274. */
  275.  
  276. byte NetListen( lana, lclname, rmtname)
  277. byte lana;
  278. byte *lclname, *rmtname;
  279. {
  280.         printf( "Listening for a call from the remote station \"%s\" ... ", rmtname);
  281.  
  282.         memset( &Ncb, 0, sizeof(union ncb_types) );
  283.         Ncb.basic_ncb.ncb_command  = NB_LISTEN_WAIT;
  284.         Ncb.basic_ncb.ncb_lana_num = lana;
  285.         Ncb.basic_ncb.ncb_rto      = RECV_TIMEOUT<<1;   /* times 2 since in   */
  286.         Ncb.basic_ncb.ncb_sto      = SEND_TIMEOUT<<1;   /* steps of 500 msecs */
  287.         strncpy( Ncb.basic_ncb.ncb_name, lclname, 16 );
  288.         strncpy( Ncb.basic_ncb.ncb_callname, rmtname, 16 );
  289.  
  290.         TRNcmd( &Ncb.basic_ncb );
  291.  
  292.         if ( ! Ncb.basic_ncb.ncb_retcode )
  293.                 puts( "Ok");
  294.  
  295.         return (Ncb.basic_ncb.ncb_retcode);
  296. }
  297.  
  298. /**********************************************************************/
  299. /*
  300. ** NetSend      Sends data to the session partner as defined by the
  301. **              session number in the NCB.LSN field.  The data to send
  302. **              is in the buffer pointed to by the NCB.BUFFER field.
  303. **
  304. **              Accepts the adapter number, the session number,
  305. **              the char array holding the message to be sent, and
  306. **              the length of the message in that array.
  307. **
  308. **              Returns the NCB return code.
  309. */
  310.  
  311. byte NetSend( lana, lsn, message, length )
  312. byte lana, lsn;
  313. byte *message;
  314. word length;
  315. {
  316.         printf( "Sending the following message to the answering station:\n" );
  317.         printf( "  \"%s\" ... ", message);
  318.  
  319.         memset( &Ncb, 0, sizeof(union ncb_types) );
  320.         Ncb.basic_ncb.ncb_command  = NB_SEND_WAIT;
  321.         Ncb.basic_ncb.ncb_lana_num = lana;
  322.         Ncb.basic_ncb.ncb_lsn      = lsn;
  323.         Ncb.basic_ncb.ncb_buffer_address = message;
  324.         Ncb.basic_ncb.ncb_length   = length;
  325.  
  326.         TRNcmd( &Ncb.basic_ncb );
  327.  
  328.         if ( ! Ncb.basic_ncb.ncb_retcode )
  329.                 puts( "Ok");
  330.  
  331.         return (Ncb.basic_ncb.ncb_retcode);
  332. }
  333.  
  334. /**********************************************************************/
  335. /*
  336. ** NetReceive   Receives data from the session partner that sends data
  337. **              to this station.
  338. **
  339. **              Accepts the adapter number, the session number,
  340. **              the char array to hold the message received, and
  341. **              the maximum length the message may occupy in that
  342. **              array.
  343. **
  344. **              Returns the NCB return code and, if successful,
  345. **              the received data in the buffer.
  346. */
  347.  
  348. byte NetReceive( lana, lsn, buffer, length )
  349. byte lana, lsn;
  350. byte *buffer;
  351. word length;
  352. {
  353.         printf( "Receiving a message ..." );
  354.  
  355.         memset( &Ncb, 0, sizeof(union ncb_types) );
  356.         Ncb.basic_ncb.ncb_command  = NB_RECEIVE_WAIT;
  357.         Ncb.basic_ncb.ncb_lana_num = lana;
  358.         Ncb.basic_ncb.ncb_lsn      = lsn;
  359.         Ncb.basic_ncb.ncb_buffer_address = buffer;
  360.         Ncb.basic_ncb.ncb_length   = length-1;
  361.  
  362.         TRNcmd( &Ncb.basic_ncb );
  363.  
  364.         if ( ! Ncb.basic_ncb.ncb_retcode )
  365.                 puts( "Ok");
  366.  
  367.         buffer[length-1] = '\0';
  368.  
  369.         return (Ncb.basic_ncb.ncb_retcode);
  370. }
  371.  
  372. /**********************************************************************/
  373. /*
  374. ** NetHangup    Closes the session with another name on the network
  375. **              specified by the session number.
  376. **
  377. **              Accepts the adapter number and session number.
  378. **
  379. **              Returns the NCB return code.
  380. */
  381.  
  382. byte NetHangup( lana, lsn )
  383. byte lana, lsn;
  384. {
  385.         printf( "Hanging up the session ... " );
  386.  
  387.         memset( &Ncb, 0, sizeof(union ncb_types) );
  388.         Ncb.basic_ncb.ncb_command  = NB_HANG_UP_WAIT;
  389.         Ncb.basic_ncb.ncb_lana_num = lana;
  390.         Ncb.basic_ncb.ncb_lsn      = lsn;
  391.  
  392.         TRNcmd( &Ncb.basic_ncb );
  393.  
  394.         if ( ! Ncb.basic_ncb.ncb_retcode || Ncb.basic_ncb.ncb_retcode == 0x0A)
  395.                 puts( "Ok");
  396.  
  397.         return (Ncb.basic_ncb.ncb_retcode);
  398. }
  399.  
  400.  
  401. /**********************************************************************/
  402. /*
  403. **  GrabArgs    Parses the command line arguments.  The first letters
  404. **              of each possible parameter keyword are sufficient to
  405. **              identify the parameter.
  406. **
  407. **              Accepts the standard argc,argv parameters
  408. **
  409. **              Modifies the global variables Mode, Lana, LclName, and
  410. **              NetName if successful, or produces an error message and exits.
  411. */
  412.  
  413. GrabArgs( argc, argv )
  414. int argc;
  415. char *argv[];
  416. {
  417.         char *cp, *strchr();
  418.  
  419.  
  420.         while( --argc )  {
  421.  
  422.                 cp = *++argv;           /* ptr to next argument string */
  423.  
  424.                 switch( toupper(*cp) )  {
  425.  
  426.                         case 'S':       /* Send option */
  427.                                         Mode = SEND;
  428.                                         break;
  429.  
  430.                         case 'R':       /* Receive option */
  431.                                         Mode = RECV;
  432.                                         break;
  433.  
  434.                         case 'A':       /* Adapter number - must be followed
  435.                                            by an '=' and either 0 or 1  */
  436.  
  437.                                         cp = strchr( cp, '=' );
  438.                                         if (! *cp)
  439.                                                 Terminate("Bad adapter number", 0);
  440.                                         if (*++cp == '0')
  441.                                                 Lana = 0;
  442.                                         else if (*cp == '1')
  443.                                                 Lana = 1;
  444.                                         else
  445.                                                 Terminate("Bad adapter number", 0);
  446.                                         break;
  447.  
  448.                         case 'L':       /* Local network name - must be
  449.                                            followed by an '=' and up to
  450.                                            15 characters for the name  */
  451.  
  452.                                         cp = strchr( cp, '=' );
  453.                                         if (! cp)
  454.                                                 Terminate("Bad local name", 0);
  455.                                         strncpy( LclName, ++cp, 15 );
  456.                                         break;
  457.  
  458.                         case 'N':       /* Remote network name - must be
  459.                                            followed by an '=' and up to
  460.                                            15 characters for the name   */
  461.  
  462.                                         cp = strchr( cp, '=' );
  463.                                         if (! cp)
  464.                                                 Terminate("Bad remote name", 0);
  465.                                         strncpy( NetName, ++cp, 15 );
  466.                                         break;
  467.  
  468.                         case '?':       /* Request for the help display */
  469.                                         return 1;
  470.  
  471.                         default:        printf( ">>Unrecognized argument: %s\n",
  472.                                                 cp );
  473.                                         Terminate( " ", 0);
  474.                                         break;
  475.                 }
  476.  
  477.         }
  478.  
  479.         return 0;
  480. }
  481.  
  482. /**********************************************************************/
  483. /*
  484. **  Help        Displays directions for running this demo program
  485. */
  486.  
  487. Help()
  488. {
  489.         puts( " ");
  490.         puts( " NETSAMPL   {Send|Recv} [Adapter={0|1}]          ");
  491.         puts( "                        [Lclname=aaaaaaaaaaaaaaa]");
  492.         puts( "                        [Netname=bbbbbbbbbbbbbbb]");
  493.         puts( " ");
  494.         puts( "            where the two names can have up to   ");
  495.         puts( "                  fifteen characters.            ");
  496.         puts( " ");
  497.         puts( "            defaults: Adapter=0                  ");
  498.         puts( "                      Lclname=NETSAMPL{SEND|RECV}");
  499.         puts( "                      Netname=NETSAMPL{RECV|SEND}");
  500.         puts( " ");
  501.  
  502.         return;
  503. }
  504.  
  505. /**********************************************************************/
  506. /*
  507. **  Terminate    Produce a formatted error message and
  508. **              terminate the program
  509. **
  510. **              Accepts a character string holding the failed action
  511. **              and an BYTE holding the return code.
  512. **
  513. **              DOES NOT RETURN
  514. */
  515.  
  516. #define BELL_CHAR       '\007'
  517.  
  518. Terminate( message, code )
  519. byte *message;
  520. byte code;
  521. {
  522.         extern char *TableLookUp();
  523.  
  524.         if (code)
  525.                 printf( "\n\n>> Error during %s: \n>>   %s%c\n",
  526.                         message, TableLookUp(NetErrorMsgs,code), BELL_CHAR );
  527.         else    {
  528.                 printf( ">> %s\n", message);
  529.                 Help();
  530.                 code=1;
  531.         }
  532.  
  533.         exit(code);
  534. }
  535.  
  536. /*****************************************************************************/
  537. /*
  538. **  TableLookUp This function scans a code table for a specified value,
  539. **              and returns a text string which can be used as a message.
  540. */
  541.  
  542. char *TableLookUp(table, key)
  543. struct CodeTable *table;
  544. unsigned char key;
  545. {
  546.         while (table->label && table->code!=key) table++;
  547.         if (table->label) return(table->label);
  548.         else return(" <unknown> ");
  549. }
  550.  
  551. /**********************************************************************/
  552. /*
  553. **  TRNcmd      Execute an NCB
  554. **
  555. **              Accepts a pointer to an NCB and passes it to
  556. **              NETBIOS.
  557. **
  558. **              Returns the value in the AX register which is the NCB
  559. **              return code.
  560. */
  561.  
  562. unsigned TRNcmd(cmdptr)
  563. char *cmdptr;
  564. {
  565.         return( NETBIOS(cmdptr));
  566. }
  567.