'\"
'\" Copyright 1989 Regents of the University of California
'\" Permission to use, copy, modify, and distribute this
'\" documentation for any purpose and without fee is hereby
'\" granted, provided that this notice appears in all copies.
'\" The University of California makes no representations about
'\" the suitability of this material for any purpose.  It is
'\" provided "as is" without express or implied warranty.
'\" 
'\" $Header: /n/picasso/users/syen/cms/doc/man/manl/RCS/dp_rpc.l,v 1.14 1993/04/17 20:03:58 syen Exp $ SPRITE (Berkeley)
'
.\" The definitions below are for supplemental macros used in Sprite
.\" manual entries.
.\"
.\" .HS name section [date [version]]
.\"	Replacement for .TH in other man pages.  See below for valid
.\"	section names.
.\"
.\" .AP type name in/out [indent]
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS [type [name]]
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .VS
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
'	# Heading for Sprite man pages
.de HS
.if '\\$2'cmds'       .TH \\$1 1 \\$3 \\$4
.if '\\$2'lib'        .TH \\$1 3 \\$3 \\$4
.if '\\$2'tcl'        .TH \\$1 3 \\$3 \\$4
.if '\\$2'tk'         .TH \\$1 3 \\$3 \\$4
.if t .wh -1.3i ^B
.nr ^l \\n(.l
.ad b
..
'	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
'	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
'	# BS - start boxed text
'	# ^y = starting y location
'	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
'	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
'	# VS - start vertical sidebar
'	# ^Y = starting y location
'	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
'	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
'	# Special macro to handle page bottom:  finish off current
'	# box/sidebar if in box/sidebar mode, then invoked standard
'	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
'	# DS - begin display
.de DS
.RS
.nf
.sp
..
'	# DE - end display
.de DE
.fi
.RE
.sp .5
..
.de UL
\\$1\l'|0\(ul'\\$2
..
.HS RPC cmds
.BS
.SH NAME
dp_RPC, dp_RDO, dp_MakeRPCClient, dp_MakeRPCServer, dp_CloseRPC, dp_CancelRPC,
dp_Host, dp_SetCheckCmd
.sp
  \- Tcl-DP remote procedure call support
.BE
.SH DESCRIPTION
.LP

The commands described here are part of the Tcl-DP (Tcl
Distributed Programming) extension to Tcl/Tk.  These Tcl/Tk
commands provide support for Tcl/Tk remote procedure calls
(RPC's).
.SH COMMANDS
.TP
\fBdp_MakeRPCServer \fI?port? ?loginProc? ?cmdCheckProc?\fR

Dp_MakeRPCServer arranges for the current Tcl/Tk interpreter
to accept RPC client connections.  Clients will connect to the
server at the given \fIport\fR number (see dp_MakeRPCClient
below).  The \fIport\fR number should be an unused port number or
should be 0 if you want a port number automatically chosen for
you.  If \fIport\fR is not supplied, a default value of 0 is used.
The port number used is returned.

\fILoginProc\fR can be used to refuse connection
attempts by unauthorized hosts.  When a host attempts to connect,
\fIloginProc\fR is called with the internet address of the connecting
party as an argument.  If \fIloginProc\fR calls the Tcl error
function during evaluation, the connection is refused and the error
message is returned to the client.  The default \fIloginProc\fR is
dp_CheckHost.

Dp_CheckHost checks an internal access control list
to verify that the host is allowed to connect.  Host may be added
to (or deleted from) this access control using the dp_Host
command described below.

When a host attempts to connect,
\fIloginProc\fR is called with the internet address of the connecting
party as an argument.  If \fIloginProc\fR calls the Tcl error
function during evaluation, the connection is refused and the error
message is returned to the client.

\fICmdCheckProc\fR, if supplied, can be used to intercept the execution
of unauthorized commands over an RPC channel.  When an RPC request is
received, the requested command will be passed as a string to
\fIcmdCheckProc\fR before evaluation.
See dp_SetCheckCmd for more details.


.TP
\fBdp_Host \fI[+/-]host\fR

This command is used to modify the internal access control list
used in Tcl-DP to determine if hosts are authorized to connect to this
server.  For backwards compatibilty, all hosts are initially allowed to
connect.  Dp_Host is functionally similar to xhost(1).
New additions to the access control list override previous directives.
Dp_Host accepts the following options:

.RS
.TP
\fBdp_Host \fI+[name]\fR
The given \fIname\fP is added to the list allowed to connect to the
server.  The name can be a host name or a pattern or internet addresses
(e.g., 128.32.149.*).  The pattern matching is the same as used in the
Tcl "string match" command.  If \fIname\fP is not supplied, any
host may connect (the default).

.TP
\fBdp_Host \fI-[name]\fR
The given \fIname\fP is removed from the list allowed to connect to the
server.  The name can be a host name or a pattern or internet addresses
(e.g., 128.32.149.*).  Existing connections are not broken, but new
connection attempts will be denied.  The pattern matching is the same
as used in the Tcl "string match" command.  If \fIname\fP is not
supplied, all connections will be refused.

.RE

.TP
\fBdp_MakeRPCClient \fIhost port ?cmdCheckProc?\fR

\fBdp_MakeRPCClient\fP establishes an RPC connection to the RPC
server at the \fIport\fR number running on the machine with the
\fIhost\fR network address.  A \fIsockId\fR
representing the RPC connection is returned.  This \fIsockId\fR
is refered to below as a \fIpeer\fR, since RPC connections are
peer to peer.

\fICmdCheckProc\fR, if supplied, can be used to intercept the execution
of unauthorized commands over the connection.  See dp_MakeRPCServer
and dp_SetCheckCmd for more details.

.TP
\fBdp_SetCheckCmd \fIpeer cmdCheckProc\fR

\fBDp_SetCheckCmd\fR arranges for \fIcmdCheckProc\fR to be called when
an RPC/RDO request comes from the specified \fIpeer\fR.
\fICmdCheckProc\fR is passed the inbound RPC/RDO request as its args
(\fIcmdCheckProc\fR should accept multiple arguments).
If \fIcmdCheckProc\fR returns normally, the requested command is evaluated
normally (i.e., no further checking).  If \fIcmdCheckProc\fR returns
with the "continue" code (see the Tcl return command for how to return
with a special code) then the requested command will be executed, but
any commands it issues will also be checked.  If \fIcmdCheckProc\fR
returns with a "return" code, then the result of \fIcmdCheckProc\fR is
returned as the result of the requested command.  If \fIcmdCheckProc\fR
returns with an "error" code, the requested command will not be
executed, and the error message from the check command will be used as
the error message from the requested command.  Any other return codes
of \fIcmdCheckProc\fR ("break", etc.) will prevent the requested
command from being executed, and an error message will be sent to the
caller.

For example, the following procedure allows the commands "Safe" and
"puts" to be executed without checking, "set" to be called with
one argument (i.e., read, but not write, variables), and "eval" to
be used with any resulting evaluations checked.

.DS
proc MyCheck {cmd args} {
    set argc [llength $args]
    case $cmd in {
	Safe   	{return}
	puts	{return}
	eval	{return -code continue}
	set	{
		    if {$argc == 2} {
			error "Permission to set variables denied"
		    } else {
			return
		    }
		}
    }
    return -code break
}
.DE


.TP
\fBdp_CloseRPC \fIpeer\fR
.br
.sp
This command arranges a clean closing of an RPC connection, on
both sides of the connection.
.TP
\fBdp_CancelRPC ?\fIpeer\fR? ?\fIpeer\fR? ...
.br
.sp
This command cancels current RPC invocations that are presently
waiting for a return value.  If no \fIpeer\fRs are specified,
then all current but waiting RPC invocations are canceled.
These cancelled RPC's will return an error.
.TP
\fBdp_RPC \fIpeer\fR ?\fI-events events\fR? 
.br
?\fI-timeout millisecs\fR ??\fI-timeoutReturn callback\fR???
.br
\fIcommand\fR ?\fIargs ...\fR?

This command arranges for the Tcl/Tk \fIcommand\fR and its
\fIargs\fR to be evaluated in the remote Tcl/Tk interpreter,
using the RPC connection specified by \fIpeer\fR.  Before the
remote evaluation of \fIcommand\fR and \fIargs\fR, the global
variable rpcFile in the remote Tcl/Tk interpreter is bound
to the \fIpeer\fR whose request is being evaluated.  (Thus, in
your \fIcommand\fR, you can access the rpcFile variable to
figure out the RPC peer that originated the \fIcommand\fR.)

The \fI-events\fR flag to the dp_RPC command lets you specify
which events should be handled while waiting for the return value
of a RPC.  The \fI-events\fR parameter should be a list of the
tokens \fIX\fR, \fIrpc\fR, \fIfile\fR, \fItimer\fR, \fIidle\fR,
\fIall\fR, or \fInone\fR, where each token represents an event
type.  Presently, a \fIrpc\fR token is the same as a \fIfile\fR
token.  The \fInone\fR token is the default.  See
Tk_DoOneEvent(3) for more information on these event types.

The \fI-timeout\fR flag to the dp_RPC command lets you specify
an integer millisecond timeout value for the RPC, which by
default will return an error value if the timeout occurs.
Supplying a \fI-timeout\fR value of zero or less than zero means
that no timeout will be checked.  If you want to use timeouts,
you must also specify \fI-events\fR to be anything but none.

The \fI-timeoutReturn\fR callback, if specified, is evaluated
when a timeout occurs.  The callback is evaluated with the
\fIpeer\fR identifier appended.  If a timeout occurs and a
\fI-timeoutReturn\fR callback was specified, then the return
value of the callback is used as the return value of the
timed-out dp_RPC.  Otherwise the timed-out RPC returns an
error.
.TP
\fBdp_RDO \fIpeer\fR ?\fI-callback fIresultCallback\fR?
?\fI-onerror errorCallback\fR? \fIcommand\fR ?\fIargs ...\fR?

This command arranges for \fIcommand\fR and its \fIargs\fR to be
remotely evaluated in the Tcl/Tk interpreter whose connection is
specified by \fIpeer\fR argument.  Unlike the dp_RPC command,
the dp_RDO command does not wait for a return value to be
returned by the remote Tcl/Tk interpreter, but returns
immediately.  Before the remote evaluation, the global variable
rpcFile in the remote Tcl/Tk interpreter is set as
described above for the dp_RPC command.

You can use the \fIresultCallback\fR parameter of dp_RDO to
asynchronously retrieve the value of the remote evaluation.  If
specified, the \fIcallback\fR command appended with the return
value of the remote \fIcommand\fR evaluation is evaluated in the
local Tcl/Tk interpreter.

If you specify an \fIerrorCallback\fR and an error occurs during the
remote evaluation, \fIerrorCallback\fP will be evaluated with the error
message as a parameter.

.SH EXAMPLES

The following example creates an RPC server to return unique 
integer identifiers.  
On the host zonker (the server):
.DS
	dp_MakeRPCServer 4545

	dp_Host -
	dp_Host +128.32.149.*
	set myId 0
	proc GetId {} {global myId; incr myId; return $myId}
.DE

On host linus (the client, address 128.32.149.59):
.DS
	set server [dp_MakeRPCClient zonker 4545]
	dp_RPC $server GetId
.DE

On a host not on the 128.32.149 subnet:
.DS
	set server [dp_MakeRPCClient zonker 4545]
	error -> Connection refused: Host not authorized
.DE

.SH "SEE ALSO"
.PP
Tcl-DP(n) dp_connect(n) dp_filehandler(n) dpwish(1)

.SH AUTHOR
Brian Smith (bsmith@cs.berkeley.edu)
.br
Steve Yen (syen@cs.berkeley.edu)
.br
Stephen Tu (tus@roger-rabbit.cs.berkeley.edu)
