/* ** File name: SYSINFO_SVC.C ** ** Copyright (c) 1991, by ** Process Software Corporation ** Framingham, Massachusetts */ /* ** Include files */ #include #include #include #include "TCPWARE_INCLUDE:RPC.H" #include "SYSINFO.H" #include "SYSINFO_DEF.H" static void system_info_prog_1(); /* **************************************** ** ** Main program ** ** Abstract: ** This program demonstrates how a server would be set up to receive ** broadcast messages. Since this server handles only broadcast messages, ** it does not require the TCP transport. Unlike a normal RPC request, a ** broadcast request does not generate a reply if an error occurs. */ main() { SVCXPRT *xprt; /* ** The server will use non-privileged ports. */ oncrpc_set_char( RPCCHAR__DEFPORTS, &RPCPORTS__NORMAL); /* ** Remove any previous mapping of this program and version to a port. ** This is done for each version. */ pmap_unset( SYSTEM_INFO_PROG, SYSTEM_INFO_VERS_1); /* ** Create the UDP transport. The transport will use the default buffer sizes ** and listen on a port assigned by RPC. The XID cache is not enabled since ** the replies are easily generated. */ if( (xprt = svcudp_create( RPC_ANYSOCK)) == 0) { fprintf( stderr, "cannot create udp service.\n"); exit( SS$_OPINCOMPL); } /* ** Register the server with the Port Mapper. */ if( !svc_register( xprt, SYSTEM_INFO_PROG, SYSTEM_INFO_VERS_1, system_info_prog_1, IPPROTO_UDP)) { fprintf( stderr, "unable to register (SYSTEM_INFO_PROG, SYSTEM_INFO_VERS_1, udp).\n"); exit( SS$_OPINCOMPL); } /* ** Wait for clients to send requests. svc_run should never return. */ svc_run(); fprintf( stderr, "svc_run returned\n"); exit( SS$_ABORT); } /* **************************************** ** ** Function: system_info_prog_1() ** ** Abstract: ** This is the dispatch routine for the sysinfo server. */ static void system_info_prog_1( rqstp, xprt) struct svc_req *rqstp; SVCXPRT *xprt; { longw argument; char *result; bool_t (*xdr_argument)(), (*xdr_result)(); char *(*local)(); switch( rqstp->rq_proc) { /* ** The null procedure always does nothing and returns a void. */ case NULLPROC: svc_sendreply( xprt, xdr_void, NULL); return; /* ** For each supported procedure, save the XDR functions for the arguments and ** the results for later use. Also, save the address of the function that will ** implement the procedure. */ case SYSTEM_INFO_PROC_1: xdr_argument = xdr_void; xdr_result = xdr_system_info; local = system_info_proc_1_1; break; /* ** The client specified a procedure that the server doesn't support. */ default: svcerr_noproc( xprt); return; } /* ** Zero the arguments structure so that memory will be allocated if needed. */ bzero( &argument, sizeof( argument)); /* ** Since the server has only 1 procedure, no tests are required to determine if ** an error message should be sent. */ if( !svc_getargs( xprt, xdr_argument, &argument)) return; /* ** Call the function to implement the procedure. A return value of 0 means ** that a reply should not be sent to the client. */ result = (*local)( &argument, rqstp); if( result != NULL) svc_sendreply( xprt, xdr_result, result); /* ** Free the memory that was allocated when the arguments were decoded. */ if( !svc_freeargs( xprt, xdr_argument, &argument)) fprintf(stderr, "unable to free arguments\n"); } /* end function system_info_prog_1() */ /* **************************************** ** ** Function: system_info_proc_1_1() ** ** Abstract: ** This function returns this host's name and operating system. ** ** Return value: ** The address of the results or 0 if an error occurred. */ system_info *system_info_proc_1_1( ignored, rqstp) byte *ignored; struct svc_req *rqstp; { quad iosb; longw status, hostid, host_len; list_3 getsyi_list[2]; char *cp; static system_info results; static char hostname[ MAX_HOST_LEN+1], op_sys[ MAX_OS_LEN+1] = "VMS "; word op_sys_len; results.si_node_name = hostname; results.si_op_sys = op_sys; /* ** Set up the item list that will be passed to sys$getsyiw. The only item in ** the list is the VMS version number. */ getsyi_list[0].l_buf_len = 8; getsyi_list[0].l_code = SYI$_VERSION; getsyi_list[0].l_buf_addr = &op_sys[4]; getsyi_list[0].l_ret_len_addr = &op_sys_len; getsyi_list[1].l_buf_len = 0; getsyi_list[1].l_code = 0; status = sys$getsyiw( 0, 0, 0, getsyi_list, &iosb, 0, 0); _error( status) return( 0); _error( iosb.val[0]) return( 0); /* ** NULL terminate the string that was returned */ op_sys[ op_sys_len + 4] = 0; /* ** Remove the blanks that sys$getsyi puts at the end of the string. */ for( cp = &op_sys[4]; *cp && *cp != ' '; cp++) ; *cp = 0; /* ** Get the host name. If no host name is available, send a string saying it ** was unavailable. */ host_len = gethostname( hostname, sizeof( hostname)-1); if( host_len == 0) strcpy( hostname, "host name unavailable"); return( &results); } /* end function system_info_proc_1_1() */ /* end file SYSINFO_SVC.C */