Index: trunk/configure.ac
===================================================================
--- trunk/configure.ac	(revision 3524)
+++ trunk/configure.ac	(working copy)
@@ -108,7 +108,7 @@
    if test `$PYTHON -c "import sys; \
        ver = sys.version.split()[[0]]; \
        print(ver >= '3.0.0')"` = "True"; then
-       AC_SUBST(SWIGPY3, [-py3])
+       AC_SUBST(SWIGPY3, ["-py3 -DPY3"])
    fi
 
    # check for swig
Index: trunk/contrib/python/ldns.i
===================================================================
--- trunk/contrib/python/ldns.i	(revision 3524)
+++ trunk/contrib/python/ldns.i	(working copy)
@@ -67,9 +67,14 @@
 %}
 
 //#define LDNS_DEBUG
+//#define SWIG_FILE3_DEBUG
 
 %include "stdint.i" // uint_16_t is known type now
+#ifdef PY3
+%include "file_py3.i" // python 3 FILE *
+#else
 %include "file.i"     // FILE * 
+#endif
 %include "typemaps.i"
 
 %inline %{
Index: trunk/contrib/python/file_py3.i
===================================================================
--- trunk/contrib/python/file_py3.i	(revision 0)
+++ trunk/contrib/python/file_py3.i	(revision 0)
@@ -0,0 +1,122 @@
+/*
+ * file_py3.i: Typemaps for FILE* for Python 3. Based on SWIG's file.i (See
+ * the COPYRIGHT file for a list of contributors to SWIG and their copyright
+ * notices.)
+ *
+ * Copyright (c) 2011, Karel Slany (karel.slany AT nic.cz)
+ *
+ * The redistribution and/or modification terms follow the SWIG licensing
+ * and distribution terms.
+ */
+
+%{
+#include <unistd.h>
+#include <fcntl.h>
+%}
+
+%types(FILE *);
+
+/* defining basic methods */
+
+%fragment("fdfl_to_str", "header") {
+const char *
+fdfl_to_str(int fdfl) {
+  static const char * const file_mode[] = {"w+", "w", "r"};
+
+  if (fdfl & O_RDWR) {
+    return file_mode[0];
+  } else if (fdfl & O_WRONLY) {
+    return file_mode[1];
+  } else {
+    return file_mode[2];
+  }
+}
+}
+
+%fragment("SWIG_AsValFilePtr","header", fragment="fdfl_to_str") {
+SWIGINTERN int
+SWIG_AsValFilePtr(PyObject *obj, FILE **val) {
+  static swig_type_info* desc = 0;
+  void *vptr = 0;
+  if (!desc) desc = SWIG_TypeQuery("FILE *");
+  if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) {
+    if (val) *val = (FILE *)vptr;
+    return SWIG_OK;
+  }
+%#if PY_VERSION_HEX >= 0x03000000
+  int fd, fdfl;
+  if (!PyLong_Check(obj) &&                                /* is not an integer */
+      PyObject_HasAttrString(obj, "fileno") &&             /* has fileno method */
+      (PyObject_CallMethod(obj, "flush", NULL) != NULL) && /* flush() succeeded */
+      ((fd = PyObject_AsFileDescriptor(obj)) != -1) &&     /* got file descriptor */
+      ((fdfl = fcntl(fd, F_GETFL)) != -1)                  /* got descriptor flags */
+    ) {
+    *val = fdopen(dup(fd), fdfl_to_str(fdfl)); /* the FILE* must be flushed
+                                                  and closed after being used */
+#ifdef SWIG_FILE3_DEBUG
+    fprintf(stderr, "opening fd %d (fl %d \"%s\") as FILE %p\n",
+            fd, fdfl, fdfl_to_str(fdfl), (void *)*val);
+#endif
+    return SWIG_OK;
+  }
+%#endif
+  return SWIG_TypeError;
+}
+}
+
+%fragment("SWIG_DisposeFilePtr", "header") {
+SWIGINTERN int
+SWIG_DisposeFilePtr(FILE **fp) {
+#ifdef SWIG_FILE3_DEBUG
+  fprintf(stderr, "flushing FILE %p\n", (void *)*fp);
+#endif
+  if (*fp == NULL) {
+    return SWIG_OK;
+  }
+  if ((fflush(*fp) == 0) && /* flush file */
+      (fclose(*fp) == 0)) { /* close file */
+    return SWIG_OK;
+  }
+
+  *fp = NULL;
+  return SWIG_IOError;
+}
+}
+
+%define %value_in_typemap_dispose(AsValMeth,AsValFrag,DisposeValMeth, DisposeValFrag, Type...)
+  %typemap(in,noblock=1,fragment=AsValFrag) Type (Type val = NULL, int ecode = 0) {
+    ecode = AsValMeth($input, &val);
+    if (!SWIG_IsOK(ecode)) {
+      %argument_fail(ecode, "$ltype", $symname, $argnum);
+    }
+    $1 = %static_cast(val,$ltype);
+  }
+  %typemap(freearg) Type "";
+  %typemap(in,noblock=1,fragment=AsValFrag) const Type & ($*ltype temp, Type val, int ecode = 0) {
+    ecode = AsValMeth($input, &val);
+    if (!SWIG_IsOK(ecode)) {
+      %argument_fail(ecode, "$*ltype", $symname, $argnum);
+    }
+    temp = %static_cast(val, $*ltype);
+    $1 = &temp;
+  }
+  %typemap(freearg) const Type& "";
+  /* TODO - the freearg typemap is not very advisable :( */
+  %typemap(freearg,noblock=1,fragment=DisposeValFrag) Type (int ecode = 0) {
+    ecode = DisposeValMeth(&val$argnum);
+    if (!SWIG_IsOK(ecode)) {
+       %argument_fail(ecode, "$*ltype", $symname, $argnum);
+    }
+  }
+%enddef
+
+%define %typemaps_asval_dispose(CheckCode, AsValMeth, AsValFrag, DisposeValMeth, DisposeValFrag, Type...)
+  %value_in_typemap_dispose(%arg(AsValMeth), %arg(AsValFrag), %arg(DisposeValMeth), %arg(DisposeValFrag), Type);
+  %value_varin_typemap(%arg(AsValMeth), %arg(AsValFrag), Type);
+  %value_directorout_typemap(%arg(AsValMeth), %arg(AsValFrag), Type);
+  %value_typecheck_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type);
+  %value_input_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type);
+%enddef
+
+/* defining the typemaps */
+%typemaps_asval_dispose(%checkcode(POINTER), SWIG_AsValFilePtr, "SWIG_AsValFilePtr", SWIG_DisposeFilePtr, "SWIG_DisposeFilePtr", FILE*);
Index: trunk/contrib/python/examples/python3/ldns-zone.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-zone.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-zone.py	(revision 0)
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+import ldns
+
+#Read zone from file
+zone = ldns.ldns_zone.new_frm_fp(open("../zone.txt","r"), None, 0, ldns.LDNS_RR_CLASS_IN)
+print(zone)
+
+print("SOA:", zone.soa())
+for r in zone.rrs().rrs():
+   print("RR:", r)
+
+
+zone = ldns.ldns_zone()
+#print zone
+

