summaryrefslogtreecommitdiff
path: root/contrib/make-ssh-known-hosts.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/make-ssh-known-hosts.pl')
-rw-r--r--contrib/make-ssh-known-hosts.pl737
1 files changed, 737 insertions, 0 deletions
diff --git a/contrib/make-ssh-known-hosts.pl b/contrib/make-ssh-known-hosts.pl
new file mode 100644
index 000000000..49c9f618e
--- /dev/null
+++ b/contrib/make-ssh-known-hosts.pl
@@ -0,0 +1,737 @@
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: /var/cvs/openssh/contrib/Attic/make-ssh-known-hosts.pl,v $
25# Author : $Author: damien $
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: 2000/03/15 01:13:03 $
32# Revision number : $Revision: 1.1 $
33# State : $State: Exp $
34# Version : 1.343
35# Edit time : 242 min
36#
37# Description : Make ssh-known-host file from dns data.
38#
39# $Log: make-ssh-known-hosts.pl,v $
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
88require 5.000;
89use Getopt::Long;
90use FileHandle;
91use POSIX;
92use Socket;
93use Fcntl;
94
95$version = ' $Id: make-ssh-known-hosts.pl,v 1.1 2000/03/15 01:13:03 damien Exp $ ';
96
97$command_line = "$0 ";
98foreach $a (@ARGV) {
99 $command_line .= $a . " ";
100}
101STDERR->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
129unlink($private_ssh_known_hosts);
130$sockaddr = 'S n a4 x8';
131($junk, $junk, $sshport) = getservbyname("ssh", "tcp");
132if (!defined($sshport)) {
133 $sshport = 22;
134}
135($tcpprotoname, $junk, $tcpproto) = getprotobyname('tcp');
136defined($tcpprotoname) || die "getprotobyname : $!";
137
138######################################################################
139# Parse options
140
141GetOptions("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
149if (defined($opt_initialdns)) { $defserver = $opt_initialdns; }
150
151if (defined($opt_server)) { $server = $opt_server; }
152
153if (defined($opt_subdomains)) { @subdomains = split(/,/, $opt_subdomains); }
154
155if (defined($opt_debug)) { $debug = $opt_debug; }
156
157if (defined($opt_timeout)) { $timeout = $opt_timeout; }
158
159if (defined($opt_pingtimeout)) { $ping_timeout = $opt_pingtimeout; }
160
161if (defined($opt_passwordtimeout)) {
162 $passwordtimeout = $opt_passwordtimeout;
163 $sshdisablepasswordoption = '';
164}
165
166if (defined($opt_trustdaemon)) { $trustdaemon = $opt_trustdaemon; }
167
168if (defined($opt_recursive)) { $recursive = $opt_recursive; }
169
170if (defined($opt_domainnamesplit)) { $domainnamesplit = $opt_domainnamesplit; }
171
172if (defined($opt_silent)) { $bell = ''; }
173
174if (defined($opt_nslookup)) { $nslookup = $opt_nslookup; }
175
176if (defined($opt_ssh)) { $ssh = $opt_ssh; } else {
177 $ssh = "$ssh $sshdisablepasswordoption";
178}
179
180if ($#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
200if (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
208if (!$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 = ();
237if (!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
258if (!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
271do {
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
455unlink($private_ssh_known_hosts);
456exit (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
462sub 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
547sub 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
633sub 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
652sub 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
696sub 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
707sub 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
731sub make_perl_happy {
732 if (0) {
733 print $opt_silent;
734 }
735}
736
7371;