UCD.pm: if at first you don't succeed, croak?
[p5sagit/p5-mst-13.2.git] / lib / Net / Config.pm
1
2 package Net::Config;
3 # $Id: //depot/libnet/Net/Config.pm#6 $
4
5 require Exporter;
6 use vars qw(@ISA @EXPORT %NetConfig $VERSION $CONFIGURE $LIBNET_CFG);
7 use Socket qw(inet_aton inet_ntoa);
8 use strict;
9
10 @EXPORT  = qw(%NetConfig);
11 @ISA     = qw(Net::LocalCfg Exporter);
12 $VERSION = "1.04";
13
14 eval { local $SIG{__DIE__}; require Net::LocalCfg };
15
16 %NetConfig = (
17     nntp_hosts => [],
18     snpp_hosts => [],
19     pop3_hosts => [],
20     smtp_hosts => [],
21     ph_hosts => [],
22     daytime_hosts => [],
23     time_hosts => [],
24     inet_domain => undef,
25     ftp_firewall => undef,
26     ftp_ext_passive => 0,
27     ftp_int_passive => 0,
28     test_hosts => 1,
29     test_exist => 1,
30 );
31
32 my $file = __FILE__;
33 my $ref;
34 $file =~ s/Config.pm/libnet.cfg/;
35 if ( -f $file ) {
36     $ref = eval { do $file };
37     if (ref($ref) eq 'HASH') {
38         %NetConfig = (%NetConfig, %{ $ref });
39         $LIBNET_CFG = $file;
40     }
41 }
42 if ($< == $> and !$CONFIGURE)  {
43     use File::Spec;
44     my $home = eval { (getpwuid($>))[7] } || $ENV{HOME} || $ENV{HOMEDRIVE} || $ENV{HOMEPATH} || File::Spec->curdir;
45     $file = File::Spec->catfile($home, ".libnetrc");
46     $ref = eval { do $file } if -f $file;
47     %NetConfig = (%NetConfig, %{ $ref })
48         if ref($ref) eq 'HASH'; 
49 }
50 my ($k,$v);
51 while(($k,$v) = each %NetConfig) {
52     $v = [ $v ]
53         if($k =~ /_hosts$/ && !ref($v));
54 }
55
56 # Take a hostname and determine if it is inside te firewall
57
58 sub requires_firewall {
59     shift; # ignore package
60     my $host = shift;
61
62     return 0 unless defined $NetConfig{'ftp_firewall'};
63
64     $host = inet_aton($host) or return -1;
65     $host = inet_ntoa($host);
66
67     if(exists $NetConfig{'local_netmask'}) {
68         my $quad = unpack("N",pack("C*",split(/\./,$host)));
69         my $list = $NetConfig{'local_netmask'};
70         $list = [$list] unless ref($list);
71         foreach (@$list) {
72             my($net,$bits) = (m#^(\d+\.\d+\.\d+\.\d+)/(\d+)$#) or next;
73             my $mask = ~0 << (32 - $bits);
74             my $addr = unpack("N",pack("C*",split(/\./,$net)));
75
76             return 0 if (($addr & $mask) == ($quad & $mask));
77         }
78         return 1;
79     }
80
81     return 0;
82 }
83
84 use vars qw(*is_external);
85 *is_external = \&requires_firewall;
86
87 1;
88
89 __END__
90
91 =head1 NAME
92
93 Net::Config - Local configuration data for libnet
94
95 =head1 SYNOPSYS
96
97     use Net::Config qw(%NetConfig);
98
99 =head1 DESCRIPTION
100
101 C<Net::Config> holds configuration data for the modules in the libnet
102 distribuion. During installation you will be asked for these values.
103
104 The configuration data is held globally in a file in the perl installation
105 tree, but a user may override any of these values by providing thier own. This
106 can be done by having a C<.libnetrc> file in thier home directory. This file
107 should return a reference to a HASH containing the keys described below.
108 For example
109
110     # .libnetrc
111     {
112         nntp_hosts => [ "my_prefered_host" ],
113         ph_hosts   => [ "my_ph_server" ],
114     }
115     __END__
116
117 =head1 METHODS
118
119 C<Net::Config> defines the following methods. They are methods as they are
120 invoked as class methods. This is because C<Net::Config> inherits from
121 C<Net::LocalCfg> so you can override these methods if you want.
122
123 =over 4
124
125 =item requires_firewall HOST
126
127 Attempts to determine if a given host is outside your firewall. Possible
128 return values are.
129
130   -1  Cannot lookup hostname
131    0  Host is inside firewall (or there is no ftp_firewall entry)
132    1  Host is outside the firewall
133
134 This is done by using hostname lookup and the C<local_netmask> entry in
135 the configuration data.
136
137 =back
138
139 =head1 NetConfig VALUES
140
141 =over 4
142
143 =item nntp_hosts
144
145 =item snpp_hosts
146
147 =item pop3_hosts
148
149 =item smtp_hosts
150
151 =item ph_hosts
152
153 =item daytime_hosts
154
155 =item time_hosts
156
157 Each is a reference to an array of hostnames (in order of preference),
158 which should be used for the given protocol
159
160 =item inet_domain
161
162 Your internet domain name
163
164 =item ftp_firewall
165
166 If you have an FTP proxy firewall (B<NOT> a HTTP or SOCKS firewall)
167 then this value should be set to the firewall hostname. If your firewall
168 does not listen to port 21, then this value should be set to
169 C<"hostname:port"> (eg C<"hostname:99">)
170
171 =item ftp_ext_passive
172
173 =item ftp_int_pasive
174
175 FTP servers normally work on a non-passive mode. That is when you want to
176 transfer data you have to tell the server the address and port to
177 connect to.
178
179 With some firewalls this does not work as te server cannot
180 connect to your machine (because you are beind a firewall) and the firewall
181 does not re-write te command. In this case you should set C<ftp_ext_passive>
182 to a I<true> value.
183
184 Some servers are configured to only work in passive mode. If you have
185 one of these you can force C<Net::FTP> to always transfer in passive
186 mode, when not going via a firewall, by cetting C<ftp_int_passive> to
187 a I<true> value.
188
189 =item local_netmask
190
191 A reference to a list of netmask strings in the form C<"134.99.4.0/24">.
192 These are used by the C<requires_firewall> function to determine if a given
193 host is inside or outside your firewall.
194
195 =back
196
197 The following entries are used during installation & testing on the
198 libnet package
199
200 =over 4
201
202 =item test_hosts
203
204 If true them C<make test> may attempt to connect to hosts given in the
205 configuration.
206
207 =item test_exists
208
209 If true the C<Configure> will check each hostname given that it exists
210
211 =back
212
213 =cut