This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: RDFStore/Vocabulary/RDF,  Next: RDFStore/Vocabulary/RDFS,  Prev: RDFStore/Vocabulary/DC,  Up: Module List

=head1 SYNOPSIS
***************

NAME         RDFStore::Vocabulary::RDF
======================================

SYNOPSIS
========

     use RDFStore::Vocabulary::RDF;
     print $RDF::type->toString;

DESCRIPTION
===========

SEE ALSO
========

AUTHOR
======

   Alberto Reggiori <alberto.reggiori@jrc.it>


File: pm.info,  Node: RDFStore/Vocabulary/RDFS,  Next: RFC/RFC822/Address,  Prev: RDFStore/Vocabulary/RDF,  Up: Module List

=head1 SYNOPSIS
***************

NAME         RDFStore::Vocabulary::RDFS
=======================================

SYNOPSIS
========

     use RDFStore::Vocabulary::RDFS;
     print $RDFS::Class->toString;

DESCRIPTION
===========

SEE ALSO
========

AUTHOR
======

   Alberto Reggiori <alberto.reggiori@jrc.it>


File: pm.info,  Node: RFC/RFC822/Address,  Next: RIPEMD160,  Prev: RDFStore/Vocabulary/RDFS,  Up: Module List

RFC 822 style address validation.
*********************************

NAME
====

   RFC::RFC822::Address  -  RFC 822 style address validation.

SYNOPSIS
========

     use RFC::RFC822::Address qw /valid/;

     print "Valid\n" if valid 'abigail@example.com';

DESCRIPTION
===========

   This module checks strings to see whether they are have the valid
syntax, as defined in RFC 822 [1]. One subroutine, valid, can be imported,
which takes a single string as argument. If the string is valid according
to RFC 822, a true value is returned, else a false value is returned.

REFERENCES
==========

[1]
     David H. Crocker (revisor): "STANDARD FOR THE FORMAT OF ARPA INTERNET
     TEXT MESSAGES". RFC 822. 13 August 1982.

CAVEATS and BUGS
================

   This module sets the variable `$Parse::RecDescent::skip'. This will
influence all other Parse::RecDescent parsers. And this parser will break
if you set `$Parse::RecDescent::skip' to another value. It doesn't look
that it is possible to set an alternative skip value for each parser,
other than setting the skip value on each production.

   Example A.1.5 in RFC 822 is wrong. It should use
*"Galloping Gourmet"@ANT.Down-Under*.

   This module should have been named `RFC::822::Address'. However, perl
5.004 doesn't like the `822' part, and at the time of this writing MacPerl
is still at 5.004.

   This module is slow.

REVISION HISTORY
================

     $Log: Address.pm,v $
     Revision 1.5  2000/08/29 22:15:01  abigail
     Changed group rule to make <leftop> part greedy.
       (Damian Conway/Douglas Wilson)
     Added a test; removed $DEBUG part, now prints message on failures.
     Changed wording of license (using BSD/X style).

     Revision 1.4  1999/10/04 09:12:58  abigail
     Fixed typo in pod.

     Revision 1.3  1999/10/04 09:07:23  abigail
     Parsing of comments.
     Completed (?) test suite. Added --debug option to test.pl, to print
        what was being matched, and what the result of validation was.
     Changed package name to RFC::RFC822::Address, to cope for 5.004 users;
        MacPerl is still on 5.004.

     Revision 1.2  1999/10/02 10:08:48  abigail
     Grammar is now aware of the whitespace rules.
     Comment rules still have to be implemented.
     used h2xs.
     Created initial test.pl file.

     Revision 1.1  1999/10/01 08:50:13  abigail
     Initial revision

AUTHOR
======

   This package was written by Abigail, abigail@foad.org.

COPYRIGHT and LICENSE
=====================

   This program is copyright 1999, 2000 by Abigail.

   Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


File: pm.info,  Node: RIPEMD160,  Next: RIPEMD160/MAC,  Prev: RFC/RFC822/Address,  Up: Module List

Perl extension for the RIPEMD-160 Hash function
***********************************************

NAME
====

   RIPEMD160 - Perl extension for the RIPEMD-160 Hash function

SYNOPSIS
========

     use RIPEMD160;
     
     $context = new RIPEMD160;
     $context->reset();
     
     $context->add(LIST);
     $context->addfile(HANDLE);
     
     $digest = $context->digest();
     $string = $context->hexdigest();

     $digest = RIPEMD160->hash(SCALAR);
     $string = RIPEMD160->hexhash(SCALAR);

DESCRIPTION
===========

   The *RIPEMD160* module allows you to use the RIPEMD160 Message Digest
algorithm from within Perl programs.

   This is a BETA Version. In the future it will be located in
Crypt::RIPEMD160 and not in RIPEMD160.

   The module is based on the implementation from Antoon Bosselaers from
Katholieke Universiteit Leuven.

   A new RIPEMD160 context object is created with the new operation.