Property changes on: trunk/contrib/python/examples/python3/ldns-zone.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-buf.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-buf.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-buf.py	(revision 0)
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+
+import ldns
+
+buf = ldns.ldns_buffer(1024)
+buf.printf("Test buffer")
+print(buf)
+

Property changes on: trunk/contrib/python/examples/python3/ldns-buf.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-dnssec.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-dnssec.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-dnssec.py	(revision 0)
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import ldns
+import sys
+
+debug = True
+
+# Check args
+argc = len(sys.argv)
+name = "www.nic.cz"
+if argc < 2:
+   print("Usage:", sys.argv[0], "domain [resolver_addr]")
+   sys.exit(1)
+else:
+   name = sys.argv[1]
+
+# Create resolver
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+resolver.set_dnssec(True)
+
+# Custom resolver
+if argc > 2:
+   # Clear previous nameservers
+   ns = resolver.pop_nameserver()
+   while ns != None:
+      ns = resolver.pop_nameserver()
+   ip = ldns.ldns_rdf.new_frm_str(sys.argv[2], ldns.LDNS_RDF_TYPE_A)
+   resolver.push_nameserver(ip)
+
+# Resolve DNS name
+pkt = resolver.query(name, ldns.LDNS_RR_TYPE_A, ldns.LDNS_RR_CLASS_IN)
+if pkt and pkt.answer():
+
+   # Debug
+   if debug:
+      print("NS returned:", pkt.get_rcode(), "(AA: %d AD: %d)" % ( pkt.ad(), pkt.ad() ))
+
+   # SERVFAIL indicated bogus name
+   if pkt.get_rcode() is ldns.LDNS_RCODE_SERVFAIL:
+      print(name, "is bogus")
+
+   # Check AD (Authenticated) bit
+   if pkt.get_rcode() is ldns.LDNS_RCODE_NOERROR:
+      if pkt.ad(): print(name, "is secure")
+      else:        print(name, "is insecure")

