Clarification: use encoding cannot be used to
[p5sagit/p5-mst-13.2.git] / pod / perlfaq9.pod
CommitLineData
68dc0745 1=head1 NAME
2
8305e449 3perlfaq9 - Networking ($Revision: 1.3 $, $Date: 2001/10/16 13:27:22 $)
68dc0745 4
5=head1 DESCRIPTION
6
7This section deals with questions related to networking, the internet,
8and a few on the web.
9
24f1ba9b 10=head2 What is the correct form of response from a CGI script?
68dc0745 11
24f1ba9b 12(Alan Flavell <flavell+www@a5.ph.gla.ac.uk> answers...)
13
14The Common Gateway Interface (CGI) specifies a software interface between
15a program ("CGI script") and a web server (HTTPD). It is not specific
16to Perl, and has its own FAQs and tutorials, and usenet group,
17comp.infosystems.www.authoring.cgi
18
19The original CGI specification is at: http://hoohoo.ncsa.uiuc.edu/cgi/
20
21Current best-practice RFC draft at: http://CGI-Spec.Golux.Com/
22
23Other relevant documentation listed in: http://www.perl.org/CGI_MetaFAQ.html
68dc0745 24
24f1ba9b 25These Perl FAQs very selectively cover some CGI issues. However, Perl
26programmers are strongly advised to use the CGI.pm module, to take care
27of the details for them.
68dc0745 28
24f1ba9b 29The similarity between CGI response headers (defined in the CGI
30specification) and HTTP response headers (defined in the HTTP
31specification, RFC2616) is intentional, but can sometimes be confusing.
68dc0745 32
24f1ba9b 33The CGI specification defines two kinds of script: the "Parsed Header"
34script, and the "Non Parsed Header" (NPH) script. Check your server
35documentation to see what it supports. "Parsed Header" scripts are
36simpler in various respects. The CGI specification allows any of the
37usual newline representations in the CGI response (it's the server's
38job to create an accurate HTTP response based on it). So "\n" written in
39text mode is technically correct, and recommended. NPH scripts are more
40tricky: they must put out a complete and accurate set of HTTP
41transaction response headers; the HTTP specification calls for records
42to be terminated with carriage-return and line-feed, i.e ASCII \015\012
43written in binary mode.
68dc0745 44
24f1ba9b 45Using CGI.pm gives excellent platform independence, including EBCDIC
46systems. CGI.pm selects an appropriate newline representation
47($CGI::CRLF) and sets binmode as appropriate.
c8db1d39 48
24f1ba9b 49=head2 My CGI script runs from the command line but not the browser. (500 Server Error)
c8db1d39 50
24f1ba9b 51If you can demonstrate that you've read the FAQs and that
52your problem isn't something simple that can be easily answered, you'll
53probably receive a courteous and useful reply to your question if you
54post it on comp.infosystems.www.authoring.cgi (if it's something to do
55with HTTP or the CGI protocols). Questions that appear to be Perl
56questions but are really CGI ones that are posted to comp.lang.perl.misc
57are not so well received.
c8db1d39 58
24f1ba9b 59The useful FAQs, related documents, and troubleshooting guides are
60listed in the CGI Meta FAQ:
61
62 http://www.perl.org/CGI_MetaFAQ.html
c8db1d39 63
c8db1d39 64
65=head2 How can I get better error messages from a CGI program?
66
67Use the CGI::Carp module. It replaces C<warn> and C<die>, plus the
68normal Carp modules C<carp>, C<croak>, and C<confess> functions with
69more verbose and safer versions. It still sends them to the normal
70server error log.
71
72 use CGI::Carp;
73 warn "This is a complaint";
74 die "But this one is serious";
75
76The following use of CGI::Carp also redirects errors to a file of your choice,
77placed in a BEGIN block to catch compile-time warnings as well:
78
79 BEGIN {
80 use CGI::Carp qw(carpout);
81 open(LOG, ">>/var/local/cgi-logs/mycgi-log")
82 or die "Unable to append to mycgi-log: $!\n";
83 carpout(*LOG);
84 }
85
86You can even arrange for fatal errors to go back to the client browser,
87which is nice for your own debugging, but might confuse the end user.
88
89 use CGI::Carp qw(fatalsToBrowser);
90 die "Bad error here";
91
92Even if the error happens before you get the HTTP header out, the module
93will try to take care of this to avoid the dreaded server 500 errors.
94Normal warnings still go out to the server error log (or wherever
95you've sent them with C<carpout>) with the application name and date
96stamp prepended.
97
68dc0745 98=head2 How do I remove HTML from a string?
99
f29c64d6 100The most correct way (albeit not the fastest) is to use HTML::Parser
bed171df 101from CPAN. Another mostly correct
7d7e76cf 102way is to use HTML::FormatText which not only removes HTML but also
103attempts to do a little simple formatting of the resulting plain text.
68dc0745 104
105Many folks attempt a simple-minded regular expression approach, like
c47ff5f1 106C<< s/<.*?>//g >>, but that fails in many cases because the tags
68dc0745 107may continue over line breaks, they may contain quoted angle-brackets,
a6dd486b 108or HTML comment may be present. Plus, folks forget to convert
109entities--like C<&lt;> for example.
68dc0745 110
111Here's one "simple-minded" approach, that works for most files:
112
113 #!/usr/bin/perl -p0777
114 s/<(?:[^>'"]*|(['"]).*?\1)*>//gs
115
116If you want a more complete solution, see the 3-stage striphtml
117program in
118http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/striphtml.gz
119.
120
c8db1d39 121Here are some tricky cases that you should think about when picking
122a solution:
123
124 <IMG SRC = "foo.gif" ALT = "A > B">
125
d92eb7b0 126 <IMG SRC = "foo.gif"
c8db1d39 127 ALT = "A > B">
128
129 <!-- <A comment> -->
130
131 <script>if (a<b && a>c)</script>
132
133 <# Just data #>
134
135 <![INCLUDE CDATA [ >>>>>>>>>>>> ]]>
136
137If HTML comments include other tags, those solutions would also break
138on text like this:
139
140 <!-- This section commented out.
141 <B>You can't see me!</B>
142 -->
143
68dc0745 144=head2 How do I extract URLs?
145
54310121 146A quick but imperfect approach is
68dc0745 147
148 #!/usr/bin/perl -n00
149 # qxurl - tchrist@perl.com
150 print "$2\n" while m{
151 < \s*
152 A \s+ HREF \s* = \s* (["']) (.*?) \1
153 \s* >
154 }gsix;
155
156This version does not adjust relative URLs, understand alternate
d92eb7b0 157bases, deal with HTML comments, deal with HREF and NAME attributes
158in the same tag, understand extra qualifiers like TARGET, or accept
159URLs themselves as arguments. It also runs about 100x faster than a
160more "complete" solution using the LWP suite of modules, such as the
161http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/xurl.gz program.
68dc0745 162
163=head2 How do I download a file from the user's machine? How do I open a file on another machine?
164
165In the context of an HTML form, you can use what's known as
166B<multipart/form-data> encoding. The CGI.pm module (available from
167CPAN) supports this in the start_multipart_form() method, which isn't
168the same as the startform() method.
169
170=head2 How do I make a pop-up menu in HTML?
171
c47ff5f1 172Use the B<< <SELECT> >> and B<< <OPTION> >> tags. The CGI.pm
68dc0745 173module (available from CPAN) supports this widget, as well as many
174others, including some that it cleverly synthesizes on its own.
175
176=head2 How do I fetch an HTML file?
177
46fc3d4c 178One approach, if you have the lynx text-based HTML browser installed
179on your system, is this:
68dc0745 180
181 $html_code = `lynx -source $url`;
182 $text_data = `lynx -dump $url`;
183
d92eb7b0 184The libwww-perl (LWP) modules from CPAN provide a more powerful way
185to do this. They don't require lynx, but like lynx, can still work
186through proxies:
46fc3d4c 187
c8db1d39 188 # simplest version
189 use LWP::Simple;
190 $content = get($URL);
191
192 # or print HTML from a URL
46fc3d4c 193 use LWP::Simple;
6cecdcac 194 getprint "http://www.linpro.no/lwp/";
46fc3d4c 195
c8db1d39 196 # or print ASCII from HTML from a URL
65acb1b1 197 # also need HTML-Tree package from CPAN
46fc3d4c 198 use LWP::Simple;
f29c64d6 199 use HTML::Parser;
46fc3d4c 200 use HTML::FormatText;
201 my ($html, $ascii);
202 $html = get("http://www.perl.com/");
203 defined $html
204 or die "Can't fetch HTML from http://www.perl.com/";
205 $ascii = HTML::FormatText->new->format(parse_html($html));
206 print $ascii;
207
c8db1d39 208=head2 How do I automate an HTML form submission?
209
210If you're submitting values using the GET method, create a URL and encode
211the form using the C<query_form> method:
212
213 use LWP::Simple;
214 use URI::URL;
215
216 my $url = url('http://www.perl.com/cgi-bin/cpan_mod');
217 $url->query_form(module => 'DB_File', readme => 1);
218 $content = get($url);
219
220If you're using the POST method, create your own user agent and encode
221the content appropriately.
222
223 use HTTP::Request::Common qw(POST);
224 use LWP::UserAgent;
225
226 $ua = LWP::UserAgent->new();
227 my $req = POST 'http://www.perl.com/cgi-bin/cpan_mod',
228 [ module => 'DB_File', readme => 1 ];
229 $content = $ua->request($req)->as_string;
230
231=head2 How do I decode or create those %-encodings on the web?
68dc0745 232
68dc0745 233
575cc754 234If you are writing a CGI script, you should be using the CGI.pm module
235that comes with perl, or some other equivalent module. The CGI module
236automatically decodes queries for you, and provides an escape()
237function to handle encoding.
68dc0745 238
575cc754 239
240The best source of detailed information on URI encoding is RFC 2396.
241Basically, the following substitutions do it:
242
243 s/([^\w()'*~!.-])/sprintf '%%%02x', $1/eg; # encode
244
245 s/%([A-Fa-f\d]{2})/chr hex $1/eg; # decode
246
247However, you should only apply them to individual URI components, not
248the entire URI, otherwise you'll lose information and generally mess
249things up. If that didn't explain it, don't worry. Just go read
250section 2 of the RFC, it's probably the best explanation there is.
251
252RFC 2396 also contains a lot of other useful information, including a
253regexp for breaking any arbitrary URI into components (Appendix B).
68dc0745 254
255=head2 How do I redirect to another page?
256
24f1ba9b 257Specify the complete URL of the destination (even if it is on the same
258server). This is one of the two different kinds of CGI "Location:"
259responses which are defined in the CGI specification for a Parsed Headers
260script. The other kind (an absolute URLpath) is resolved internally to
261the server without any HTTP redirection. The CGI specifications do not
262allow relative URLs in either case.
263
264Use of CGI.pm is strongly recommended. This example shows redirection
265with a complete URL. This redirection is handled by the web browser.
266
267 use CGI qw/:standard/;
268
269 my $url = 'http://www.perl.com/CPAN/';
270 print redirect($url);
68dc0745 271
68dc0745 272
24f1ba9b 273This example shows a redirection with an absolute URLpath. This
274redirection is handled by the local web server.
68dc0745 275
24f1ba9b 276 my $url = '/CPAN/index.html';
277 print redirect($url);
c8db1d39 278
d92eb7b0 279
24f1ba9b 280But if coded directly, it could be as follows (the final "\n" is
281shown separately, for clarity), using either a complete URL or
282an absolute URLpath.
d92eb7b0 283
24f1ba9b 284 print "Location: $url\n"; # CGI response header
285 print "\n"; # end of headers
d92eb7b0 286
c8db1d39 287
68dc0745 288=head2 How do I put a password on my web pages?
289
290That depends. You'll need to read the documentation for your web
291server, or perhaps check some of the other FAQs referenced above.
292
293=head2 How do I edit my .htpasswd and .htgroup files with Perl?
294
295The HTTPD::UserAdmin and HTTPD::GroupAdmin modules provide a
296consistent OO interface to these files, regardless of how they're
426affbf 297stored. Databases may be text, dbm, Berkeley DB or any database with
298a DBI compatible driver. HTTPD::UserAdmin supports files used by the
68dc0745 299`Basic' and `Digest' authentication schemes. Here's an example:
300
301 use HTTPD::UserAdmin ();
302 HTTPD::UserAdmin
303 ->new(DB => "/foo/.htpasswd")
304 ->add($username => $password);
305
46fc3d4c 306=head2 How do I make sure users can't enter values into a form that cause my CGI script to do bad things?
307
24f1ba9b 308See the security references listed in the CGI Meta FAQ
46fc3d4c 309
24f1ba9b 310 http://www.perl.org/CGI_MetaFAQ.html
46fc3d4c 311
5a964f20 312=head2 How do I parse a mail header?
68dc0745 313
314For a quick-and-dirty solution, try this solution derived
b73a15ae 315from L<perlfunc/split>:
68dc0745 316
317 $/ = '';
318 $header = <MSG>;
319 $header =~ s/\n\s+/ /g; # merge continuation lines
320 %head = ( UNIX_FROM_LINE, split /^([-\w]+):\s*/m, $header );
321
322That solution doesn't do well if, for example, you're trying to
323maintain all the Received lines. A more complete approach is to use
324the Mail::Header module from CPAN (part of the MailTools package).
325
326=head2 How do I decode a CGI form?
327
c8db1d39 328You use a standard module, probably CGI.pm. Under no circumstances
329should you attempt to do so by hand!
330
331You'll see a lot of CGI programs that blindly read from STDIN the number
332of bytes equal to CONTENT_LENGTH for POSTs, or grab QUERY_STRING for
333decoding GETs. These programs are very poorly written. They only work
334sometimes. They typically forget to check the return value of the read()
335system call, which is a cardinal sin. They don't handle HEAD requests.
336They don't handle multipart forms used for file uploads. They don't deal
337with GET/POST combinations where query fields are in more than one place.
338They don't deal with keywords in the query string.
339
340In short, they're bad hacks. Resist them at all costs. Please do not be
341tempted to reinvent the wheel. Instead, use the CGI.pm or CGI_Lite.pm
342(available from CPAN), or if you're trapped in the module-free land
343of perl1 .. perl4, you might look into cgi-lib.pl (available from
65acb1b1 344http://cgi-lib.stanford.edu/cgi-lib/ ).
c8db1d39 345
346Make sure you know whether to use a GET or a POST in your form.
347GETs should only be used for something that doesn't update the server.
348Otherwise you can get mangled databases and repeated feedback mail
349messages. The fancy word for this is ``idempotency''. This simply
350means that there should be no difference between making a GET request
351for a particular URL once or multiple times. This is because the
352HTTP protocol definition says that a GET request may be cached by the
353browser, or server, or an intervening proxy. POST requests cannot be
354cached, because each request is independent and matters. Typically,
355POST requests change or depend on state on the server (query or update
356a database, send mail, or purchase a computer).
68dc0745 357
5a964f20 358=head2 How do I check a valid mail address?
68dc0745 359
c8db1d39 360You can't, at least, not in real time. Bummer, eh?
68dc0745 361
c8db1d39 362Without sending mail to the address and seeing whether there's a human
363on the other hand to answer you, you cannot determine whether a mail
364address is valid. Even if you apply the mail header standard, you
365can have problems, because there are deliverable addresses that aren't
366RFC-822 (the mail header standard) compliant, and addresses that aren't
367deliverable which are compliant.
68dc0745 368
c8db1d39 369Many are tempted to try to eliminate many frequently-invalid
d92eb7b0 370mail addresses with a simple regex, such as
b8c8cfe2 371C</^[\w.-]+\@(?:[\w-]+\.)+\w+$/>. It's a very bad idea. However,
c8db1d39 372this also throws out many valid ones, and says nothing about
b8c8cfe2 373potential deliverability, so it is not suggested. Instead, see
374http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz,
68dc0745 375which actually checks against the full RFC spec (except for nested
5a964f20 376comments), looks for addresses you may not wish to accept mail to
68dc0745 377(say, Bill Clinton or your postmaster), and then makes sure that the
c8db1d39 378hostname given can be looked up in the DNS MX records. It's not fast,
379but it works for what it tries to do.
380
381Our best advice for verifying a person's mail address is to have them
382enter their address twice, just as you normally do to change a password.
383This usually weeds out typos. If both versions match, send
384mail to that address with a personal message that looks somewhat like:
385
386 Dear someuser@host.com,
387
388 Please confirm the mail address you gave us Wed May 6 09:38:41
389 MDT 1998 by replying to this message. Include the string
390 "Rumpelstiltskin" in that reply, but spelled in reverse; that is,
391 start with "Nik...". Once this is done, your confirmed address will
392 be entered into our records.
393
394If you get the message back and they've followed your directions,
395you can be reasonably assured that it's real.
68dc0745 396
c8db1d39 397A related strategy that's less open to forgery is to give them a PIN
398(personal ID number). Record the address and PIN (best that it be a
399random one) for later processing. In the mail you send, ask them to
400include the PIN in their reply. But if it bounces, or the message is
401included via a ``vacation'' script, it'll be there anyway. So it's
402best to ask them to mail back a slight alteration of the PIN, such as
403with the characters reversed, one added or subtracted to each digit, etc.
46fc3d4c 404
68dc0745 405=head2 How do I decode a MIME/BASE64 string?
406
6a0af2f1 407The MIME-Base64 package (available from CPAN) handles this as well as
408the MIME/QP encoding. Decoding BASE64 becomes as simple as:
68dc0745 409
6a0af2f1 410 use MIME::Base64;
68dc0745 411 $decoded = decode_base64($encoded);
412
26d9b02f 413The MIME-Tools package (available from CPAN) supports extraction with
6a0af2f1 414decoding of BASE64 encoded attachments and content directly from email
415messages.
416
417If the string to decode is short (less than 84 bytes long)
418a more direct approach is to use the unpack() function's "u"
68dc0745 419format after minor transliterations:
420
421 tr#A-Za-z0-9+/##cd; # remove non-base64 chars
422 tr#A-Za-z0-9+/# -_#; # convert to uuencoded format
423 $len = pack("c", 32 + 0.75*length); # compute length byte
424 print unpack("u", $len . $_); # uudecode and print
425
5a964f20 426=head2 How do I return the user's mail address?
68dc0745 427
a6dd486b 428On systems that support getpwuid, the $< variable, and the
68dc0745 429Sys::Hostname module (which is part of the standard perl distribution),
430you can probably try using something like this:
431
432 use Sys::Hostname;
231ab6d1 433 $address = sprintf('%s@%s', scalar getpwuid($<), hostname);
68dc0745 434
5a964f20 435Company policies on mail address can mean that this generates addresses
436that the company's mail system will not accept, so you should ask for
437users' mail addresses when this matters. Furthermore, not all systems
68dc0745 438on which Perl runs are so forthcoming with this information as is Unix.
439
440The Mail::Util module from CPAN (part of the MailTools package) provides a
441mailaddress() function that tries to guess the mail address of the user.
442It makes a more intelligent guess than the code above, using information
443given when the module was installed, but it could still be incorrect.
444Again, the best way is often just to ask the user.
445
c8db1d39 446=head2 How do I send mail?
68dc0745 447
c8db1d39 448Use the C<sendmail> program directly:
449
450 open(SENDMAIL, "|/usr/lib/sendmail -oi -t -odq")
451 or die "Can't fork for sendmail: $!\n";
452 print SENDMAIL <<"EOF";
453 From: User Originating Mail <me\@host>
454 To: Final Destination <you\@otherhost>
455 Subject: A relevant subject line
456
65acb1b1 457 Body of the message goes here after the blank line
458 in as many lines as you like.
c8db1d39 459 EOF
460 close(SENDMAIL) or warn "sendmail didn't close nicely";
461
462The B<-oi> option prevents sendmail from interpreting a line consisting
463of a single dot as "end of message". The B<-t> option says to use the
464headers to decide who to send the message to, and B<-odq> says to put
465the message into the queue. This last option means your message won't
466be immediately delivered, so leave it out if you want immediate
467delivery.
468
d92eb7b0 469Alternate, less convenient approaches include calling mail (sometimes
470called mailx) directly or simply opening up port 25 have having an
471intimate conversation between just you and the remote SMTP daemon,
472probably sendmail.
473
474Or you might be able use the CPAN module Mail::Mailer:
c8db1d39 475
476 use Mail::Mailer;
477
478 $mailer = Mail::Mailer->new();
479 $mailer->open({ From => $from_address,
480 To => $to_address,
481 Subject => $subject,
482 })
483 or die "Can't open: $!\n";
484 print $mailer $body;
485 $mailer->close();
486
487The Mail::Internet module uses Net::SMTP which is less Unix-centric than
488Mail::Mailer, but less reliable. Avoid raw SMTP commands. There
d92eb7b0 489are many reasons to use a mail transport agent like sendmail. These
8305e449 490include queuing, MX records, and security.
c8db1d39 491
575cc754 492=head2 How do I use MIME to make an attachment to a mail message?
493
494This answer is extracted directly from the MIME::Lite documentation.
495Create a multipart message (i.e., one with attachments).
496
497 use MIME::Lite;
498
499 ### Create a new multipart message:
500 $msg = MIME::Lite->new(
501 From =>'me@myhost.com',
502 To =>'you@yourhost.com',
503 Cc =>'some@other.com, some@more.com',
504 Subject =>'A message with 2 parts...',
505 Type =>'multipart/mixed'
506 );
507
508 ### Add parts (each "attach" has same arguments as "new"):
509 $msg->attach(Type =>'TEXT',
510 Data =>"Here's the GIF file you wanted"
511 );
512 $msg->attach(Type =>'image/gif',
513 Path =>'aaa000123.gif',
514 Filename =>'logo.gif'
515 );
516
517 $text = $msg->as_string;
518
519MIME::Lite also includes a method for sending these things.
520
521 $msg->send;
522
523This defaults to using L<sendmail(1)> but can be customized to use
524SMTP via L<Net::SMTP>.
525
c8db1d39 526=head2 How do I read mail?
527
d92eb7b0 528While you could use the Mail::Folder module from CPAN (part of the
529MailFolder package) or the Mail::Internet module from CPAN (also part
a6dd486b 530of the MailTools package), often a module is overkill. Here's a
d92eb7b0 531mail sorter.
532
533 #!/usr/bin/perl
c8db1d39 534 # bysub1 - simple sort by subject
535 my(@msgs, @sub);
536 my $msgno = -1;
537 $/ = ''; # paragraph reads
538 while (<>) {
539 if (/^From/m) {
540 /^Subject:\s*(?:Re:\s*)*(.*)/mi;
541 $sub[++$msgno] = lc($1) || '';
542 }
543 $msgs[$msgno] .= $_;
d92eb7b0 544 }
c8db1d39 545 for my $i (sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msgs)) {
546 print $msgs[$i];
547 }
548
d92eb7b0 549Or more succinctly,
c8db1d39 550
551 #!/usr/bin/perl -n00
552 # bysub2 - awkish sort-by-subject
553 BEGIN { $msgno = -1 }
554 $sub[++$msgno] = (/^Subject:\s*(?:Re:\s*)*(.*)/mi)[0] if /^From/m;
555 $msg[$msgno] .= $_;
556 END { print @msg[ sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msg) ] }
557
68dc0745 558=head2 How do I find out my hostname/domainname/IP address?
559
c8db1d39 560The normal way to find your own hostname is to call the C<`hostname`>
561program. While sometimes expedient, this has some problems, such as
562not knowing whether you've got the canonical name or not. It's one of
563those tradeoffs of convenience versus portability.
68dc0745 564
565The Sys::Hostname module (part of the standard perl distribution) will
566give you the hostname after which you can find out the IP address
567(assuming you have working DNS) with a gethostbyname() call.
568
569 use Socket;
570 use Sys::Hostname;
571 my $host = hostname();
65acb1b1 572 my $addr = inet_ntoa(scalar gethostbyname($host || 'localhost'));
68dc0745 573
574Probably the simplest way to learn your DNS domain name is to grok
575it out of /etc/resolv.conf, at least under Unix. Of course, this
576assumes several things about your resolv.conf configuration, including
577that it exists.
578
579(We still need a good DNS domain name-learning method for non-Unix
580systems.)
581
582=head2 How do I fetch a news article or the active newsgroups?
583
584Use the Net::NNTP or News::NNTPClient modules, both available from CPAN.
a6dd486b 585This can make tasks like fetching the newsgroup list as simple as
68dc0745 586
587 perl -MNews::NNTPClient
588 -e 'print News::NNTPClient->new->list("newsgroups")'
589
590=head2 How do I fetch/put an FTP file?
591
592LWP::Simple (available from CPAN) can fetch but not put. Net::FTP (also
593available from CPAN) is more complex but can put as well as fetch.
594
595=head2 How can I do RPC in Perl?
596
a6dd486b 597A DCE::RPC module is being developed (but is not yet available) and
68dc0745 598will be released as part of the DCE-Perl package (available from
65acb1b1 599CPAN). The rpcgen suite, available from CPAN/authors/id/JAKE/, is
600an RPC stub generator and includes an RPC::ONC module.
68dc0745 601
602=head1 AUTHOR AND COPYRIGHT
603
65acb1b1 604Copyright (c) 1997-1999 Tom Christiansen and Nathan Torkington.
5a964f20 605All rights reserved.
606
5a7beb56 607This documentation is free; you can redistribute it and/or modify it
608under the same terms as Perl itself.
5a964f20 609
610Irrespective of its distribution, all code examples in this file
611are hereby placed into the public domain. You are permitted and
612encouraged to use this code in your own programs for fun
613or for profit as you see fit. A simple comment in the code giving
614credit would be courteous but is not required.