URI:
       tdnsquery.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdnsquery.c (2837B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <ndb.h>
            5 #include <ndbhf.h>
            6 
            7 static void nstrcpy(char*, char*, int);
            8 static void mkptrname(char*, char*, int);
            9 static Ndbtuple *doquery(int, char *dn, char *type);
           10 
           11 /*
           12  *  search for a tuple that has the given 'attr=val' and also 'rattr=x'.
           13  *  copy 'x' into 'buf' and return the whole tuple.
           14  *
           15  *  return 0 if not found.
           16  */
           17 Ndbtuple*
           18 dnsquery(char *net, char *val, char *type)
           19 {
           20         char rip[128];
           21         char *p;
           22         Ndbtuple *t;
           23         int fd;
           24 
           25         /* if the address is V4 or V6 null address, give up early vwhoi*/
           26         if(strcmp(val, "::") == 0 || strcmp(val, "0.0.0.0") == 0)
           27                 return nil;
           28 
           29         if(net == nil)
           30                 net = "/net";
           31         snprint(rip, sizeof(rip), "%s/dns", net);
           32         fd = open(rip, ORDWR);
           33         if(fd < 0){
           34                 if(strcmp(net, "/net") == 0)
           35                         snprint(rip, sizeof(rip), "/srv/dns");
           36                 else {
           37                         snprint(rip, sizeof(rip), "/srv/dns%s", net);
           38                         p = strrchr(rip, '/');
           39                         *p = '_';
           40                 }
           41                 fd = open(rip, ORDWR);
           42                 if(fd < 0)
           43                         return nil;
           44                 if(mount(fd, -1, net, MBEFORE, "") < 0){
           45                         close(fd);
           46                         return nil;
           47                 }
           48                 /* fd is now closed */
           49                 snprint(rip, sizeof(rip), "%s/dns", net);
           50                 fd = open(rip, ORDWR);
           51                 if(fd < 0)
           52                         return nil;
           53         }
           54 
           55         /* zero out the error string */
           56         werrstr("");
           57 
           58         /* if this is a reverse lookup, first lookup the domain name */
           59         if(strcmp(type, "ptr") == 0){
           60                 mkptrname(val, rip, sizeof rip);
           61                 t = doquery(fd, rip, "ptr");
           62         } else
           63                 t = doquery(fd, val, type);
           64 
           65         close(fd);
           66         return t;
           67 }
           68 
           69 /*
           70  *  convert address into a reverse lookup address
           71  */
           72 static void
           73 mkptrname(char *ip, char *rip, int rlen)
           74 {
           75         char buf[128];
           76         char *p, *np;
           77         int len;
           78 
           79         if(strstr(ip, "in-addr.arpa") || strstr(ip, "IN-ADDR.ARPA")){
           80                 nstrcpy(rip, ip, rlen);
           81                 return;
           82         }
           83 
           84         nstrcpy(buf, ip, sizeof buf);
           85         for(p = buf; *p; p++)
           86                 ;
           87         *p = '.';
           88         np = rip;
           89         len = 0;
           90         while(p >= buf){
           91                 len++;
           92                 p--;
           93                 if(*p == '.'){
           94                         memmove(np, p+1, len);
           95                         np += len;
           96                         len = 0;
           97                 }
           98         }
           99         memmove(np, p+1, len);
          100         np += len;
          101         strcpy(np, "in-addr.arpa");
          102 }
          103 
          104 static void
          105 nstrcpy(char *to, char *from, int len)
          106 {
          107         strncpy(to, from, len);
          108         to[len-1] = 0;
          109 }
          110 
          111 static Ndbtuple*
          112 doquery(int fd, char *dn, char *type)
          113 {
          114         char buf[1024];
          115         int n;
          116         Ndbtuple *t, *first, *last;
          117 
          118         seek(fd, 0, 0);
          119         snprint(buf, sizeof(buf), "!%s %s", dn, type);
          120         if(write(fd, buf, strlen(buf)) < 0)
          121                 return nil;
          122 
          123         seek(fd, 0, 0);
          124 
          125         first = last = nil;
          126 
          127         for(;;){
          128                 n = read(fd, buf, sizeof(buf)-2);
          129                 if(n <= 0)
          130                         break;
          131                 if(buf[n-1] != '\n')
          132                         buf[n++] = '\n';        /* ndbparsline needs a trailing new line */
          133                 buf[n] = 0;
          134 
          135                 /* check for the error condition */
          136                 if(buf[0] == '!'){
          137                         werrstr("%s", buf+1);
          138                         return nil;
          139                 }
          140 
          141                 t = _ndbparseline(buf);
          142                 if(t != nil){
          143                         if(first)
          144                                 last->entry = t;
          145                         else
          146                                 first = t;
          147                         last = t;
          148 
          149                         while(last->entry)
          150                                 last = last->entry;
          151                 }
          152         }
          153 
          154         setmalloctag(first, getcallerpc(&fd));
          155         return first;
          156 }