Multiple simultaneous digest contexts can be maintained, if desired.  The
context is updated with the add operation which adds the strings contained
in the LIST parameter. Note, however, that `add('foo', 'bar')',
`add('foo')' followed by `add('bar')' and `add('foobar')' should all give
the same result.

   The final message digest value is returned by the digest operation as a
20-byte binary string. This operation delivers the result of add
operations since the last new or reset operation. Note that the digest
operation is effectively a destructive, read-once operation. Once it has
been performed, the context must be reset before being used to calculate
another digest value.

   Several convenience functions are also provided. The *addfile*
operation takes an open file-handle and reads it until end-of file in 8192
byte blocks adding the contents to the context. The file-handle can either
be specified by name or passed as a type-glob reference, as shown in the
examples below. The *hexdigest* operation calls digest and returns the
result as a printable string of hexdecimal digits. This is exactly the
same operation as performed by the unpack operation in the examples below.

   The hash operation can act as either a static member function (ie you
invoke it on the RIPEMD160 class as in the synopsis above) or as a normal
virtual function. In both cases it performs the complete RIPEMD160 cycle
(reset, add, digest) on the supplied scalar value. This is convenient for
handling small quantities of data. When invoked on the class a temporary
context is created. When invoked through an already created context
object, this context is used. The latter form is slightly more efficient.
The *hexhash* operation is analogous to *hexdigest*.

EXAMPLES
========

     use RIPEMD160;
     
     $ripemd160 = new RIPEMD160;
     $ripemd160->add('foo', 'bar');
     $ripemd160->add('baz');
     $digest = $ripemd160->digest();
     
     print("Digest is " . unpack("H*", $digest) . "\n");

   The above example would print out the message

     Digest is f137cb536c05ec2bc97e73327937b6e81d3a4cc9

   provided that the implementation is working correctly.

   Remembering the Perl motto ("There's more than one way to do it"), the
following should all give the same result:

     use RIPEMD160;
     $ripemd160 = new RIPEMD160;

     die "Can't open /etc/passwd ($!)\n" unless open(P, "/etc/passwd");

     seek(P, 0, 0);
     $ripemd160->reset;
     $ripemd160->addfile(P);
     $d = $ripemd160->hexdigest;
     print "addfile (handle name) = $d\n";

     seek(P, 0, 0);
     $ripemd160->reset;
     $ripemd160->addfile(\*P);
     $d = $ripemd160->hexdigest;
     print "addfile (type-glob reference) = $d\n";

     seek(P, 0, 0);
     $ripemd160->reset;
     while (<P>)
     {
         $ripemd160->add($_);
     }
     $d = $ripemd160->hexdigest;
     print "Line at a time = $d\n";

     seek(P, 0, 0);
     $ripemd160->reset;
     $ripemd160->add(<P>);
     $d = $ripemd160->hexdigest;
     print "All lines at once = $d\n";

     seek(P, 0, 0);
     $ripemd160->reset;
     while (read(P, $data, (rand % 128) + 1))
     {
         $ripemd160->add($data);
     }
     $d = $ripemd160->hexdigest;
     print "Random chunks = $d\n";

     seek(P, 0, 0);
     $ripemd160->reset;
     undef $/;
     $data = <P>;
     $d = $ripemd160->hexhash($data);
     print "Single string = $d\n";

     close(P);

NOTE
====

   The RIPEMD160 extension may be redistributed under the same terms as
Perl.  The RIPEMD160 algorithm is published in "Fast Software Encryption,
LNCS 1039, D. Gollmann (Ed.), pp.71-82".

   The basic C code implementing the algorithm is covered by the following
copyright:

   ` /********************************************************************\
*  *      FILE:     rmd160.c  *  *      CONTENTS: A sample
C-implementation of the RIPEMD-160  *                hash-function.   *
 TARGET:   any computer with an ANSI C compiler  *  *      AUTHOR:
Antoon Bosselaers, ESAT-COSIC  *      DATE:     1 March 1996  *
VERSION:  1.0  *  *      Copyright (c) Katholieke Universiteit Leuven  *
  1996, All Rights Reserved  *
\********************************************************************/ '

RIPEMD-160 test suite results (ASCII):
======================================

   ` * message: "" (empty string)   hashcode:
9c1185a5c5e9fc54612808977ee8f548b2258d31 * message: "a"   hashcode:
0bdc9d2d256b3ee9daae347be6f4dc835a467ffe * message: "abc"   hashcode:
8eb208f7e05d987a9b044a8e98c6b087f15a0bfc * message: "message digest"
hashcode: 5d0689ef49d2fae572b881b123a85ffa21595f36 * message:
"abcdefghijklmnopqrstuvwxyz"   hashcode:
f71c27109c692c1b56bbdceb5b9d2865b3708dbc * message:
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"   hashcode:
12a053384a9c0c88e405a06c27dcf49ada62eb2b * message: "A...Za...z0...9"
hashcode: b0e20b6e3116640286ed3a87a5713079b21f5189 * message: 8 times
"1234567890"   hashcode: 9b752e45573d4b39f4dbd3323cab82bf63326bfb *
message: 1 million times "a"   hashcode:
52783243c1697bdbe16d37f97f68f08325dc1528 '

   This copyright does not prohibit distribution of any version of Perl
containing this extension under the terms of the GNU or Artistic licences.

AUTHOR
======

   The RIPEMD-160 interface was written by Christian H. Geuer
(`christian.geuer@crypto.gun.de').

SEE ALSO
========

   MD5(3pm) and SHA(1).


File: pm.info,  Node: RIPEMD160/MAC,  Next: RPC/ONC,  Prev: RIPEMD160,  Up: Module List

Perl extension for RIPEMD-160 MAC function
******************************************

NAME
====

   RIPEMD160::MAC - Perl extension for RIPEMD-160 MAC function

SYNOPSIS
========

     use RIPEMD160::MAC;
     
     $key = "This is the secret key";

     $mac = new RIPEMD160::MAC($key);

     $mac->reset();
     
     $mac->add(LIST);
     $mac->addfile(HANDLE);
     
     $digest = $mac->mac();
     $string = $mac->hexmac();

DESCRIPTION
===========

   The *RIPEMD160* module allows you to use the RIPEMD160 Message Digest
algorithm from within Perl programs.

EXAMPLES
========

     use RIPEMD160;
     
     $ripemd160 = new RIPEMD160;
     $ripemd160->add('foo', 'bar');
     $ripemd160->add('baz');
     $digest = $ripemd160->digest();
     
     print("Digest is " . unpack("H*", $digest) . "\n");

   The above example would print out the message

     Digest is f137cb536c05ec2bc97e73327937b6e81d3a4cc9

   provided that the implementation is working correctly.

