summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian>1999-04-11 19:42:06 +0000
committerian <ian>1999-04-11 19:42:06 +0000
commiteaa4473118b245a9dc1d806309eb70d4b2c6eaa4 (patch)
tree3baecbfeae97100fe65d2c1b2a00e201d921cdf5
parent44895c1bc9a7b214f5691df4d1c160810e356051 (diff)
Mailbox quoting seems to work.
-rw-r--r--regress/case-mailboxes.err0
-rw-r--r--regress/case-mailboxes.out9
-rw-r--r--regress/case-mailboxes.sys35
-rwxr-xr-xregress/dorecord17
-rw-r--r--src/adns.h2
-rw-r--r--src/internal.h9
-rw-r--r--src/parse.c20
-rw-r--r--src/types.c54
8 files changed, 138 insertions, 8 deletions
diff --git a/regress/case-mailboxes.err b/regress/case-mailboxes.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/regress/case-mailboxes.err
diff --git a/regress/case-mailboxes.out b/regress/case-mailboxes.out
new file mode 100644
index 0000000..ad5e633
--- /dev/null
+++ b/regress/case-mailboxes.out
@@ -0,0 +1,9 @@
+adns debug: using nameserver 172.18.45.6
+silly-rp.test.iwj.relativity.greenend.org.uk type 131089 RP(822) submitted
+silly-rp.test.iwj.relativity.greenend.org.uk type RP(822): OK; nrrs=6; cname=$; ttl=60
+ "<>" ""
+ "i@ucam.org" ""
+ "i.j@ucam.org" ""
+ "\x22i\\.\\.j\x22@ucam.org" ""
+ "\x22\\.i\x22@ucam.org" ""
+ "\x22i\\.\x22@ucam.org" ""
diff --git a/regress/case-mailboxes.sys b/regress/case-mailboxes.sys
new file mode 100644
index 0000000..2f60354
--- /dev/null
+++ b/regress/case-mailboxes.sys
@@ -0,0 +1,35 @@
+default
+:131089 silly-rp.test.iwj.relativity.greenend.org.uk
+ start 923859567.899146
+ socket type=SOCK_DGRAM
+ socket=4
+ +0.000411
+ fcntl fd=4 cmd=F_GETFL
+ fcntl=2
+ +0.000094
+ fcntl fd=4 cmd=F_SETFL 2050
+ fcntl=0
+ +0.000073
+ sendto fd=4 addr=172.18.45.6:53
+ 311f0100 00010000 00000000 0873696c 6c792d72 70047465 73740369 776a0a72
+ 656c6174 69766974 79086772 65656e65 6e64036f 72670275 6b000011 0001.
+ sendto=62
+ +0.000670
+ select max=5 rfds=[4] wfds=[] efds=[] to=1.999330
+ select=1 rfds=[4] wfds=[] efds=[]
+ +0.008169
+ recvfrom fd=4 buflen=512 *addrlen=16
+ recvfrom=OK addr=172.18.45.6:53
+ 311f8180 00010006 00000000 0873696c 6c792d72 70047465 73740369 776a0a72
+ 656c6174 69766974 79086772 65656e65 6e64036f 72670275 6b000011 0001c00c
+ 00110001 0000003c 00020000 c00c0011 00010000 003c000d 01690475 63616d03
+ 6f726700 00c00c00 11000100 00003c00 0703692e 6ac05a00 c00c0011 00010000
+ 003c0008 04692e2e 6ac05a00 c00c0011 00010000 003c0006 022e69c0 5a00c00c
+ 00110001 0000003c 00060269 2ec05a00.
+ +0.000992
+ recvfrom fd=4 buflen=512 *addrlen=16
+ recvfrom=EAGAIN
+ +0.000604
+ close fd=4
+ close=OK
+ +0.000359
diff --git a/regress/dorecord b/regress/dorecord
new file mode 100755
index 0000000..c636182
--- /dev/null
+++ b/regress/dorecord
@@ -0,0 +1,17 @@
+#!/bin/sh
+# usage: ./dorecord <casename> <initfile> <args>
+
+set -e
+casename="$1"; shift
+initfile="$1"; shift
+
+initstring="`cat \"init-$initfile.text\"`"
+
+exec 3>"case-$casename.sys"
+echo >&3 "$initfile"
+echo >&3 "$@"
+
+ADNS_TEST_OUT_FD=3
+export ADNS_TEST_OUT_FD
+
+./hrecord "/$initstring" "$@" 1>"case-$casename.out" 2>"case-$casename.err"
diff --git a/src/adns.h b/src/adns.h
index 9c011e5..32addba 100644
--- a/src/adns.h
+++ b/src/adns.h
@@ -89,7 +89,7 @@ typedef enum {
} adns_rrtype;
-/* In queries without qtf_anyquote, all domains must have standard
+/* In queries without qtf_quoteok_*, all domains must have standard
* legal syntax. In queries _with_ qtf_anyquote, domains in the query
* or response may contain any characters, quoted according to
* RFC1035 5.1. On input to adns, the char* is a pointer to the
diff --git a/src/internal.h b/src/internal.h
index 5e59a12..5e42ade 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -482,6 +482,15 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
* serv may be -1 and qu may be 0 - they are used for error reporting only.
*/
+adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads,
+ adns_query qu, vbuf *vb, parsedomain_flags flags,
+ const byte *dgram);
+/* Like adns__parse_domain, but you pass it a pre-initialised findlabel_state,
+ * for continuing an existing domain or some such of some kind. Also, unlike
+ * _parse_domain, the domain data will be appended to vb, rather than replacing
+ * the existing contents.
+ */
+
adns_status adns__findrr(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
int *type_r, int *class_r, unsigned long *ttl_r,
diff --git a/src/parse.c b/src/parse.c
index 842556a..5c4bdaf 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -117,18 +117,28 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
const byte *dgram, int dglen, int *cbyte_io, int max) {
findlabel_state fls;
- int lablen, labstart, i, ch;
- adns_status st;
-
adns__findlabel_start(&fls,ads, serv,qu, dgram,dglen,max, *cbyte_io,cbyte_io);
vb->used= 0;
+ return adns__parse_domain_more(&fls,ads,qu, vb,flags,dgram);
+}
+
+adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads,
+ adns_query qu, vbuf *vb, parsedomain_flags flags,
+ const byte *dgram) {
+ int lablen, labstart, i, ch, first;
+ adns_status st;
+
+ first= 1;
for (;;) {
- st= adns__findlabel_next(&fls,&lablen,&labstart);
+ st= adns__findlabel_next(fls,&lablen,&labstart);
if (st) return st;
if (lablen<0) { vb->used=0; return adns_s_ok; }
if (!lablen) break;
- if (vb->used)
+ if (first) {
+ first= 0;
+ } else {
if (!adns__vbuf_append(vb,".",1)) return adns_s_nomemory;
+ }
if (flags & pdf_quoteok) {
if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen))
return adns_s_nomemory;
diff --git a/src/types.c b/src/types.c
index deac6c4..e4e56f6 100644
--- a/src/types.c
+++ b/src/types.c
@@ -790,8 +790,58 @@ static adns_status pa_hinfo(const parseinfo *pai, int cbyte, int max, void *data
static adns_status pap_mailbox(const parseinfo *pai, int *cbyte_io, int max,
char **mb_r) {
- return pap_domain(pai, cbyte_io, max, mb_r, pdf_quoteok);
- /* fixme: mailbox quoting */
+ int lablen, labstart, i, needquote, c, r, neednorm;
+ const unsigned char *p;
+ char *str;
+ findlabel_state fls;
+ adns_status st;
+ vbuf *vb;
+
+ vb= &pai->qu->vb;
+ vb->used= 0;
+ adns__findlabel_start(&fls, pai->ads,
+ -1, pai->qu,
+ pai->dgram, pai->dglen, max,
+ *cbyte_io, cbyte_io);
+ st= adns__findlabel_next(&fls,&lablen,&labstart);
+ if (!lablen) {
+ adns__vbuf_appendstr(vb,"<>");
+ goto x_ok;
+ }
+
+ neednorm= 1;
+ for (i=0, needquote=0, p= pai->dgram+labstart; i<lablen; i++) {
+ c= *p++;
+ if ((c&~128) < 32 || (c&~128) == 127) return adns_s_invaliddata;
+ if (c == '.' && !neednorm) neednorm= 1;
+ else if (strchr("()<>@,;:\\\".[]",c)) needquote++;
+ else neednorm= 0;
+ }
+
+ if (needquote || neednorm) {
+ r= adns__vbuf_ensure(vb, lablen+needquote+4); if (!r) R_NOMEM;
+ adns__vbuf_appendq(vb,"\"",1);
+ for (i=0, needquote=0, p= pai->dgram+labstart; i<lablen; i++, p++) {
+ c= *p;
+ if (strchr("()<>@,;:\\\".[]",c)) adns__vbuf_appendq(vb,"\\",1);
+ adns__vbuf_appendq(vb,p,1);
+ }
+ adns__vbuf_appendq(vb,"\"",1);
+ } else {
+ r= adns__vbuf_append(vb, pai->dgram+labstart, lablen); if (!r) R_NOMEM;
+ }
+
+ r= adns__vbuf_appendstr(vb,"@"); if (!r) R_NOMEM;
+
+ st= adns__parse_domain_more(&fls,pai->ads, pai->qu,vb,0, pai->dgram);
+ if (st) return st;
+
+ x_ok:
+ str= adns__alloc_interim(pai->qu, vb->used+1); if (!str) R_NOMEM;
+ memcpy(str,vb->buf,vb->used);
+ str[vb->used]= 0;
+ *mb_r= str;
+ return adns_s_ok;
}
/*