Made the resolver process stream oriented.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 26 Aug 2004 09:49:28 +0000 (09:49 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 26 Aug 2004 09:49:28 +0000 (09:49 +0000)
win/resolver.c

index e4e35b2d62d54f5bd193c64230df72447500be26..b83d4dadacb6cdec6693691cdddc8fa8c3a6866f 100644 (file)
@@ -1,6 +1,12 @@
-/*
+/* resolver.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
  *
+ * This is a resolver process. This program reads hostnames from standard
+ * input and uses the standard system resolver to obtain the IP address (or
+ * addresses) and returns these as a line on standard output.
+ *
+ * $Id$
  */
+
 #if defined(_UNICODE) && !defined(UNICODE)
 #define UNICODE
 #endif
 #pragma comment(lib, "ws2_32")
 #endif
 
-void Win32Error(LPCTSTR sz, HRESULT hr);
-LPSTR W2A(LPCWSTR wstr);
+void Win32Error(FILE *fp, LPCTSTR sz, HRESULT hr);
+void DumpData(LPCTSTR szLabel, LPBYTE pData, DWORD cbData);
 
 int
 _tmain(int argc, LPCTSTR argv[])
 {
     WSADATA wsd;
-    struct addrinfo hints = {0};
-    struct addrinfo *res = NULL;
-    const char * hostname;
     DWORD dwCookie = 0;
-    int  r = 0;
-
-    if (argc < 2) {
-        _ftprintf(stderr, _T("usage: resolver <hostname>\n"));
-        return -1;
-    }
 
     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
-        Win32Error(_T("WSAStartup failed"), GetLastError());
+        Win32Error(stderr, _T("WSAStartup failed"), GetLastError());
         return -1;
     }
 
@@ -47,75 +44,127 @@ _tmain(int argc, LPCTSTR argv[])
         return -1;
     }
     
