Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37599782
en ru br
Репозитории ALT
S:2.2-alt7
5.1: 2.2-alt5
4.1: 2.2-alt4
4.0: 2.2-alt4
3.0: 2.2-alt2
www.altlinux.org/Changes

Группа :: Система/Настройка/Сеть
Пакет: hostinfo

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 


/*
Resolves IP addresses to hostnames and hostnames to IP addresses.

Copyright (C) 2000 MySQL AB
Copyright (C) 2002,2003 Dmitry V. Levin <ldv@altlinux.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#define RESOLVE_VERSION "2.2"

#include <stdio.h>
#include <errno.h>
#include <error.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <getopt.h>

static int silent;
static int status;

static struct option long_options[] = {
{"silent", no_argument, 0, 's'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}
};

static void
print_version (void)
{
printf ("%s version %s\n", program_invocation_short_name,
RESOLVE_VERSION);
}

static void __attribute__ ((__noreturn__)) usage (int rc)
{
printf ("Usage: %s [OPTION]... <hostname or IP address>...\n",
program_invocation_short_name);
puts ("Get hostname based on IP address or IP address based on hostname.\n");
puts ("\
-s, --silent Be more silent.\n\
-h, --help Displays this help and exits.\n\
-V, --version Displays version information and exits.\n");

exit (rc);
}

static void
print_hostbyaddr (const char *name, const char *addr, int len, int type)
{
struct hostent *hp;

if ((hp = gethostbyaddr (addr, len, type)))
{
char **aliases;

if (silent)
{
puts (hp->h_name);
return;
}

printf ("Host name%s of %s: %s",
*hp->h_aliases ? "s" : "", name, hp->h_name);
for (aliases = hp->h_aliases; *aliases; ++aliases)
printf (", %s", *aliases);
putchar ('\n');
} else
{
status = 2;
error (EXIT_SUCCESS, 0, "unable to resolve: %s: %s", name,
h_errno ? hstrerror (h_errno) : strerror (errno));
}
}

static void
resolve_addr4 (const char *name, struct in_addr *inp)
{
if (inp->s_addr == INADDR_ANY)
{
puts ("any");
return;
}

if (inp->s_addr == INADDR_LOOPBACK)
{
puts ("loopback");
return;
}

if (inp->s_addr == INADDR_BROADCAST)
{
puts ("broadcast");
return;
}

print_hostbyaddr (name, (const char *) inp, sizeof (*inp), AF_INET);
}

static void
resolve_addr6 (const char *name, struct in6_addr *inp)
{
if (IN6_IS_ADDR_UNSPECIFIED (inp->in6_u.u6_addr32))
{
puts ("any");
return;
}

if (IN6_IS_ADDR_LOOPBACK (inp->in6_u.u6_addr32))
{
puts ("loopback");
return;
}

print_hostbyaddr (name, (const char *) inp, sizeof (*inp), AF_INET6);
}

static const char *
my_inet_ntop (int af, const void *src)
{
static char dst[INET6_ADDRSTRLEN];

if (AF_INET6 == af)
{
struct in6_addr *in = (struct in6_addr *) src;

if (IN6_IS_ADDR_V4MAPPED (in->in6_u.u6_addr32))
{
af = AF_INET;
src = &in->in6_u.u6_addr32[3];
}
}

return inet_ntop (af, src, dst, sizeof (dst));
}

static void
resolve_name (const char *name)
{
struct hostent *hp = gethostbyname (name);

if (!hp)
{
status = 2;
error (EXIT_SUCCESS, 0, "unable to resolve: %s: %s", name,
h_errno ? hstrerror (h_errno) : strerror (errno));
return;
}

if (silent)
{
puts (my_inet_ntop (hp->h_addrtype, hp->h_addr_list[0]));
} else
{
char **p;

printf ("IP address%s of %s:",
hp->h_addr_list[0] && hp->h_addr_list[1] ? "es" : "",
name);
for (p = hp->h_addr_list; *p; ++p)
{
printf (" %s", my_inet_ntop (hp->h_addrtype, *p));
}
putchar ('\n');
}
}

typedef union
{
struct in_addr in4;
struct in6_addr in6;
} in_46_addr;

int
main (int ac, char **av)
{
int c;

while ((c = getopt_long (ac, av, "?shV", long_options, 0)) != EOF)
{
switch (c)
{
case 's':
silent = 1;
break;
case 'V':
print_version ();
exit (EXIT_SUCCESS);
case 'h':
usage (EXIT_SUCCESS);
default:
usage (EXIT_FAILURE);
}
}
ac -= optind;
av += optind;
if (ac <= 0)
usage (EXIT_FAILURE);

while (ac--)
{
const char *name = *(av++);
in_46_addr dst;

if (inet_pton (AF_INET, name, &dst) > 0)
resolve_addr4 (name, &dst.in4);
else if (inet_pton (AF_INET6, name, &dst) > 0)
resolve_addr6 (name, &dst.in6);
else
resolve_name (name);
}

return status;
}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin