document [PATCH] lib/feature.pm
[p5sagit/p5-mst-13.2.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.11";
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 => 1,
31   ftp_int_passive => 1,
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
89 sub requires_firewall {
90   shift;    # ignore package
91   my $host = shift;
92
93   return 0 unless defined $NetConfig{'ftp_firewall'};
94
95   $host = inet_aton($host) or return -1;
96   $host = inet_ntoa($host);
97
98   if (exists $NetConfig{'local_netmask'}) {
99     my $quad = unpack("N", pack("C*", split(/\./, $host)));
100     my $list = $NetConfig{'local_netmask'};
101     $list = [$list] unless ref($list);
102     foreach (@$list) {
103       my ($net, $bits) = (m#^(\d+\.\d+\.\d+\.\d+)/(\d+)$#) or next;
104       my $mask = ~0 << (32 - $bits);
105       my $addr = unpack("N", pack("C*", split(/\./, $net)));
106
107       return 0 if (($addr & $mask) == ($quad & $mask));
108     }
109     return 1;
110   }
111
112   return 0;
113 }
114
115 use vars qw(*is_external);
116 *is_external = \&requires_firewall;
117
118 1;
119
120 __END__
121
122 =head1 NAME
123
124 Net::Config - Local configuration data for libnet
125
126 =head1 SYNOPSYS
127
128     use Net::Config qw(%NetConfig);
129
130 =head1 DESCRIPTION
131
132 C<Net::Config> holds configuration data for the modules in the libnet
133 distribution. During installation you will be asked for these values.
134
135 The configuration data is held globally in a file in the perl installation
136 tree, but a user may override any of these values by providing their own. This
137 can be done by having a C<.libnetrc> file in their home directory. This file
138 should return a reference to a HASH containing the keys described below.
139 For example
140
141     # .libnetrc
142     {
143         nntp_hosts => [ "my_preferred_host" ],
144         ph_hosts   => [ "my_ph_server" ],
145     }
146     __END__
147
148 =head1 METHODS
149
150 C<Net::Config> defines the following methods. They are methods as they are
151 invoked as class methods. This is because C<Net::Config> inherits from
152 C<Net::LocalCfg> so you can override these methods if you want.
153
154 =over 4
155
156 =item requires_firewall HOST
157
158 Attempts to determine if a given host is outside your firewall. Possible
159 return values are.
160
161   -1  Cannot lookup hostname
162    0  Host is inside firewall (or there is no ftp_firewall entry)
163    1  Host is outside the firewall
164
165 This is done by using hostname lookup and the C<local_netmask> entry in
166 the configuration data.
167
168 =back
169
170 =head1 NetConfig VALUES
171
172 =over 4
173
174 =item nntp_hosts
175
176 =item snpp_hosts
177
178 =item pop3_hosts
179
180 =item smtp_hosts
181
182 =item ph_hosts
183
184 =item daytime_hosts
185
186 =item time_hosts
187
188 Each is a reference to an array of hostnames (in order of preference),
189 which should be used for the given protocol
190
191 =item inet_domain
192
193 Your internet domain name
194
195 =item ftp_firewall
196
197 If you have an FTP proxy firewall (B<NOT> an HTTP or SOCKS firewall)
198 then this value should be set to the firewall hostname. If your firewall
199 does not listen to port 21, then this value should be set to
200 C<"hostname:port"> (eg C<"hostname:99">)
201
202 =item ftp_firewall_type
203
204 There are many different ftp firewall products available. But unfortunately
205 there is no standard for how to traverse a firewall.  The list below shows the
206 sequence of commands that Net::FTP will use
207
208   user        Username for remote host
209   pass        Password for remote host
210   fwuser      Username for firewall
211   fwpass      Password for firewall
212   remote.host The hostname of the remote ftp server
213
214 =over 4
215
216 =item 0
217
218 There is no firewall
219
220 =item 1
221
222      USER user@remote.host
223      PASS pass
224
225 =item 2
226
227      USER fwuser
228      PASS fwpass
229      USER user@remote.host
230      PASS pass
231
232 =item 3
233
234      USER fwuser
235      PASS fwpass
236      SITE remote.site
237      USER user
238      PASS pass
239
240 =item 4
241
242      USER fwuser
243      PASS fwpass
244      OPEN remote.site
245      USER user
246      PASS pass
247
248 =item 5
249
250      USER user@fwuser@remote.site
251      PASS pass@fwpass
252
253 =item 6
254
255      USER fwuser@remote.site
256      PASS fwpass
257      USER user
258      PASS pass
259
260 =item 7
261
262      USER user@remote.host
263      PASS pass
264      AUTH fwuser
265      RESP fwpass
266
267 =back
268
269 =item ftp_ext_passive
270
271 =item ftp_int_passive
272
273 FTP servers can work in passive or active mode. Active mode is when
274 you want to transfer data you have to tell the server the address and
275 port to connect to.  Passive mode is when the server provide the
276 address and port and you establish the connection.
277  
278 With some firewalls active mode does not work as the server cannot
279 connect to your machine (because you are behind a firewall) and the firewall
280 does not re-write the command. In this case you should set C<ftp_ext_passive>
281 to a I<true> value.
282
283 Some servers are configured to only work in passive mode. If you have
284 one of these you can force C<Net::FTP> to always transfer in passive
285 mode; when not going via a firewall, by setting C<ftp_int_passive> to
286 a I<true> value.
287
288 =item local_netmask
289
290 A reference to a list of netmask strings in the form C<"134.99.4.0/24">.
291 These are used by the C<requires_firewall> function to determine if a given
292 host is inside or outside your firewall.
293
294 =back
295
296 The following entries are used during installation & testing on the
297 libnet package
298
299 =over 4
300
301 =item test_hosts
302
303 If true then C<make test> may attempt to connect to hosts given in the
304 configuration.
305
306 =item test_exists
307
308 If true then C<Configure> will check each hostname given that it exists
309
310 =back
311
312 =cut