File: dns_ptodn.c

package info (click to toggle)
rbldnsd 0.998b~pre1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 744 kB
  • ctags: 1,132
  • sloc: ansic: 8,212; python: 549; sh: 502; makefile: 249; awk: 33
file content (62 lines) | stat: -rw-r--r-- 1,720 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* dns_ptodn() parses external textual dot-separated format
 * into a domain name
 */

#include "dns.h"
#include <errno.h>

unsigned dns_ptodn(const char *name, unsigned char *dn, unsigned dnsiz) {
  unsigned char *d;	/* current position in dn (len byte first) */
  unsigned char *label;	/* start of last label */
  unsigned char *m;	/* max byte can be filled up */
  unsigned l;		/* length of current label */
  unsigned c;		/* next input character */

  d = dn + 1;
  label = d;
  m = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz) - 1;

  while((c = (unsigned char)*name++) != 0) {
    if (c == '.') {
      if ((l = d - label) != 0) { /* if there was a non-empty label */
        if (l > DNS_MAXLABEL) {
          errno = EMSGSIZE;
          return 0;
        }
        label[-1] = (char)l; /* update len of last label */
        label = ++d; /* start new label, label[-1] will be len of it */
      }
      continue;
    }
    if (c == '\\') { /* handle escapes */
      if (!(c = (unsigned char)*name++))
        break;
      if (c >= '0' && c <= '9') { /* dec number: will be in c */
        c -= '0';
        if (*name >= '0' && *name <= '9') { /* 2digits */
          c = (c * 10) + (*name++ - '0');
          if (*name >= '0' && *name <= '9') { /* 3digits */
            c = (c * 10) + (*name++ - '0');
            if (c > 255) {
              errno = EINVAL;
              return 0;
            }
          }
        }
      }
    }
    if (d >= m) { /* too long? */
      errno = EMSGSIZE;
      return 0;
    }
    *d++ = (char)c; /* place next out byte */
  }

  if ((l = d - label) > DNS_MAXLABEL) {
    errno = EMSGSIZE;
    return 0;
  }
  if ((label[-1] = (char)l) != 0)
    *d++ = 0;
  return d - dn;
}