Mercurial > repo
diff interps/clc-intercal/inst/lib/perl5/Language/INTERCAL/HostIP.pm @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interps/clc-intercal/inst/lib/perl5/Language/INTERCAL/HostIP.pm Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,101 @@ +package Language::INTERCAL::HostIP; + +# Finds information about local network interfaces; this has been inspired +# by Sys::HostIP, but completely rewritten. I did email the author of +# Sys::HostIP offering patches which would make it more general (general +# enough for what I need) and more portable, but I never received an +# answer so I have decided to write my own version. At the same time, +# some of the extra bits of Sys::HostIP which I don't need have not +# been duplicated. + +# This file is part of CLC-INTERCAL + +# Copyright (c) 2007-2008 Claudio Calvelli, all rights reserved. + +# CLC-INTERCAL is copyrighted software. However, permission to use, modify, +# and distribute it is granted provided that the conditions set out in the +# licence agreement are met. See files README and COPYING in the distribution. + +use strict; +use vars qw($VERSION $PERVERSION); +($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base INTERCAL/HostIP.pm 1.-94.-2") =~ /\s(\S+)$/; + +use Carp; +use Language::INTERCAL::Exporter '1.-94.-2'; +use vars qw(@EXPORT_OK); +@EXPORT_OK = qw(find_interfaces); + +sub find_interfaces { + @_ == 0 or croak "Usage: find_interfaces()"; + if ($^O =~ /MSWin32|cygwin/i) { + return _find_interfaces_windows(); + } else { + return _find_interfaces_unix(); + } +} + +sub _find_interfaces_unix { + my $ifconfig = undef; + # if the system has some form of ifconfig, assume we can use it... + for my $path (qw(/sbin /usr/sbin /etc /usr/etc), split(/:/, $ENV{PATH})) { + -f "$path/ifconfig" or next; + $ifconfig = "$path/ifconfig"; + last; + } + $ifconfig or return {}; # sorry, can't do it + # try $ifconfig -a first; if that fails, try $ifconfig + my $res = _parse_unix("$ifconfig -a"); + keys %$res and return $res; + _parse_unix($ifconfig); +} + +sub _parse_unix { + my ($ifconfig) = @_; + open(IFCONFIG, "$ifconfig 2>&1 |") or return {}; + my %res = (); + my $name = undef; + # this parses the output of both Linux' and *BSD's ifconfig + while (<IFCONFIG>) { + /^(\w+):?\s/ and $name = $1; + /\S/ or $name = undef; + defined $name or next; + /\binet(?:\s+addr)?\s*(?::\s*)?(\d+(?:\.\d+){3})\b/i + and $res{$name}{addr} = $1; + /\bb(?:road)?cast\s*(?::\s*)?(\d+(?:\.\d+){3})\b/i + and $res{$name}{bcast} = $1; + /\b(?:net)?mask\s*(?::\s*)?(\d+(?:\.\d+){3})\b/i # linux mask + and $res{$name}{mask} = $1; + /\b(?:net)?mask\s*(?::\s*)?0x([[:xdigit:]]{2}) # *bsd mask + ([[:xdigit:]]{2}) + ([[:xdigit:]]{2}) + ([[:xdigit:]]{2})\b/ix + and $res{$name}{mask} = join('.', map { hex } $1, $2, $3, $4); + # XXX IPv6 + } + close IFCONFIG; + \%res; +} + +sub _find_interfaces_windows { + # XXX tested on 98 and eXtra Perverse, but not on Vista + open(IPCONFIG, 'ipconfig |') or return {}; + my %res = (); + my $name = undef; + while (<IFCONFIG>) { + /^Windows .* IP Configuration/i and next; + /\S/ or next; + /^(?:Ethernet|Wireless)\s+adapter\s+(.*):/i and $name = $1; + /^(.*)\s+(?:Ethernet|Wireless)\s+adapter/i and $name = $1; + defined $name or next; + /\sIP\s+Address.*:\s+(\d+(?:\.\d+){3})/i + and $res{$name}{addr} = $1; + /\sMask.*:\s+(\d+(?:\.\d+){3})/i + and $res{$name}{mask} = $1; + /\sBroadcast.*:\s+(\d+(?:\.\d+){3})/i + and $res{$name}{bcast} = $1; + } + close IPCONFIG; + \%res; +} + +1;