This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

A new hostent function?


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]