AUTHOR
======

   The RIPEMD-160 interface was written by Christian H. Geuer
(`christian.geuer@crypto.gun.de').

SEE ALSO
========

   MD5(3pm) and SHA(1).


File: pm.info,  Node: RPC/ONC,  Next: RPC/PlClient,  Prev: RIPEMD160/MAC,  Up: Module List

Perl interface to ONC RPC
*************************

NAME
====

   RPC::ONC - Perl interface to ONC RPC

SYNOPSIS
========

     use RPC::ONC;

     # Create a client of the NFS service.

     $clnt = &RPC::ONC::Client::clnt_create('foo.bar.com',
     				      NFS_PROGRAM, NFS_VERSION,
     				      'netpath');

     # Set the timeout to 3 seconds.
     $clnt->clnt_control(CLSET_TIMEOUT, pack('LL', 3, 0));

DESCRIPTION
===========

   The RPC::ONC module provides access to some of the ONC RPC routines for
making and receiving remote procedure calls, as well as functions to
access members of RPC-related structures. It's intended to be used with
'perlrpcgen', which generates Perl XS stubs for RPC clients and servers.

   Most of these routines work the same as their C equivalents and are
thus not described in detail.

CAVEAT
======

   Not all of the ONC RPC calls are provided in this alpha version-I've
been filling them in more or less as needed. Let me know if there's one
you really need.

GLOBALS
=======

RPC::ONC::errno
     Number of the error that just occurred.

RPC::ONC::errstr
     Message corresponding to error that just occurred.

CLASSES
=======

RPC::ONC::Client
----------------

   RPC::ONC::Client wraps CLIENT *.

clnt_create(host, prognum, versnum, nettype)
     If the call fails, clnt_create will set RPC::ONC::errno and
     RPC::ONC::errstr and croak.

clnt_control(clnt, req, info)
     The info argument should be packed as an appropriate structure for the
     operation.

clnt_destroy(clnt)
set_cl_auth(clnt, auth)
     Takes an RPC::ONC::Client object and an RPC::ONC::Auth object and
     assigns the cl_auth field of the first to the second.

RPC::ONC::Auth
--------------

   RPC::ONC::Auth wraps AUTH *.

authnone_create
authsys_create_default
auth_destroy(auth)
RPC::ONC::svc_req
-----------------

   RPC::ONC::svc_req wraps struct svc_req *.

rq_prog(svc_req)
     Returns the rq_prog field.

rq_vers(svc_req)
     Returns the rq_vers field.

rq_proc(svc_req)
     Returns the rq_proc field.

rq_cred(svc_req)
     Returns the rq_cred field as an RPC::ONC::opaque_auth object.

authsys_parms(svc_req)
     Returns the rq_clntcred field as an RPC::ONC::authsys_parms object.
     Will croak if the credentials are not the right flavor.

authdes_cred(svc_req)
     Returns the rq_clntcred field as an RPC::ONC::authdes_cred object.
     Will croak if the credentials are not the right flavor.

RPC::ONC::opaque_auth
---------------------

oa_flavor(opaque_auth)
     Returns the oa_flavor field.

RPC::ONC::authsys_parms
-----------------------

aup_time(authsys_parms)
     Returns the aup_time field.

aup_machname(authsys_parms)
     Returns the aup_machname field.

aup_uid(authsys_parms)
     Returns the aup_uid field.

aup_gid(authsys_parms)
     Returns the aup_gid field.

aup_gids(authsys_parms)
     Returns the aup_gids field as an array.

RPC::ONC::Svcxprt
-----------------

   RPC::ONC::Svcxprt wraps struct svcxprt *.

svc_getcaller(transp)
     Returns a sockaddr_in * which you can unpack to get the IP address of
     the caller.

SEE ALSO
========

   `perlrpcgen(1)' in this node

AUTHOR
======

   Jake Donham <jake@organic.com>

THANKS
======

   Thanks to Organic Online <http://www.organic.com/> for letting me hack
at work.


File: pm.info,  Node: RPC/PlClient,  Next: RPC/PlServer,  Prev: RPC/ONC,  Up: Module List

Perl extension for writing PlRPC clients
****************************************

NAME
====

   RPC::PlClient - Perl extension for writing PlRPC clients

SYNOPSIS
========

     require RPC::PlClient;

     # Create a client object and connect it to the server
     my $client = RPC::PlClient->new('peeraddr' => 'joes.host.de',
     				  'peerport' => 2570,
     				  'application' => 'My App',
     				  'version' => '1.0',
     				  'user' => 'joe',
     				  'password' => 'hello!');

     # Create an instance of $class on the server by calling $class->new()
     # and an associated instance on the client.
     my $object = $client->Call('NewHandle', $class, 'new', @args);

     # Call a method on $object, effectively calling the same method
     # on the associated server instance.
     my $result = $object->do_method(@args);

DESCRIPTION
===========

   PlRPC (Perl RPC) is a package that simplifies the writing of Perl based
client/server applications. RPC::PlServer is the package used on the
server side, and you guess what RPC::PlClient is for. See
`RPC::PlServer(3)' in this node for this part.

   PlRPC works by defining a set of methods that may be executed by the
client.  For example, the server might offer a method "multiply" to the
client. Now a function call

     @result = $client->Call('multiply', $a, $b);

   on the client will be mapped to a corresponding call

     $server->multiply($a, $b);

   on the server. The function calls result will be transferred to the
client and returned as result of the clients method. Simple, eh? :-)

Client methods
--------------

$client = new(%attr);
     (Class method) The client constructor. Returns a client object,
     connected to the server. A Perl exception is thrown in case of
     errors, thus you typically use it like this:

          $client = eval { RPC::PlClient->new ( ... ) };
          if ($@) {
          	print STDERR "Cannot create client object: $@\n";
          	exit 0;
          }

     The method accepts a list of key/value pairs as arguments. Known
     arguments are:

    peeraddr
    peerport
    socket_proto
    socket_type
    timeout
          These correspond to the attributes *PeerAddr*, *PeerPort*, Proto,
          Type and Timeout of IO::Socket::INET. The server connection will
          be established by passing them to IO::Socket::INET->new().

    socket
          After a connection was established, the IO::Socket instance will
          be stored in this attribute. If you prefer establishing the
          connection on your own, you may as well create an own instance
          of IO::Socket and pass it as attribute socket to the new method.
          The above attributes will be ignored in that case.

    application
    version
    user
    password
          it is part of the PlRPC authorization process, that the client
          must obeye a login procedure where he will pass an application
          name, a protocol version and optionally a user name and password.
          These arguments are handled by the servers Application, Version
          and User methods.

    compression
          Set this to off (default, no compression) or gzip (requires the
          Compress::Zlib module).

    cipher
          This attribute can be used to add encryption quite easily. PlRPC
          is not bound to a certain encryption method, but to a block
          encryption API. The attribute is an object supporting the
          methods blocksize, encrypt and decrypt. For example, the modules
          Crypt::DES and Crypt::IDEA support such an interface.

          Note that you can set or remove encryption on the fly (putting
          undef as attribute value will stop encryption), but you have to
          be sure, that both sides change the encryption mode.

          Example:

               use Crypt::DES;
               $cipher = Crypt::DES->new(pack("H*", "0123456789abcdef"));
               $client = RPC::PlClient->new('cipher' => $cipher,
               				...);

    maxmessage
          The size of messages exchanged between client and server is
          restricted, in order to omit denial of service attacks. By
          default the limit is 65536 bytes.

    debug
          Enhances logging level by emitting debugging messages.

    logfile
          By default the client is logging to syslog (Unix) or the event
          log (Windows).  If neither is available or you pass a TRUE value
          as logfile, then logging will happen to the given file handle,
          an instance of IO::Handle. If the value is scalar, then logging
          will occur to stderr.

          Examples:

               # Logging to stderr:
               my $client = RPC::PlClient->new('logfile' => 1, ...);

               # Logging to 'my.log':
               my $file = IO::File->new('my.log', 'a')
                   || die "Cannot create log file 'my.log': $!";
               my $client = RPC::PlClient->new('logfile' => $file, ...);

@result = $client->Call($method, @args);
     (Instance method) Calls a method on the server; the arguments are a
     method name of the server class and the method call arguments. It
     returns the method results, if successfull, otherwise a Perl
     exception is thrown.

     Example:

          @results = eval { $client->Call($method, @args };
          if ($@) {
              print STDERR "An error occurred while executing $method: $@\n";
              exit 0;
          }

$cobj = $client->ClientObject($class, $method, @args)
     (Instance method) A set of predefined methods is available that make
     dealing with client side objects incredibly easy: In short the client
     creates a representation of the server object for you. Say we have an
     object $sobj on the server and an associated object $cobj on the
     client: Then a call

          @results = $cobj->my_method(@args);

     will be immediately mapped to a call

          @results = $sobj->my_method(@args);

     on the server and the results returned to you without any additional
     programming. Here's how you create $cobj, an instance of
     *RPC::PlClient::Object*:

          my $cobj = $client->ClientObject($class, 'new', @args);

     This will trigger a call

          my $sobj = $class->new(@args);

     on the server for you. Note that the server has the ability to
     restrict access to both certain classes and methods by setting
     $server->{'methods'} appropriately.

EXAMPLE
=======

   We'll create a simple example application, an MD5 client. The server
will have installed the MD5 module and create digests for us. We present
the client part only, the server example is part of the RPC::PlServer man
page. See `RPC::PlServer(3)' in this node.

     #!/usr/local/bin/perl

     use strict;               # Always a good choice.

     require RPC::PlClient;

     # Constants
     my $MY_APPLICATION = "MD5_Server";
     my $MY_VERSION = 1.0;
     my $MY_USER = "";		# The server doesn't require user
     my $MY_PASSWORD = "";	# authentication.

     my $hexdigest = eval {
         RPC::PlClient->new('peeraddr'    => 'joes.host.de',
     			   'peerport'    => 5000,
     			   'application' => $MY_APPLICATION,
     			   'version'     => $MY_VERSION,
     			   'user'        => $MY_USER,
     			   'password'    => $MY_PASSWORD);

     # Create an MD5 object on the server and an associated
     # client object. Executes a
     #     $context = MD5->new()
     # on the server.
     my $context = $client->ClientObject('MD5', 'new');

     # Let the server calculate a digest for us. Executes a
     #     $context->add("This is a silly string!");
     #     $context->hexdigest();
     # on the server.
     	$context->add("This is a silly string!");
     	$context->hexdigest();
         };
         if ($@) {
     die "An error occurred: $@";
         }

     print "Got digest $hexdigest\n";

AUTHOR AND COPYRIGHT
====================

   The PlRPC-modules are

     Copyright (C) 1998, Jochen Wiedmann
                         Am Eisteich 9
                         72555 Metzingen
                         Germany

     Phone: +49 7123 14887
     Email: joe@ispsoft.de

     All rights reserved.

   You may distribute this package under the terms of either the GNU
General Public License or the Artistic License, as specified in the Perl
README file.

SEE ALSO
========

   `PlRPC::Server(3)' in this node, `Net::Daemon(3)' in this node,
`Storable(3)' in this node, `Sys::Syslog(3)' in this node, *Note
Win32/EventLog: Win32/EventLog,

   An example application is the DBI Proxy client:

   `DBD::Proxy(3)' in this node.


File: pm.info,  Node: RPC/PlServer,  Next: RPC/Simple,  Prev: RPC/PlClient,  Up: Module List

Perl extension for writing PlRPC servers
****************************************

NAME
====

   RPC::PlServer - Perl extension for writing PlRPC servers

SYNOPSIS
========

     # Create a subclass of RPC::PlServer
     use RPC::PlServer;

     package MyServer;
     $MyServer::VERSION = '0.01';
     @MyServer::ISA = qw(RPC::PlServer);

     # Overwrite the Run() method to handle a single connection
     sub Run {
         my $self = shift;
         my $socket = $self->{'socket'};
     }

     # Create an instance of the MyServer class
     package main;
     my $server = MyServer->new({'localport' => '1234'}, \@ARGV);

     # Bind the server to its port to make it actually running
     $server->Bind();

DESCRIPTION
===========

   PlRPC (Perl RPC) is a package for implementing servers and clients that
are written in Perl entirely. The name is borrowed from Sun's RPC (Remote
Procedure Call), but it could as well be RMI like Java's "Remote Method
Interface), because PlRPC gives you the complete power of Perl's OO
framework in a very simple manner.

   RPC::PlServer is the package used on the server side, and you guess what
RPC::PlClient is for. Both share the package RPC::PlServer::Comm for
communication purposes. See `PlRPC::Client(3)' in this node and
`RPC::PlServer::Comm' in this node for these parts.

   PlRPC works by defining a set of methods that may be executed by the
client.  For example, the server might offer a method "multiply" to the
client. Now the clients method call

     @result = $client->multiply($a, $b);

   will be immediately mapped to a method call

     @result = $server->multiply($a, $b);

   on the server. The arguments and results will be transferred to or from
the server automagically. (This magic has a name in Perl: It's the
Storable module, my thanks to Raphael Manfredi for this excellent
package.) Simple, eh? :-)

   The RPC::PlServer and RPC::PlClient are abstract servers and clients:
You have to derive your own classes from it.

Additional options
------------------

   The RPC::PlServer inherits all of Net::Daemon's options and attributes
and adds the following:

cipher
     The attribute value is an instance of Crypt::DES, Crypt::IDEA or any
     other class with the same API for block encryption. If you supply
     such an attribute, the traffic between client and server will be
     encrypted using this option.

maxmessage (*-maxmessage=size*)
     The size of messages exchanged between client and server is
     restricted, in order to omit denial of service attacks. By default
     the limit is 65536 bytes.

users
     This is an attribute of the client object used for Permit/Deny rules
     in the config file. It's value is an array ref of user names that are
     allowed to connect from the given client. See the example config file
     below. `CONFIGURATION FILE' in this node.

Error Handling
--------------

   Error handling is simple with the RPC package, because it is based on
Perl exceptions completely. Thus your typical code looks like this:

     eval {
         # Do something here. Don't care for errors.
         ...
     };
     if ($@) {
         # An error occurred.
         ...
     }

Server Constructors
-------------------

     my $server = RPC::PlServer(\%options, \@args);

   (Class method) This constructor is immediately inherited from the
Net::Daemon package. See `Net::Daemon(3)' in this node for details.

Access Control
--------------

     $ok = $self->AcceptApplication($app);
     $ok = $self->AcceptVersion($version);
     $ok = $self->AcceptUser($user, $password);

   The RPC::PlServer package has a very detailed access control scheme:
First of all it inherits Net::Daemon's host based access control. It adds
version control and user authorization. To achieve that, the method Accept
from Net::Daemon is split into three methods, *AcceptApplication*,
*AcceptVersion* and *AcceptUser*, each of them returning TRUE or FALSE.
The client receives the arguments as the attributes application, version,
user and password. A client is accepted only if all of the above methods
are returning TRUE.

   The default implementations are as follows: The AcceptApplication method
returns TRUE, if *$self* is a subclass of *$app*. The AcceptVersion method
returns TRUE, if the requested version is less or equal to
*${$class}::VERSION*, $self being an instance of $class. Whether a user is
permitted to connect depends on the client configuration. See
`CONFIGURATION FILE' in this node below for examples.

Method based access control
---------------------------

   Giving a client the ability to invoke arbitrary methods can be a
terrible security hole. Thus the server has a methods attribute. This is a
hash ref of class names as keys, the values being hash refs again with
method names as the keys. That is, if your hash looks as follows:

     $self->{'methods'} = {
         'CalcServer' => {
             'NewHandle' => 1,
             'CallMethod' => 1 },
         'Calculator' => {
             'new' => 1,
             'multiply' => 1,
             'add' => 1,
             'divide' => 1,
             'subtract' => 1 }
         };

   then the client may use the CalcServer's NewHandle method to create
objects, but only via the permitted constructor Calculator->new. Once a
Calculator object is created, the server may invoke the methods multiply,
add, divide and subtract.

CONFIGURATION FILE
==================

   The server config file is inherited from Net::Daemon. It adds the users
and cipher attribute to the client list. Thus a typical config file might
look as follows:

     # Load external modules; this is not required unless you use
     # the chroot() option.
     #require DBD::mysql;
     #require DBD::CSV;

     # Create keys
     my $myhost_key = Crypt::IDEA->new('83fbd23390ade239');
     my $bob_key    = Crypt::IDEA->new('be39893df23f98a2');

     {
         # 'chroot' => '/var/dbiproxy',
         'facility' => 'daemon',
         'pidfile' => '/var/dbiproxy/dbiproxy.pid',
         'user' => 'nobody',
         'group' => 'nobody',
         'localport' => '1003',
         'mode' => 'fork',

     # Access control
     'clients' => [
         # Accept the local LAN (192.168.1.*)
         {
             'mask' => '^192\.168\.1\.\d+$',
             'accept' => 1,
             'users' => [ 'bob', 'jim' ],
             'cipher' => $myhost_key
         },
         # Accept myhost.company.com
         {
             'mask' => '^myhost\.company\.com$',
             'accept' => 1,
             'users' => [ {
                 'name' => 'bob',
                 'cipher' => $bob_key
                 } ]
         },
         # Deny everything else
         {
             'mask' => '.*',
             'accept' => 0
         }
     ]
         }

   Things you should note: The user list of 192.168.1.* contains scalar
values, but the user list of myhost.company.com contains hash refs: This
is required, because the user configuration is more specific for user
based encryption.

EXAMPLE
=======

   Enough wasted time, spread the example, not the word. :-) Let's write a
