This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
File::CheckTree hates @'s
[perl5.git] / lib / Net / Config.pm
1 # Net::Config.pm
2 #
3 # Copyright (c) 2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the same terms as Perl itself.
6
7 package Net::Config;
8
9 require Exporter;
10 use vars qw(@ISA @EXPORT %NetConfig $VERSION $CONFIGURE $LIBNET_CFG);
11 use Socket qw(inet_aton inet_ntoa);
12 use strict;
13
14 @EXPORT  = qw(%NetConfig);
15 @ISA     = qw(Net::LocalCfg Exporter);
16 $VERSION = "1.10"; # $Id: //depot/libnet/Net/Config.pm#17 $
17
18 eval { local $SIG{__DIE__}; require Net::LocalCfg };
19
20 %NetConfig = (
21     nntp_hosts => [],
22     snpp_hosts => [],
23     pop3_hosts => [],
24     smtp_hosts => [],
25     ph_hosts => [],
26     daytime_hosts => [],
27     time_hosts => [],
28     inet_domain => undef,
29     ftp_firewall => undef,
30     ftp_ext_passive => 0,
31     ftp_int_passive => 0,
32     test_hosts => 1,
33     test_exist => 1,
34 );
35
36 #
37 # Try to get as much configuration info as possible from InternetConfig
38 #
39 $^O eq 'MacOS' and eval <<TRY_INTERNET_CONFIG;
40 use Mac::InternetConfig;
41
42 {
43 my %nc = (
44     nntp_hosts      => [ \$InternetConfig{ kICNNTPHost() } ],
45     pop3_hosts      => [ \$InternetConfig{ kICMailAccount() } =~ /\@(.*)/ ],
46     smtp_hosts      => [ \$InternetConfig{ kICSMTPHost() } ],
47     ftp_testhost    => \$InternetConfig{ kICFTPHost() } ? \$InternetConfig{ kICFTPHost()} : undef,
48     ph_hosts        => [ \$InternetConfig{ kICPhHost() }   ],
49     ftp_ext_passive => \$InternetConfig{"646F676F\xA5UsePassiveMode"} || 0,
50     ftp_int_passive => \$InternetConfig{"646F676F\xA5UsePassiveMode"} || 0,
51     socks_hosts     => 
52         \$InternetConfig{ kICUseSocks() }    ? [ \$InternetConfig{ kICSocksHost() }    ] : [],
53     ftp_firewall    => 
54         \$InternetConfig{ kICUseFTPProxy() } ? [ \$InternetConfig{ kICFTPProxyHost() } ] : [],
55 );
56 \@NetConfig{keys %nc} = values %nc;
57 }
58 TRY_INTERNET_CONFIG
59
60 my $file = __FILE__;
61 my $ref;
62 $file =~ s/Config.pm/libnet.cfg/;
63 if ( -f $file ) {
64     $ref = eval { local $SIG{__DIE__}; do $file };
65     if (ref($ref) eq 'HASH') {
66         %NetConfig = (%NetConfig, %{ $ref });
67         $LIBNET_CFG = $file;
68     }
69 }
70 if ($< == $> and !$CONFIGURE)  {
71     my $home = eval { local $SIG{__DIE__}; (getpwuid($>))[7] } || $ENV{HOME};
72     $home ||= $ENV{HOMEDRIVE} . ($ENV{HOMEPATH}||'') if defined $ENV{HOMEDRIVE};
73     if (defined $home) {
74         $file = $home . "/.libnetrc";
75         $ref = eval { local $SIG{__DIE__}; do $file } if -f $file;
76         %NetConfig = (%NetConfig, %{ $ref })
77             if ref($ref) eq 'HASH';     
78     }
79 }
80 my ($k,$v);
81 while(($k,$v) = each %NetConfig) {
82         $NetConfig{$k} = [ $v ]
83                 if($k =~ /_hosts$/ and $k ne "test_hosts" and defined($v) and !ref($v));
84 }
85
86 # Take a hostname and determine if it is inside the firewall
87
88 sub requires_firewall {
89     shift; # ignore package
90     my $host = shift;
91
92     return 0 unless defined $NetConfig{'ftp_firewall'};
93
94     $host = inet_aton($host) or return -1;
95     $host = inet_ntoa($host);
96
97     if(exists $NetConfig{'local_netmask'}) {
98         my $quad = unpack("N",pack("C*",split(/\./,$host)));
99         my $list = $NetConfig{'local_netmask'};
100         $list = [$list] unless ref($list);
101         foreach (@$list) {
102             my($net,$bits) = (m#^(\d+\.\d+\.\d+\.\d+)/(\d+)$#) or next;
103             my $mask = ~0 << (32 - $bits);
104             my $addr = unpack("N",pack("C*",split(/\./,$net)));
105
106             return 0 if (($addr & $mask) == ($quad & $mask));
107         }
108         return 1;
109     }
110
111     return 0;
112 }
113
114 use vars qw(*is_external);
115 *is_external = \&requires_firewall;
116
117 1;
118
119 __END__
120
121 =head1 NAME
122
123 Net::Config - Local configuration data for libnet
124
125 =head1 SYNOPSYS
126
127     use Net::Config qw(%NetConfig);
128
129 =head1 DESCRIPTION
130
131 C<Net::Config> holds configuration data for the modules in the libnet
132 distribuion. During installation you will be asked for these values.
133
134 The configuration data is held globally in a file in the perl installation
135 tree, but a user may override any of these values by providing their own. This
136 can be done by having a C<.libnetrc> file in their home directory. This file
137 should return a reference to a HASH containing the keys described below.
138 For example
139
140     # .libnetrc
141     {
142         nntp_hosts => [ "my_prefered_host" ],
143         ph_hosts   => [ "my_ph_server" ],
144     }
145     __END__
146
147 =head1 METHODS
148
149 C<Net::Config> defines the following methods. They are methods as they are
150 invoked as class methods. This is because C<Net::Config> inherits from
151 C<Net::LocalCfg> so you can override these methods if you want.
152
153 =over 4
154
155 =item requires_firewall HOST
156
157 Attempts to determine if a given host is outside your firewall. Possible
158 return values are.
159
160   -1  Cannot lookup hostname
161    0  Host is inside firewall (or there is no ftp_firewall entry)
162    1  Host is outside the firewall
163
164 This is done by using hostname lookup and the C<local_netmask> entry in
165 the configuration data.
166
167 =back
168
169 =head1 NetConfig VALUES
170
171 =over 4
172
173 =item nntp_hosts
174
175 =item snpp_hosts
176
177 =item pop3_hosts
178
179 =item smtp_hosts
180
181 =item ph_hosts
182
183 =item daytime_hosts
184
185 =item time_hosts
186
187 Each is a reference to an array of hostnames (in order of preference),
188 which should be used for the given protocol
189
190 =item inet_domain
191
192 Your internet domain name
193
194 =item ftp_firewall
195
196 If you have an FTP proxy firewall (B<NOT> an HTTP or SOCKS firewall)
197 then this value should be set to the firewall hostname. If your firewall
198 does not listen to port 21, then this value should be set to
199 C<"hostname:port"> (eg C<"hostname:99">)
200
201 =item ftp_firewall_type
202
203 There are many different ftp firewall products available. But unfortunately
204 there is no standard for how to traverse a firewall.  The list below shows the
205 sequence of commands that Net::FTP will use
206
207   user        Username for remote host
208   pass        Password for remote host
209   fwuser      Username for firewall
210   fwpass      Password for firewall
211   remote.host The hostname of the remote ftp server
212
213 =over 4
214
215 =item 0
216
217 There is no firewall
218
219 =item 1
220
221      USER user@remote.host
222      PASS pass
223
224 =item 2
225
226      USER fwuser
227      PASS fwpass
228      USER user@remote.host
229      PASS pass
230
231 =item 3
232
233      USER fwuser
234      PASS fwpass
235      SITE remote.site
236      USER user
237      PASS pass
238
239 =item 4
240
241      USER fwuser
242      PASS fwpass
243      OPEN remote.site
244      USER user
245      PASS pass
246
247 =item 5
248
249      USER user@fwuser@remote.site
250      PASS pass@fwpass
251
252 =item 6
253
254      USER fwuser@remote.site
255      PASS fwpass
256      USER user
257      PASS pass
258
259 =item 7
260
261      USER user@remote.host
262      PASS pass
263      AUTH fwuser
264      RESP fwpass
265
266 =back
267
268 =item ftp_ext_passive
269
270 =item ftp_int_pasive
271
272 FTP servers normally work on a non-passive mode. That is when you want to
273 transfer data you have to tell the server the address and port to
274 connect to.
275
276 With some firewalls this does not work as the server cannot
277 connect to your machine (because you are behind a firewall) and the firewall
278 does not re-write the command. In this case you should set C<ftp_ext_passive>
279 to a I<true> value.
280
281 Some servers are configured to only work in passive mode. If you have
282 one of these you can force C<Net::FTP> to always transfer in passive
283 mode; when not going via a firewall, by setting C<ftp_int_passive> to
284 a I<true> value.
285
286 =item local_netmask
287
288 A reference to a list of netmask strings in the form C<"134.99.4.0/24">.
289 These are used by the C<requires_firewall> function to determine if a given
290 host is inside or outside your firewall.
291
292 =back
293
294 The following entries are used during installation & testing on the
295 libnet package
296
297 =over 4
298
299 =item test_hosts
300
301 If true then C<make test> may attempt to connect to hosts given in the
302 configuration.
303
304 =item test_exists
305
306 If true then C<Configure> will check each hostname given that it exists
307
308 =back
309
310 =for html <hr>
311
312 I<$Id: //depot/libnet/Net/Config.pm#17 $>
313
314 =cut