release
[hcoop/zz_old/debian/djbdns.git] / dns_dfd.c
CommitLineData
dc0d77d7
CE
1#include "error.h"
2#include "alloc.h"
3#include "byte.h"
4#include "dns.h"
5
6int dns_domain_fromdot(char **out,const char *buf,unsigned int n)
7{
8 char label[63];
9 unsigned int labellen = 0; /* <= sizeof label */
10 char name[255];
11 unsigned int namelen = 0; /* <= sizeof name */
12 char ch;
13 char *x;
14
15 errno = error_proto;
16
17 for (;;) {
18 if (!n) break;
19 ch = *buf++; --n;
20 if (ch == '.') {
21 if (labellen) {
22 if (namelen + labellen + 1 > sizeof name) return 0;
23 name[namelen++] = labellen;
24 byte_copy(name + namelen,labellen,label);
25 namelen += labellen;
26 labellen = 0;
27 }
28 continue;
29 }
30 if (ch == '\\') {
31 if (!n) break;
32 ch = *buf++; --n;
33 if ((ch >= '0') && (ch <= '7')) {
34 ch -= '0';
35 if (n && (*buf >= '0') && (*buf <= '7')) {
36 ch <<= 3;
37 ch += *buf - '0';
38 ++buf; --n;
39 if (n && (*buf >= '0') && (*buf <= '7')) {
40 ch <<= 3;
41 ch += *buf - '0';
42 ++buf; --n;
43 }
44 }
45 }
46 }
47 if (labellen >= sizeof label) return 0;
48 label[labellen++] = ch;
49 }
50
51 if (labellen) {
52 if (namelen + labellen + 1 > sizeof name) return 0;
53 name[namelen++] = labellen;
54 byte_copy(name + namelen,labellen,label);
55 namelen += labellen;
56 labellen = 0;
57 }
58
59 if (namelen + 1 > sizeof name) return 0;
60 name[namelen++] = 0;
61
62 x = alloc(namelen);
63 if (!x) return 0;
64 byte_copy(x,namelen,name);
65
66 if (*out) alloc_free(*out);
67 *out = x;
68 return 1;
69}