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

📄 gethost.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (addr == INADDR_BROADCAST ||      /* 255.255.255.255    */
      (~ntohl(addr) & ~sin_mask) == 0) /* directed broadcast */
  {
    ret.h_address = addr;
    ret.h_name    = "broadcast";
    return FillHostEnt (&ret);
  }

  for (h = host0; h; h = h->h_next)
      if (h->h_address == addr)
      {
       /* if cached entry expired, do a new reverse lookup
        */
        if (h->h_timeout && time(NULL) >= h->h_timeout)
           break;
        return FillHostEnt (h);
      }


  rc = resolve_ip (addr, name);  /* do a reverse ip lookup */

  /* interrupted or timedout
   */
  if (!rc && (_resolve_exit || _resolve_timeout))
     return (NULL);

  if (rc)                        /* successfully resolved */
  {
    AddHostEnt (h, name, addr, TRUE);
    ret.h_address = addr;
    ret.h_name    = name;
    ret.h_aliases = h ? h->h_aliases : NULL;
    return FillHostEnt (&ret);
  }

 /* Add the IP to the list even if reverse lookup failed and not
  * interrupted by _resolve_hook(). Thus the next call to gethostbyxx()
  * will return immediately.
  */

  AddHostEnt (h, "*unknown*", addr, FALSE);
  return (NULL);
}

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

void sethostent (int stayopen)
{
  hostClose = (stayopen == 0);
  if (!netdb_init() || !hostFname)
     return;

  if (!hostFile)
       hostFile = fopen (hostFname, "rt");
  else rewind (hostFile);
}

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

static __inline void free_aliases (const struct _hostent *h)
{
  if (h->h_aliases)
  {
    int i;
    for (i = 0; i < MAX_HOST_ALIASES; i++)
        if (h->h_aliases[i])
           free (h->h_aliases[i]);
    free (h->h_aliases);
  }
}

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

void endhostent (void)
{
  struct _hostent *h, *next = NULL;

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

  free (hostFname);
  fclose (hostFile);
  hostFname = NULL;
  hostFile  = NULL;

  for (h = host0; h; h = next)
  {
    free_aliases (h);
    next = h->h_next;
    free (h->h_name);
    free (h);
  }
  host0 = NULL;
  hostClose = 1;
}                          

#endif /* USE_BSD_FUNC */

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

u_long gethostid (void)
{
  if (!netdb_init())
     return (INADDR_NONE);
  return htonl (my_ip_addr);
}

u_long sethostid (DWORD ip)
{
  return (my_ip_addr = ntohl(ip));
}

/*
 * Fill in the reverse lookup question packet
 */
static __inline void qinit (question_t *q, DWORD ip)
{
  char *c;
  BYTE  i;

  q->h.ident   = set_timeout (0);  /* Random ID */
  q->h.flags   = intel16 (DRD);    /* recursion desired */
  q->h.qdcount = intel16 (1);
  q->h.ancount = 0;
  q->h.nscount = 0;
  q->h.arcount = 0;

  c  = q->x;
  ip = ntohl (ip);
  for (i = 0; i < 4; ++i)
  {
    BYTE x = (BYTE) ip;
    ip >>= 8;
    *c = (x < 10) ? 1 : (x < 100) ? 2 : 3;
    itoa (x,c+1,10);
    c += *c + 1;
  }
  strcpy (c, "\7in-addr\4arpa");
  c += 14;
  *(short*) c = intel16 (DTYPEPTR);
  c += sizeof(short);
  *(short*) c = intel16 (DIN);
}

/*
 * getresult() - read answer and extract host name
 *               return 0 on error, 1 on success
 */
static __inline int getresult (sock_type *s, char *name)
{
  answer_t a;
  struct   rrpart *rr;
  char    *c;    
  int      len = sock_fastread (s, (BYTE*)&a, sizeof(a));

  if (len < sizeof(struct dhead) ||
      a.h.qdcount != intel16(1)  ||
      a.h.ancount == 0)
     return (0);

  /* Skip question */
  c = a.x;
  while (*c)
        ++c;
  c += 5;

  /* Skip name */
  while (*c)
  {
    if ((*c & 0xC0) == 0xC0)
    {
      c += 2;
      break;
    }
    else
      ++c;
  }
  rr = (struct rrpart*) c;
  if (rr->rtype != intel16(DTYPEPTR))
     return (0);

  c = (char*) &rr->rdata;
  while (*c)
  {
    if ((*c & 0xC0) == 0xC0)
        c = a.x + (*(int*)c & 0x3FFF);
    strncpy (name,c+1,*c);
    name += *c;
    c += *c + 1;
    if (*c)
        *name++ = '.';
  }
  *name = 0;
  return (1);
}