simple server, say a server for MD5 digests. The server uses the external
package MD5, but the client doesn't need to install the package. `MD5(3)'
in this node. We present the server source here, the client is part of the
RPC::PlClient man page. See `RPC::PlClient(3)' in this node.

     #!/usr/bin/perl -wT
     # Note the -T switch! This is always recommended for Perl servers.

     use strict;               # Always a good choice.

     require RPC::PlServer;
     require MD5;

     package MD5_Server;  # Clients need to request application
                          # "MD5_Server"

     $MD5_Server::VERSION = '1.0'; # Clients will be refused, if they
                                   # request version 1.1
     @MD5_Server::ISA = qw(RPC::PlServer);

     eval {
         # Server options below can be overwritten in the config file or
         # on the command line.
         my $server = MD5_Server->new({
     	    'pidfile'    => '/var/run/md5serv.pid',
     	    'configfile' => '/etc/md5serv.conf',
     	    'facility'   => 'daemon', # Default
     	    'user'       => 'nobody',
     	    'group'      => 'nobody',
     	    'localport'  => 2000,
     	    'logfile'    => 0,        # Use syslog
             'mode'       => 'fork',   # Recommended for Unix
             'methods'    => {
     	        'MD5_Server' => {
     		    'ClientObject' => 1,
     		    'CallMethod' => 1,
     		    'NewHandle' => 1
     		    },
     	        'MD5' => {
     		    'new' => 1,
     		    'add' => 1,
     		    'hexdigest' => 1
     		    },
     	        }
         });
         $server->Bind();
     };

SECURITY
========

   It has to be said: PlRPC based servers are a potential security problem!
I did my best to avoid security problems, but it is more than likely, that
I missed something. Security was a design goal, but not *the* design goal.
(A well known problem ...)

   I highly recommend the following design principles:

Protection against "trusted" users
----------------------------------

perlsec
     Read the perl security FAQ (`perldoc perlsec') and use the -T switch.

