home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixlib_1 / !UnixLib37_netlib_netlib_c_host < prev    next >
Encoding:
Text File  |  1996-07-28  |  5.0 KB  |  266 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source$
  4.  * $Date$
  5.  * $Revision$
  6.  * $State$
  7.  * $Author$
  8.  *
  9.  * $Log$
  10.  ***************************************************************************/
  11.  
  12. static const char rcs_id[] = "$Id$";
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include <arpa/inet.h>
  19. #include <netdb.h>
  20. #include <netinet/in.h>
  21. #include <sys/socket.h>
  22.  
  23. #include <socketlib.h>
  24.  
  25. /*
  26.  * File handle for the hosts file
  27.  */
  28. static FILE *hostfile = NULL;
  29.  
  30. /*
  31.  * Keep the file open between calls to these routines?
  32.  */
  33. static int keepopen = 0;
  34.  
  35. /*
  36.  * Local routines
  37.  */
  38. static int __sethostent (int allowrewind);
  39. static struct hostent *__gethostent (void);
  40.  
  41. /*
  42.  * Open and rewind the hosts file
  43.  */
  44. int
  45. sethostent (int stayopen)
  46. {
  47.   /* Record whether the file should be kept open */
  48.   keepopen = stayopen;
  49.  
  50.   return __sethostent (1);
  51. }
  52.  
  53. /*
  54.  * Do the real work of opening/rewinding the hosts file
  55.  */
  56. static int
  57. __sethostent (int allowrewind)
  58. {
  59.   /* Open or rewind the file as necessary */
  60.   if (hostfile)
  61.     {
  62.       if (allowrewind)
  63.     rewind (hostfile);
  64.     }
  65.   else
  66.     {
  67.       hostfile = fopen ("InetDBase:Hosts", "r");
  68.     }
  69.  
  70.   return (hostfile == NULL) ? -1 : 0;
  71. }
  72.  
  73. /*
  74.  * Fetch the next entry from the hosts file
  75.  */
  76. struct hostent *
  77. gethostent ()
  78. {
  79.   struct hostent *host;
  80.  
  81.   /* Open the file if necessary */
  82.   if (hostfile == NULL)
  83.     if (__sethostent (0) == -1)
  84.       return NULL;
  85.  
  86.   /* Do the actual read */
  87.   host = __gethostent ();
  88.  
  89.   /* Close the file unless the user has prohibited it */
  90.   if (!keepopen)
  91.     endhostent ();
  92.  
  93.   return host;
  94. }
  95.  
  96. /*
  97.  * Do the real work of getting an entry from the file
  98.  */
  99. struct hostent *
  100. __gethostent ()
  101. {
  102.   static struct hostent host =
  103.   {
  104.     NULL, NULL, AF_INET, sizeof (struct in_addr), NULL
  105.   };
  106.  
  107.   char **item;
  108.   char *line;
  109.   char *element;
  110.   int aliases;
  111.  
  112.   /* Free up any memory in use */
  113.   if (host.h_name)
  114.     {
  115.       for (item = host.h_aliases; *item; item++)
  116.     free (*item);
  117.       for (item = host.h_addr_list; *item; item++)
  118.     free (*item);
  119.       free (host.h_name);
  120.       free (host.h_aliases);
  121.       free (host.h_addr_list);
  122.  
  123.       host.h_name = NULL;
  124.     }
  125.  
  126.   /* Read a line from the file */
  127.   if ((line = __socketlib_readline (hostfile)) == NULL)
  128.     return NULL;
  129.  
  130.   /* Extract the address from the line */
  131.   host.h_addr_list = malloc (2 * sizeof (struct in_addr *));
  132.   host.h_addr_list[0] = malloc (sizeof (struct in_addr));
  133.   host.h_addr_list[1] = NULL;
  134.   element = strtok (line, " \t");
  135.   ((struct in_addr *) (host.h_addr_list[0]))->s_addr = inet_addr (element);
  136.  
  137.   /* Extract the offical hostname from the line */
  138.   element = strtok (NULL, " \t");
  139.   host.h_name = strdup (element);
  140.  
  141.   /* Initialialise the alias list */
  142.   host.h_aliases = malloc (sizeof (char *));
  143.   host.h_aliases[0] = NULL;
  144.   aliases = 1;
  145.  
  146.   /* Extract the aliases */
  147.   while ((element = strtok (NULL, " \t")) != NULL)
  148.     {
  149.       aliases += 1;
  150.       host.h_aliases = realloc (host.h_aliases, aliases * sizeof (char *));
  151.       host.h_aliases[aliases - 2] = strdup (element);
  152.       host.h_aliases[aliases - 1] = NULL;
  153.     }
  154.  
  155.   return &host;
  156. }
  157.  
  158. /*
  159.  * Close the hosts file
  160.  */
  161. int
  162. endhostent ()
  163. {
  164.   int status = 0;
  165.  
  166.   /* If its open, close it */
  167.   if (hostfile)
  168.     {
  169.       status = fclose (hostfile);
  170.       hostfile = 0;
  171.     }
  172.  
  173.   return status;
  174. }
  175.  
  176. /*
  177.  * Search the hosts file for a given host name
  178.  */
  179. struct hostent *
  180. gethostbyname (const char *name)
  181. {
  182.   struct hostent *host;
  183.   char **alias;
  184.  
  185.   /* Try the resolver first */
  186.   if ((host = _gethostbyname (name)) != NULL)
  187.     {
  188.       return host;
  189.     }
  190.  
  191.   /* Open/rewind the file */
  192.   if (__sethostent (1) == -1)
  193.     return NULL;
  194.  
  195.   /* Look through the file for a match */
  196.   while ((host = __gethostent ()) != NULL)
  197.     {
  198.       /* Does the offical name match? */
  199.       if (strcmp (host->h_name, name) == 0)
  200.     break;
  201.  
  202.       /* Do any of the aliases match? */
  203.       for (alias = host->h_aliases; *alias; alias++)
  204.     {
  205.       if (strcmp (*alias, name) == 0)
  206.         break;
  207.     }
  208.  
  209.       /* Did any of the aliases match? */
  210.       if (*alias)
  211.     break;
  212.     }
  213.  
  214.   /* Close the file unless the user has prohibited it */
  215.   if (!keepopen)
  216.     endhostent ();
  217.  
  218.   return host;
  219. }
  220.  
  221. /*
  222.  * Search the hosts file for a given address
  223.  */
  224. struct hostent *
  225. gethostbyaddr (const char *addr, int len, int type)
  226. {
  227.   struct hostent *host;
  228.   char **address;
  229.  
  230.   /* Try the resolver first */
  231.   if ((host = _gethostbyaddr (addr, len, type)) != NULL)
  232.     {
  233.       return host;
  234.     }
  235.  
  236.   /* Open/rewind the file */
  237.   if (__sethostent (1) == -1)
  238.     return NULL;
  239.  
  240.   /* Look through the file for a match */
  241.   while ((host = __gethostent ()) != NULL)
  242.     {
  243.  
  244.       /* If the type and length don't match, try the next one */
  245.       if ((host->h_length != len) || (host->h_addrtype != type))
  246.     continue;
  247.  
  248.       /* Do any of the addresses match? */
  249.       for (address = host->h_addr_list; *address; address++)
  250.     {
  251.       if (memcmp (*address, addr, len) == 0)
  252.         break;
  253.     }
  254.  
  255.       /* Did any of the aliases match? */
  256.       if (*address)
  257.     break;
  258.     }
  259.  
  260.   /* Close the file unless the user has prohibited it */
  261.   if (!keepopen)
  262.     endhostent ();
  263.  
  264.   return host;
  265. }
  266.