'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" All rights reserved.
'\"
'\" Permission is hereby granted, without written agreement and without
'\" license or royalty fees, to use, copy, modify, and distribute this
'\" documentation for any purpose, provided that the above copyright
'\" notice and the following two paragraphs appear in all copies.
'\"
'\" IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
'\" ARISING OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
'\" CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'\"
'\" THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
'\" AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
'\" ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
'\" PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
'\" 
.\" The definitions below are for supplemental macros used in Tcl/Tk
.\" 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 Tcl/Tk man pages
.de HS
.ds ^3 \\0
.if !"\\$3"" .ds ^3 \\$3
.if '\\$2'cmds'       .TH \\$1 1 \\*(^3 \\$4
.if '\\$2'lib'        .TH \\$1 3 \\*(^3 \\$4
.if '\\$2'tcldp'         .TH \\$1 n \\*(^3 Tcl-DP "Tcl-DP Commands"
.if '\\$2'tcldpc'         .TH \\$1 3 \\*(^3 Tcl-DP "Tcl-DP Library Procedures"
.if '\\$2'tcldpcmds'         .TH \\$1 1 \\*(^3 Tcl-DP "Tcl-DP Applications"
.if '\\$2'tcldpintro'         .TH \\$1 n \\*(^3 Tcl-DP "Introduction to Tcl-DP"
.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
..
.HS dp_RPC tcldp
.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? ?retFile?\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 (see dp_MakeRPCClient below).  The \fIport\fR should
be an unused port or 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 unless \fIretFile\fP in non-zero,
in which case both the file identifier and the port number for the
listening socket 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.  If \fIcmdCheckProc\fR is the
keyword "none," no command checking is performed.  \fICmdCheckProc\fR
defaults to "none." See dp_SetCheckCmd for more details on security.

.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 running on the machine with the \fIhost\fR network
address.  \fIPort\fP can be specified either by number or by service
name (see services(5) for further information on specifying services by
name).  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.  The transmission protocol used for
Tcl-DP RPC services is TCP/IP.

\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 resultCallback\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.  The default value for \fIerrorCallback\fR is
tkerror.  If you wish to ignore errors generated during RDO
evaluation, specify the keyword "none" as \fIerrorCallback\fR.

.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)
