#module IPC_CLIENT /* ************************************************************************** * Copyright (C) 1990 by * * DIGITAL Equipment Corporation, Maynard, Mass. * * * * This software is furnished under a license and may be used and copied * * only in accordance with the terms of such license and with the * * inclusion of the above copyright notice. This software or any other * * copies thereof may not be provided or otherwise made available to any * * other person. No title to or ownership of the software is hereby * * transferred. * * * * The information in this software is subject to change without notice * * and should not be construed as a commitment by DIGITAL Equipment * * Corporation. * * * * DIGITAL assumes no responsibility for the use or reliability of its * * software on equipment which is not supplied by DIGITAL. * * * ************************************************************************** */ /* * * FACILITY: * * DECnet-Vax OSI IPC Example Programs * * ABSTRACT: * * This program is an example of a client that communicates with a * (remote) server via the IPC system service. * * It is built by IPC_BUILD.COM. (Note: If you build the executables * in the EXAMPLES directory, you may want to set the file protections * to allow non-privileged users to execute them.) * * It must be executed as a foreign command, and expects 3 command line * arguments: * * : The name of the server's node * : The name of the server task to connect to * : A string to pass to the server task * * Define the foreign command as, for example: * * $ client :== $sys$common:[syshlp.examples.dnvosi]ipc_client.exe * * Execute it by, for example: * * $ client srvr01 task1 "Bad sneakers and a pina colada, my friend." * * The server program must be running on node srvr01 and declare itself * as task "task1". Refer to IPC_SERVER.C. * * The argument may be in one of 3 formats: * * o DECnet OSI Name (e.g., NAMESPACE:.DIR1.DIR2.OBJECT_NAME) * o DECnet Phase IV Name (e.g., srvr01) * o DECnet Phase IV Address (e.g., 17834) * * (You may also specify a node name of 0, to connect to a local task.) * * All of these are valid formats when using the NET$K_TAG_NODENAME item * with the IPC$K_FC_CONNECT_INITIATE function. * * Program Summary : * * Validate command line arguments * Open an association * Initiate a connection to the server * Transmit a message * Receive a message, and print it out * Disconnect * Close the association * * AUTHOR: * * MwD * * CREATION DATE: Dec-1991 * * MODIFICATION HISTORY: * * X-08 LES0074 LES 15-Jul-1992 * Fix edit history * * X-07 LES0070 LES 08-Jun-1992 * merge gen 6n2 changes to mainline to incorporate * symbol name changes * * X-06N2 LES0070 LES 14-May-1992 * Oops...make some aggregate name fixes from last time * (change NET$IPCBDEF back to Ipcb, change IPCBDEF * to NET$IPCBDEF) * * X-06N1 LES0070 LES 11-May-1992 * Change aggregate name Ipcb to NET$IPCBDEF * * X-00 MWD0000 MwD Dec-1991 * Creation. * */ /* * Include the definition of an IPCB. */ #include /* * Include the definitions for the IPC example common routines. */ #include "ipc_def.h" #define CONNECT_LIST_SIZE 128 #define RECEIVE_BUFFER_SIZE 128 main( unsigned int argc, char *argv[] ) { struct NET$IPCBDEF Ipcb; char Receive_Buffer[ RECEIVE_BUFFER_SIZE ]; void *List1_P; int Sts; /* * Validate the command line arguments. */ if( argc != 4 ) { printf( "Usage: $ipc_client \n" ); printf( "See the comments in IPC_CLIENT.C for details.\n" ); exit( 0 ); } /* * Allocate the item list. */ List1_P = item_list__new( CONNECT_LIST_SIZE ); if( List1_P == NULL ) { printf( "Can't allocate VM\n" ); exit( 0 ); } /* * Clear the fields in the IPCB. This is important, since the * $IPC system service will attempt to interpret many/all of the flag * values, and all three item list descriptors, on most calls. */ clear_ipcb( &Ipcb ); /* * Open an association, and check the return status(es). */ Sts = SYS$IPCW( 0, /* no efn */ IPC$K_FC_OPEN_ASSOCIATION, &Ipcb, 0, /* No AST addr */ 0 ); /* or param */ VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); /* * Build an input item list containing the and * command line arguments. */ Sts = item_list__add( List1_P, strlen( argv[ 1 ] ), NET$K_TAG_NODENAME, argv[ 1 ] ); VMS_CHECK( Sts ); Sts = item_list__add( List1_P, strlen( argv[ 2 ] ), NET$K_TAG_ENDUSERID_TASK, argv[ 2 ] ); VMS_CHECK( Sts ); /* * Set up the IPCB input list descriptor for this item list. */ item_list__to_desc( List1_P, &Ipcb.IPCB$R_INPUTLSTDESC ); /* * Initiate a connection to the server task. * This call will complete successfully if the task is running * on the node we specified, AND the task accepts the connection. * Otherwise this call will fail with %IPC-E-USERREJECT. */ Sts = SYS$IPCW( 0, IPC$K_FC_CONNECT_INITIATE, &Ipcb, 0, 0 ); VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); /* * OK, we have a connection. Clear the IPCB input list descriptor, * and the item list for reuse. */ item_list__clear( List1_P, &Ipcb.IPCB$R_INPUTLSTDESC ); /* * Transmit a buffer to the server task. * The buffer is the command line argument (which is a * null-terminated string). Set the IPCB buffer length to include the * terminator (for the sake of the server). */ Ipcb.IPCB$A_BUFFER = argv[ 3 ]; Ipcb.IPCB$L_BUFFER_LENGTH = strlen( argv[ 3 ] ) + 1; Sts = SYS$IPCW( 0, IPC$K_FC_TRANSMIT, &Ipcb, 0, 0 ); VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); /* * Wait for the server task to send a buffer to us. * If we get one, assume it is a printable, null-terminated * string and print it out. */ Ipcb.IPCB$A_BUFFER = Receive_Buffer; Ipcb.IPCB$L_BUFFER_LENGTH = RECEIVE_BUFFER_SIZE; Sts = SYS$IPCW( 0, IPC$K_FC_RECEIVE, &Ipcb, 0, 0 ); VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); printf( "Received buffer: \n%s\n", Receive_Buffer ); /* * Disconnect the connection. Clear the buffer fields because * we're not sending any user data with the disconnect. */ Ipcb.IPCB$A_BUFFER = NULL; Ipcb.IPCB$L_BUFFER_LENGTH = 0; Sts = SYS$IPCW( 0, IPC$K_FC_DISCONNECT_CONNECTION, &Ipcb, 0, 0 ); VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); /* * Close the association. */ Sts = SYS$IPCW( 0, IPC$K_FC_CLOSE_ASSOCIATION, &Ipcb, 0, 0 ); VMS_CHECK( Sts ); IPC_CHECK( Ipcb ); }