1# $Id: hostname.pl,v 1.8 2002/07/04 13:18:02 jylefort Exp $
2
3use strict;
4use Irssi 20020121.2020 ();
5use vars qw($VERSION %IRSSI);
6$VERSION = "1.01";
7%IRSSI = (
8	  authors     => 'Jean-Yves Lefort',
9	  contact     => 'jylefort\@brutele.be, decadix on IRCNet',
10	  name        => 'hostname',
11	  description => 'Adds a /HOSTNAME command; it will list all IP addresses on all interfaces found on your machine, resolve them, and allow you to choose one easily',
12	  license     => 'BSD',
13	  url         => 'http://void.adminz.be/irssi.shtml',
14	  changed     => '$Date: 2002/07/04 13:18:02 $ ',
15);
16
17# description:
18#
19#	hostname.pl will add a /HOSTNAME command similar to the one that can
20#	be found in BitchX.
21#
22#	/HOSTNAME will list all IP addresses of your system, and resolve them.
23#	/HOSTNAME <index> will switch to the selected IP address.
24#
25#	The IP addresses are collected by running ifconfig and parsing
26#	the output. It has been tested on the following systems:
27#
28#		FreeBSD 4.4-RELEASE
29#		FreeBSD 4.5-RELEASE
30#		NetBSD 1.5.2
31#		Linux 2.4.16
32#		IRIX 6.5
33#		OSF/1 4.0
34#		SunOS 5.8
35#
36#	It will probably work on any recent version of the following systems:
37#
38#		FreeBSD
39#		NetBSD
40#		OpenBSD
41#		Linux
42#		IRIX
43#		OSF/1 / Tru64
44#		SunOS / Solaris
45#
46#	It may or may not work on other systems / versions, but it will not
47#	work on the following pieces of crap:
48#
49#		M$-DO$ all versions
50#		Windoze all versions
51#
52#	You'll also need to have the module Socket6.pm installed, the address
53#	resolution needs it; on FreeBSD it can be installed easily by typing
54#	cd /usr/ports/net/p5-Socket6 && make install
55#
56# /format's:
57#
58#	hostname
59#
60#		$0	index number
61#		$1	IP address
62#		$2	hostname
63#
64# new theme abstracts:
65#
66#	Insert the following in the abstracts section of your theme file:
67#
68#		index = "[$*]";
69#		ip = "%g$*%n";
70#		hostname = "{comment $*}";
71#
72# usage:
73#
74#	/HOSTNAME [<index>]
75#
76#	Without arguments, display the list of IP addresses and resolve them.
77#
78#	With a numerical argument, set the hostname setting to the IP
79#	address matching that index in the list.
80#
81# acknowledgements:
82#
83#	The following people have sent the ifconfig output of their system:
84#	darix, plett, zur
85#
86# changes:
87#
88#	2002-07-04	release 1.01
89#			* command_bind uses a reference instead of a string
90#
91#	2002-04-25	release 1.00
92#			* increased version number
93#
94#	2002-02-02	release 0.02
95#			* reads ifconfig output one line at a time
96#			* excluded too many IP addresses in result: fixed
97#			* much '2' today ;)
98#
99#	2002-02-01	initial release
100
101use Socket;
102use Socket6;
103
104my %addresses;
105
106sub hostname {
107  my ($args, $server, $item) = @_;
108
109  get_addresses();
110  if ($args) {
111    set_address($args);
112  } else {
113    print_addresses();
114  }
115}
116
117sub get_addresses {
118  Irssi::print("Resolving IP addresses...");
119  %addresses = ();
120  open(IFCONFIG, "-|", "ifconfig");
121  while (<IFCONFIG>) {
122    $addresses{$2} = resolve($2)
123      if (/(inet addr:|inet6 addr: |inet |inet6 )([0-9a-f.:]*)/
124	  && ! ($2 =~ /^(127\.0\.0\.1|::1|fe80:.*)$/));
125  }
126  close(IFCONFIG);
127}
128
129sub print_addresses {
130  my $i = 0;
131  Irssi::printformat(MSGLEVEL_CRAP, "hostname", ++$i, $_, $addresses{$_})
132      foreach (keys %addresses);
133}
134
135sub set_address {
136  my ($index, $i) = (shift, 0);
137  foreach (keys %addresses) {
138    if (++$i == $index) {
139      Irssi::print("Hostname set to $_");
140      Irssi::command("^SET HOSTNAME $_");
141      return;
142    }
143  }
144  Irssi::print("Hostname #$index not found", MSGLEVEL_CLIENTERROR);
145}
146
147sub resolve {
148  my $ip = shift;
149  my @res = getaddrinfo($ip, 0, AF_UNSPEC, SOCK_STREAM);
150  my ($name, $port) = getnameinfo($res[3]);
151  return $name;
152}
153
154Irssi::theme_register(['hostname',
155		       '{index $0} {ip $[20]1} {hostname $[39]2}']);
156
157Irssi::command_bind("hostname", \&hostname);
158