This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
A new hostent function?
- To: libc-hacker@cygnus.com (GNU C Library)
- Subject: A new hostent function?
- From: hjl@innovix.com (H.J. Lu)
- Date: Tue, 22 Sep 1998 16:42:23 -0700 (PDT)
Hi,
When I was working in knfsd, I found this function is very useful.
What do you think?
--
H.J. Lu (hjl@gnu.org)
----
#define TEST
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#define ALIGNMENT sizeof (char *)
static int
align (int len, int al)
{
int i;
i = len % al;
if (i)
len += al - i;
return len;
}
struct hostent *
duphostent (struct hostent *hp)
{
int len_ent = align (sizeof (*hp), ALIGNMENT);
int len_name = align (strlen (hp->h_name) + 1, ALIGNMENT);
int num_aliases = 1;
int len_aliases = sizeof (char *);
int num_addr_list = 1;
int len_addr_list = sizeof (char *);
int pos, i;
char **sp;
struct hostent *cp;
for (sp = hp->h_aliases; *sp; sp++)
{
num_aliases++;
len_aliases += align (strlen (*sp) + 1, ALIGNMENT)
+ sizeof (char *);
}
for (sp = hp->h_addr_list; *sp; sp++)
{
num_addr_list++;
len_addr_list += align (hp->h_length, ALIGNMENT)
+ sizeof (char *);
}
cp = (struct hostent *) malloc (len_ent + len_name + len_aliases
+ len_addr_list);
if (!cp)
return cp;
*cp = *hp;
pos = len_ent;
cp->h_name = (char *) &(((char *) cp) [pos]);
strcpy (cp->h_name, hp->h_name);
pos += len_name;
cp->h_aliases = (char **) &(((char *) cp) [pos]);
pos += num_aliases * sizeof (char *);
for (sp = hp->h_aliases, i = 0; i < num_aliases; i++, sp++)
if (*sp)
{
cp->h_aliases [i] = (char *) &(((char *) cp) [pos]);
strcpy (cp->h_aliases [i], *sp);
pos += align (strlen (*sp) + 1, ALIGNMENT);
}
else
cp->h_aliases [i] = *sp;
pos = len_ent + len_name + len_aliases;
cp->h_addr_list = (char **) &(((char *) cp) [pos]);
pos += num_addr_list * sizeof (char *);
for (sp = hp->h_addr_list, i = 0; i < num_addr_list; i++, sp++)
if (*sp)
{
cp->h_addr_list [i] = (char *) &(((char *) cp) [pos]);
memcpy (cp->h_addr_list [i], *sp, hp->h_length);
pos += align (hp->h_length, ALIGNMENT);
}
else
cp->h_addr_list [i] = *sp;
return cp;
}
#ifdef TEST
void
print_host (struct hostent *hp)
{
char **sp;
if (hp)
{
printf ("official hostname: %s\n", hp->h_name);
printf ("aliases:\n");
for (sp = hp->h_aliases; *sp; sp++)
printf (" %s\n", *sp);
printf ("IP addresses:\n");
for (sp = hp->h_addr_list; *sp; sp++)
printf (" %s\n", inet_ntoa (*(struct in_addr *) *sp));
}
else
printf ("Not host information\n");
}
int
main (int argc, char **argv)
{
struct hostent *hp = gethostbyname (argv [1]);
print_host (hp);
if (hp)
{
hp = duphostent (hp);
print_host (hp);
free (hp);
}
return 0;
}
#endif