summaryrefslogtreecommitdiff
path: root/src
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 /src
parent44895c1bc9a7b214f5691df4d1c160810e356051 (diff)
Mailbox quoting seems to work.
Diffstat (limited to 'src')
-rw-r--r--src/adns.h2
-rw-r--r--src/internal.h9
-rw-r--r--src/parse.c20
-rw-r--r--src/types.c54
4 files changed, 77 insertions, 8 deletions
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;
}
/*