summaryrefslogtreecommitdiff
path: root/Contrib/NSISdl/asyncdns.cpp
blob: 360a37229ca228f8071d2828bcb5bfec82668f66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
** JNetLib
** Copyright (C) 2000-2001 Nullsoft, Inc.
** Author: Justin Frankel
** File: asyncdns.cpp - JNL portable asynchronous DNS implementation
** License: see jnetlib.h
*/


#include "netinc.h"
#include "util.h"
#include "asyncdns.h"

JNL_AsyncDNS::JNL_AsyncDNS()
{
  m_thread=0;
  m_addr=0;
  m_hostname[0]=0;
}

JNL_AsyncDNS::~JNL_AsyncDNS()
{
  wait_for_thread_death();
}

unsigned long WINAPI JNL_AsyncDNS::_threadfunc(LPVOID _d)
{
  JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d;
  struct hostent *hostentry;
  hostentry=::gethostbyname(_this->m_hostname);
  if (hostentry)
  {
    _this->m_addr=*((int*)hostentry->h_addr);
  }
  else
    _this->m_addr=INADDR_NONE;
  return 0;
}

int JNL_AsyncDNS::resolve(char *hostname, unsigned long *addr)
{
  // return 0 on success, 1 on wait, -1 on unresolvable
  unsigned long ip=inet_addr(hostname);
  if (ip != INADDR_NONE) 
  {
    *addr=ip;
    return 0;
  }

  if (lstrcmpi(m_hostname,hostname)) m_addr=0;
  else if (m_addr == INADDR_NONE)
  {
    wait_for_thread_death();
    return -1;
  }
  else if (m_addr)
  {
    *addr=m_addr;
    wait_for_thread_death();
    return 0;
  }
  lstrcpy(m_hostname,hostname);

  if (!m_thread)
  {
    DWORD id;
    m_thread=CreateThread(NULL,0,_threadfunc,(LPVOID)this,0,&id);
    if (!m_thread) return -1;
  }
  return 1;
}  

void JNL_AsyncDNS::wait_for_thread_death()
{
  if (m_thread)
  {
    WaitForSingleObject(m_thread,INFINITE);
    CloseHandle(m_thread);
  }

  m_thread=0;
}