]> andersk Git - openssh.git/blob - contrib/make-ssh-known-hosts.pl
- Created contrib/ subdirectory. Included helpers from Phil Hands'
[openssh.git] / contrib / make-ssh-known-hosts.pl
1 #!/usr/bin/perl -w
2 # -*- perl -*-
3 ######################################################################
4 # make-ssh-known-hosts.pl -- Make ssh-known-hosts file
5 # Copyright (c) 1995 Tero Kivinen
6 # All Rights Reserved.
7 #
8 # Make-ssh-known-hosts is distributed in the hope that it will be
9 # useful, but WITHOUT ANY WARRANTY.  No author or distributor accepts
10 # responsibility to anyone for the consequences of using it or for
11 # whether it serves any particular purpose or works at all, unless he
12 # says so in writing.  Refer to the GNU General Public License for full
13 # details.
14 #
15 # Everyone is granted permission to copy, modify and redistribute
16 # make-ssh-known-hosts, but only under the conditions described in
17 # the GNU General Public License.  A copy of this license is supposed to
18 # have been given to you along with make-ssh-known-hosts so you can
19 # know your rights and responsibilities.  It should be in a file named
20 # gnu-COPYING-GPL.  Among other things, the copyright notice and this notice
21 # must be preserved on all copies.
22 ######################################################################
23 #         Program: make-ssh-known-hosts.pl
24 #         $Source$
25 #         Author : $Author$
26 #
27 #         (C) Tero Kivinen 1995 <Tero.Kivinen@hut.fi>
28 #
29 #         Creation          : 19:52 Jun 27 1995 kivinen
30 #         Last Modification : 00:07 Jul  8 1998 kivinen
31 #         Last check in     : $Date$
32 #         Revision number   : $Revision$
33 #         State             : $State$
34 #         Version           : 1.343
35 #         Edit time         : 242 min
36 #
37 #         Description       : Make ssh-known-host file from dns data.
38 #
39 #         $Log$
40 #         Revision 1.1  2000/03/15 01:13:03  damien
41 #          - Created contrib/ subdirectory. Included helpers from Phil Hands'
42 #            Debian package, README file and chroot patch from Ricardo Cerqueira
43 #            <rmcc@clix.pt>
44 #          - Moved gnome-ssh-askpass.c to contrib directory and reomved config
45 #            option.
46 #          - Slight cleanup to doc files
47 #       
48 #         Revision 1.6  1998/07/08 00:44:23  kivinen
49 #               Fixed to understand bind 8 nslookup output.
50 #
51 # Revision 1.5  1998/04/30  01:53:33  kivinen
52 #       Moved kill before close and added sending SIGINT first and
53 #       then 1 second sleep before sending SIGKILL.
54 #
55 #         Revision 1.4  1998/04/17 00:39:19  kivinen
56 #               Changed to close ssh program filedescriptor before killing it.
57 #               Removed ^ from the password matching prompt.
58 #
59 #         Revision 1.3  1997/04/17 04:21:27  kivinen
60 #               Changed to use 3des by default.
61 #
62 #         Revision 1.2  1997/03/26 07:14:01  kivinen
63 #               Added EWOULDBLOCK.
64 #
65 #         Revision 1.1.1.1  1996/02/18 21:38:10  ylo
66 #               Imported ssh-1.2.13.
67 #
68 # Revision 1.4  1995/10/02  01:23:45  ylo
69 #       Ping packet size fixes from Kivinen.
70 #
71 # Revision 1.3  1995/08/29  22:37:39  ylo
72 #       Now uses GlobalKnownHostsFile and UserKnownHostsFile.
73 #
74 # Revision 1.2  1995/07/15  13:26:37  ylo
75 #       Changes from kivinen.
76 #
77 # Revision 1.1.1.1  1995/07/12  22:41:05  ylo
78 # Imported ssh-1.0.0.
79 #
80 #
81 #
82 # If you have any useful modifications or extensions please send them to
83 # Tero.Kivinen@hut.fi
84 #
85 ######################################################################
86 # initialization
87
88 require 5.000;
89 use Getopt::Long;
90 use FileHandle;
91 use POSIX;
92 use Socket;
93 use Fcntl;
94
95 $version = ' $Id$ ';
96
97 $command_line = "$0 ";
98 foreach $a (@ARGV) {
99     $command_line .= $a . " ";
100 }
101 STDERR->autoflush(1);
102
103 ######################################################################
104 # default values for options
105
106 $debug = 5;
107 $defserver = '';
108 $bell='\a';
109 $public_key = '/etc/ssh_host_key.pub';
110 $private_ssh_known_hosts = "/tmp/ssh_known_hosts$$";
111 $timeout = 60;
112 $ping_timeout = 3;
113 $passwordtimeout = undef;
114 $trustdaemon = 1;
115 $domainnamesplit = 0;
116 $recursive = 1;
117
118 ######################################################################
119 # Programs and their options
120
121 $nslookup = "nslookup";
122
123 $ssh="ssh -a -c 3des -x -o 'ConnectionAttempts 1' -o 'FallBackToRsh no' -o 'GlobalKnownHostsFile /dev/null' -o 'KeepAlive yes' -o 'StrictHostKeyChecking no' -o 'UserKnownHostsFile $private_ssh_known_hosts'";
124 $sshdisablepasswordoption="-o 'BatchMode yes' -o 'PasswordAuthentication no'";
125
126 ######################################################################
127 # Cleanup and initialization
128
129 unlink($private_ssh_known_hosts);
130 $sockaddr = 'S n a4 x8';
131 ($junk, $junk, $sshport) = getservbyname("ssh", "tcp");
132 if (!defined($sshport)) {
133     $sshport = 22;
134 }
135 ($tcpprotoname, $junk, $tcpproto) = getprotobyname('tcp');
136 defined($tcpprotoname) || die "getprotobyname : $!";
137
138 ######################################################################
139 # Parse options
140
141 GetOptions("initialdns=s", "server=s", "subdomains=s",
142            "debug=i", "timeout=i", "passwordtimeout=i",
143            "trustdaemon!", "domainnamesplit", "silent",
144            "nslookup=s", "pingtimeout=i", "recursive!",
145            "keyscan", 
146            "ssh=s")
147     || die "Getopt : $!";
148
149 if (defined($opt_initialdns)) { $defserver = $opt_initialdns; }
150
151 if (defined($opt_server)) { $server = $opt_server; }
152
153 if (defined($opt_subdomains)) { @subdomains = split(/,/, $opt_subdomains); }
154
155 if (defined($opt_debug)) { $debug = $opt_debug; }
156
157 if (defined($opt_timeout)) { $timeout = $opt_timeout; }
158
159 if (defined($opt_pingtimeout)) { $ping_timeout = $opt_pingtimeout; }
160
161 if (defined($opt_passwordtimeout)) {
162     $passwordtimeout = $opt_passwordtimeout;
163     $sshdisablepasswordoption = '';
164 }
165
166 if (defined($opt_trustdaemon)) { $trustdaemon = $opt_trustdaemon; }
167
168 if (defined($opt_recursive)) { $recursive = $opt_recursive; }
169
170 if (defined($opt_domainnamesplit)) { $domainnamesplit = $opt_domainnamesplit; }
171
172 if (defined($opt_silent)) { $bell = ''; }
173
174 if (defined($opt_nslookup)) { $nslookup = $opt_nslookup; }
175
176 if (defined($opt_ssh)) { $ssh = $opt_ssh; } else {
177     $ssh = "$ssh $sshdisablepasswordoption";
178 }
179
180 if ($#ARGV == 0) {
181     $domain = "\L$ARGV[0]\E";
182     $grep_yes = '.*';
183     $grep_no = '^$';
184 } elsif ($#ARGV == 1) {
185     $domain = "\L$ARGV[0]\E";
186     $grep_yes = $ARGV[1];
187     $grep_no = '^$';
188 } elsif ($#ARGV == 2) {
189     $domain = "\L$ARGV[0]\E";
190     $grep_yes = $ARGV[1];
191     $grep_no = $ARGV[2];
192 } else {
193     print(STDERR "$0 [--initialdns initial_dns_server] [--server dns_server] [--subdomains sub.sub.domain,sub.sub,sub,] [--debug debug_level] [--timeout ssh_exec_timeout_in_secs] [--pingtimeout ping_timeout_in_secs] [--passwordtimeout timeout_for_password_in_secs] [--notrustdaemon] [--norecursive] [--domainnamesplit] [--silent] [--keyscan] [--nslookup path_to_nslookup] [--ssh path_to_ssh] full.domain [ host_info_take_regexp [ host_info_remove_regex ]]\n");
194     exit(1);
195 }
196
197 ######################################################################
198 # Check that ssh program exists
199
200 if (system("$ssh > /dev/null 2>&1 ") != 256) {
201     print(STDERR "Error: Could not run ssh program ($ssh): $!\nError: Try giving the path to it with --ssh option\n");
202     exit(1);
203 }
204
205 ######################################################################
206 # Generate subdomains list
207
208 if (!$domainnamesplit) {
209     debug(6, "Auto splitting host entries");
210 } elsif (!defined(@subdomains)) {
211     debug(6, "Generating subdomain list");
212     
213     # split domain to pieces
214     @domain_pieces = split(/\./, $domain);
215     
216     # add empty domain part
217     push(@subdomains, '');
218     
219     # add rest parts, except the one before full domain name
220     $entry='';
221     for(; $#domain_pieces > 1; ) {
222         $entry .= "." . shift(@domain_pieces);
223         push(@subdomains, $entry);
224     }
225     
226     # add full domain name
227     push(@subdomains, ".$domain");
228     debug(5, "Subdomain list: " . join(',', @subdomains));
229 } else {
230     debug(5, "Using given subdomain list:" . join(',', @subdomains));
231 }
232
233 ######################################################################
234 # finding SOA entry for domain
235
236 @other_servers = ();
237 if (!defined($server)) {
238     debug(6, "Finding DNS database SOA entry");
239
240     ($server, @other_servers) = find_soa($domain, $defserver);
241     
242     if (!defined($server)) {
243         print(STDERR "Error: Could not find DNS SOA entry from default dns server\nError: Try giving the initial nameserver with --initialdns option\n");
244         exit(1);
245     } else {
246         debug(5, "DNS server found : $server");
247     }
248 } else {
249     debug(5, "Using given DNS server : $server");
250 }
251
252 ######################################################################
253 # Print header
254     
255 ($name, $junk, $junk, $junk, $junk, $junk, $gecos) = getpwuid($<);
256 $gecos =~ s/,.*$//g;
257
258 if (!defined($opt_keyscan)) {
259     print(STDOUT "# This file is generated with make-ssh-known-hosts.pl\n");
260     print(STDOUT "#$version\n");
261     print(STDOUT "# with command line :\n");
262     print(STDOUT "# $command_line\n");
263     print(STDOUT "#\n");
264     print(STDOUT "# The script was run by $gecos ($name) at " . localtime() . "\n");
265     print(STDOUT "# using perl ($^X) version $].\n");
266 }
267
268 ######################################################################
269 # Get DNS database list from server
270
271 do {    
272     $domains_done{$domain} = 1;
273     delete $domains_waiting{$domain};
274
275     $hostcnt = 0;
276     $cnamecnt = 0;
277     $lines = 0;
278     $soa = 0;
279     undef %host;
280     undef %cname;
281     undef %hostdata;
282     
283   dnsagain:
284     debug(1, "Getting DNS database for $domain from server $server");
285     open(DNS, "echo ls -d $domain | nslookup - $server 2>&1 |") ||
286         die "Error: Could not start nslookup to make dns list : $!\nError: Try giving --nslookup option and telling the path to nslookup program\n";
287     
288     while(<DNS>) {
289         $lines++;
290         chomp;
291         undef $hostname if/^\s*$/;
292         if (/^\s{0,1}([a-zA-Z0-9-]\S*)/) {
293             $hostname = "\L$1\E";
294         }
295         next unless defined $hostname;
296         if (/^.*\s(SOA)\s+(.*)\s*$/ || $hostname eq "SOA") {
297             undef $soa if(/^.*\s(SOA)\s+(.*)\s*$/);
298             $data = $_ if ($hostname eq "SOA");
299             $data = $2 unless $hostname eq "SOA";
300             $data =~ s/\s*;.*$//;
301             $data =~ s/^\s+//;
302             if( defined $soa ) {
303                 $soa .= " \L$data\E";
304             } else {
305                 $soa = "\L$data\E";
306             }
307             $hostname = "SOA";
308         } elsif (/^.*\s(A|CNAME|NS)\s+(.*)\s*$/) {
309             $host = $hostname;
310             $field = "\L$1\E";
311             $data = "\L$2\E";
312             debug(70, "Line = /$host/$field/$data/");
313             if ($host !~ /\.$/) {
314                 $host .= ".$domain";
315             } else {
316                 $host =~ s/\.$//g;
317             }
318             if ($field eq "a") {
319                 if ($host =~ /$domain$/) {
320                     if (defined($host{$host})) {
321                         $host{$host} .= ",$data";
322                     } else {
323                         $host{$host} = "$data";
324                         $hostcnt++;
325                     }
326                     debug(30, "$host A == $host{$host}");
327                 }
328             } elsif ($field eq "cname") {
329                 if ($data !~ /\.$/ && ! /^\s/ ) {
330                     $data .= ".$domain";
331                 } else {
332                     $data =~ s/\.$//g;
333                 }
334                 if ($host =~ /$domain$/) {
335                     if (defined($cname{$data})) {
336                         $cname{$data} .= ",$host";
337                     } else {
338                         $cname{$data} = "$host";
339                         $cnamecnt++;
340                     }
341                     debug(30, "$host CNAME $data");
342                     $junk = $data;
343                     $data = $host;
344                     $host = $junk;
345                 }
346             } elsif ($field eq "ns") {
347                 if (!defined($domains_done{$host})) {
348                     if (!defined($domains_waiting{$host})) {
349                         debug(10, "Adding subdomain $host to domains list, with NS $data");
350                         $domains_waiting{$host} = $data;
351                         push(@domains_waiting, $host);
352                     } else {
353                         debug(10, "Adding NS $data for domain $host");
354                         $domains_waiting{$host} .= ",$data";
355                     }
356                 }
357             }
358             if (!defined($hostdata{$host})) {
359                 $hostdata{$host} = "$host\n$field=$data\n";
360             } else {
361                 $hostdata{$host} .= "$field=$data\n";
362             }
363         }
364     }
365     close(DNS);
366     if ($hostcnt == 0 && $cnamecnt == 0) {
367         if ($#other_servers != -1) {
368             $server = shift(@other_servers);
369             goto dnsagain;
370         }
371     }
372     debug(1, "Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)");
373     if (!defined($opt_keyscan)) {
374         print(STDOUT "#\n");
375         print(STDOUT "# Domain = $domain, server = $server\n");
376         print(STDOUT "# Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)\n");
377         print(STDOUT "# SOA = $soa\n");
378         print(STDOUT "#\n");
379     }
380
381 ######################################################################
382 # Loop through hosts and try to connect to hosts
383
384     foreach $i (sort (keys %host)) {
385         debug(50, "Host = $i, Hostdata = $hostdata{$i}");
386         if ($hostdata{$i} =~ /$grep_yes/im &&
387             $hostdata{$i} !~ /$grep_no/im &&
388             $i !~ /^localhost\./ &&
389             $host{$i} !~ /^127.0.0.1$|^127.0.0.1,|,127.0.0.1$|,127.0.0.1,/) {
390             debug(2, "Trying host $i");
391             
392             @hostnames = ();
393             if (defined($cname{$i})) {
394                 expand($i, \@hostnames, \@subdomains);
395                 foreach $j (split(/,/, $cname{$i})) {
396                     expand($j, \@hostnames, \@subdomains);
397                 }
398             } else {
399                 expand($i, \@hostnames, \@subdomains);
400             }
401             foreach $j (split(/,/, $host{$i})) {
402                 push(@hostnames, $j);
403             }
404             $hostnames = join(',', (@hostnames));
405             
406             if (defined($opt_keyscan)) {
407                 printf(STDOUT "$host{$i}\t$hostnames\n");
408             } elsif (try_ping($i, $host{$i})) {
409                 $trusted = 1;
410                 $err = 'Timeout expired';
411                 $ssh_key = try_ssh("$i");
412                 if (!defined($ssh_key)) {
413                     $ssh_key = find_host_from_known_hosts($i);
414                     $trusted = 0;
415                 }
416                 if (defined($ssh_key)) {
417                     if ($trusted) {
418                         debug(2, "Ssh to $i succeded");
419                     } else {
420                         debug(2, "Ssh to $i failed, using local known_hosts entry");
421                     }
422                     debug(4, "adding entries : $hostnames");
423                     $ssh_key =~ s/root@//i;
424                     if (!$trusted && !$trustdaemon) {
425                         print(STDOUT "# $hostnames $ssh_key\n");
426                     } else {
427                         print(STDOUT "$hostnames $ssh_key\n");
428                     }
429                 } else {
430                     debug(2, "ssh failed : $err");
431                 }
432             } else {
433                 debug(2, "ping failed");
434             }
435         } else {
436             debug(10, "Skipped host $i");
437         }
438     }
439   again:
440     $domain = shift(@domains_waiting);
441     if (defined($domain)) {
442         $server = $domains_waiting{$domain};
443         @other_servers = split(',', $server);
444         $server = shift(@other_servers);
445         ($server, @other_servers) = find_soa($domain, $server);
446         if(!defined($server)) {
447             debug(1, "Skipping domain $domain because no DNS SOA entry found");
448             $domains_done{$domain} = 1;
449             delete $domains_waiting{$domain};
450             goto again;
451         }
452     }
453 } while ($recursive && defined($domain));
454
455 unlink($private_ssh_known_hosts);
456 exit (0);
457
458 ######################################################################
459 # try_ping -- try to ping to host and return 1 if success
460 # $success = try_ping($host, $list_ip_addrs);
461
462 sub try_ping {
463     my($host, $ipaddrs) = @_;
464     my(@ipaddrs, $ipaddr, $serv, $ip);
465     my($rin, $rout, $win, $wout, $nfound, $tmout, $buf, $len, $ret, $err);
466
467     $buf = '';
468     debug(51,"Trying to ping host $host");
469     @ipaddrs = split(/,/, $ipaddrs);
470
471     while ($ipaddr = shift(@ipaddrs)) {
472         
473         debug(55,"Trying ipaddr $ipaddr");
474         
475         #initialize socket
476         socket(PING, PF_INET, SOCK_STREAM, $tcpproto) ||
477             die "socket failed : $!";
478         setsockopt(PING, SOL_SOCKET, SO_REUSEADDR, 1) ||
479             die "setsockopt failed : $!";
480         PING->autoflush(1);
481         fcntl(PING, F_SETFL, fcntl(PING, F_GETFL, 0) | POSIX::O_NONBLOCK) ||
482             die "fcntl failed : $!";
483         
484         $ip = pack('C4', split(/\./, $ipaddr, 4));
485         $serv = pack($sockaddr, AF_INET, $sshport, $ip);
486         
487       again:
488         # try connect
489         $ret = connect(PING, $serv);
490         $err = $!;
491         if (!$ret) {
492             debug(60, "Connect failed : $err");
493             if ($err == EINTR) {
494                 goto again;
495             }
496             # socket not yet connected, wait for result, it will
497             # wake up for writing when done
498             $tmout = $ping_timeout;
499             
500             $rin = '';
501             $win = '';
502             vec($rin, fileno(PING), 1) = 1;
503             vec($win, fileno(PING), 1) = 1;
504             debug(60, "Waiting in select, rin = " . unpack('H*', $rin) .
505                   ", win = " . unpack('H*', $win));
506             ($nfound) = select($rout = $rin, $wout = $win, undef, $tmout);
507             $err = $!;
508             debug(80, "Select returned $nfound, rout = " . unpack('H*', $rout) .
509                   ", wout = " . unpack('H*', $wout));
510             if ($nfound != 0) {
511                 # connect done, read the status with sysread
512                 $ret = sysread(PING, $buf, 1);
513                 $err = $!;
514                 if (defined($ret) || $err == EAGAIN || $err == EWOULDBLOCK) {
515                     debug(60, "Select ok, read ok ($err), returning ok");
516                     # connection done, return ok
517                     shutdown(PING, 2);
518                     close(PING);
519                     return 1;
520                 } else {
521                     # connection failed, try next ipaddr
522                     debug(60, "Select ok, read failed : $err, trying next");
523                     close(PING);
524                 }
525             } else {
526                 # timeout exceeded, try next ipaddr
527                 debug(60, "Select failed : $err, trying next");
528                 close(PING);
529             }
530         } else {
531             # connect succeeded, return ok.
532             debug(60, "Connect ok, returning ok");
533             shutdown(PING, 2);
534             close(PING);
535             return 1;
536         }
537     }
538     debug(60, "Returning fail");
539     return 0;
540 }
541
542 ######################################################################
543 # try_ssh -- try ssh connection to host and return ssh_key if success
544 # if failure return undef, and set $err string to contain error message.
545 # $ssh_key = try_ssh($host);
546
547 sub try_ssh {
548     my($host) = @_;
549     my($buf, $ret, $pos, $pid, $rin, $nfound, $tmout);
550
551     $pid = open(SSH, "$ssh $host cat $public_key 2>&1 |");
552     $err = undef;
553
554     if ($pid == 0) {
555         $err = "could not open ssh connection to host";
556         return undef;
557     }
558     $ret = 1;
559     $pos = 0;
560     $buf = '';
561     $tmout = $timeout;
562     debug(10, "Starting ssh select loop");
563   loop:
564     while (1) {
565         
566         $rin = '';
567         vec($rin, fileno(SSH), 1) = 1;
568         ($nfound, $tmout) = select($rin, undef, undef, $tmout);
569         
570         # Timeout
571         if ($nfound <= 0) {
572             debug(20, "Ssh select timed out");
573             kill(2, $pid); sleep(1); kill(9, $pid);
574             close(SSH);
575             $err = "Timeout expired";
576             return undef;
577         }
578         
579         $ret = sysread(SSH, $buf, 256, $pos);
580         # EOF or error
581         if ($ret <= 0) {
582             # Yes, close the pipe and return
583             close(SSH);
584             debug(20, "Ssh select closed status = $?");
585             $err = "No reply from ssh";
586             return undef;
587         }
588         $pos += $ret;
589         while ($buf =~ /^(.*)\n\r?([\000-\377]*)$/) {
590             $_ = $1;
591             $buf = $2;
592             $pos = length($buf);
593             debug(20, "Ssh select loop, line = \"$_\"");
594             if (/^connection.*refused/i) {
595                 $err = "connection refused";
596             } elsif (/^permission/i) {
597                 $err = "permission denied";
598             } elsif (/$public_key.*no\s+file/i) {
599                 $err = "$public_key file not found";
600             } elsif (/$public_key.*permission\s+denied/i) {
601                 $err = "$public_key file permission denied";
602             } elsif (/^\d+\s+\d+\s+\d/) {
603                 kill(2, $pid); sleep(1); kill(9, $pid);
604                 close(SSH);
605                 return $_;
606             }
607             if (defined($err)) {
608                 kill(2, $pid); sleep(1); kill(9, $pid);
609                 close(SSH);
610                 return undef;
611             }
612         }
613         if ($buf =~ /password: $/i) {
614             if (defined($passwordtimeout)) {
615                 $tmout = $passwordtimeout;
616                 print(STDERR "$bell\n\rPassword: ");
617                 if ($tmout == 0) {
618                     $tmout = undef;
619                 }
620             } else {
621                 $tmout = 0;
622             }
623             $buf = '';
624             $pos = 0;
625         }
626     }
627 }
628
629 ######################################################################
630 # find_hosts_from_known_hosts -- find host key from private known_hosts file
631 # $ssh_key = find_host_from_known_hosts($host);
632
633 sub find_host_from_known_hosts {
634     my($host) = @_;
635     open(KNOWNHOSTS, "<$private_ssh_known_hosts") || return undef;
636     while(<KNOWNHOSTS>) {
637         @_ = split(/\s+/, $_);
638         if ($_[0] =~ /^$host$|^$host,|,$host$/) {
639             shift(@_);
640             close(KNOWNHOSTS);
641             return join(' ', @_);
642         }
643     }
644     close(KNOWNHOSTS);
645     return undef;
646 }
647
648 ######################################################################
649 # expand -- insert expanded hostnames to hostnames table
650 # expand($hostname, \@hostnames, \@subdomains);
651
652 sub expand {
653     my($host, $hostnames, $subdomains) = @_;
654     my($newhost, $sub, $entry);
655
656     if (!$domainnamesplit) {
657         my(@domain_pieces);
658         
659         # split domain to pieces
660         @domain_pieces = split(/\./, $host);
661     
662         # add rest parts, except the one before full domain name
663         $entry = shift(@domain_pieces);
664         
665         debug(20, "Adding autosplit entry $entry");
666         push(@$hostnames, $entry);
667         
668         for(; $#domain_pieces > 1; ) {
669             $entry .= "." . shift(@domain_pieces);
670             debug(20, "Adding autosplit entry $entry");
671             push(@$hostnames, $entry);
672         }
673         # add full domain name
674         debug(20, "Adding autosplit entry $host");
675         push(@$hostnames, $host);
676     } else {
677         if ($host =~ /^(.*)$domain$/i) {
678             $newhost = $1;
679             $newhost =~ s/\.$//g;
680             foreach $sub (@$subdomains) {
681                 $entry = $newhost . $sub;
682                 $entry =~ s/^\.//g;
683                 if ($entry ne '') {
684                     debug(20, "Adding entry $entry");
685                     push(@$hostnames, $entry);
686                 }
687             }
688         }
689     }
690 }
691
692 ######################################################################
693 # Print debug text
694 # debug(text_debug_level, string)
695
696 sub debug {
697     my($level, $str) = @_;
698     if ($debug > $level) {
699         print(STDERR "$0:debug[$level]: $str\n");
700     }
701 }
702
703 ######################################################################
704 # find_soa -- find soa entry for domain
705 # ($soa_origin, @other_servers) = find_soa($domain, $initial_server)
706
707 sub find_soa {
708     my($domain, $initial_server) = @_;
709     my($field, $data, $server, @other_servers);
710
711     open(DNS, "$nslookup -type=soa $domain $initial_server 2>&1 |") ||
712         die "Error: Could not start nslookup to find SOA entry for $domain : $!\nError: Try giving the path to it with --nslookup option\n";
713     
714     while (<DNS>) {
715         if (/^[^=]*origin\s*=\s*(.*)/) {
716             $server = $1;
717             debug(10, "Found origin : $1");
718         } elsif (/^[^=]*nameserver\s*=\s*(.*)\s*$/) {
719             push(@other_servers, $1);
720             debug(10, "Found nameserver : $1");
721         }
722     }
723     close(DNS);
724     return($server, @other_servers);
725 }
726
727 ######################################################################
728 # make_perl_happy -- use some symbols, so perl doesn't complain so much
729 # make_perl_happy();
730
731 sub make_perl_happy {
732     if (0) {
733         print $opt_silent;
734     }
735 }
736
737 1;
This page took 3.019433 seconds and 5 git commands to generate.