Property changes on: trunk/contrib/python/examples/python3/ldns-dnssec.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py	(revision 0)
@@ -0,0 +1,12 @@
+import ldns
+import sys
+
+if len(sys.argv) <= 1:
+    print("Usage: %s zone_file" % sys.argv[0])
+    sys.exit()
+
+inp = open(sys.argv[1],"r");
+for rr in ldns.ldns_rr_iter_frm_fp_l(inp):
+  print(rr)
+
+inp.close()
Index: trunk/contrib/python/examples/python3/ldns-axfr.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-axfr.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-axfr.py	(revision 0)
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+# vim:fileencoding=utf-8
+#
+# AXFR client with IDN (Internationalized Domain Names) support
+#
+
+import ldns
+import encodings.idna
+
+def utf2name(name):
+    return '.'.join([encodings.idna.ToASCII(a).decode("utf-8") for a in name.split('.')])
+def name2utf(name):
+    return '.'.join([encodings.idna.ToUnicode(a) for a in name.split('.')])
+
+
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+
+#addr = ldns.ldns_get_rr_list_addr_by_name(resolver, "zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD);
+addr = resolver.get_addr_by_name("zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD);
+if (not addr):
+    raise Exception("Can't retrieve server address")
+
+print("Addr_by_name:",str(addr).replace("\n","; "))
+
+#remove all nameservers
+while resolver.pop_nameserver(): 
+    pass
+
+#insert server addr
+for rr in addr.rrs():
+    resolver.push_nameserver_rr(rr)
+
+#AXFR transfer
+status = resolver.axfr_start(utf2name("háčkyčárky.cz"), ldns.LDNS_RR_CLASS_IN)
+if status != ldns.LDNS_STATUS_OK:
+    raise Exception("Can't start AXFR. Error: %s" % ldns.ldns_get_errorstr_by_id(status))
+
+#Print results
+while True:
+    rr = resolver.axfr_next()
+    if not rr: 
+        break
+
+    rdf = rr.owner()
+    if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME):
+        print("RDF owner: type=",rdf.get_type_str(),"data=",name2utf(str(rdf)))
+    else:
+        print("RDF owner: type=",rdf.get_type_str(),"data=",str(rdf))
+    print("   RR type=", rr.get_type_str()," ttl=",rr.ttl())
+    for rdf in rr.rdfs():
+        if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME):
+            print("   RDF: type=",rdf.get_type_str(),"data=",name2utf(str(rdf)))
+        else:
+            print("   RDF: type=",rdf.get_type_str(),"data=",str(rdf))
+
+    print()

Property changes on: trunk/contrib/python/examples/python3/ldns-axfr.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-keygen.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-keygen.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-keygen.py	(revision 0)
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+#
+# This example shows how to generate public/private key pair
+#
+import ldns
+
+algorithm = ldns.LDNS_SIGN_DSA
+bits = 512
+
+ldns.ldns_init_random(open("/dev/random","rb"), (bits+7)//8)
+
+domain = ldns.ldns_dname("example.")
+
+#generate a new key
+key = ldns.ldns_key.new_frm_algorithm(algorithm, bits);
+print(key)
+
+#set owner
+key.set_pubkey_owner(domain)
+
+#create the public from the ldns_key
+pubkey = key.key_to_rr()
+#previous command is equivalent to
+# pubkey = ldns.ldns_key2rr(key)
+print(pubkey)
+
+#calculate and set the keytag
+key.set_keytag(ldns.ldns_calc_keytag(pubkey))
+
+#build the DS record
+ds = ldns.ldns_key_rr2ds(pubkey, ldns.LDNS_SHA1)
+print(ds)
+
+owner, tag = pubkey.owner(), key.keytag()
+
+#write public key to .key file
+fw = open("key-%s-%d.key" % (owner,tag), "wb")
+pubkey.print_to_file(fw)
+
+#write private key to .priv file
+fw = open("key-%s-%d.private" % (owner,tag), "wb")
+key.print_to_file(fw)
+
+#write DS to .ds file
+fw = open("key-%s-%d.ds" % (owner,tag), "wb")
+ds.print_to_file(fw)

Property changes on: trunk/contrib/python/examples/python3/ldns-keygen.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-mx.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-mx.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-mx.py	(revision 0)
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+#
+# MX is a small program that prints out the mx records for a particular domain
+#
+import ldns
+
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+
+pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN)
+
+if (pkt):
+    mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER)
+    if (mx):
+       mx.sort()
+       print(mx)

Property changes on: trunk/contrib/python/examples/python3/ldns-mx.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-mx1.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-mx1.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-mx1.py	(revision 0)
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+#
+# MX is a small program that prints out the mx records for a particular domain
+#
+import ldns
+
+dname = ldns.ldns_dname("nic.cz")
+print(dname)
+
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+
+pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN)
+
+if (pkt):
+    mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER)
+    if (mx):
+       mx.sort()
+       print(mx)