taintperl
     Use the -T switch. I mean it!

Verify data
     Never untaint strings withouth verification, better verify twice.
     For example the CallMethod function first checks, whether an object
     handle is valid before coercing a method on it.

Be restrictive
     Think twice, before you give a client access to a method.

perlsec
     And just in case I forgot it: Read the perlsec man page. :-)

Protection against untrusted users
----------------------------------

Host based authorization
     PlRPC has a builtin host based authorization scheme; use it!  See `'
     in this node.

User based authorization
     PlRPC has a builtin user based authorization scheme; use it!  See `'
     in this node.

Encryption
     Using encryption with PlRPC is extremely easy. There is absolutely no
     reason for communicating unencrypted with the clients. Even more: I
     recommend two phase encryption: The first phase is the login phase,
     where to use a host based key. As soon as the user has authorized,
     you should switch to a user based key. See the DBI::ProxyServer for
     an example.

AUTHOR AND COPYRIGHT
====================

   The PlRPC-modules are

     Copyright (C) 1998, Jochen Wiedmann
                         Am Eisteich 9
                         72555 Metzingen
                         Germany

     Phone: +49 7123 14887
     Email: joe@ispsoft.de

     All rights reserved.

   You may distribute this package under the terms of either the GNU
General Public License or the Artistic License, as specified in the Perl
README file.