/*
 * reverse_lookup() - Translate an IP into a host name.
 * Returns 1 on success, 0 on error or timeout
 */
static DWORD resolve_timeout = 0UL;

static int reverse_lookup (question_t *q, char *name, DWORD nameserver)
{
  int        sec, ret;
  int        ready = 0;
  int        quit  = 0;
  udp_Socket dom_sock;
  sock_type *s = (sock_type*)&dom_sock;

  if (!nameserver ||         /* no nameserver, give up */
      dns_timeout == 0)
     return (0);

  if (!udp_open(&s->udp, 997, nameserver, 53, NULL))
     return (0);

  for (sec = 2; sec < dns_timeout-1 && !quit && !_resolve_exit; sec *= 2)
  {
    sock_write (s, (BYTE*)q, sizeof(*q));
    ip_timer_init (&s->udp, sec);
    do
    {
      kbhit();
      tcp_tick (s);

      if (watcbroke || (_resolve_hook && (*_resolve_hook)() == 0))
      {
        _resolve_exit = 1;
        quit  = 1;
        ready = 0;
        break;
      }
      if (sock_dataready(s))
      {
        quit  = 1;
        ready = 1;
      }
      if (ip_timer_expired(&s->udp) || chk_timeout(resolve_timeout))
      {
        ready = 0;
        resolve_timeout = 1;
        break;  /* retry */
      }
    }
    while (!quit);
  }

  if (ready)
       ret = getresult (s, name);
  else ret = 0;

  sock_close (s);
  return (ret);
}

/*
 * Do a reverse lookup on `my_ip_addr'. If successfull, replace
 * `hostname' and `def_domain' with returned result.
 */
int reverse_lookup_myip (void)
{
  char myname [MAX_HOSTLEN];

  if (!resolve_ip(htonl(my_ip_addr),myname))
     return (0);

  if (debug_on >= 1)
  {
    outs (_LANG("My FQDN: "));
    outsnl (myname);
  }
  if (sethostname(myname,sizeof(myname)) < 0)
     return (0);
  return (1);
}

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

int resolve_ip (DWORD ip, char *result)
{
  question_t q;
  int        i;
  WORD oldhndlcbrk;

  if (dns_timeout == 0)
      dns_timeout = (UINT)sock_delay << 2;

  resolve_timeout = set_timeout (1000 * dns_timeout);
  oldhndlcbrk = wathndlcbrk;
  wathndlcbrk = 1;        /* enable special interrupt mode */
  watcbroke   = 0;
  *result     = 0;

  _resolve_exit = _resolve_timeout = 0;

  qinit (&q, ip);

  for (i = 0; i < last_nameserver; ++i)
      if (reverse_lookup(&q,result,def_nameservers[i]))
         break;

  watcbroke   = 0;          /* always clean up */
  wathndlcbrk = oldhndlcbrk;
  return (*result != 0);
}

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

#ifdef TEST_PROG

#include <conio.h>
#include <unistd.h>

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

/*
 *  Print list of hosts unsorted.
 */
static void print_hosts (void)
{
  struct _hostent *h;

  for (h = host0; h; h = h->h_next)
  {
    int i;

    printf ("h->h_address = %-17.17s h->h_name = %s; ",
            inet_ntoa(*(struct in_addr*)&h->h_address), h->h_name);

    for (i = 0; h->h_aliases && h->h_aliases[i]; i++)
    {
      if (i == 0)
        printf ("Aliases: ");
      printf ("%s,", h->h_aliases[i]);
    }
    puts ("");
  }
}

void Sleep (int time)
{
  while (time)
  {
    if (kbhit() && getch() == 27)
    {
      fputc ('\n', stderr);
      return;
    }
    fprintf (stderr, "%4d\b\b\b\b", time--);
    sleep (1);
  }
}

int main (void)
{
  struct hostent *h;
  int    wait_time;
  char  *host_name = "test-address";

  dbug_init();
  sock_init();
  print_hosts();

  wait_time = netdbCacheLife + 1;

  AddHostEnt (NULL, host_name, inet_aton("11.22.33.44",NULL), TRUE);
  h = gethostbyname (host_name);
  if (!h)
  {
    fprintf (stderr, "gethostbyname() failed!. h_errno = %d\n", h_errno);
    return (1);
  }
  fprintf (stderr, "Waiting for cache-entry to timeout..");
  Sleep (wait_time);

  fprintf (stderr, "gethostbyname() should do a DNS lookup now.\n");
  h = gethostbyname (host_name);
  if (h)
  {
    fprintf (stderr, "entry didn't timeout!.\n");
    return (1);
  }

#if defined(USE_FORTIFY)
  Fortify_ListAllMemory();
  Fortify_OutputStatistics();
#endif
  return (0);
}
#endif /* TEST_PROG */

⌨️ 快捷键说明

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