Property changes on: trunk/contrib/python/examples/python3/ldns-mx1.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py	(revision 0)
@@ -0,0 +1,43 @@
+import ldns
+import sys
+
+if len(sys.argv) <= 1:
+    print("Usage: %s zone_file" % sys.argv[0])
+    sys.exit()
+
+inp = open(sys.argv[1],"r");
+# variables that preserve the parsers state
+my_ttl = 3600;
+my_origin = None
+my_prev = None
+# additional state variables
+last_pos = 0
+line_nr = 0
+
+while True:
+    ret = ldns.ldns_rr_new_frm_fp_l_(inp, my_ttl, my_origin, my_prev)
+    s, rr, line_inc, new_ttl, new_origin, new_prev = ret  # unpack the result
+    line_nr += line_inc # increase number of parsed lines
+    my_prev = new_prev  # update ref to previous owner
+
+    if s == ldns.LDNS_STATUS_SYNTAX_TTL:
+        my_ttl = new_ttl  # update default TTL
+        print("$TTL:", my_ttl)
+    elif s == ldns.LDNS_STATUS_SYNTAX_ORIGIN:
+        my_origin = new_origin  # update reference to origin
+        print("$ORIGIN:", my_origin)
+    elif s == ldns.LDNS_STATUS_SYNTAX_EMPTY:
+        if last_pos == inp.tell():
+            break  # no advance since last read - EOF
+        last_pos = inp.tell()
+    elif s != ldns.LDNS_STATUS_OK:
+        print("! parse error in line", line_nr)
+    else:
+        # we are sure to have LDNS_STATUS_OK
+        print(rr)
+
+inp.close()
+print("--------------------")
+print("Read %d lines" % line_nr)
+    
+
Index: trunk/contrib/python/examples/python3/ldns-mx2.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-mx2.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-mx2.py	(revision 0)
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+#
+# MX is a small program that prints out the mx records for a particular domain
+#
+import ldns
+
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+
+pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN)
+if (pkt) and (pkt.answer()):
+
+    for rr in pkt.answer().rrs():
+        if (rr.get_type() != ldns.LDNS_RR_TYPE_MX):
+            continue
+
+        rdf = rr.owner()
+        print(rdf," ",rr.ttl()," ",rr.get_class_str()," ",rr.get_type_str()," ", end=" ")
+        print(" ".join(str(rdf) for rdf in rr.rdfs()))
+

Property changes on: trunk/contrib/python/examples/python3/ldns-mx2.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-higher.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-higher.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-higher.py	(revision 0)
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+import ldns
+
+resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
+
+dnn = ldns.ldns_dname("www.google.com")
+print(dnn.get_type_str(), dnn)
+
+dna = ldns.ldns_rdf.new_frm_str("74.125.43.99",ldns.LDNS_RDF_TYPE_A)
+print(dna.get_type_str(), dna)
+
+name = resolver.get_name_by_addr(dna)
+if (not name): raise Exception("Can't retrieve server name")
+for rr in name.rrs():
+    print(rr)
+
+name = resolver.get_name_by_addr("74.125.43.99")
+if (not name): raise Exception("Can't retrieve server name")
+for rr in name.rrs():
+    print(rr)
+
+addr = resolver.get_addr_by_name(dnn)
+if (not addr): raise Exception("Can't retrieve server address")
+for rr in addr.rrs():
+    print(rr)
+
+addr = resolver.get_addr_by_name("www.google.com")
+if (not addr): raise Exception("Can't retrieve server address")
+for rr in addr.rrs():
+    print(rr)
+
+hosts = ldns.ldns_rr_list.new_frm_file("/etc/hosts")
+if (not hosts): raise Exception("Can't retrieve the content of file")
+for rr in hosts.rrs():
+    print(rr)
+

Property changes on: trunk/contrib/python/examples/python3/ldns-higher.py
___________________________________________________________________
Added: svn:executable
   + *

Index: trunk/contrib/python/examples/python3/ldns-newpkt.py
===================================================================
--- trunk/contrib/python/examples/python3/ldns-newpkt.py	(revision 0)
+++ trunk/contrib/python/examples/python3/ldns-newpkt.py	(revision 0)
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import ldns
+
+pkt = ldns.ldns_pkt.new_query_frm_str("www.google.com",ldns.LDNS_RR_TYPE_ANY, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_QR | ldns.LDNS_AA)
+
+rra = ldns.ldns_rr.new_frm_str("www.google.com. IN A 192.168.1.1",300)
+rrb = ldns.ldns_rr.new_frm_str("www.google.com. IN TXT Some\ Description",300)
+
+list = ldns.ldns_rr_list()
+if (rra): list.push_rr(rra)
+if (rrb): list.push_rr(rrb)
+
+pkt.push_rr_list(ldns.LDNS_SECTION_ANSWER, list)
+
+print("Packet:")
+print(pkt)

Property changes on: trunk/contrib/python/examples/python3/ldns-newpkt.py
___________________________________________________________________
Added: svn:executable
   + *

