/* ** File name: PRINT_SVC.C ** ** Copyright (c) 1991, by ** Process Software Corporation ** Framingham, Massachusetts */ #include #include #include #include "TCPWARE_INCLUDE:RPC.H" #include "PRINT.H" #include "PRINT_DEF.H" static void print_prog_1(); /* **************************************** ** ** Main program ** ** Abstract: ** This program demonstrates how a server would be set up to receive ** batched requests. Unlike a normal RPC request, a batched 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( PRINT_FILE_PROG, PRINT_FILE_VERS_1); /* ** Create a server handle using the TCP transport. The transport will use the ** default send and receive sizes and listen on a port assigned by RPC. ** Batched RPC must use the TCP (or TCPA) transport. To use the TCPA ** transport, change the following line to a call to svctcpa_create and add the ** line described in the function print_prog_1. */ if( (xprt = svctcp_create( RPC_ANYSOCK, 0, 0)) == 0) { fprintf( stderr, "cannot create TCP service.\n"); exit( SS$_OPINCOMPL); } /* ** Register the server with the Port Mapper. */ if( !svc_register( xprt, PRINT_FILE_PROG, PRINT_FILE_VERS_1, print_prog_1, IPPROTO_TCP)) { fprintf( stderr, "unable to register (PRINT_FILE_PROG, PRINT_FILE_VERS_1, TCP).\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); } /* end main program */ /* **************************************** ** ** Function: print_prog_1() ** ** Abstract: ** This is the dispatch routine for the print file server. */ static void print_prog_1( rqstp, xprt) struct svc_req *rqstp; SVCXPRT *xprt; { longw argument, junk; a_record the_record; char buffer[ MAX_STRING_LEN+1]; static u_long record_count = 0; switch( rqstp->rq_proc) { /* ** The null procedure always does nothing and returns a void. */ case NULLPROC: svc_sendreply( xprt, xdr_void, NULL); return; /* ** Unlike the getsyi server, this server does not save the XDR functions and ** the local procedure in variables. This is because PRINT_RECORD never sends ** a reply while SHOW_COUNT does. */ case PRINT_RECORD: the_record.ar_buffer = buffer; if( !svc_getargs( xprt, xdr_a_record, &the_record)) break; if( record_count++ == 0) putchar( '\n'); printf( "%4d: %s", record_count, the_record.ar_buffer); /* ** To use the TCPA transport, add this line here. This will requeue a receive ** of an RPC request. The TCPA transport ignores the second argument. ** svc_recv( xprt, 0); */ break; case SHOW_COUNT: if( !svc_getargs( xprt, xdr_void, &junk)) { svcerr_decode( xprt); break; } if( !svc_sendreply( xprt, xdr_u_long, &record_count)) svcerr_systemerr( xprt); record_count = 0; break; /* ** The client specified a procedure that the server doesn't support. */ default: svcerr_noproc( xprt); return; } /* ** This server doesn't need to free the arguments since no memory was allocated. */ return; } /* end function print_prog_1() */ /* end file PRINT_SVC.C */