home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / network / netlib_1 / NetLibSrc / c / host < prev    next >
Text File  |  1995-05-24  |  5KB  |  247 lines

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