diff options
Diffstat (limited to 'lib/libc/rpc/clnt_tcp.c')
-rw-r--r-- | lib/libc/rpc/clnt_tcp.c | 89 |
1 files changed, 87 insertions, 2 deletions
diff --git a/lib/libc/rpc/clnt_tcp.c b/lib/libc/rpc/clnt_tcp.c index 0f457b3..cfb3746 100644 --- a/lib/libc/rpc/clnt_tcp.c +++ b/lib/libc/rpc/clnt_tcp.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id$"; +static char *rcsid = "$Id: clnt_tcp.c,v 1.7 1996/12/30 14:36:17 peter Exp $"; #endif /* @@ -355,6 +355,7 @@ clnttcp_abort() { } + static bool_t clnttcp_control(cl, request, info) CLIENT *cl; @@ -362,18 +363,102 @@ clnttcp_control(cl, request, info) char *info; { register struct ct_data *ct = (struct ct_data *)cl->cl_private; + register struct timeval *tv; + int len; switch (request) { + case CLSET_FD_CLOSE: + ct->ct_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + ct->ct_closeit = FALSE; + break; case CLSET_TIMEOUT: - ct->ct_wait = *(struct timeval *)info; + if (info == NULL) + return(FALSE); + tv = (struct timeval *)info; + ct->ct_wait.tv_sec = tv->tv_sec; + ct->ct_wait.tv_usec = tv->tv_usec; ct->ct_waitset = TRUE; break; case CLGET_TIMEOUT: + if (info == NULL) + return(FALSE); *(struct timeval *)info = ct->ct_wait; break; case CLGET_SERVER_ADDR: + if (info == NULL) + return(FALSE); *(struct sockaddr_in *)info = ct->ct_addr; break; + case CLGET_FD: + if (info == NULL) + return(FALSE); + *(int *)info = ct->ct_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + if (info == NULL) + return(FALSE); + *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + if (info == NULL) + return(FALSE); + *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1); + /* decrement by 1 as clnttcp_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + if (info == NULL) + return(FALSE); + *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + if (info == NULL) + return(FALSE); + *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + if (info == NULL) + return(FALSE); + *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + if (info == NULL) + return(FALSE); + *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + case CLGET_LOCAL_ADDR: + len = sizeof(struct sockaddr); + if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0) + return(FALSE); + break; + case CLGET_RETRY_TIMEOUT: + case CLSET_RETRY_TIMEOUT: + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: default: return (FALSE); } |