1 # /DNS <nick>|<host>|<ip> ...
8 use vars qw($VERSION %IRSSI);
11 authors => 'Timo Sirainen',
13 description => '/DNS <nick>|<host>|<ip> ...',
14 license => 'Public Domain',
15 changed => 'Sun Mar 10 23:23 EET 2002'
18 my (%resolve_hosts, %resolve_nicks, %resolve_print); # resolve queues
19 my $userhosts; # number of USERHOSTs currently waiting for reply
20 my $lookup_waiting; # 1 if we're waiting a reply for host lookup
22 # for the current host lookup
23 my ($print_server, $print_host, $print_name, @print_ips);
24 my ($input_skip_next, $input_query);
29 my ($nicks, $server) = @_;
32 # get list of nicks/hosts we want to know
33 my $tag = !$server ? undef : $server->{tag};
36 foreach my $nick (split(" ", $nicks)) {
38 if ($nick =~ /[\.:]/) {
39 # it's an IP or hostname
40 $resolve_hosts{$nick} = $tag;
43 if (!$print_error && (!$server || !$server->{connected})) {
45 Irssi::print("Not connected to server");
47 $resolve_nicks{$nick} = 1;
48 $ask_nicks .= "$nick ";
53 if ($ask_nicks ne "") {
54 # send the USERHOST query
56 $server->redirect_event('userhost', 1, $ask_nicks, 0, 'redir dns failure', {
57 'event 302' => 'redir dns host',
58 '' => 'event empty' } );
59 $server->send_raw("USERHOST :$nicks");
62 # ask the IPs/hostnames immediately
63 host_lookup() if (!$lookup_waiting);
67 Irssi::print("Error getting hostname for nick");
68 %resolve_nicks = () if (--$userhosts == 0);
72 my ($server, $data) = @_;
73 $data =~ s/^[^ ]* :?//;
74 my @hosts = split(/ +/, $data);
76 # move resolve_nicks -> resolve_hosts
77 foreach my $host (@hosts) {
78 if ($host =~ /^([^=\*]*)\*?=.(.*)@(.*)/) {
83 $resolve_hosts{$host} = $resolve_nicks{$nick};
84 delete $resolve_nicks{$nick};
85 $resolve_print{$host} = "[$nick!$user"."@"."$host]";
89 if (--$userhosts == 0 && %resolve_nicks) {
90 # unknown nicks - they didn't contain . or : so it can't be
92 Irssi::print("Unknown nicks: ".join(' ', keys %resolve_nicks));
96 host_lookup() if (!$lookup_waiting);
100 return if (!%resolve_hosts);
102 my ($host) = keys %resolve_hosts;
103 $print_server = $resolve_hosts{$host};
106 $print_name = $resolve_print{$host};
109 delete $resolve_hosts{$host};
110 delete $resolve_print{$host};
112 $input_query = $host;
113 $input_skip_next = 0;
115 # pipe is used to get the reply from child
119 # non-blocking host lookups with fork()ing
121 if (!defined($pid)) {
124 Irssi::print("Can't fork() - aborting");
125 close($rh); close($wh);
131 # parent, wait for reply
133 Irssi::pidwait_add($pid);
134 $pipe_tag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, $rh);
140 # child, do the lookup
142 if ($host =~ /^[0-9\.]*$/) {
144 $name = gethostbyaddr(inet_aton($host), AF_INET);
147 my @addrs = gethostbyname($host);
149 @addrs = map { inet_ntoa($_) } @addrs[4 .. $#addrs];
150 $name = join (" ", @addrs);
154 $print_name = $input_query if !$print_name;
156 $text = "No information for $print_name";
158 $text = "$print_name: $name";
161 $text = $! if (!$text);
176 Irssi::input_remove($pipe_tag);
179 my $server = Irssi::server_find_tag($print_server);
181 $server->print('', $text);
190 Irssi::command_bind('dns', 'cmd_dns');
192 'redir dns failure' => \&sig_failure,
193 'redir dns host' => \&sig_userhost } );