コード例 #1
0
ファイル: dns_mx.c プロジェクト: darcyg/chaosircd
int dns_mx_packet(stralloc *out,const char *buf,unsigned int len)
{
  unsigned int pos;
  char header[12];
  char pref[2];
  uint16 numanswers;
  uint16 datalen;

  if (!stralloc_copys(out,"")) return -1;

  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1;
  uint16_unpack_big(header + 6,&numanswers);
  pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
  pos += 4;

  while (numanswers--) {
    pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
    pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1;
    uint16_unpack_big(header + 8,&datalen);
    if (byte_equal(header,2,DNS_T_MX))
      if (byte_equal(header + 2,2,DNS_C_IN)) {
	if (!dns_packet_copy(buf,len,pos,pref,2)) return -1;
	if (!dns_packet_getname(buf,len,pos + 2,&q)) return -1;
	if (!stralloc_catb(out,pref,2)) return -1;
	if (!dns_domain_todot_cat(out,q)) return -1;
	if (!stralloc_0(out)) return -1;
      }
    pos += datalen;
  }

  return 0;
}
コード例 #2
0
ファイル: dns_dpnd.c プロジェクト: gislik/djbdns-1.05g
int dns_domain_prependb2(char **out, const char *d, const char *s1, unsigned int n1, const char *s2, unsigned int n2) {
  static stralloc sa;
  if (!stralloc_copyb(&sa, s1, n1)) return 0;
  if (s2 && n2) if (!stralloc_catb(&sa, s2, n2)) return 0;
  if (!dns_domain_todot_cat(&sa, d)) return 0;
  if (!dns_domain_fromdot(out, sa.s, sa.len)) return 0;
  return 1;
}
コード例 #3
0
ファイル: dnsq.c プロジェクト: axlecrusher/djbdns
int main(int argc,char **argv)
{
  uint16 u16;

  dns_random_init(seed);

  if (!*argv) usage();
  if (!*++argv) usage();
  if (!parsetype(*argv,type)) usage();

  if (!*++argv) usage();
  if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops();

  if (!*++argv) usage();
  if (!stralloc_copys(&out,*argv)) oops();
  if (dns_ip6_qualify(&ip,&fqdn,&out) == -1) oops();
  if (ip.len >= 256) ip.len = 256;
  byte_zero(servers,256);
  byte_copy(servers,ip.len,ip.s);

  if (!stralloc_copys(&out,"")) oops();
  uint16_unpack_big(type,&u16);
  if (!stralloc_catulong0(&out,u16,0)) oops();
  if (!stralloc_cats(&out," ")) oops();
  if (!dns_domain_todot_cat(&out,q)) oops();
  if (!stralloc_cats(&out,":\n")) oops();

  if (resolve(q,type,servers) == -1) {
    if (!stralloc_cats(&out,error_str(errno))) oops();
    if (!stralloc_cats(&out,"\n")) oops();
  }
  else {
    if (!printpacket_cat(&out,tx.packet,tx.packetlen)) oops();
  }

  buffer_putflush(buffer_1,out.s,out.len);
  _exit(0);
}
コード例 #4
0
ファイル: tinydns-edit.c プロジェクト: axlecrusher/djbdns
int main(int argc,char **argv)
{
  unsigned long ttl;
  struct stat st;
  int i;
  int j;
  int k;
  char ch;

  if (!*argv) die_usage();

  if (!*++argv) die_usage();
  fn = *argv;

  if (!*++argv) die_usage();
  fnnew = *argv;

  if (!*++argv) die_usage();
  if (str_diff(*argv,"add")) die_usage();

  if (!*++argv) die_usage();
  if (str_equal(*argv,"ns")) mode = '.';
  else if (str_equal(*argv,"childns")) mode = '&';
  else if (str_equal(*argv,"host")) mode = '=';
  else if (str_equal(*argv,"host6")) mode = '6';
  else if (str_equal(*argv,"alias")) mode = '+';
  else if (str_equal(*argv,"alias6")) mode = '3';
  else if (str_equal(*argv,"mx")) mode = '@';
  else die_usage();

  if (!*++argv) die_usage();
  if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem();

  if (!*++argv) die_usage();
  if (mode == '6' || mode == '3') {
    if (!ip6_scan(*argv,targetip6)) die_usage();
  } else {
    if (!ip4_scan(*argv,targetip)) die_usage();
  }

  umask(077);

  fd = open_read(fn);
  if (fd == -1) die_read();
  if (fstat(fd,&st) == -1) die_read();
  buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);

  fdnew = open_trunc(fnnew);
  if (fdnew == -1) die_write();
  if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write();
  buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace);

  switch(mode) {
    case '.': case '&':
      ttl = TTL_NS;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".ns.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
    case '+': case '=': case '6': case '3':
      ttl = TTL_POSITIVE;
      break;
    case '@':
      ttl = TTL_POSITIVE;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".mx.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
  }

  while (match) {
    if (getln(&b,&line,&match,'\n') == -1) die_read();

    put(line.s,line.len);
    if (line.len && !match) put("\n",1);

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(mode) {
      case '.': case '&':
	if (line.s[0] == mode) {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".ns.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[3])) nomem();
	    if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;

      case '=':
	if (line.s[0] == '=') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip4_scan(f[1].s,ip))
	    if (byte_equal(ip,4,targetip))
	      strerr_die2x(100,FATAL,"IP address already used");
	}
	break;

      case '6':
	if (line.s[0] == '6') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip6_scan(f[1].s,ip6))
	    if (byte_equal(ip,16,targetip6))
	      strerr_die2x(100,FATAL,"IPv6 address already used");
	}
	break;

      case '@':
	if (line.s[0] == '@') {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".mx.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[4])) nomem();
	    if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;
    }
  }

  if (!stralloc_copyb(&f[0],&mode,1)) nomem();
  if (!dns_domain_todot_cat(&f[0],target)) nomem();
  if (!stralloc_cats(&f[0],":")) nomem();
  if (mode == '6' || mode == '3') {
    if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem();
  } else {
    if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem();
  }
  switch(mode) {
    case '.': case '&': case '@':
      for (i = 0;i < 26;++i)
	if (!used[i])
	  break;
      if (i >= 26)
	strerr_die2x(100,FATAL,"too many records for that domain");
      ch = 'a' + i;
      if (!stralloc_cats(&f[0],":")) nomem();
      if (!stralloc_catb(&f[0],&ch,1)) nomem();
      if (mode == '@')
        if (!stralloc_cats(&f[0],":")) nomem();
      break;
  }
  if (!stralloc_cats(&f[0],":")) nomem();
  if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem();
  if (!stralloc_cats(&f[0],"\n")) nomem();
  put(f[0].s,f[0].len);

  if (buffer_flush(&bnew) == -1) die_write();
  if (fsync(fdnew) == -1) die_write();
  if (close(fdnew) == -1) die_write(); /* NFS dorks */
  if (rename(fnnew,fn) == -1)
    strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": ");
  _exit(0);
}
コード例 #5
0
ファイル: tinydns-edit.c プロジェクト: LordSpacehog/ndjbdns
int
main (int argc, char *argv[])
{
    char ch = 0;
    struct stat st;
    unsigned long ttl = 0;
    unsigned i = 0, j = 0, k = 0;

    prog = strdup ((d1 = strrchr (argv[0], '/')) != NULL ? d1 + 1 : argv[0]);
    i = check_option (argc, argv);
    argv += i;
    argc -= i;
    d1 = NULL;

    if (argc < 6)
    {
        usage ();
        return -1;
    }

    fn = *argv;

    argv++;
    fnnew = *argv;

    argv++;
    if (str_diff (*argv, "add"))
    {
        usage ();
        return -1;
    }

    argv++;
    if (str_equal (*argv, "ns"))
        mode = '.';
    else if (str_equal (*argv, "childns"))
        mode = '&';
    else if (str_equal (*argv, "host"))
        mode = '=';
    else if (str_equal (*argv, "alias"))
        mode = '+';
    else if (str_equal (*argv, "mx"))
        mode = '@';
    else
        errx (-1, "invalid record type `%s'", *argv);

    argv++;
    if (!dns_domain_fromdot (&target, *argv, str_len (*argv)))
        err (-1, "could not allocate enough memory");

    argv++;
    if (!ip4_scan (*argv, targetip))
        errx (-1, "could not parse IP `%s'", *argv);

    umask(077);

    fd = open_read (fn);
    if (fd == -1)
        err (-1, "could not read from `%s'", fn);
    if (fstat (fd, &st) == -1)
        err (-1, "could not read from `%s'", fn);
    buffer_init (&b, buffer_unixread, fd, bspace, sizeof bspace);

    fdnew = open_trunc (fnnew);
    if (fdnew == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (fchmod (fdnew, st.st_mode & 0644) == -1)
        err (-1, "could not write to `%s'", fnnew);
    buffer_init (&bnew, buffer_unixwrite, fdnew, bnewspace, sizeof bnewspace);

    switch (mode)
    {
    case '.':
    case '&':
        ttl = TTL_NS;
        for (i = 0; i < 26; i++)
        {
            ch = 'a' + i;
            if (!stralloc_copyb (&f[0], &ch, 1))
                err (-1, "could not allocate enough memory");
            if (!stralloc_cats (&f[0], ".ns."))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_todot_cat (&f[0], target))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
        }
        break;

    case '+':
    case '=':
        ttl = TTL_POSITIVE;
        break;

    case '@':
        ttl = TTL_POSITIVE;
        for (i = 0; i < 26; i++)
        {
            ch = 'a' + i;
            if (!stralloc_copyb (&f[0], &ch, 1))
                err (-1, "could not allocate enough memory");
            if (!stralloc_cats (&f[0], ".mx."))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_todot_cat (&f[0], target))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
        }
        break;
    }

    while (match)
    {
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read from `%s'", fn);

        put (line.s, line.len);
        if (line.len && !match)
            put ("\n", 1);

        while (line.len)
        {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n'))
                break;

            --line.len;
        }
        if (!line.len || line.s[0] == '#')
            continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; i++)
        {
            if (j >= line.len)
            {
                if (!stralloc_copys (&f[i], ""))
                    err (-1, "could not allocate enough memory");
            }
            else
            {
                k = byte_chr (line.s + j, line.len - j, ':');
                if (!stralloc_copyb (&f[i], line.s + j, k))
                    err (-1, "could not allocate enough memory");
                j += k + 1;
            }
        }

        switch(mode)
        {
        case '.':
        case '&':
            if (line.s[0] == mode)
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                {
                    if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
                    {
                        if (!stralloc_cats (&f[2], ".ns."))
                            err (-1, "could not allocate enough memory");
                        if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                            err (-1, "could not allocate enough memory");
                    }
                    if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                        err (-1, "could not allocate enough memory");
                    if (!stralloc_0 (&f[3]))
                        err (-1, "could not allocate enough memory");
                    if (!scan_ulong (f[3].s, &ttl))
                        ttl = TTL_NS;
                    for (i = 0; i < 26; i++)
                    {
                        if (dns_domain_equal (d2, names[i]))
                        {
                            used[i] = 1;
                            break;
                        }
                    }
                }
            }
            break;

        case '=':
            if (line.s[0] == '=')
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                    errx (-1, "host name is already used");
                if (!stralloc_0 (&f[1]))
                    err (-1, "could not allocate enough memory");
                if (ip4_scan (f[1].s, ip))
                    if (byte_equal(ip, 4, targetip))
                        errx (-1, "IP address is already used");
            }
            break;

        case '@':
            if (line.s[0] == '@')
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                {
                    if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
                    {
                        if (!stralloc_cats (&f[2], ".mx."))
                            err (-1, "could not allocate enough memory");
                        if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                            err (-1, "could not allocate enough memory");
                    }
                    if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                        err (-1, "could not allocate enough memory");
                    if (!stralloc_0 (&f[4]))
                        err (-1, "could not allocate enough memory");
                    if (!scan_ulong (f[4].s, &ttl))
                        ttl = TTL_POSITIVE;
                    for (i = 0; i < 26; i++)
                    {
                        if (dns_domain_equal (d2, names[i]))
                        {
                            used[i] = 1;
                            break;
                        }
                    }
                }
            }
            break;
        }
    }

    if (!stralloc_copyb (&f[0], &mode, 1))
        err (-1, "could not allocate enough memory");
    if (!dns_domain_todot_cat (&f[0], target))
        err (-1, "could not allocate enough memory");
    if (!stralloc_cats (&f[0], ":"))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (&f[0], ipstr, ip4_fmt (ipstr, targetip)))
        err (-1, "could not allocate enough memory");

    switch (mode)
    {
    case '.':
    case '&':
    case '@':
        for (i = 0; i < 26; i++)
        {
            if (!used[i])
                break;
        }
        if (i >= 26)
            errx (-1, "too many records for domain `%s'", target);

        ch = 'a' + i;
        if (!stralloc_cats (&f[0], ":"))
            err (-1, "could not allocate enough memory");
        if (!stralloc_catb (&f[0], &ch, 1))
            err (-1, "could not allocate enough memory");
        if (mode == '@')
            if (!stralloc_cats (&f[0], ":"))
                err (-1, "could not allocate enough memory");

        break;
    }

    if (!stralloc_cats (&f[0], ":"))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (&f[0], strnum, fmt_ulong (strnum, ttl)))
        err (-1, "could not allocate enough memory");
    if (!stralloc_cats (&f[0], "\n"))
        err (-1, "could not allocate enough memory");
    put (f[0].s, f[0].len);

    if (buffer_flush (&bnew) == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (fsync (fdnew) == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (close (fdnew) == -1)
        err (-1, "could not write to `%s'", fnnew); /* NFS dorks */

    if (rename (fnnew, fn) == -1)
        err (-1, "could not move `%s' to `%s'", fnnew, fn);

    return 0;
}
コード例 #6
0
ファイル: dnstrace.c プロジェクト: axlecrusher/djbdns
void printdomain(const char *d)
{
  if (!stralloc_copys(&tmp,"")) nomem();
  if (!dns_domain_todot_cat(&tmp,d)) nomem();
  buffer_put(buffer_1,tmp.s,tmp.len);
}
コード例 #7
0
ファイル: dns_domain_todot.c プロジェクト: bruceg/bglibs
void testit(const char* data)
{
  str result = {0};
  debugstrfn(dns_domain_todot_cat(&result, data), &result);
}
コード例 #8
0
ファイル: printrecord.c プロジェクト: kjseefried/didentd
unsigned int printrecord_cat(stralloc *out,char *buf,unsigned int len,unsigned int pos,char *q,char qtype[2])
{
  char *x;
  char misc[20];
  uint16 datalen;
  uint16 u16;
  uint32 u32;
  unsigned int newpos;
  int i;
  unsigned char ch;

  pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
  pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0;
  uint16_unpack_big(misc + 8,&datalen);
  newpos = pos + datalen;

  if (q) {
    if (!dns_domain_equal(d,q))
      return newpos;
    if (byte_diff(qtype,2,misc) && byte_diff(qtype,2,DNS_T_ANY))
      return newpos;
  }

  if (!dns_domain_todot_cat(out,d)) return 0;
  if (!stralloc_cats(out," ")) return 0;
  uint32_unpack_big(misc + 4,&u32);
  if (!stralloc_catulong0(out,u32,0)) return 0;

  if (byte_diff(misc + 2,2,DNS_C_IN)) {
    if (!stralloc_cats(out," weird class\n")) return 0;
    return newpos;
  }

  x = 0;
  if (byte_equal(misc,2,DNS_T_NS)) x = " NS ";
  if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR ";
  if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME ";
  if (x) {
    pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
    if (!stralloc_cats(out,x)) return 0;
    if (!dns_domain_todot_cat(out,d)) return 0;
  }
  else if (byte_equal(misc,2,DNS_T_MX)) {
    if (!stralloc_cats(out," MX ")) return 0;
    pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0;
    pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
    uint16_unpack_big(misc,&u16);
    if (!stralloc_catulong0(out,u16,0)) return 0;
    if (!stralloc_cats(out," ")) return 0;
    if (!dns_domain_todot_cat(out,d)) return 0;
  }
  else if (byte_equal(misc,2,DNS_T_SOA)) {
    if (!stralloc_cats(out," SOA ")) return 0;
    pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
    if (!dns_domain_todot_cat(out,d)) return 0;
    if (!stralloc_cats(out," ")) return 0;
    pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
    if (!dns_domain_todot_cat(out,d)) return 0;
    pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0;
    for (i = 0;i < 5;++i) {
      if (!stralloc_cats(out," ")) return 0;
      uint32_unpack_big(misc + 4 * i,&u32);
      if (!stralloc_catulong0(out,u32,0)) return 0;
    }
  }
  else if (byte_equal(misc,2,DNS_T_A)) {
    if (datalen != 4) { errno = error_proto; return 0; }
    if (!stralloc_cats(out," A ")) return 0;
    pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0;
    for (i = 0;i < 4;++i) {
      ch = misc[i];
      if (i) if (!stralloc_cats(out,".")) return 0;
      if (!stralloc_catulong0(out,ch,0)) return 0;
    }
  }
  else if (byte_equal(misc,2,DNS_T_AAAA)) {
    char ip6str[IP6_FMT];
    int stringlen;
    if (datalen != 16) { errno = error_proto; return 0; }
    if (!stralloc_cats(out," AAAA ")) return 0;
    pos = dns_packet_copy(buf,len,pos,misc,16); if (!pos) return 0;
    stringlen=ip6_fmt(ip6str,misc);
    if (!stralloc_cats(out,ip6str)) return 0;
  }
  else {
    if (!stralloc_cats(out," ")) return 0;
    uint16_unpack_big(misc,&u16);
    if (!stralloc_catulong0(out,u16,0)) return 0;
    if (!stralloc_cats(out," ")) return 0;
    while (datalen--) {
      pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0;
      if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) {
        if (!stralloc_catb(out,misc,1)) return 0;
      }
      else {
        ch = misc[0];
        misc[3] = '0' + (7 & ch); ch >>= 3;
        misc[2] = '0' + (7 & ch); ch >>= 3;
        misc[1] = '0' + (7 & ch);
        misc[0] = '\\';
        if (!stralloc_catb(out,misc,4)) return 0;
      }
    }
  }

  if (!stralloc_cats(out,"\n")) return 0;
  if (pos != newpos) { errno = error_proto; return 0; }
  return newpos;
}