summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/pods/perlfaq9.pod
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/pods/perlfaq9.pod')
-rwxr-xr-xMaster/tlpkg/tlperl/lib/pods/perlfaq9.pod690
1 files changed, 690 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl/lib/pods/perlfaq9.pod b/Master/tlpkg/tlperl/lib/pods/perlfaq9.pod
new file mode 100755
index 00000000000..ce0cf072419
--- /dev/null
+++ b/Master/tlpkg/tlperl/lib/pods/perlfaq9.pod
@@ -0,0 +1,690 @@
+=head1 NAME
+
+perlfaq9 - Networking
+
+=head1 DESCRIPTION
+
+This section deals with questions related to networking, the internet,
+and a few on the web.
+
+=head2 What is the correct form of response from a CGI script?
+
+(Alan Flavell <flavell+www@a5.ph.gla.ac.uk> answers...)
+
+The Common Gateway Interface (CGI) specifies a software interface between
+a program ("CGI script") and a web server (HTTPD). It is not specific
+to Perl, and has its own FAQs and tutorials, and usenet group,
+comp.infosystems.www.authoring.cgi
+
+The CGI specification is outlined in an informational RFC:
+http://www.ietf.org/rfc/rfc3875
+
+Other relevant documentation listed in: http://www.perl.org/CGI_MetaFAQ.html
+
+These Perl FAQs very selectively cover some CGI issues. However, Perl
+programmers are strongly advised to use the CGI.pm module, to take care
+of the details for them.
+
+The similarity between CGI response headers (defined in the CGI
+specification) and HTTP response headers (defined in the HTTP
+specification, RFC2616) is intentional, but can sometimes be confusing.
+
+The CGI specification defines two kinds of script: the "Parsed Header"
+script, and the "Non Parsed Header" (NPH) script. Check your server
+documentation to see what it supports. "Parsed Header" scripts are
+simpler in various respects. The CGI specification allows any of the
+usual newline representations in the CGI response (it's the server's
+job to create an accurate HTTP response based on it). So "\n" written in
+text mode is technically correct, and recommended. NPH scripts are more
+tricky: they must put out a complete and accurate set of HTTP
+transaction response headers; the HTTP specification calls for records
+to be terminated with carriage-return and line-feed, i.e ASCII \015\012
+written in binary mode.
+
+Using CGI.pm gives excellent platform independence, including EBCDIC
+systems. CGI.pm selects an appropriate newline representation
+($CGI::CRLF) and sets binmode as appropriate.
+
+=head2 My CGI script runs from the command line but not the browser. (500 Server Error)
+
+Several things could be wrong. You can go through the "Troubleshooting
+Perl CGI scripts" guide at
+
+ http://www.perl.org/troubleshooting_CGI.html
+
+If, after that, you can demonstrate that you've read the FAQs and that
+your problem isn't something simple that can be easily answered, you'll
+probably receive a courteous and useful reply to your question if you
+post it on comp.infosystems.www.authoring.cgi (if it's something to do
+with HTTP or the CGI protocols). Questions that appear to be Perl
+questions but are really CGI ones that are posted to comp.lang.perl.misc
+are not so well received.
+
+The useful FAQs, related documents, and troubleshooting guides are
+listed in the CGI Meta FAQ:
+
+ http://www.perl.org/CGI_MetaFAQ.html
+
+=head2 How can I get better error messages from a CGI program?
+
+Use the CGI::Carp module. It replaces C<warn> and C<die>, plus the
+normal Carp modules C<carp>, C<croak>, and C<confess> functions with
+more verbose and safer versions. It still sends them to the normal
+server error log.
+
+ use CGI::Carp;
+ warn "This is a complaint";
+ die "But this one is serious";
+
+The following use of CGI::Carp also redirects errors to a file of your choice,
+placed in a BEGIN block to catch compile-time warnings as well:
+
+ BEGIN {
+ use CGI::Carp qw(carpout);
+ open(LOG, ">>/var/local/cgi-logs/mycgi-log")
+ or die "Unable to append to mycgi-log: $!\n";
+ carpout(*LOG);
+ }
+
+You can even arrange for fatal errors to go back to the client browser,
+which is nice for your own debugging, but might confuse the end user.
+
+ use CGI::Carp qw(fatalsToBrowser);
+ die "Bad error here";
+
+Even if the error happens before you get the HTTP header out, the module
+will try to take care of this to avoid the dreaded server 500 errors.
+Normal warnings still go out to the server error log (or wherever
+you've sent them with C<carpout>) with the application name and date
+stamp prepended.
+
+=head2 How do I remove HTML from a string?
+
+The most correct way (albeit not the fastest) is to use HTML::Parser
+from CPAN. Another mostly correct
+way is to use HTML::FormatText which not only removes HTML but also
+attempts to do a little simple formatting of the resulting plain text.
+
+Many folks attempt a simple-minded regular expression approach, like
+C<< s/<.*?>//g >>, but that fails in many cases because the tags
+may continue over line breaks, they may contain quoted angle-brackets,
+or HTML comment may be present. Plus, folks forget to convert
+entities--like C<&lt;> for example.
+
+Here's one "simple-minded" approach, that works for most files:
+
+ #!/usr/bin/perl -p0777
+ s/<(?:[^>'"]*|(['"]).*?\1)*>//gs
+
+If you want a more complete solution, see the 3-stage striphtml
+program in
+http://www.cpan.org/authors/Tom_Christiansen/scripts/striphtml.gz
+.
+
+Here are some tricky cases that you should think about when picking
+a solution:
+
+ <IMG SRC = "foo.gif" ALT = "A > B">
+
+ <IMG SRC = "foo.gif"
+ ALT = "A > B">
+
+ <!-- <A comment> -->
+
+ <script>if (a<b && a>c)</script>
+
+ <# Just data #>
+
+ <![INCLUDE CDATA [ >>>>>>>>>>>> ]]>
+
+If HTML comments include other tags, those solutions would also break
+on text like this:
+
+ <!-- This section commented out.
+ <B>You can't see me!</B>
+ -->
+
+=head2 How do I extract URLs?
+
+You can easily extract all sorts of URLs from HTML with
+C<HTML::SimpleLinkExtor> which handles anchors, images, objects,
+frames, and many other tags that can contain a URL. If you need
+anything more complex, you can create your own subclass of
+C<HTML::LinkExtor> or C<HTML::Parser>. You might even use
+C<HTML::SimpleLinkExtor> as an example for something specifically
+suited to your needs.
+
+You can use URI::Find to extract URLs from an arbitrary text document.
+
+Less complete solutions involving regular expressions can save
+you a lot of processing time if you know that the input is simple. One
+solution from Tom Christiansen runs 100 times faster than most
+module based approaches but only extracts URLs from anchors where the first
+attribute is HREF and there are no other attributes.
+
+ #!/usr/bin/perl -n00
+ # qxurl - tchrist@perl.com
+ print "$2\n" while m{
+ < \s*
+ A \s+ HREF \s* = \s* (["']) (.*?) \1
+ \s* >
+ }gsix;
+
+=head2 How do I download a file from the user's machine? How do I open a file on another machine?
+
+In this case, download means to use the file upload feature of HTML
+forms. You allow the web surfer to specify a file to send to your web
+server. To you it looks like a download, and to the user it looks
+like an upload. No matter what you call it, you do it with what's
+known as B<multipart/form-data> encoding. The CGI.pm module (which
+comes with Perl as part of the Standard Library) supports this in the
+start_multipart_form() method, which isn't the same as the startform()
+method.
+
+See the section in the CGI.pm documentation on file uploads for code
+examples and details.
+
+=head2 How do I make an HTML pop-up menu with Perl?
+
+(contributed by brian d foy)
+
+The CGI.pm module (which comes with Perl) has functions to create
+the HTML form widgets. See the CGI.pm documentation for more
+examples.
+
+ use CGI qw/:standard/;
+ print header,
+ start_html('Favorite Animals'),
+
+ start_form,
+ "What's your favorite animal? ",
+ popup_menu(
+ -name => 'animal',
+ -values => [ qw( Llama Alpaca Camel Ram ) ]
+ ),
+ submit,
+
+ end_form,
+ end_html;
+
+=head2 How do I fetch an HTML file?
+
+(contributed by brian d foy)
+
+Use the libwww-perl distribution. The C<LWP::Simple> module can fetch web
+resources and give their content back to you as a string:
+
+ use LWP::Simple qw(get);
+
+ my $html = get( "http://www.example.com/index.html" );
+
+It can also store the resource directly in a file:
+
+ use LWP::Simple qw(getstore);
+
+ getstore( "http://www.example.com/index.html", "foo.html" );
+
+If you need to do something more complicated, you can use
+C<LWP::UserAgent> module to create your own user-agent (e.g. browser)
+to get the job done. If you want to simulate an interactive web
+browser, you can use the C<WWW::Mechanize> module.
+
+=head2 How do I automate an HTML form submission?
+
+If you are doing something complex, such as moving through many pages
+and forms or a web site, you can use C<WWW::Mechanize>. See its
+documentation for all the details.
+
+If you're submitting values using the GET method, create a URL and encode
+the form using the C<query_form> method:
+
+ use LWP::Simple;
+ use URI::URL;
+
+ my $url = url('http://www.perl.com/cgi-bin/cpan_mod');
+ $url->query_form(module => 'DB_File', readme => 1);
+ $content = get($url);
+
+If you're using the POST method, create your own user agent and encode
+the content appropriately.
+
+ use HTTP::Request::Common qw(POST);
+ use LWP::UserAgent;
+
+ $ua = LWP::UserAgent->new();
+ my $req = POST 'http://www.perl.com/cgi-bin/cpan_mod',
+ [ module => 'DB_File', readme => 1 ];
+ $content = $ua->request($req)->as_string;
+
+=head2 How do I decode or create those %-encodings on the web?
+X<URI> X<CGI.pm> X<CGI> X<URI::Escape> X<RFC 2396>
+
+(contributed by brian d foy)
+
+Those C<%> encodings handle reserved characters in URIs, as described
+in RFC 2396, Section 2. This encoding replaces the reserved character
+with the hexadecimal representation of the character's number from
+the US-ASCII table. For instance, a colon, C<:>, becomes C<%3A>.
+
+In CGI scripts, you don't have to worry about decoding URIs if you are
+using C<CGI.pm>. You shouldn't have to process the URI yourself,
+either on the way in or the way out.
+
+If you have to encode a string yourself, remember that you should
+never try to encode an already-composed URI. You need to escape the
+components separately then put them together. To encode a string, you
+can use the the C<URI::Escape> module. The C<uri_escape> function
+returns the escaped string:
+
+ my $original = "Colon : Hash # Percent %";
+
+ my $escaped = uri_escape( $original )
+
+ print "$string\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25%20'
+
+To decode the string, use the C<uri_unescape> function:
+
+ my $unescaped = uri_unescape( $escaped );
+
+ print $unescaped; # back to original
+
+If you wanted to do it yourself, you simply need to replace the
+reserved characters with their encodings. A global substitution
+is one way to do it:
+
+ # encode
+ $string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;
+
+ #decode
+ $string =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg;
+
+=head2 How do I redirect to another page?
+
+Specify the complete URL of the destination (even if it is on the same
+server). This is one of the two different kinds of CGI "Location:"
+responses which are defined in the CGI specification for a Parsed Headers
+script. The other kind (an absolute URLpath) is resolved internally to
+the server without any HTTP redirection. The CGI specifications do not
+allow relative URLs in either case.
+
+Use of CGI.pm is strongly recommended. This example shows redirection
+with a complete URL. This redirection is handled by the web browser.
+
+ use CGI qw/:standard/;
+
+ my $url = 'http://www.cpan.org/';
+ print redirect($url);
+
+This example shows a redirection with an absolute URLpath. This
+redirection is handled by the local web server.
+
+ my $url = '/CPAN/index.html';
+ print redirect($url);
+
+But if coded directly, it could be as follows (the final "\n" is
+shown separately, for clarity), using either a complete URL or
+an absolute URLpath.
+
+ print "Location: $url\n"; # CGI response header
+ print "\n"; # end of headers
+
+=head2 How do I put a password on my web pages?
+
+To enable authentication for your web server, you need to configure
+your web server. The configuration is different for different sorts
+of web servers--apache does it differently from iPlanet which does
+it differently from IIS. Check your web server documentation for
+the details for your particular server.
+
+=head2 How do I edit my .htpasswd and .htgroup files with Perl?
+
+The HTTPD::UserAdmin and HTTPD::GroupAdmin modules provide a
+consistent OO interface to these files, regardless of how they're
+stored. Databases may be text, dbm, Berkeley DB or any database with
+a DBI compatible driver. HTTPD::UserAdmin supports files used by the
+"Basic" and "Digest" authentication schemes. Here's an example:
+
+ use HTTPD::UserAdmin ();
+ HTTPD::UserAdmin
+ ->new(DB => "/foo/.htpasswd")
+ ->add($username => $password);
+
+=head2 How do I make sure users can't enter values into a form that cause my CGI script to do bad things?
+
+See the security references listed in the CGI Meta FAQ
+
+ http://www.perl.org/CGI_MetaFAQ.html
+
+=head2 How do I parse a mail header?
+
+For a quick-and-dirty solution, try this solution derived
+from L<perlfunc/split>:
+
+ $/ = '';
+ $header = <MSG>;
+ $header =~ s/\n\s+/ /g; # merge continuation lines
+ %head = ( UNIX_FROM_LINE, split /^([-\w]+):\s*/m, $header );
+
+That solution doesn't do well if, for example, you're trying to
+maintain all the Received lines. A more complete approach is to use
+the Mail::Header module from CPAN (part of the MailTools package).
+
+=head2 How do I decode a CGI form?
+
+(contributed by brian d foy)
+
+Use the CGI.pm module that comes with Perl. It's quick,
+it's easy, and it actually does quite a bit of work to
+ensure things happen correctly. It handles GET, POST, and
+HEAD requests, multipart forms, multivalued fields, query
+string and message body combinations, and many other things
+you probably don't want to think about.
+
+It doesn't get much easier: the CGI module automatically
+parses the input and makes each value available through the
+C<param()> function.
+
+ use CGI qw(:standard);
+
+ my $total = param( 'price' ) + param( 'shipping' );
+
+ my @items = param( 'item' ); # multiple values, same field name
+
+If you want an object-oriented approach, CGI.pm can do that too.
+
+ use CGI;
+
+ my $cgi = CGI->new();
+
+ my $total = $cgi->param( 'price' ) + $cgi->param( 'shipping' );
+
+ my @items = $cgi->param( 'item' );
+
+You might also try CGI::Minimal which is a lightweight version
+of the same thing. Other CGI::* modules on CPAN might work better
+for you, too.
+
+Many people try to write their own decoder (or copy one from
+another program) and then run into one of the many "gotchas"
+of the task. It's much easier and less hassle to use CGI.pm.
+
+=head2 How do I check a valid mail address?
+
+(partly contributed by Aaron Sherman)
+
+This isn't as simple a question as it sounds. There are two parts:
+
+a) How do I verify that an email address is correctly formatted?
+
+b) How do I verify that an email address targets a valid recipient?
+
+Without sending mail to the address and seeing whether there's a human
+on the other end to answer you, you cannot fully answer part I<b>, but
+either the C<Email::Valid> or the C<RFC::RFC822::Address> module will do
+both part I<a> and part I<b> as far as you can in real-time.
+
+If you want to just check part I<a> to see that the address is valid
+according to the mail header standard with a simple regular expression,
+you can have problems, because there are deliverable addresses that
+aren't RFC-2822 (the latest mail header standard) compliant, and
+addresses that aren't deliverable which, are compliant. However, the
+following will match valid RFC-2822 addresses that do not have comments,
+folding whitespace, or any other obsolete or non-essential elements.
+This I<just> matches the address itself:
+
+ my $atom = qr{[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+};
+ my $dot_atom = qr{$atom(?:\.$atom)*};
+ my $quoted = qr{"(?:\\[^\r\n]|[^\\"])*"};
+ my $local = qr{(?:$dot_atom|$quoted)};
+ my $quotedpair = qr{\\[\x00-\x09\x0B-\x0c\x0e-\x7e]};
+ my $domain_lit = qr{\[(?:$quotedpair|[\x21-\x5a\x5e-\x7e])*\]};
+ my $domain = qr{(?:$dot_atom|$domain_lit)};
+ my $addr_spec = qr{$local\@$domain};
+
+Just match an address against C</^${addr_spec}$/> to see if it follows
+the RFC2822 specification. However, because it is impossible to be
+sure that such a correctly formed address is actually the correct way
+to reach a particular person or even has a mailbox associated with it,
+you must be very careful about how you use this.
+
+Our best advice for verifying a person's mail address is to have them
+enter their address twice, just as you normally do to change a
+password. This usually weeds out typos. If both versions match, send
+mail to that address with a personal message. If you get the message
+back and they've followed your directions, you can be reasonably
+assured that it's real.
+
+A related strategy that's less open to forgery is to give them a PIN
+(personal ID number). Record the address and PIN (best that it be a
+random one) for later processing. In the mail you send, ask them to
+include the PIN in their reply. But if it bounces, or the message is
+included via a "vacation" script, it'll be there anyway. So it's
+best to ask them to mail back a slight alteration of the PIN, such as
+with the characters reversed, one added or subtracted to each digit, etc.
+
+=head2 How do I decode a MIME/BASE64 string?
+
+The MIME-Base64 package (available from CPAN) handles this as well as
+the MIME/QP encoding. Decoding BASE64 becomes as simple as:
+
+ use MIME::Base64;
+ $decoded = decode_base64($encoded);
+
+The MIME-Tools package (available from CPAN) supports extraction with
+decoding of BASE64 encoded attachments and content directly from email
+messages.
+
+If the string to decode is short (less than 84 bytes long)
+a more direct approach is to use the unpack() function's "u"
+format after minor transliterations:
+
+ tr#A-Za-z0-9+/##cd; # remove non-base64 chars
+ tr#A-Za-z0-9+/# -_#; # convert to uuencoded format
+ $len = pack("c", 32 + 0.75*length); # compute length byte
+ print unpack("u", $len . $_); # uudecode and print
+
+=head2 How do I return the user's mail address?
+
+On systems that support getpwuid, the $< variable, and the
+Sys::Hostname module (which is part of the standard perl distribution),
+you can probably try using something like this:
+
+ use Sys::Hostname;
+ $address = sprintf('%s@%s', scalar getpwuid($<), hostname);
+
+Company policies on mail address can mean that this generates addresses
+that the company's mail system will not accept, so you should ask for
+users' mail addresses when this matters. Furthermore, not all systems
+on which Perl runs are so forthcoming with this information as is Unix.
+
+The Mail::Util module from CPAN (part of the MailTools package) provides a
+mailaddress() function that tries to guess the mail address of the user.
+It makes a more intelligent guess than the code above, using information
+given when the module was installed, but it could still be incorrect.
+Again, the best way is often just to ask the user.
+
+=head2 How do I send mail?
+
+Use the C<sendmail> program directly:
+
+ open(SENDMAIL, "|/usr/lib/sendmail -oi -t -odq")
+ or die "Can't fork for sendmail: $!\n";
+ print SENDMAIL <<"EOF";
+ From: User Originating Mail <me\@host>
+ To: Final Destination <you\@otherhost>
+ Subject: A relevant subject line
+
+ Body of the message goes here after the blank line
+ in as many lines as you like.
+ EOF
+ close(SENDMAIL) or warn "sendmail didn't close nicely";
+
+The B<-oi> option prevents sendmail from interpreting a line consisting
+of a single dot as "end of message". The B<-t> option says to use the
+headers to decide who to send the message to, and B<-odq> says to put
+the message into the queue. This last option means your message won't
+be immediately delivered, so leave it out if you want immediate
+delivery.
+
+Alternate, less convenient approaches include calling mail (sometimes
+called mailx) directly or simply opening up port 25 have having an
+intimate conversation between just you and the remote SMTP daemon,
+probably sendmail.
+
+Or you might be able use the CPAN module Mail::Mailer:
+
+ use Mail::Mailer;
+
+ $mailer = Mail::Mailer->new();
+ $mailer->open({ From => $from_address,
+ To => $to_address,
+ Subject => $subject,
+ })
+ or die "Can't open: $!\n";
+ print $mailer $body;
+ $mailer->close();
+
+The Mail::Internet module uses Net::SMTP which is less Unix-centric than
+Mail::Mailer, but less reliable. Avoid raw SMTP commands. There
+are many reasons to use a mail transport agent like sendmail. These
+include queuing, MX records, and security.
+
+=head2 How do I use MIME to make an attachment to a mail message?
+
+This answer is extracted directly from the MIME::Lite documentation.
+Create a multipart message (i.e., one with attachments).
+
+ use MIME::Lite;
+
+ ### Create a new multipart message:
+ $msg = MIME::Lite->new(
+ From =>'me@myhost.com',
+ To =>'you@yourhost.com',
+ Cc =>'some@other.com, some@more.com',
+ Subject =>'A message with 2 parts...',
+ Type =>'multipart/mixed'
+ );
+
+ ### Add parts (each "attach" has same arguments as "new"):
+ $msg->attach(Type =>'TEXT',
+ Data =>"Here's the GIF file you wanted"
+ );
+ $msg->attach(Type =>'image/gif',
+ Path =>'aaa000123.gif',
+ Filename =>'logo.gif'
+ );
+
+ $text = $msg->as_string;
+
+MIME::Lite also includes a method for sending these things.
+
+ $msg->send;
+
+This defaults to using L<sendmail> but can be customized to use
+SMTP via L<Net::SMTP>.
+
+=head2 How do I read mail?
+
+While you could use the Mail::Folder module from CPAN (part of the
+MailFolder package) or the Mail::Internet module from CPAN (part
+of the MailTools package), often a module is overkill. Here's a
+mail sorter.
+
+ #!/usr/bin/perl
+
+ my(@msgs, @sub);
+ my $msgno = -1;
+ $/ = ''; # paragraph reads
+ while (<>) {
+ if (/^From /m) {
+ /^Subject:\s*(?:Re:\s*)*(.*)/mi;
+ $sub[++$msgno] = lc($1) || '';
+ }
+ $msgs[$msgno] .= $_;
+ }
+ for my $i (sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msgs)) {
+ print $msgs[$i];
+ }
+
+Or more succinctly,
+
+ #!/usr/bin/perl -n00
+ # bysub2 - awkish sort-by-subject
+ BEGIN { $msgno = -1 }
+ $sub[++$msgno] = (/^Subject:\s*(?:Re:\s*)*(.*)/mi)[0] if /^From/m;
+ $msg[$msgno] .= $_;
+ END { print @msg[ sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msg) ] }
+
+=head2 How do I find out my hostname, domainname, or IP address?
+X<hostname, domainname, IP address, host, domain, hostfqdn, inet_ntoa,
+gethostbyname, Socket, Net::Domain, Sys::Hostname>
+
+(contributed by brian d foy)
+
+The Net::Domain module, which is part of the standard distribution starting
+in perl5.7.3, can get you the fully qualified domain name (FQDN), the host
+name, or the domain name.
+
+ use Net::Domain qw(hostname hostfqdn hostdomain);
+
+ my $host = hostfqdn();
+
+The C<Sys::Hostname> module, included in the standard distribution since
+perl5.6, can also get the hostname.
+
+ use Sys::Hostname;
+
+ $host = hostname();
+
+To get the IP address, you can use the C<gethostbyname> built-in function
+to turn the name into a number. To turn that number into the dotted octet
+form (a.b.c.d) that most people expect, use the C<inet_ntoa> function
+from the <Socket> module, which also comes with perl.
+
+ use Socket;
+
+ my $address = inet_ntoa(
+ scalar gethostbyname( $host || 'localhost' )
+ );
+
+=head2 How do I fetch a news article or the active newsgroups?
+
+Use the Net::NNTP or News::NNTPClient modules, both available from CPAN.
+This can make tasks like fetching the newsgroup list as simple as
+
+ perl -MNews::NNTPClient
+ -e 'print News::NNTPClient->new->list("newsgroups")'
+
+=head2 How do I fetch/put an FTP file?
+
+LWP::Simple (available from CPAN) can fetch but not put. Net::FTP (also
+available from CPAN) is more complex but can put as well as fetch.
+
+=head2 How can I do RPC in Perl?
+
+(Contributed by brian d foy)
+
+Use one of the RPC modules you can find on CPAN (
+http://search.cpan.org/search?query=RPC&mode=all ).
+
+=head1 REVISION
+
+Revision: $Revision$
+
+Date: $Date$
+
+See L<perlfaq> for source control details and availability.
+
+=head1 AUTHOR AND COPYRIGHT
+
+Copyright (c) 1997-2009 Tom Christiansen, Nathan Torkington, and
+other authors as noted. All rights reserved.
+
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+Irrespective of its distribution, all code examples in this file
+are hereby placed into the public domain. You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit. A simple comment in the code giving
+credit would be courteous but is not required.