⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getserv.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/*
 *  Simple BSD-like services functions
 *
 *  G. Vanem <giva@bgnett.no>
 *
 *  20.aug 1996 - Created
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "wattcp.h"
#include "strings.h"
#include "misc.h"
#include "language.h"
#include "pcconfig.h"
#include "pcbsd.h"

#if defined(USE_BSD_FUNC)

struct _servent {
        struct  servent  s;
        struct _servent *next;
      };


#define MAX_SERV_ALIASES  5

static struct _servent *serv0 = NULL;
static char   *servFname      = NULL;
static FILE   *servFile       = NULL;
static BOOL    servClose      = 0;

/* For DOSX targets we use a small hash table to speed up searches
 */
#if (DOSX)
  #define PORT_HASH_SIZE  256   /* must be 2^n */
  #define GET_HASH(p)     port_hash [(p) & (PORT_HASH_SIZE-1)]
  #define SET_HASH(se)    port_hash [se->s.s_port & (PORT_HASH_SIZE-1)] = se
  static struct _servent *port_hash [PORT_HASH_SIZE];
#else
  #define GET_HASH(p)     serv0
  #define SET_HASH(se)    ((void)0)
#endif

/*------------------------------------------------------------------*/

void ReadServFile (const char *fname)
{
  static int been_here = 0;

  if (!fname || !*fname)
     return;

  if (been_here)  /* loading multiple service files */
  {
    free (servFname);
    fclose (servFile);
    servFile = NULL;
  }
  been_here = 1;

  servFname = strdup (fname);
  if (!servFname)
     return;

  setservent (1);
  if (!servFile)
     return;

  while (1)
  {
    struct _servent *se, *se2 = (struct _servent*) getservent();

    if (!se2)
       break;

    if ((se = malloc(sizeof(*se))) == NULL)
    {
      outsnl (_LANG("Service-file too big!\7"));
      return;
    }
    *se = *se2;
    se->next = serv0;
    serv0    = se;
    SET_HASH (se);
  }
  rewind (servFile);
  atexit (endservent);
}

/*------------------------------------------------------------------*/

const char *GetServFile (void)
{
  return (servFname);
}

void CloseServFile (void)
{
  fclose (servFile);
  servFile = NULL;
}

void ReopenServFile (void)
{
  ReadServFile (servFname);
}

/*------------------------------------------------------------------*/

struct servent * getservent (void)
{
  static struct _servent se;
  WORD   port;
  char  *name, *alias, *proto;
  char   buf[200];

  if (!netdb_init() || !servFile)
     return (NULL);

  do
  {
    do
    {
      if (!fgets(buf,sizeof(buf)-1,servFile))
         return (NULL);
    }
    while (buf[0] == '#' || buf[0] == '\n');

    if (servClose)
       endservent();

    /*  # Service         port/prot       alias(es)
     *  #-------------------------------------------
     *    rtmp            1/udp   <- only support "udp"/"tcp"
     *    echo            7/tcp
     *    echo            7/udp
     *    discard         9/tcp           sink null
     *    discard         9/udp           sink null
     */

    name  = strtok (buf, " \t");
    port  = intel16 (atoi (strtok (NULL, "/ \t\n")));
    proto = strtok (NULL, " \t\n");

  }
  while (stricmp(proto,"udp") && stricmp(proto,"tcp"));

  se.s.s_name    = strdup (name);
  se.s.s_proto   = strdup (proto);
  se.s.s_port    = port;
  se.s.s_aliases = NULL;

  if (!se.s.s_name || !se.s.s_proto)
     return (NULL);

  alias = strtok (NULL, " \t\n");

  if (alias && *alias != '#' && *alias != ';')
  {
    char **alist = calloc ((1+MAX_SERV_ALIASES) * sizeof(char*), 1);
    int  i = 0;
    do
    {
      if (*alias == '#' || *alias == ';')
         break;
      if (!alist || (i == MAX_SERV_ALIASES) ||
          (alist[i++] = strdup(alias)) == NULL)
         break;
      alias = strtok (NULL, " \t\n");
    }
    while (alias);
    se.s.s_aliases = alist;
  }
  return (&se.s);
}

/*------------------------------------------------------------------*/

struct servent * getservbyname (const char *serv, const char *proto)
{
  struct _servent *se;

  if (!netdb_init())
     return (NULL);

  for (se = serv0; se && serv; se = se->next)
  {
    char **alias;
    BOOL chk_prot = 0;

    if (se->s.s_name && !stricmp(se->s.s_name,serv))
       chk_prot = TRUE;

    else for (alias = se->s.s_aliases; alias && *alias; alias++)
             if (!stricmp(serv,*alias))
             {
               chk_prot = TRUE;
               break;
             }
    if (chk_prot && (!proto || !stricmp(se->s.s_proto,proto)))
       return (&se->s);
  }
  return (NULL);
}

/*------------------------------------------------------------------*/

struct servent * getservbyport (int port, const char *proto)
{
  struct _servent *se;

  if (!netdb_init())
     return (NULL);

  for (se = GET_HASH(port); se && port; se = se->next)
  {
    if (se->s.s_port == port &&
        (!proto || !stricmp(se->s.s_proto,proto)))
       return (&se->s);
  }
  return (NULL);
}

/*------------------------------------------------------------------*/

void setservent (int stayopen)
{
  servClose = (stayopen == 0);
  if (!netdb_init() || !servFname)
     return;

  if (!servFile)
       servFile = fopen (servFname, "rt");
  else rewind (servFile);
}

/*------------------------------------------------------------------*/

void endservent (void)
{
  struct _servent *se, *next = NULL;

  if (!netdb_init() || !servFile)
     return;

  free (servFname);
  fclose (servFile);
  servFname = NULL;
  servFile  = NULL;

  for (se = serv0; se; se = next)
  {
    if (se->s.s_aliases)
    {
      int i;
      for (i = 0; i < MAX_SERV_ALIASES; i++)
          if (se->s.s_aliases[i])
             free (se->s.s_aliases[i]);
      free (se->s.s_aliases);
    }
    next = se->next;
    free (se->s.s_name);
    free (se->s.s_proto);
    free (se);
  }
  serv0 = NULL;
  servClose = 1;
}

#endif /* USE_BSD_FUNC */

#if defined(TEST_PROG)

#include "pcdbug.h"
#include "sock_ini.h"

int main (void)
{
  struct _servent *se;
  int    i;

  dbug_init();
  sock_init();

  for (se = serv0; se; se = se->next)
  {
    printf ("proto %-6.6s  port %4d  name %-10.10s  aliases:",
            se->s.s_proto, intel16(se->s.s_port), se->s.s_name);
    for (i = 0; se->s.s_aliases && se->s.s_aliases[i]; i++)
         printf (" %s", se->s.s_aliases[i]);
    puts ("");
  }
  return (0);
}
#endif /* TEST_PROG */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -