summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ndb
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2013-11-24 11:55:26 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2013-11-24 11:55:26 +0100
commit3720b5ab9c4cb485c64e83d8af740aea3680123b (patch)
tree876c1111414a17e9867ddb9886dee94fc1b0e26c /sys/src/cmd/ndb
parent94fd92cb6903b7b1319d8f87bf6cdfd86c43b125 (diff)
ndb/dns: add support for internationalized domain names
Diffstat (limited to 'sys/src/cmd/ndb')
-rw-r--r--sys/src/cmd/ndb/dblookup.c97
-rw-r--r--sys/src/cmd/ndb/dn.c52
-rw-r--r--sys/src/cmd/ndb/dnresolve.c6
-rw-r--r--sys/src/cmd/ndb/dns.h5
-rw-r--r--sys/src/cmd/ndb/dnsdebug.c2
-rw-r--r--sys/src/cmd/ndb/idn.c262
-rw-r--r--sys/src/cmd/ndb/mkfile6
7 files changed, 370 insertions, 60 deletions
diff --git a/sys/src/cmd/ndb/dblookup.c b/sys/src/cmd/ndb/dblookup.c
index 5260f47af..50d9e367d 100644
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -103,8 +103,7 @@ RR*
dblookup(char *name, int class, int type, int auth, int ttl)
{
int err;
- char *wild;
- char buf[256];
+ char buf[Domlen], *wild;
RR *rp, *tp;
DN *dp, *ndp;
@@ -124,7 +123,7 @@ dblookup(char *name, int class, int type, int auth, int ttl)
}
lock(&dblock);
- dp = dnlookup(name, class, 1);
+ dp = idnlookup(name, class, 1);
if(opendatabase() < 0)
goto out;
@@ -142,7 +141,7 @@ dblookup(char *name, int class, int type, int auth, int ttl)
/* walk the domain name trying the wildcard '*' at each position */
for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
snprint(buf, sizeof buf, "*%s", wild);
- ndp = dnlookup(buf, class, 1);
+ ndp = idnlookup(buf, class, 1);
if(ndp->rr)
err = 0;
if(cfg.cachedb)
@@ -162,7 +161,7 @@ out:
* don't call it non-existent if it's not ours
* (unless we're a resolver).
*/
- if(err == Rname && (!inmyarea(name) || cfg.resolver))
+ if(err == Rname && (!inmyarea(dp->name) || cfg.resolver))
err = Rserver;
dp->respcode = err;
}
@@ -179,6 +178,18 @@ intval(Ndbtuple *entry, Ndbtuple *pair, char *attr, ulong def)
return (t? strtoul(t->val, 0, 10): def);
}
+static void
+mklowcase(char *cp)
+{
+ Rune r;
+
+ while(*cp != 0){
+ chartorune(&r, cp);
+ r = tolowerrune(r);
+ cp += runetochar(cp, &r);
+ }
+}
+
/*
* lookup an RR in the network database
*/
@@ -236,34 +247,43 @@ dblookup1(char *name, int type, int auth, int ttl)
case Tixfr:
return doaxfr(db, name);
default:
-// dnslog("dnlookup1(%s) bad type", name);
+// dnslog("dblookup1(%s) bad type", name);
return nil;
}
/*
* find a matching entry in the database
*/
- t = nil;
nstrcpy(dname, name, sizeof dname);
- free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
- if(t == nil && strchr(dname, '.') == nil)
- free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
- if(t == nil) {
- char *cp;
-
- /* try lower case */
- for(cp = dname; *cp; cp++)
- if(isupper(*cp)) {
- for(; *cp; cp++)
- *cp = tolower(*cp);
- free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
- if(t == nil && strchr(dname, '.') == nil)
- free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
- break;
+ for(x=0; x<4; x++){
+ switch(x){
+ case 1: /* try unicode */
+ if(idn2utf(name, dname, sizeof dname) == nil){
+ nstrcpy(dname, name, sizeof dname);
+ continue;
}
+ if(strcmp(name, dname) == 0)
+ continue;
+ break;
+ case 3: /* try ascii (lower case) */
+ if(utf2idn(name, dname, sizeof dname) == nil)
+ continue;
+ case 2:
+ mklowcase(dname);
+ if(strcmp(name, dname) == 0)
+ continue;
+ break;
+ }
+ t = nil;
+ free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
+ if(t == nil && strchr(dname, '.') == nil)
+ free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
+ if(t != nil)
+ break;
}
+
if(t == nil) {
-// dnslog("dnlookup1(%s) name not found", name);
+// dnslog("dblookup1(%s) name not found", name);
return nil;
}
@@ -303,7 +323,7 @@ dblookup1(char *name, int type, int auth, int ttl)
if(ttl)
rp->ttl = ttl;
if(dp == nil)
- dp = dnlookup(dname, Cin, 1);
+ dp = idnlookup(dname, Cin, 1);
rp->owner = dp;
*l = rp;
l = &rp->next;
@@ -323,14 +343,14 @@ dblookup1(char *name, int type, int auth, int ttl)
rp->ttl = ttl;
rp->auth = auth;
if(dp == nil)
- dp = dnlookup(dname, Cin, 1);
+ dp = idnlookup(dname, Cin, 1);
rp->owner = dp;
*l = rp;
l = &rp->next;
}
ndbfree(t);
-// dnslog("dnlookup1(%s) -> %#p", name, list);
+// dnslog("dblookup1(%s) -> %#p", name, list);
return list;
}
@@ -406,7 +426,7 @@ cnamerr(Ndbtuple *entry, Ndbtuple *pair)
USED(entry);
rp = rralloc(Tcname);
- rp->host = dnlookup(pair->val, Cin, 1);
+ rp->host = idnlookup(pair->val, Cin, 1);
return rp;
}
static RR*
@@ -415,7 +435,7 @@ mxrr(Ndbtuple *entry, Ndbtuple *pair)
RR *rp;
rp = rralloc(Tmx);
- rp->host = dnlookup(pair->val, Cin, 1);
+ rp->host = idnlookup(pair->val, Cin, 1);
rp->pref = intval(entry, pair, "pref", 1);
return rp;
}
@@ -426,7 +446,7 @@ nsrr(Ndbtuple *entry, Ndbtuple *pair)
Ndbtuple *t;
rp = rralloc(Tns);
- rp->host = dnlookup(pair->val, Cin, 1);
+ rp->host = idnlookup(pair->val, Cin, 1);
t = look(entry, pair, "soa");
if(t && t->val[0] == 0)
rp->local = 1;
@@ -466,7 +486,7 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
ns = look(entry, pair, "ns");
if(ns == nil)
ns = look(entry, pair, "dom");
- rp->host = dnlookup(ns->val, Cin, 1);
+ rp->host = idnlookup(ns->val, Cin, 1);
/* accept all of:
* mbox=person
@@ -481,15 +501,15 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
p = strchr(mb->val, '@');
if(p != nil)
*p = '.';
- rp->rmb = dnlookup(mb->val, Cin, 1);
+ rp->rmb = idnlookup(mb->val, Cin, 1);
} else {
snprint(mailbox, sizeof mailbox, "%s.%s",
mb->val, ns->val);
- rp->rmb = dnlookup(mailbox, Cin, 1);
+ rp->rmb = idnlookup(mailbox, Cin, 1);
}
else {
snprint(mailbox, sizeof mailbox, "postmaster.%s", ns->val);
- rp->rmb = dnlookup(mailbox, Cin, 1);
+ rp->rmb = idnlookup(mailbox, Cin, 1);
}
/*
@@ -509,7 +529,7 @@ srvrr(Ndbtuple *entry, Ndbtuple *pair)
RR *rp;
rp = rralloc(Tsrv);
- rp->host = dnlookup(pair->val, Cin, 1);
+ rp->host = idnlookup(pair->val, Cin, 1);
rp->srv->pri = intval(entry, pair, "pri", 0);
rp->srv->weight = intval(entry, pair, "weight", 0);
/* TODO: translate service name to port # */
@@ -624,7 +644,7 @@ dbtuple2cache(Ndbtuple *t)
for(et = t; et; et = et->entry)
if(strcmp(et->attr, "dom") == 0){
- dp = dnlookup(et->val, Cin, 1);
+ dp = idnlookup(et->val, Cin, 1);
/* first same line */
for(nt = et->line; nt != et; nt = nt->line){
@@ -787,9 +807,6 @@ lookupinfo(char *attr)
return t;
}
-char *localservers = "local#dns#servers";
-char *localserverprefix = "local#dns#server";
-
/*
* return non-zero if this is a bad delegation
*/
@@ -892,7 +909,7 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
/* ns record for name server, make up an impossible name */
rp = rralloc(Tns);
- snprint(buf, sizeof buf, "%s%d", localserverprefix, i);
+ snprint(buf, sizeof buf, "local#dns#server%d", i);
nsdp = dnlookup(buf, class, 1);
rp->host = nsdp;
rp->owner = dp; /* e.g., local#dns#servers */
@@ -932,7 +949,7 @@ dnsservers(int class)
RR *nsrp;
DN *dp;
- dp = dnlookup(localservers, class, 1);
+ dp = dnlookup("local#dns#servers", class, 1);
nsrp = rrlookup(dp, Tns, NOneg);
if(nsrp != nil)
return nsrp;
diff --git a/sys/src/cmd/ndb/dn.c b/sys/src/cmd/ndb/dn.c
index 0628f8ee5..08b86369f 100644
--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -224,6 +224,16 @@ dnlookup(char *name, int class, int enter)
return dp;
}
+DN*
+idnlookup(char *name, int class, int enter)
+{
+ char dom[Domlen];
+
+ if(utf2idn(name, dom, sizeof dom) != nil)
+ name = dom;
+ return dnlookup(name, class, enter);
+}
+
static int
rrsame(RR *rr1, RR *rr2)
{
@@ -1156,6 +1166,17 @@ dnname(DN *dn)
return dn? dn->name: "<null>";
}
+static char *
+idnname(DN *dn, char *buf, int nbuf)
+{
+ char *name;
+
+ name = dnname(dn);
+ if(idn2utf(name, buf, nbuf) != nil)
+ return buf;
+ return name;
+}
+
/*
* print conversion for rr records
*/
@@ -1287,7 +1308,7 @@ int
rravfmt(Fmt *f)
{
int rv, quote;
- char *strp;
+ char buf[Domlen], *strp;
Fmt fstr;
RR *rp;
Server *s;
@@ -1306,34 +1327,37 @@ rravfmt(Fmt *f)
if(rp->type == Tptr)
fmtprint(&fstr, "ptr=%s", dnname(rp->owner));
else
- fmtprint(&fstr, "dom=%s", dnname(rp->owner));
+ fmtprint(&fstr, "dom=%s", idnname(rp->owner, buf, sizeof(buf)));
switch(rp->type){
case Thinfo:
fmtprint(&fstr, " cpu=%s os=%s",
- dnname(rp->cpu), dnname(rp->os));
+ idnname(rp->cpu, buf, sizeof(buf)),
+ idnname(rp->os, buf, sizeof(buf)));
break;
case Tcname:
- fmtprint(&fstr, " cname=%s", dnname(rp->host));
+ fmtprint(&fstr, " cname=%s", idnname(rp->host, buf, sizeof(buf)));
break;
case Tmb:
case Tmd:
case Tmf:
- fmtprint(&fstr, " mbox=%s", dnname(rp->host));
+ fmtprint(&fstr, " mbox=%s", idnname(rp->host, buf, sizeof(buf)));
break;
case Tns:
- fmtprint(&fstr, " ns=%s", dnname(rp->host));
+ fmtprint(&fstr, " ns=%s", idnname(rp->host, buf, sizeof(buf)));
break;
case Tmg:
case Tmr:
- fmtprint(&fstr, " mbox=%s", dnname(rp->mb));
+ fmtprint(&fstr, " mbox=%s", idnname(rp->mb, buf, sizeof(buf)));
break;
case Tminfo:
fmtprint(&fstr, " mbox=%s mbox=%s",
- dnname(rp->mb), dnname(rp->rmb));
+ idnname(rp->mb, buf, sizeof(buf)),
+ idnname(rp->rmb, buf, sizeof(buf)));
break;
case Tmx:
- fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, dnname(rp->host));
+ fmtprint(&fstr, " pref=%lud mx=%s", rp->pref,
+ idnname(rp->host, buf, sizeof(buf)));
break;
case Ta:
case Taaaa:
@@ -1346,7 +1370,8 @@ rravfmt(Fmt *f)
soa = rp->soa;
fmtprint(&fstr,
" ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud",
- dnname(rp->host), dnname(rp->rmb),
+ idnname(rp->host, buf, sizeof(buf)),
+ idnname(rp->rmb, buf, sizeof(buf)),
(soa? soa->serial: 0),
(soa? soa->refresh: 0), (soa? soa->retry: 0),
(soa? soa->expire: 0), (soa? soa->minttl: 0));
@@ -1357,7 +1382,7 @@ rravfmt(Fmt *f)
srv = rp->srv;
fmtprint(&fstr, " pri=%ud weight=%ud port=%ud target=%s",
(srv? srv->pri: 0), (srv? srv->weight: 0),
- rp->port, dnname(rp->host));
+ rp->port, idnname(rp->host, buf, sizeof(buf)));
break;
case Tnull:
if (rp->null == nil)
@@ -1381,7 +1406,8 @@ rravfmt(Fmt *f)
break;
case Trp:
fmtprint(&fstr, " rp=%s txt=%s",
- dnname(rp->rmb), dnname(rp->rp));
+ idnname(rp->rmb, buf, sizeof(buf)),
+ idnname(rp->rp, buf, sizeof(buf)));
break;
case Tkey:
if (rp->key == nil)
@@ -1399,7 +1425,7 @@ rravfmt(Fmt *f)
" type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s",
rp->sig->type, rp->sig->alg, rp->sig->labels,
rp->sig->ttl, rp->sig->exp, rp->sig->incep,
- rp->sig->tag, dnname(rp->sig->signer));
+ rp->sig->tag, idnname(rp->sig->signer, buf, sizeof(buf)));
break;
case Tcert:
if (rp->cert == nil)
diff --git a/sys/src/cmd/ndb/dnresolve.c b/sys/src/cmd/ndb/dnresolve.c
index 7ca39619b..6d7be2291 100644
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -177,7 +177,7 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
* try the name directly
*/
rp = dnresolve1(name, class, type, req, depth, recurse);
- if(rp == nil && (dp = dnlookup(name, class, 0)) != nil) {
+ if(rp == nil && (dp = idnlookup(name, class, 0)) != nil) {
/*
* try it as a canonical name if we weren't told
* that the name didn't exist
@@ -348,7 +348,7 @@ issuequery(Query *qp, char *name, int class, int depth, int recurse)
}
/* look for ns in cache */
- nsdp = dnlookup(cp, class, 0);
+ nsdp = idnlookup(cp, class, 0);
nsrp = nil;
if(nsdp)
nsrp = randomize(rrlookup(nsdp, Tns, NOneg));
@@ -387,7 +387,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
if(class != Cin)
return nil;
- dp = dnlookup(name, class, 1);
+ dp = idnlookup(name, class, 1);
/*
* Try the cache first
diff --git a/sys/src/cmd/ndb/dns.h b/sys/src/cmd/ndb/dns.h
index 6f938c781..51feb5739 100644
--- a/sys/src/cmd/ndb/dns.h
+++ b/sys/src/cmd/ndb/dns.h
@@ -453,6 +453,7 @@ void dndump(char*);
void dnget(void);
void dninit(void);
DN* dnlookup(char*, int, int);
+DN* idnlookup(char*, int, int);
void dnptr(uchar*, uchar*, char*, int, int, int);
void dnpurge(void);
void dnput(void);
@@ -534,4 +535,8 @@ int convDNS2M(DNSmsg*, uchar*, int);
/* convM2DNS.c */
char* convM2DNS(uchar*, int, DNSmsg*, int*);
+/* idn.c */
+char* utf2idn(char *, char *, int);
+char* idn2utf(char *, char *, int);
+
#pragma varargck argpos dnslog 1
diff --git a/sys/src/cmd/ndb/dnsdebug.c b/sys/src/cmd/ndb/dnsdebug.c
index ee047a653..4ab24a85f 100644
--- a/sys/src/cmd/ndb/dnsdebug.c
+++ b/sys/src/cmd/ndb/dnsdebug.c
@@ -292,7 +292,7 @@ getdnsservers(int class)
rr = rralloc(Tns);
rr->owner = dnlookup("local#dns#servers", class, 1);
- rr->host = dnlookup(servername, class, 1);
+ rr->host = idnlookup(servername, class, 1);
return rr;
}
diff --git a/sys/src/cmd/ndb/idn.c b/sys/src/cmd/ndb/idn.c
new file mode 100644
index 000000000..46d421a45
--- /dev/null
+++ b/sys/src/cmd/ndb/idn.c
@@ -0,0 +1,262 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dns.h"
+
+enum {
+ base = 36,
+ tmin = 1,
+ tmax = 26,
+ skew = 38,
+ damp = 700,
+ initial_bias = 72,
+ initial_n = 0x80,
+};
+
+static uint maxint = ~0;
+
+static uint
+decode_digit(uint cp)
+{
+ if((cp - '0') < 10)
+ return cp - ('0' - 26);
+ if((cp - 'A') < 26)
+ return cp - 'A';
+ if((cp - 'a') < 26)
+ return cp - 'a';
+ return base;
+}
+
+static char
+encode_digit(uint d, int flag)
+{
+ if(d < 26)
+ return d + (flag ? 'A' : 'a');
+ return d + ('0' - 26);
+}
+
+static uint
+adapt(uint delta, uint numpoints, int firsttime)
+{
+ uint k;
+
+ delta = firsttime ? delta / damp : delta >> 1;
+ delta += delta / numpoints;
+ for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)
+ delta /= base - tmin;
+ return k + (base - tmin + 1) * delta / (delta + skew);
+}
+
+static int
+punyencode(uint input_length, Rune input[], uint max_out, char output[])
+{
+ uint n, delta, h, b, out, bias, j, m, q, k, t;
+
+ n = initial_n;
+ delta = out = 0;
+ bias = initial_bias;
+
+ for (j = 0; j < input_length; ++j) {
+ if ((uint)input[j] < 0x80) {
+ if (max_out - out < 2)
+ return -1;
+ output[out++] = input[j];
+ }
+ }
+
+ h = b = out;
+
+ if (b > 0)
+ output[out++] = '-';
+
+ while (h < input_length) {
+ for (m = maxint, j = 0; j < input_length; ++j) {
+ if (input[j] >= n && input[j] < m)
+ m = input[j];
+ }
+
+ if (m - n > (maxint - delta) / (h + 1))
+ return -1;
+
+ delta += (m - n) * (h + 1);
+ n = m;
+
+ for (j = 0; j < input_length; ++j) {
+ if (input[j] < n) {
+ if (++delta == 0)
+ return -1;
+ }
+
+ if (input[j] == n) {
+ for (q = delta, k = base;; k += base) {
+ if (out >= max_out)
+ return -1;
+ if (k <= bias)
+ t = tmin;
+ else if (k >= bias + tmax)
+ t = tmax;
+ else
+ t = k - bias;
+ if (q < t)
+ break;
+ output[out++] = encode_digit(t + (q - t) % (base - t), 0);
+ q = (q - t) / (base - t);
+ }
+ output[out++] = encode_digit(q, isupperrune(input[j]));
+ bias = adapt(delta, h + 1, h == b);
+ delta = 0;
+ ++h;
+ }
+ }
+
+ ++delta, ++n;
+ }
+
+ return (int)out;
+}
+
+static int
+punydecode(uint input_length, char input[], uint max_out, Rune output[])
+{
+ uint n, out, i, bias, b, j, in, oldi, w, k, digit, t;
+
+ n = initial_n;
+ out = i = 0;
+ bias = initial_bias;
+
+ for (b = j = 0; j < input_length; ++j)
+ if (input[j] == '-')
+ b = j;
+
+ if (b > max_out)
+ return -1;
+
+ for (j = 0; j < b; ++j) {
+ if (input[j] & 0x80)
+ return -1;
+ output[out++] = input[j];
+ }
+
+ for (in = b > 0 ? b + 1 : 0; in < input_length; ++out) {
+ for (oldi = i, w = 1, k = base;; k += base) {
+ if (in >= input_length)
+ return -1;
+ digit = decode_digit(input[in++]);
+ if (digit >= base)
+ return -1;
+ if (digit > (maxint - i) / w)
+ return -1;
+ i += digit * w;
+ if (k <= bias)
+ t = tmin;
+ else if (k >= bias + tmax)
+ t = tmax;
+ else
+ t = k - bias;
+ if (digit < t)
+ break;
+ if (w > maxint / (base - t))
+ return -1;
+ w *= (base - t);
+ }
+
+ bias = adapt(i - oldi, out + 1, oldi == 0);
+
+ if (i / (out + 1) > maxint - n)
+ return -1;
+ n += i / (out + 1);
+ i %= (out + 1);
+
+ if (out >= max_out)
+ return -1;
+
+ memmove(output + i + 1, output + i, (out - i) * sizeof *output);
+ if(((uint)input[in-1] - 'A') < 26)
+ output[i++] = toupperrune(n);
+ else
+ output[i++] = tolowerrune(n);
+ }
+
+ return (int)out;
+}
+
+/*
+ * convert punycode encoded internationalized
+ * domain name to unicode string
+ */
+char*
+idn2utf(char *name, char *buf, int nbuf)
+{
+ char *dp, *de, *cp;
+ Rune rb[Domlen], r;
+ int nc, nr, n;
+
+ cp = name;
+ dp = buf;
+ de = dp+nbuf-1;
+ for(;;){
+ nc = nr = 0;
+ while(cp[nc] != 0){
+ n = chartorune(&r, cp+nc);
+ if(r == '.')
+ break;
+ rb[nr++] = r;
+ nc += n;
+ }
+ if(cistrncmp(cp, "xn--", 4) == 0)
+ if((nr = punydecode(nc-4, cp+4, nelem(rb), rb)) < 0)
+ return nil;
+ dp = seprint(dp, de, "%.*S", nr, rb);
+ if(dp >= de)
+ return nil;
+ if(cp[nc] == 0)
+ break;
+ *dp++ = '.';
+ cp += nc+1;
+ }
+ *dp = 0;
+ return buf;
+}
+
+/*
+ * convert unicode string to punycode
+ * encoded internationalized domain name
+ */
+char*
+utf2idn(char *name, char *buf, int nbuf)
+{
+ char *dp, *de, *cp;
+ Rune rb[Domlen], r;
+ int nc, nr, n;
+
+ dp = buf;
+ de = dp+nbuf-1;
+ cp = name;
+ for(;;){
+ nc = nr = 0;
+ while(cp[nc] != 0 && nr < nelem(rb)){
+ n = chartorune(&r, cp+nc);
+ if(r == '.')
+ break;
+ rb[nr++] = r;
+ nc += n;
+ }
+ if(nc == nr)
+ dp = seprint(dp, de, "%.*s", nc, cp);
+ else {
+ dp = seprint(dp, de, "xn--");
+ if((n = punyencode(nr, rb, de - dp, dp)) < 0)
+ return nil;
+ dp += n;
+ }
+ if(dp >= de)
+ return nil;
+ if(cp[nc] == 0)
+ break;
+ *dp++ = '.';
+ cp += nc+1;
+ }
+ *dp = 0;
+ return buf;
+}
+
diff --git a/sys/src/cmd/ndb/mkfile b/sys/src/cmd/ndb/mkfile
index 1ec0dbdb8..2d00b81ae 100644
--- a/sys/src/cmd/ndb/mkfile
+++ b/sys/src/cmd/ndb/mkfile
@@ -17,13 +17,13 @@ TARG = \
DNSOBJ = dns.$O dnudpserver.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O dnnotify.$O\
- dnarea.$O convM2DNS.$O convDNS2M.$O # lock.$O coherence.$O
+ dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
DNSTCPOBJ = dnstcp.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
- dnarea.$O convM2DNS.$O convDNS2M.$O
+ dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
DNSDEBUGOBJ = dnsdebug.$O dn.$O dnresolve.$O dblookup.$O dnserver.$O\
- dnarea.$O convM2DNS.$O convDNS2M.$O
+ dnarea.$O convM2DNS.$O convDNS2M.$O idn.$O
HFILES = dns.h /$objtype/lib/libndb.a