michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #if defined(AIX) || defined(__linux) michael@0: #include // for fd_set michael@0: #endif michael@0: michael@0: #if defined(__linux) michael@0: // Didn't find gettdtablehi() or gettdtablesize() on linux. Using FD_SETSIZE michael@0: #define getdtablehi() FD_SETSIZE michael@0: #else michael@0: #define getdtablehi() getdtablesize() michael@0: michael@0: // If you find a system doesn't have getdtablesize try #define getdtablesize michael@0: // to FD_SETSIZE. And if you encounter a system that doesn't even have michael@0: // FD_SETSIZE, just grab your ankles and use 255. michael@0: #endif michael@0: michael@0: michael@0: #include "nspr.h" michael@0: #include "nsCRT.h" michael@0: #include "unix_dns.h" michael@0: michael@0: struct sockaddr_un unix_addr; michael@0: michael@0: int async_dns_lookup(char* hostName) michael@0: { michael@0: fprintf(stderr, "start async_dns_lookup\n"); michael@0: int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); michael@0: if (socket_fd == -1) { michael@0: fprintf(stderr, "socket returned error.\n"); michael@0: return -1; michael@0: } michael@0: michael@0: unix_addr.sun_family = AF_UNIX; michael@0: strcpy(unix_addr.sun_path, DNS_SOCK_NAME); michael@0: michael@0: int err = connect(socket_fd,(struct sockaddr*)&unix_addr, sizeof(unix_addr)); michael@0: if (err == -1) { michael@0: fprintf(stderr, "connect failed (errno = %d).\n",errno); michael@0: close(socket_fd); michael@0: return -1; michael@0: } michael@0: michael@0: char buf[256]; michael@0: strcpy(buf, "lookup: "); michael@0: strcpy(&buf[8], hostName); michael@0: michael@0: err = send(socket_fd, buf, strlen(buf)+1, 0); michael@0: if (err < 0) michael@0: fprintf(stderr, "send(%s) returned error (errno=%d).\n",buf, errno); michael@0: michael@0: // receive 4 byte ID michael@0: err = recv(socket_fd, buf, 256, 0); michael@0: if (err < 0) michael@0: fprintf(stderr, "recv() returned error (errno=%d).\n", errno); michael@0: else michael@0: { michael@0: // printf("recv() returned %d bytes."); michael@0: int id = *(int *)buf; michael@0: fprintf(stderr, "id: %d\n", id); michael@0: } michael@0: michael@0: return socket_fd; michael@0: } michael@0: michael@0: static char * michael@0: string_trim(char *s) michael@0: { michael@0: char *s2; michael@0: if (!s) return 0; michael@0: s2 = s + strlen(s) - 1; michael@0: while (s2 > s && (*s2 == '\n' || *s2 == '\r' || *s2 == ' ' || *s2 == '\t')) michael@0: *s2-- = 0; michael@0: while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r') michael@0: s++; michael@0: return s; michael@0: } michael@0: michael@0: hostent * michael@0: bytesToHostent(char *buf) michael@0: { michael@0: int i; michael@0: // int size = 0; michael@0: int len, aliasCount, addressCount; michael@0: int addrtype, addrlength; michael@0: char* p = buf; michael@0: char s[1024]; michael@0: michael@0: len = *(int *)p; // length of name michael@0: p += sizeof(int); // advance past name length michael@0: michael@0: memcpy(s, p, len); s[len] = 0; michael@0: fprintf(stderr, "hostname: %s\n", s); michael@0: michael@0: p += len; // advance past name michael@0: aliasCount = *(int *)p; // number of aliases michael@0: p += sizeof(int); // advance past alias count michael@0: michael@0: for (i=0; i 0) michael@0: FD_SET(socket_fd, &fdset); michael@0: michael@0: status = select(getdtablehi(), &fdset, 0, 0, 0); michael@0: if (status <= 0) michael@0: { michael@0: fprintf(stderr, "%s: select() returned %d\n", argv[0], status); michael@0: exit(-1); michael@0: } michael@0: michael@0: // which fd is set? michael@0: michael@0: if (FD_ISSET(fileno(stdin), &fdset)) michael@0: { michael@0: char *line = fgets(buf, sizeof(buf)-1, stdin); michael@0: line = string_trim(line); michael@0: michael@0: if(!strcmp(line, "quit") || !strcmp(line, "exit")) michael@0: { michael@0: fprintf(stderr, "bye now.\n"); michael@0: notDone = false; michael@0: } michael@0: else if (!strncmp(line, "abort ", 6)) michael@0: { michael@0: // abort id michael@0: } michael@0: else if (strchr(line, ' ') || strchr(line, '\t')) michael@0: { michael@0: fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line); michael@0: } michael@0: else michael@0: { michael@0: fprintf(stderr, "%s: looking up %s...\n", argv[0], line); michael@0: // initiate dns lookup michael@0: socket_fd = async_dns_lookup(line); michael@0: } michael@0: } michael@0: michael@0: if (socket_fd && FD_ISSET(socket_fd, &fdset)) michael@0: { michael@0: // read from socket, parse results michael@0: int size = read(socket_fd, buf, 1024); michael@0: if (size > 0) michael@0: { michael@0: // parse buffer into hostent michael@0: char *p = buf; michael@0: fprintf(stderr, "bytes read: %d\n", size); michael@0: fprintf(stderr, "response code: %d\n", *(int *)p); michael@0: p += sizeof(int); michael@0: michael@0: for (int i=0; i < size; i++) { michael@0: if (!(i%8)) michael@0: fprintf(stderr, "\n"); michael@0: fprintf(stderr, "%2.2x ",(unsigned char)buf[i]); michael@0: } michael@0: fprintf(stderr, "\n"); michael@0: hostent *h; michael@0: h = bytesToHostent(p); michael@0: } michael@0: close(socket_fd); michael@0: socket_fd = 0; michael@0: } michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: /* michael@0: buffer michael@0: michael@0: int nameLen; michael@0: michael@0: if (nameLen > 0) michael@0: char [nameLen+1] name michael@0: michael@0: int aliasCount michael@0: for each alias michael@0: int aliasNameLen michael@0: char [aliasNameLen+1] aliasName michael@0: michael@0: int h_addrtype michael@0: int h_length michael@0: int addrCount michael@0: for each addr michael@0: char[h_length] addr michael@0: michael@0: michael@0: michael@0: */