home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixlib_1 / !UnixLib37_netlib_netlib_c_serv < prev    next >
Encoding:
Text File  |  1996-07-28  |  4.6 KB  |  251 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 <netdb.h>
  19. #include <netinet/in.h>
  20. #include <sys/byteorder.h>
  21. #include <sys/socket.h>
  22.  
  23. #include <socketlib.h>
  24.  
  25. /*
  26.  * File handle for the services file
  27.  */
  28. static FILE *servfile = 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 __setservent (int allowrewind);
  39. static struct servent *__getservent (void);
  40.  
  41. /*
  42.  * Open and rewind the services file
  43.  */
  44. int
  45. setservent (int stayopen)
  46. {
  47.   /* Record whether the file should be kept open */
  48.   keepopen = stayopen;
  49.  
  50.   return __setservent (1);
  51. }
  52.  
  53. /*
  54.  * Do the real work of opening/rewinding the services file
  55.  */
  56. static int
  57. __setservent (int allowrewind)
  58. {
  59.   /* Open or rewind the file as necessary */
  60.   if (servfile)
  61.     {
  62.       if (allowrewind)
  63.     rewind (servfile);
  64.     }
  65.   else
  66.     {
  67.       servfile = fopen ("InetDBase:Services", "r");
  68.     }
  69.  
  70.   return (servfile == NULL) ? -1 : 0;
  71. }
  72.  
  73. /*
  74.  * Fetch the next entry from the services file
  75.  */
  76. struct servent *
  77. getservent ()
  78. {
  79.   struct servent *serv;
  80.  
  81.   /* Open the file if necessary */
  82.   if (servfile == NULL)
  83.     if (__setservent (0) == -1)
  84.       return NULL;
  85.  
  86.   /* Do the actual read */
  87.   serv = __getservent ();
  88.  
  89.   /* Close the file unless the user has prohibited it */
  90.   if (!keepopen)
  91.     endservent ();
  92.  
  93.   return serv;
  94. }
  95.  
  96. /*
  97.  * Do the real work of getting an entry from the file
  98.  */
  99. struct servent *
  100. __getservent ()
  101. {
  102.   static struct servent serv =
  103.   {
  104.     NULL, NULL, 0, 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 (serv.s_name)
  114.     {
  115.       for (item = serv.s_aliases; *item; item++)
  116.     free (*item);
  117.       free (serv.s_name);
  118.       free (serv.s_aliases);
  119.       free (serv.s_proto);
  120.  
  121.       serv.s_name = NULL;
  122.     }
  123.  
  124.   /* Read a line from the file */
  125.   if ((line = __socketlib_readline (servfile)) == NULL)
  126.     return NULL;
  127.  
  128.   /* Extract the offical service name from the line */
  129.   element = strtok (line, " \t");
  130.   serv.s_name = strdup (element);
  131.  
  132.   /* Extract the port number from the line */
  133.   element = strtok (NULL, "/");
  134.   serv.s_port = htons (atoi (element));
  135.  
  136.   /* Extract the protocol name from the line */
  137.   element = strtok (NULL, " \t");
  138.   serv.s_proto = strdup (element);
  139.  
  140.   /* Initialise the alias list */
  141.   serv.s_aliases = malloc (sizeof (char *));
  142.   serv.s_aliases[0] = NULL;
  143.   aliases = 1;
  144.  
  145.   /* Extract the aliases */
  146.   while ((element = strtok (NULL, " \t")) != NULL)
  147.     {
  148.       aliases += 1;
  149.       serv.s_aliases = realloc (serv.s_aliases, aliases * sizeof (char *));
  150.       serv.s_aliases[aliases - 2] = strdup (element);
  151.       serv.s_aliases[aliases - 1] = NULL;
  152.     }
  153.  
  154.   return &serv;
  155. }
  156.  
  157. /*
  158.  * Close the services file
  159.  */
  160. int
  161. endservent ()
  162. {
  163.   int status = 0;
  164.  
  165.   /* If its open, close it */
  166.   if (servfile)
  167.     {
  168.       status = fclose (servfile);
  169.       servfile = 0;
  170.     }
  171.  
  172.   return status;
  173. }
  174.  
  175. /*
  176.  * Search the services file for a given service name
  177.  */
  178. struct servent *
  179. getservbyname (const char *name, const char *proto)
  180. {
  181.   struct servent *serv;
  182.   char **alias;
  183.  
  184.   /* Open/rewind the file */
  185.   if (__setservent (1) == -1)
  186.     return NULL;
  187.  
  188.   /* Look through the file for a match */
  189.   while ((serv = __getservent ()) != NULL)
  190.     {
  191.  
  192.       /* Give up now if the protocol doesn't match */
  193.       if (proto && (strcmp (serv->s_proto, proto) != 0))
  194.     continue;
  195.  
  196.       /* Does the offical name match? */
  197.       if (strcmp (serv->s_name, name) == 0)
  198.     break;
  199.  
  200.       /* Do any of the aliases match? */
  201.       for (alias = serv->s_aliases; *alias; alias++)
  202.     {
  203.       if (strcmp (*alias, name) == 0)
  204.         break;
  205.     }
  206.  
  207.       /* Did any of the aliases match? */
  208.       if (*alias)
  209.     break;
  210.     }
  211.  
  212.   /* Close the file unless the user has prohibited it */
  213.   if (!keepopen)
  214.     endservent ();
  215.  
  216.   return serv;
  217. }
  218.  
  219. /*
  220.  * Search the services file for a given port
  221.  */
  222. struct servent *
  223. getservbyport (int port, const char *proto)
  224. {
  225.   struct servent *serv;
  226.  
  227.   /* Open/rewind the file */
  228.   if (__setservent (1) == -1)
  229.     return NULL;
  230.  
  231.   /* Look through the file for a match */
  232.   while ((serv = __getservent ()) != NULL)
  233.     {
  234.  
  235.       /* Give up now if the protocol doesn't match */
  236.       if (proto && (strcmp (serv->s_proto, proto) != 0))
  237.     continue;
  238.  
  239.       /* If the port matches, we've found it */
  240.       if (serv->s_port == port)
  241.     break;
  242.  
  243.     }
  244.  
  245.   /* Close the file unless the user has prohibited it */
  246.   if (!keepopen)
  247.     endservent ();
  248.  
  249.   return serv;
  250. }
  251.