SEE ALSO
========

   `RPC::PlClient(3)' in this node, `RPC::PlServer::Comm(3)' in this node,
`Net::Daemon(3)' in this node, `Net::Daemon::Log(3)' in this node,
`Storable(3)' in this node, `Sys::Syslog(3)' in this node,
`Win32::EventLog(3)' in this node

   See `DBI::ProxyServer(3)' in this node for an example application.


File: pm.info,  Node: RPC/Simple,  Next: RPC/Simple/Agent,  Prev: RPC/PlServer,  Up: Module List

Perl classes to handle SRPC calls with call-back
************************************************

NAME
====

   RPC::Simple - Perl classes to handle SRPC calls with call-back

SYNOPSIS
========

     use RPC::Simple;

     #see test.pl file

DESCRIPTION
===========

   Dummy class which loads RPC::Simple::AnyLocal and
RPC::Simple::AnyRemote ;

   This module deals with remote procedure call. I've tried to keep things
simple.

   So this module should be :  - quite simple to use (thanks to autoload
mechanisms)  - lightweight

   It sure is not :  - DCE  - CORBA  - bulletproof  - securityproof  -
foolproof

   But it works. (Although I'm opened to suggestion regarging the
"un-proof" areas)

   The module is made of the following sub-classes :

     RPC::Simple::Agent - Perl extension for an agent object
     RPC::Simple::AnyLocal - Perl extension defining a virtual RPC client class

     RPC::Simple::AnyRemote - Perl base class for a remote object
     RPC::Simple::CallHandler - Perl class to handle RPC::Simple calls with call-back
     RPC::Simple::Factory - Perl extension for creating client
     RPC::Simple::ObjectHandler - Perl class to handle a remote object
     RPC::Simple::Server - Perl class to use in the RPC::Simple server script.
     RPC::Simple::AnyWhere - Common parts for AnyLocal and AnyRemote

   Anyway, the casual user should worry only about inheriting the
