geektron has asked for the wisdom of the Perl Monks concerning the following question:

i've been trying to use the built-in networking functions (specifically gethostbyname), but it seems the documentation (both perldoc -f AND the Camel) are wrong.

according to the Camel:

"In scalar context, gethostbyname returns only the host address.

I'm assuming this means: my $ip = gethostbyname foo.bar.net; would return an IP address. it returns the hostname.

and perldoc -f gethostbyname says that the get* functions return name:

" In scalar context, you get the name, unless the function was a lookup by name, in which case you get the other thing, whatever it is."

both documents lead me to believe that a scalar call to gethostbyname would return an IP address. but i only get the hostname.

I can use the long way ( $name, undef, undef, undef, @ips ) = gethostbyname foo.bar.net successfully.

so why doesn't the scalar call work?

Replies are listed 'Best First'.
Re: gethostbyname bug?
by chromatic (Archbishop) on Sep 09, 2000 at 04:49 UTC
    gethostbyname seems to return a packed ip address, in scalar context. You might use the Socket library to get the inet_ntoa function:
    use Socket; my $packed_ip = gethostbyname('slashdot.org'); my $ip = inet_ntoa($packed_ip); print "$ip\n";

    Update: The parenthesis don't matter in this case. I usually use them to avoid precedence misunderstandings, though.

      so do the parens make the difference? (silly question, but i've had issues w/ parens and precedence before).

      w/out divulging the actual hostnames, here's what i've gotten:

      my $ip = gethostbyname foo.bar.net; print $ip;

      gives me back 'foo.bar.net'

      UPDATE: now it's working. i don't get it. i've been agonizing over this for hours (and all my previous attempts have never worked.)

        You were probably doing something like this:
        my ($ip) = gethostbyname("slashdot.org");

        In that code, $ip is in a list, and the statement is in list context, so the statement is equivalent to:

        my ($ip, undef, undef, undef, undef) = gethostbyname("slashdot.org");

        which will put the name in returned from gethostbyname in $ip.

        Aside: This is the reason I rail against unnecessary parenthisation in perl programs---there can be nasty context bugs until you get used to it.

Re: gethostbyname bug?
by redmist (Deacon) on Sep 09, 2000 at 05:11 UTC
    This worked for me:
    use strict; my @returnVal = gethostbyname "www.perlmonks.org"; my @packedIP = $returnVal[4]; my ($a, $b, $c, $d); my @a = ($a, $b, $c, $d) = unpack('C4', $packedIP[0]); my $ip = "$a.$b.$c.$d"; print $ip; exit(0);


    Perhaps your problem was that you didn't grab the packed data from the second level array. (Caveat: I barely knew what I was doing in this situation.)

    redmist
    redmist.dyndns.org
    redmist@altavista.net
      You shouldn't need to do this. gethostbyname() should in fact return only the packed ip when referenced as a scalar
      my $packedIP = gethostbyname("www.perlmonks.org"); print join('.', unpack("C4", $packedIP)), "\n";
      This should work like a champ, although (myself and OzzyOzbourne were talking about this in the chatterbox), someone (tilly?) mentioned that in 5.6 the unpack isn't necessary. I can't confirm this though.
        This was my ending code on this. $input was a standard IP...
        @ip = split(/\./, $input); $newname=gethostbyaddr(pack("C4", @ip), AF_INET);
        -Ozzyosbourne
      no, that way worked for me, too. (but i had a join ',', unpack('C4', @packed_ip); instead of the temp variables.

      i wasn't getting the packed data at all, for some reason. the call to  gethostbyname was only returning the first value ( which is name, if all args are requested, but address if called in scalar context according to the docs.)

      and, as the update says, now it's working as expected. perl magic - ask someone why things don't work, and they start working! kinda like taking the car to the mechanic. . . :) UPDATE: typo - the join had a dot, not a comma.