Back to index

lightning-sunbird  0.9+nobinonly
TestDNSDaemon.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <stdio.h>
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <sys/un.h>
00042 #include <unistd.h>
00043 #include <errno.h>
00044 
00045 #if defined(AIX) || defined(__linux)
00046 #include <sys/select.h>         // for fd_set
00047 #endif
00048 
00049 #if defined(__linux)
00050 // Didn't find gettdtablehi() or gettdtablesize() on linux. Using FD_SETSIZE
00051 #define getdtablehi() FD_SETSIZE
00052 #elif !defined(__irix)
00053 // looks like Irix is the only one that has getdtablehi()?
00054 #define getdtablehi() getdtablesize()
00055 
00056 //  If you find a system doesn't have getdtablesize try #define getdtablesize
00057 //  to FD_SETSIZE.  And if you encounter a system that doesn't even have 
00058 //  FD_SETSIZE, just grab your ankles and use 255.
00059 #endif
00060 
00061 
00062 #include "nspr.h"
00063 #include "nsCRT.h"
00064 #include "unix_dns.h"
00065 
00066 struct sockaddr_un  unix_addr;
00067 
00068 int async_dns_lookup(char* hostName)
00069 {
00070   fprintf(stderr, "start async_dns_lookup\n");
00071   int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
00072   if (socket_fd == -1) {
00073     fprintf(stderr, "socket returned error.\n");
00074     return -1;
00075   }
00076 
00077   unix_addr.sun_family = AF_UNIX;
00078   strcpy(unix_addr.sun_path, DNS_SOCK_NAME);
00079 
00080   int err = connect(socket_fd,(struct sockaddr*)&unix_addr, sizeof(unix_addr));
00081   if (err == -1) {
00082     fprintf(stderr, "connect failed (errno = %d).\n",errno);
00083     close(socket_fd);
00084     return -1;
00085   }
00086 
00087   char buf[256];
00088   strcpy(buf, "lookup: ");
00089   strcpy(&buf[8], hostName);
00090 
00091   err = send(socket_fd, buf, strlen(buf)+1, 0);
00092   if (err < 0)
00093     fprintf(stderr, "send(%s) returned error (errno=%d).\n",buf, errno);
00094 
00095   // receive 4 byte ID
00096   err = recv(socket_fd, buf, 256, 0);
00097   if (err < 0)
00098     fprintf(stderr, "recv() returned error (errno=%d).\n", errno);
00099   else
00100     {
00101       //  printf("recv() returned %d bytes.");
00102       int id = *(int *)buf;
00103       fprintf(stderr, "id: %d\n", id);
00104     }
00105 
00106   return socket_fd;
00107 }
00108 
00109 static char *
00110 string_trim(char *s)
00111 {
00112   char *s2;
00113   if (!s) return 0;
00114   s2 = s + strlen(s) - 1;
00115   while (s2 > s && (*s2 == '\n' || *s2 == '\r' || *s2 == ' ' || *s2 == '\t'))
00116     *s2-- = 0;
00117   while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
00118     s++;
00119   return s;
00120 }
00121 
00122 hostent *
00123 bytesToHostent(char *buf)
00124 {
00125   int i;
00126   // int size = 0;
00127   int len, aliasCount, addressCount;
00128   int addrtype, addrlength;
00129   char* p = buf;
00130   char s[1024];
00131 
00132   len = *(int *)p;            // length of name
00133   p += sizeof(int);           // advance past name length
00134 
00135   memcpy(s, p, len); s[len] = 0;
00136   fprintf(stderr, "hostname: %s\n", s);
00137 
00138   p += len;                   // advance past name
00139   aliasCount  = *(int *)p;    // number of aliases
00140   p += sizeof(int);           // advance past alias count
00141 
00142   for (i=0; i<aliasCount; i++) {
00143     len = *(int *)p;          // length of alias name
00144     p += sizeof(int);         // advance past alias name length
00145 
00146     memcpy(s, p, len); s[len] = 0;
00147     fprintf(stderr, "alias: %s\n", s);
00148 
00149     p += len;                 // advance past alias name
00150   }
00151 
00152   addrtype = *(int *)p;
00153 
00154   fprintf(stderr, "addrtype: %d\n", addrtype);
00155 
00156   p += sizeof(int);
00157   addrlength = *(int *)p;
00158 
00159   fprintf(stderr, "addrlength: %d\n", addrlength);
00160 
00161   p += sizeof(int);
00162   addressCount = *(int *)p;
00163   p += sizeof(int);
00164 
00165   for (i=0; i<addressCount; i++) {
00166     len = *(int *)p;    
00167     p += sizeof(int);
00168 
00169     fprintf(stderr, "addr len: %d\n", len);
00170     fprintf(stderr, "addr    : %x\n", *(int *)p);
00171 
00172     p += len;
00173   }
00174 
00175   // size = p - buf;
00176   // size += 1 + aliasCount;
00177   return 0;
00178 }
00179 
00180 int
00181 main(int argc, char* argv[])
00182 {
00183   PRStatus status;
00184 
00185   // launch daemon
00186   printf("### launch daemon...\n");
00187 
00188   PRProcessAttr *attributes = PR_NewProcessAttr();
00189   if (attributes == nsnull) {
00190     printf("PR_NewProcessAttr() failed.\n");
00191     return -1;
00192   }
00193 
00194   PRProcess *daemon = PR_CreateProcess("nsDnsAsyncLookup", nsnull, nsnull, attributes);
00195   if (daemon == nsnull) {
00196     printf("PR_CreateProcess failed.\n");
00197   } else {
00198     //    status = PR_DetachProcess(daemon);
00199     //if (status != 0)
00200     //  printf("PR_DetachProcess returned %d\n", status);
00201     //daemon = nsnull;
00202   }
00203 
00204   PR_DestroyProcessAttr(attributes);
00205 
00206   // create socket and connect to daemon
00207   int socket_fd = 0;
00208 
00209 
00210   PRBool notDone = PR_TRUE;
00211   char buf[1024];
00212 
00213   while(notDone) {
00214     int status = 0;
00215     fd_set fdset;
00216 
00217     FD_ZERO(&fdset);
00218     FD_SET(fileno(stdin), &fdset);
00219     if (socket_fd > 0)
00220       FD_SET(socket_fd, &fdset);
00221           
00222     status = select(getdtablehi(), &fdset, 0, 0, 0);
00223     if (status <= 0)
00224       {
00225        fprintf(stderr, "%s: select() returned %d\n", argv[0], status);
00226        exit(-1);
00227       }
00228 
00229     // which fd is set?
00230 
00231     if (FD_ISSET(fileno(stdin), &fdset))
00232       {
00233        char *line = fgets(buf, sizeof(buf)-1, stdin);
00234        line = string_trim(line);
00235        
00236        if(!strcmp(line, "quit") || !strcmp(line, "exit"))
00237          {
00238            fprintf(stderr, "bye now.\n");
00239            notDone = PR_FALSE;
00240          }
00241        else if (!strncmp(line, "abort ", 6))
00242          {
00243            // abort id
00244          }
00245        else if (strchr(line, ' ') || strchr(line, '\t'))
00246          {
00247            fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line);
00248          }
00249        else
00250          {
00251            fprintf(stderr, "%s: looking up %s...\n", argv[0], line);
00252            // initiate dns lookup
00253            socket_fd = async_dns_lookup(line);
00254          }
00255       }
00256 
00257     if (socket_fd && FD_ISSET(socket_fd, &fdset))
00258       {
00259        // read from socket, parse results
00260        int size = read(socket_fd, buf, 1024);
00261        if (size > 0)
00262          {
00263            // parse buffer into hostent
00264            char *p = buf;
00265            fprintf(stderr, "bytes read: %d\n", size);
00266            fprintf(stderr, "response code: %d\n", *(int *)p);
00267            p += sizeof(int);
00268 
00269            for (int i=0; i < size; i++) {
00270              if (!(i%8))
00271               fprintf(stderr, "\n");
00272              fprintf(stderr, "%2.2x ",(unsigned char)buf[i]);
00273            }
00274            fprintf(stderr, "\n");
00275            hostent *h;
00276            h = bytesToHostent(p);
00277          }
00278        close(socket_fd);
00279        socket_fd = 0;
00280       }
00281   }
00282 
00283   return 0;
00284 }
00285 
00286 /*
00287 buffer
00288 
00289 int nameLen;
00290 
00291 if (nameLen > 0)
00292   char [nameLen+1] name
00293 
00294 int aliasCount
00295 for each alias
00296   int aliasNameLen
00297   char [aliasNameLen+1] aliasName
00298 
00299 int h_addrtype
00300 int h_length
00301 int addrCount
00302 for each addr
00303   char[h_length] addr
00304 
00305 
00306 
00307 */