RPC::Simple::AnyLocal class and creating a RPC::Simple::Factory on the
local side.

   On the remote side, the user will only have to inherit
RPC::Simple::AnyRemote and run the mainLoop method of RPC::Simple::Server.

   In each side you must declare all methods available on the other side
in a global array of your class.

   How it works ? The user (i.e. you) must write a local class which
inherit from AnyLocal. AnyLocal is designed to handle Agent and Factory.

     AnyLocal --1---<>---1-- Agent --*--<>---Factory----<>--LAN
         |
        /\____
             |
             |
         LocalClass

   First, the user script will have to :  - instantiate one Factory.   -
Create its instance of LocalClass  - LocalClass::new will call
$self->createRemote, this will create the Agent class.

     - Now any call to an undefined method (BUT declared in @RPC_SUB)
     of LocalClass will be forwarded to the Remote class.
     If this call has a code reference as first parameter, Agent
     will call this code when the remote call is over. I.e. all remote
     procedure call must be designed in asynchronous mode.

   Note that undefined method not declared in @RPC_SUB will be autoloaded
(or at least, I'll try to autoload them).

   Note that Factory and Agent actually use Tk to manage the socket
connection.

   On the remote side, the user will write its RemoteClass which will
inherit from AnyRemote.

     LAN --1--<>--*-- Server --1--<>--*--ObjectHandler--1--<>--*--CallHandler
                                               |                        |
                                               1                        *
                                               |                        |
                                               --<>--1--AnyRemote--1-<>--
                                                            |
                                                           /\____
                                                                |
                                                                |
                                                           RemoteClass

   RemoteClass will be called with the method name that was invoked for
LocalClass. RemtoeClass may call a function from local class using the
same mechanism but it may NOT expect a call-back from this call to the
local side.

   Note that the remote class may call directly method from the Local
class.  (Provided the local method is declared in the @RPC_SUB array of
the remote class)

   Note that the instance variable of the local class or remote class are
not shared or updated or replicated magically. If you must pass data from
one side to the other, you have to do it explicitely. In most case you'll
pass the variable value as a method parameter.

CAVEATS
=======

   Well, this stuff is supposed to be pretty simple, the code to handle the
RPC and callback is not much complicated, but I sure have a lot of problem
to write a doc which make using this module simple. Future version may get
better depending on your comments or questions.

AUTHOR
======

   Dominique_Dumont@grenoble.hp.com

SEE ALSO
========

   perl(1), RPC::Simple::AnyLocal(3), RPC::Simple::AnyRemote(3) .


File: pm.info,  Node: RPC/Simple/Agent,  Next: RPC/Simple/AnyLocal,  Prev: RPC/Simple,  Up: Module List

Perl extension for an agent object for RPC
******************************************

NAME
====

   RPC::Simple::Agent - Perl extension for an agent object for RPC

SYNOPSIS
========

     use RPC::Simple::Agent ;

DESCRIPTION
===========

   This class is an agent for client class inheriting PRC::AnyLocal. This
class will handle all the boring stuff to create, access store call-back
when dealing with the remote object.

   Casual user should not worry about this class. RPC::Simple::AnyLocal
will deal with it.

Methods
=======

new( $factory_ref, client_ref, index, remote_class, ... .)
----------------------------------------------------------

   Create the agent.

   factory_ref is the SPRC::Factory object.

   client_ref is the client object itself.

   index is an index handled by the Factory.

   remote_class if the name of the class created on the remote side. By
default, it is set to the client's class name with a 'Real' prepended to
the name.

   I.e if the client is Foo::Bar, the remote will be Foo::RealBar.

   The remaining parameters will forwarded to the constructor of the remote
class.

getRemoteHostName
-----------------

   returns the remote host name

delegate( method_name , [code_ref ],                 parameters ,... )
----------------------------------------------------------------------

   Call a method of the remote object. If code_ref is specified, the code
will be executed with whatever parameters the remote functions passed in
its reply.

   The remaining optionnal parameters are passed as is to the remote
method.

   Note that ref are copied. You can't expect the remote to be able to
modify a client's variable because you passed it's ref to the remote.

callMethod( method_name, argument_array_ref )
---------------------------------------------

   Function used to call the owner of the agent. All arguments of the
function to be called back are passed in the array ref.

CALLBACKS
=========

remoteCreated(result, string)
-----------------------------

   Called when the remote object is created. 'result' will be true or false
depending on whether the remote object was created or not.

   'string' contains the error message in case of a failure.

treatCallBack ( request_id, argument_array_ref)
-----------------------------------------------

   Function used to call-back the owner of the agent. All arguments of the
function to be called back are passed in the array ref.

   'request_id' is used to know what object and methos are to be called
back.  These info were stored by the delegate function.

AUTHOR
======

   Dominique_Dumont@grenoble.hp.com

SEE ALSO
========

   perl(1), RPC::Simple::AnyLocal(3).


File: pm.info,  Node: RPC/Simple/AnyLocal,  Next: RPC/Simple/AnyRemote,  Prev: RPC/Simple/Agent,  Up: Module List

Perl extension defining a virtual SRPC client class
***************************************************

NAME
====

   RPC::Simple::AnyLocal - Perl extension defining a virtual SRPC client
class

SYNOPSIS
========

     package MyLocal ;

     use RPC::Simple::AnyLocal;
     use vars qw($VERSION @ISA @RPC_SUB) ;
     @ISA = qw(RPC::Simple::AnyLocal [other_class] );
     @RPC_SUB = qw(remoteHello remoteAsk);

     sub new
      {
        my $type = shift ;

     my $self = {} ;
     my $remote =  shift ;
     bless $self,$type ;

     $self->createRemote($remote,'your_class_name') ;
     return $self ;
       }

     # Note that the 'remoteHello' method is not part of MyLocal

     package main;

     use Tk ;
     use RPC::Simple::Server ;
     use RPC::Simple::Factory ;

     my $pid = &spawn ; # spawn server if needed
     
     # client part
     my $mw = MainWindow-> new ;
     my $verbose = 1 ;

     # create factory
     my $factory = new RPC::Simple::Factory($mw,\$verbose) ;
     my $local = new MyLocal($factory) ;
     $mw -> Button (text => 'quit', command => sub {exit;} ) -> pack ;
     $mw -> Button (text => 'remoteAct',
       command => sub {$local->remoteHello();} ) -> pack ;

     MainLoop ; # Tk's

DESCRIPTION
===========

   This class must be inherited by a sub-class so this one can use the RPC
facility.

   Note that this class (and the Factory class) was designed to use Tk's
fileevent facilities.

   The child object must declare in the @RPC_SUB array the name of the
methods available on the remote side.

Methods
=======

createRemote(factory_object_ref, [remote_class_name], ... )
-----------------------------------------------------------

   This method should be called by the child object during start-up. It
will ask the SRPC factory to create a ClientAgent class dedicated to this
new object.

   The server on the other side of the socket will load the code necessary
for the remote class. By default the remote class name will be
...::Real<LocalClass>. I.e if your local class is Test::Foo the remote
class name will be Test::RealFoo.

   If the remote class name has no prefix, '.pm' will be appended to get
the file name to load

   The remaining parameters will passed to the remote object's new method
during its creation.

   returns self.

destroy()
---------

   Objects derived from AnyLocal must be explicitely destroy. If you just
undef the object reference, you will not release the memory and the remote
object will not be destroyed.

AUTOLOAD()
----------

   When this method is called (generally through perl mechanism), the call
will be forwarded with all parameter to the remote object. If the first
parameters is  : \&one_callback

   the function &one_callback will be called when the remote side has
finished its function.

   If you want to call-back an object method, use a closure. Such as

     $self->remote_method(sub {$self-> finished(@_)})

   Note that if the remote method name is not declared in the @RPC_SUB
array, AnyLocal will try to autoload this method.

   returns self.

instance variable
=================

   AnyLocal will create the following instance variables:

_twinHandle
-----------

   Will contains the ref of the RPC::Simple::Agent object.

remoteHostName
--------------

   Will contains the name of the remote host.

Inheritance and Autoload
========================

   Since RPC::Simple uses the AUTOLOAD subroutine to delegate unknown
calls to the remote class, you must pay attention if you use or inherit
classes which use the AutoLoader mechanism.

   The AUTOLOAD defined in this class will first check if the called
function is declared in the @RPC_SUB arrays of all inherited classes. If
yes it will call the remote function. If not it will forward the call to
the AutoLoader::AUTOLOAD routine. In this case you fall back on the usual
AutoLoad mechanism.

   For this scheme to work, it is important that RPC::Simple::AUTOLOAD is
run BEFORE the AutoLoader::AUTOLOAD routine.

   So when inheriting from RPC::Simple and another class (say Foo::Bar),
you must put RPC::Simple::AnyLocal BEFORE your class in the @ISA array.

   For instance, you must declare :  @ISA = qw(RPC::Simple::AnyLocal
Foo::Bar);

   BTW, if you are mixing autoloading, remote calls and inheritance, which
is a recipe for a good headache, you really (I mean it) should use
subroutine stubs for the auloaded functions. (It does really work better).
See AutoLoad(3).

AUTHOR
======

   Dominique Dumont, Dominique_Dumont@grenoble.hp.com

SEE ALSO
========

   perl(1), RPC::Simple::Factory(3), RPC::Simple::AnyRemote(3)


File: pm.info,  Node: RPC/Simple/AnyRemote,  Next: RPC/Simple/AnyWhere,  Prev: RPC/Simple/AnyLocal,  Up: Module List

Perl base class for a remote object accessible by RPC
*****************************************************

NAME
====

   RPC::Simple::AnyRemote - Perl base class for a remote object accessible
by RPC

SYNOPSIS
========

     package myClass ;
     use vars qw(@ISA @RPC_SUB);
     use RPC::Simple::AnyRemote;

     @ISA=('RPC::Simple::AnyRemote') ;
     @RPC_SUB = qw(localMethod);

DESCRIPTION
===========

   This class must be inherited by the user's class actually performing the
remote functions.

   Note that any user defined method which can be called by the local
object must be able to handle the following optionnal parameters :

   'callback' => code_reference

   Usually, the methods will be like :

     sub remoteMethod
     {
       my $self = shift ;
       my $param = shift ;
       my $callback ;

     if ($param eq 'callback')
       {
         # callback required
         $callback = shift
       }

     # user code

     # can call a method from local object
     $self->localMethod("Hey, remoteMethod was called !!");

     # when the user code is over
     return unless defined $callback ;

     &$callback("Hello local object" ) ;
      }

Methods
=======

new('controller_ref')
---------------------

   controller_ref is the RPC::Simple::ObjectHandler object actually
controlling this instance.

   If you overload 'new', don't forget to call also the inherited 'new'
method.

AUTOLOAD()
----------

   When this method is called (generally through perl mechanism), the call
will be forwarded with all parameter to the local object.  Note that if
the remote method name is not declated in the @RPC_SUB array, AnyLocal
will try to autoload this mehtod.

   Note that this method is not able to handle sub_reference and call back
mechanism is not possible fromthis side.

   returns self.

instance variable
=================

   AnyRemote will create the following instance variables:

_twinHandle
-----------

   RPC::Simple::ObjectHandler object reference

origDir
-------

   Store the pwd of the object during its creation.

AUTHOR
======

   Dominique Dumont, Dominique_Dumont@grenoble.hp.com

SEE ALSO
========

   perl(1), RPC::Simple::AnyLocal(3)