-#ifdef UNICODE
-    hostname = W2A(argv[1]);
+    while (1) {
+        struct addrinfo hints = {0};
+        struct addrinfo *res = NULL;
+        LPSTR hostname;
+        TCHAR buffer[1024];
+        LPTSTR line, q, tname;
+        int r = 0, nc = 0;
+    
+        line = _fgetts(buffer, 1024, stdin);
+        if (line == NULL)
+            break;
+        
+        /* trim whitespace */
+        while(*line && _istspace(*line))
+            line++;
+        q = line + lstrlen(line) - 1;
+        while (q > line && *q && isspace(*q))
+            q--;
+        *++q = 0;
+
+#ifdef _UNICODE
+        nc = WideCharToMultiByte(CP_ACP, 0, line, -1, NULL, 0, NULL, NULL);
+        hostname = (LPSTR)_alloca(nc + 1);
+        WideCharToMultiByte(CP_ACP, 0, line, -1, hostname, nc, NULL, NULL);
 #else
-    hostname = argv[1];
+        hostname = line;
 #endif
-    
-    dwCookie = GetCurrentProcessId();
-    ZeroMemory(&hints, sizeof(hints));
-    hints.ai_family = PF_UNSPEC;
 
-    r = getaddrinfo(hostname, "", &hints, &res);
+        dwCookie++;
+        ZeroMemory(&hints, sizeof(hints));
+        hints.ai_family = PF_UNSPEC;
+        hints.ai_flags = AI_CANONNAME;
+        hints.ai_socktype = SOCK_STREAM;
+        r = getaddrinfo(hostname, "", &hints, &res);
 
-#ifdef UNICODE
-    HeapFree(GetProcessHeap(), 0, (LPVOID)hostname);
+        if (r != 0) {
+            Win32Error(stdout, _T("error"), WSAGetLastError());
+        } else {
+            struct addrinfo *p = res;
+            while (p != NULL) {
+                char name[NI_MAXHOST];
+                /*
+                printf("fam:%x prot:%x len:%d res:%s\n", 
+                       p->ai_family, p->ai_protocol, p->ai_addrlen,
+                       p->ai_canonname);
+                DumpData(_T("addrinfo"), (LPBYTE)p, sizeof(struct addrinfo));
+                */
+                getnameinfo(p->ai_addr, p->ai_addrlen, 
+                            name, NI_MAXHOST,
+                            NULL, 0,
+                            NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef _UNICODE
+                nc = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
+                tname = (LPWSTR)_alloca(nc + sizeof(WCHAR));
+                MultiByteToWideChar(CP_ACP, 0, name, -1, tname, nc);
+#else
+                tname = name;
 #endif
-
-    if (r != 0) {
-        Win32Error(_T("getaddrinfo"), WSAGetLastError());
-    } else {
-        struct addrinfo *p = res;
-        printf("%d", dwCookie);
-        while (p != NULL) {
-            char name[NI_MAXHOST];
-            getnameinfo(p->ai_addr, p->ai_addrlen, 
-                        name, NI_MAXHOST,
-                        NULL, 0,
-                        NI_NUMERICHOST | NI_NUMERICSERV);
-            printf(" %s", name);
-            p = p->ai_next;
+                _tprintf(_T("%s "), tname);
+                p = p->ai_next;
+            }
+            _tprintf(_T("\n"));
+            freeaddrinfo(res);
         }
-        printf("\n");
-        freeaddrinfo(res);
+
+        fflush(stdout);
     }
 
     WSACleanup();
     return 0;
 }
 
-LPSTR
-W2A(LPCWSTR wstr)
+void
+Win32Error(FILE *fp, LPCTSTR szMessage, HRESULT hr)
 {
-    LPSTR str = NULL;
-    int slen = 0;
-
-    if (wstr == NULL)
-        return NULL;
-
-    slen = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
-    str = HeapAlloc(GetProcessHeap(), 0, slen * sizeof(CHAR));
-    if (str != NULL)
-        slen = WideCharToMultiByte(CP_ACP, 0, wstr, slen, str, slen, NULL, NULL);
-    return str;
+    LPTSTR lpBuffer = NULL;
+    DWORD  dwLen = 0;
+    
+    dwLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER 
+                          | FORMAT_MESSAGE_FROM_SYSTEM,
+                          NULL, (DWORD)hr, LANG_NEUTRAL,
+                          (LPTSTR)&lpBuffer, 0, NULL);
+    if (dwLen < 1) {
+        dwLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER 
+                              | FORMAT_MESSAGE_FROM_STRING
+                              | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+                              _T("code 0x%1!08X!%n"), 0, LANG_NEUTRAL,
+                              (LPTSTR)&lpBuffer, 0, (va_list *)&hr);
+    }
+    _ftprintf(fp, _T("%s"), szMessage);
+    if (dwLen > 0) {
+        _ftprintf(fp, _T(": "));
+        _ftprintf(fp, lpBuffer);
+    }
+    LocalFree((HLOCAL)lpBuffer);
 }
 
 void
-Win32Error(LPCTSTR sz, HRESULT hr)
+DumpData(LPCTSTR szLabel, LPBYTE pData, DWORD cbData)
 {
-    LPTSTR lpBuffer = NULL;
-    TCHAR  sBuffer[30];
-    
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-                  NULL, (DWORD)hr, LANG_NEUTRAL,
-                  (LPTSTR)&lpBuffer, 0, NULL);
-    
-    _ftprintf(stderr, _T("%s: "), sz);
-    if (lpBuffer == NULL) {
-        lpBuffer = sBuffer;
-        _ftprintf(stderr, _T("code: %08lX\n"), hr);
-    } else {
-        _ftprintf(stderr, lpBuffer);
+    TCHAR line[120];
+    DWORD cn = 0;
+    LPTSTR p = line, q = line + 40;
+    FillMemory(line, 80 * sizeof(TCHAR), 32);
+    _sntprintf(p, 80, _T("%s:"), szLabel);
+    p += lstrlen(szLabel) + 1;
+    *p = 32;
+    for (cn = 0; cn < cbData; cn++) {
+        if (cn % 16 == 0) {
+            _sntprintf(q, 80, _T("\n% 4d: "), cn);
+            p = line, q = line + 40;
+            _ftprintf(stdout, line);
+            FillMemory(line, 80 * sizeof(TCHAR), 32);
+        }
+        _stprintf(p, _T("%02x"), (int)pData[cn]);
+        _stprintf(q, _T("%c"), 
+                   _istprint(pData[cn]) ? (int)pData[cn] : _T('.'));
+        p += 2;
+        q += 1;
+        *p = _T(' ');
     }
+    _stprintf(q, _T("\n"));
+    _ftprintf(stdout, line);
 }