From b3ed4429d63d4966d1dfbe9783b3a3b9b2fdd348 Mon Sep 17 00:00:00 2001 From: Melinda Shore Date: Sun, 16 Jun 2013 17:50:14 -0800 Subject: [PATCH] Initial checkin Rough autoconf-ification of Paul's source. No changes to his code --- src/.deps/example_all_functions.Po | 1 + src/.deps/example_simple_answers.Po | 161 ++ src/.deps/example_synchronous.Po | 1 + src/.deps/example_tree.Po | 1 + src/Makefile.in | 50 + src/src/.DS_Store | Bin 0 -> 6148 bytes src/src/.deps/example_all_functions.Po | 1 + src/src/.deps/example_simple_answers.Po | 1 + src/src/.deps/example_synchronous.Po | 1 + src/src/.deps/example_tree.Po | 1 + src/src/AUTHORS | 0 src/src/COPYING | 1 + src/src/ChangeLog | 0 src/src/INSTALL | 365 ++++ src/src/Makefile.in | 67 + src/src/NEWS | 0 src/src/README | 0 src/src/aclocal.m4 | 951 ++++++++++ src/src/config.h.in | 104 ++ src/src/configure.ac | 31 + src/src/depcomp | 630 +++++++ src/src/example-all-functions.c | 297 +++ src/src/example-simple-answers.c | 99 + src/src/example-synchronous.c | 71 + src/src/example-tree.c | 138 ++ src/src/getdns_core_only.c | 403 +++++ src/src/getdns_core_only.h | 558 ++++++ src/src/getdns_libevent.h | 9 + src/src/index.html | 2182 +++++++++++++++++++++++ src/src/install-sh | 520 ++++++ src/src/make-examples-linux.sh | 22 + src/src/make-examples-mac.sh | 22 + src/src/missing | 376 ++++ 33 files changed, 7064 insertions(+) create mode 100644 src/.deps/example_all_functions.Po create mode 100644 src/.deps/example_simple_answers.Po create mode 100644 src/.deps/example_synchronous.Po create mode 100644 src/.deps/example_tree.Po create mode 100644 src/Makefile.in create mode 100644 src/src/.DS_Store create mode 100644 src/src/.deps/example_all_functions.Po create mode 100644 src/src/.deps/example_simple_answers.Po create mode 100644 src/src/.deps/example_synchronous.Po create mode 100644 src/src/.deps/example_tree.Po create mode 100644 src/src/AUTHORS create mode 120000 src/src/COPYING create mode 100644 src/src/ChangeLog create mode 100644 src/src/INSTALL create mode 100644 src/src/Makefile.in create mode 100644 src/src/NEWS create mode 100644 src/src/README create mode 100644 src/src/aclocal.m4 create mode 100644 src/src/config.h.in create mode 100644 src/src/configure.ac create mode 100755 src/src/depcomp create mode 100644 src/src/example-all-functions.c create mode 100644 src/src/example-simple-answers.c create mode 100644 src/src/example-synchronous.c create mode 100644 src/src/example-tree.c create mode 100644 src/src/getdns_core_only.c create mode 100644 src/src/getdns_core_only.h create mode 100644 src/src/getdns_libevent.h create mode 100644 src/src/index.html create mode 100755 src/src/install-sh create mode 100755 src/src/make-examples-linux.sh create mode 100755 src/src/make-examples-mac.sh create mode 100755 src/src/missing diff --git a/src/.deps/example_all_functions.Po b/src/.deps/example_all_functions.Po new file mode 100644 index 00000000..9ce06a81 --- /dev/null +++ b/src/.deps/example_all_functions.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/.deps/example_simple_answers.Po b/src/.deps/example_simple_answers.Po new file mode 100644 index 00000000..e2a083eb --- /dev/null +++ b/src/.deps/example_simple_answers.Po @@ -0,0 +1,161 @@ +example_simple_answers.o: example_simple_answers.c /usr/include/stdio.h \ + /usr/include/features.h /usr/include/i386-linux-gnu/bits/predefs.h \ + /usr/include/i386-linux-gnu/sys/cdefs.h \ + /usr/include/i386-linux-gnu/bits/wordsize.h \ + /usr/include/i386-linux-gnu/gnu/stubs.h \ + /usr/include/i386-linux-gnu/gnu/stubs-32.h \ + /usr/lib/gcc/i686-linux-gnu/4.6.1/include/stddef.h \ + /usr/include/i386-linux-gnu/bits/types.h \ + /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdarg.h \ + /usr/include/i386-linux-gnu/bits/stdio_lim.h \ + /usr/include/i386-linux-gnu/bits/sys_errlist.h \ + /usr/include/i386-linux-gnu/bits/stdio.h \ + /usr/include/i386-linux-gnu/bits/stdio2.h \ + /usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdint.h /usr/include/stdint.h \ + /usr/include/i386-linux-gnu/bits/wchar.h /usr/include/stdlib.h \ + /usr/include/i386-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/i386-linux-gnu/bits/string.h \ + /usr/include/i386-linux-gnu/bits/string2.h /usr/include/endian.h \ + /usr/include/i386-linux-gnu/bits/endian.h \ + /usr/include/i386-linux-gnu/bits/string3.h /usr/include/inttypes.h \ + getdns_libevent.h /usr/include/event2/event.h \ + /usr/include/event2/event-config.h \ + /usr/include/i386-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/i386-linux-gnu/sys/time.h \ + /usr/include/i386-linux-gnu/bits/time.h \ + /usr/include/i386-linux-gnu/sys/select.h \ + /usr/include/i386-linux-gnu/bits/select.h \ + /usr/include/i386-linux-gnu/bits/sigset.h /usr/include/event2/util.h \ + /usr/include/netdb.h /usr/include/netinet/in.h \ + /usr/include/i386-linux-gnu/sys/socket.h \ + /usr/include/i386-linux-gnu/sys/uio.h \ + /usr/include/i386-linux-gnu/bits/uio.h \ + /usr/include/i386-linux-gnu/bits/socket.h \ + /usr/include/i386-linux-gnu/bits/sockaddr.h \ + /usr/include/i386-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/i386-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/i386-linux-gnu/bits/socket2.h \ + /usr/include/i386-linux-gnu/bits/in.h \ + /usr/include/i386-linux-gnu/bits/byteswap.h \ + /usr/include/i386-linux-gnu/bits/netdb.h getdns_core_only.h \ + /usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdbool.h + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/i386-linux-gnu/bits/predefs.h: + +/usr/include/i386-linux-gnu/sys/cdefs.h: + +/usr/include/i386-linux-gnu/bits/wordsize.h: + +/usr/include/i386-linux-gnu/gnu/stubs.h: + +/usr/include/i386-linux-gnu/gnu/stubs-32.h: + +/usr/lib/gcc/i686-linux-gnu/4.6.1/include/stddef.h: + +/usr/include/i386-linux-gnu/bits/types.h: + +/usr/include/i386-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdarg.h: + +/usr/include/i386-linux-gnu/bits/stdio_lim.h: + +/usr/include/i386-linux-gnu/bits/sys_errlist.h: + +/usr/include/i386-linux-gnu/bits/stdio.h: + +/usr/include/i386-linux-gnu/bits/stdio2.h: + +/usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/i386-linux-gnu/bits/wchar.h: + +/usr/include/stdlib.h: + +/usr/include/i386-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/i386-linux-gnu/bits/string.h: + +/usr/include/i386-linux-gnu/bits/string2.h: + +/usr/include/endian.h: + +/usr/include/i386-linux-gnu/bits/endian.h: + +/usr/include/i386-linux-gnu/bits/string3.h: + +/usr/include/inttypes.h: + +getdns_libevent.h: + +/usr/include/event2/event.h: + +/usr/include/event2/event-config.h: + +/usr/include/i386-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/i386-linux-gnu/sys/time.h: + +/usr/include/i386-linux-gnu/bits/time.h: + +/usr/include/i386-linux-gnu/sys/select.h: + +/usr/include/i386-linux-gnu/bits/select.h: + +/usr/include/i386-linux-gnu/bits/sigset.h: + +/usr/include/event2/util.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/i386-linux-gnu/sys/socket.h: + +/usr/include/i386-linux-gnu/sys/uio.h: + +/usr/include/i386-linux-gnu/bits/uio.h: + +/usr/include/i386-linux-gnu/bits/socket.h: + +/usr/include/i386-linux-gnu/bits/sockaddr.h: + +/usr/include/i386-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/i386-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/i386-linux-gnu/bits/socket2.h: + +/usr/include/i386-linux-gnu/bits/in.h: + +/usr/include/i386-linux-gnu/bits/byteswap.h: + +/usr/include/i386-linux-gnu/bits/netdb.h: + +getdns_core_only.h: + +/usr/lib/gcc/i686-linux-gnu/4.6.1/include/stdbool.h: diff --git a/src/.deps/example_synchronous.Po b/src/.deps/example_synchronous.Po new file mode 100644 index 00000000..9ce06a81 --- /dev/null +++ b/src/.deps/example_synchronous.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/.deps/example_tree.Po b/src/.deps/example_tree.Po new file mode 100644 index 00000000..9ce06a81 --- /dev/null +++ b/src/.deps/example_tree.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 00000000..e57446c8 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,50 @@ +# +# @configure_input@ +# + + +package = @PACKAGE_NAME@ +version = @PACKAGE_VERSION@ +tarname = @PACKAGE_TARNAME@ +distdir = $(tarname)-$(version) + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +all clean getdns: + cd src && $(MAKE) $@ + +$(distdir): FORCE + mkdir -p $(distdir)/src + cp $(srcdir)/configure.ac $(distdir) + cp $(srcdir)/configure $(distdir) + cp $(srcdir)/Makefile.in $(distdir) + cp $(srcdir)/src/Makefile.in $(distdir)/src + +distcheck: $(distdir).tar.gz + gzip -cd $(distdir).tar.gz | tar xvf - + cd $(distdir) && ./configure + cd $(distdir) && $(MAKE) all + cd $(distdir) && $(MAKE) check + cd $(distdir) && $(MAKE) DESTDIR=$${PWD}/_inst install + cd $(distdir) && $(MAKE) DESTDIR=$${PWD}/_inst uninstall + @remaining="`find $${PWD}/$(distdir)/_inst -type f | wc -l`"; \ + if test "$${remaining}" -ne 0; then + echo "@@@ $${remaining} file(s) remaining in stage directory!"; \ + exit 1; \ + fi + cd $(distdir) && $(MAKE) clean + rm -rf $(distdir) + @echo "*** Package $(distdir).tar.gz is ready for distribution" + +Makefile: Makefile.in config.status + ./config.status $@ + +configure.status: configure + ./config.status --recheck + +.PHONY: all clean diff --git a/src/src/.DS_Store b/src/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/src/src/Makefile.in b/src/src/Makefile.in new file mode 100644 index 00000000..3c7cac18 --- /dev/null +++ b/src/src/Makefile.in @@ -0,0 +1,67 @@ +# +# @configure_input@ +# + +package = @PACKAGE_NAME@ +version = @PACKAGE_VERSION@ +tarname = @PACKAGE_TARNAME@ +distdir = $(tarname)-$(version) + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC=gcc +CFLAGS=-g -I. -std=c99 +LDFLAGS=-L. +LDLIBS=-levent_core -lgetdns +PROGRAMS=example-simple-answers example-tree example-all-functions example-synchronous + +# example-simple-answers.c example-tree.c +# example-all-functions.c example-synchronous.c getdns_core_only.c + +all: libgetdns example-simple-answers example-tree example-all-functions example-synchronous + +getdns_core_only.o: getdns_core_only.c + $(CC) -c -Wall -fPIC $(CFLAGS) $^ + +libgetdns: getdns_core_only.o + $(CC) -shared -o libgetdns.so $^ + +clean: + rm -f *.o $(PROGRAMS) libgetdns.so + +$(distdir): FORCE + mkdir -p $(distdir)/src + cp configure.ac $(distdir) + cp configure $(distdir) + cp Makefile.in $(distdir) + cp src/Makefile.in $(distdir)/src + +distcheck: $(distdir).tar.gz + gzip -cd $(distdir).tar.gz | tar xvf - + cd $(distdir) && ./configure + cd $(distdir) && $(MAKE) all + cd $(distdir) && $(MAKE) check + cd $(distdir) && $(MAKE) DESTDIR=$${PWD}/_inst install + cd $(distdir) && $(MAKE) DESTDIR=$${PWD}/_inst uninstall + @remaining="`find $${PWD}/$(distdir)/_inst -type f | wc -l`"; \ + if test "$${remaining}" -ne 0; then + echo "@@@ $${remaining} file(s) remaining in stage directory!"; \ + exit 1; \ + fi + cd $(distdir) && $(MAKE) clean + rm -rf $(distdir) + @echo "*** Package $(distdir).tar.gz is ready for distribution" + +Makefile: Makefile.in config.status + ./config.status $@ + +configure.status: configure + ./config.status --recheck + +.PHONY: clean + diff --git a/src/src/NEWS b/src/src/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/src/src/README b/src/src/README new file mode 100644 index 00000000..e69de29b diff --git a/src/src/aclocal.m4 b/src/src/aclocal.m4 new file mode 100644 index 00000000..1bc55f42 --- /dev/null +++ b/src/src/aclocal.m4 @@ -0,0 +1,951 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/src/src/config.h.in b/src/src/config.h.in new file mode 100644 index 00000000..fdd46fa3 --- /dev/null +++ b/src/src/config.h.in @@ -0,0 +1,104 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `event_core' library (-levent_core). */ +#undef HAVE_LIBEVENT_CORE + +/* Define to 1 if you have the `getdns' library (-lgetdns). */ +#undef HAVE_LIBGETDNS + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/src/src/configure.ac b/src/src/configure.ac new file mode 100644 index 00000000..18efae44 --- /dev/null +++ b/src/src/configure.ac @@ -0,0 +1,31 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. +# @configure_input@ +# + +AC_PREREQ([2.68]) +AC_INIT([getdns], [0.320], [melinda.shore@nomountain.net]) +AM_INIT_AUTOMAKE([getkey], [0.320]) +AC_CONFIG_SRCDIR([configure.ac]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC + +# Checks for libraries. +AC_CHECK_LIB([event_core], [event_base_new]) +AC_CHECK_LIB([getdns], [getdns_context_create]) + +# Checks for header files. +AC_CHECK_HEADERS([inttypes.h netinet/in.h stdint.h stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_TYPE_SIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/src/src/depcomp b/src/src/depcomp new file mode 100755 index 00000000..df8eea7e --- /dev/null +++ b/src/src/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/src/example-all-functions.c b/src/src/example-all-functions.c new file mode 100644 index 00000000..c4ad41c5 --- /dev/null +++ b/src/src/example-all-functions.c @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include +#include +#include + +#define UNUSED_PARAM(x) ((void)(x)) + +/* The return values */ +getdns_return_t retregular; +char * retcharstar; + +/* The args */ +bool boolarg; +char * charstararg; +getdns_callback_t callbackarg; +uint16_t regulararg; +uint16_t *regularptrarg; +getdns_transaction_t txidarg; +getdns_transaction_t * txidptrarg; + +getdns_data_type * datatypeptrarg; +struct getdns_bindata ** bindataptrarg; +struct getdns_dict * dictarg; +struct getdns_bindata * bindataarg; +struct getdns_list * listarg; +struct getdns_dict ** dictptrarg; +struct getdns_list ** listptrarg; + +size_t sizetarg; +size_t * sizetptrarg; +getdns_context_t contextarg = NULL; +uint8_t uint8arg; +uint16_t uint16arg; +uint32_t uint32arg; +uint8_t * uint8ptrarg; +uint16_t * uint16ptrarg; +uint32_t * uint32ptrarg; +void * arrayarg; +void allocfunctionarg(size_t foo) {UNUSED_PARAM(foo);} +void deallocfunctionarg(void* foo) {UNUSED_PARAM(foo);} +void setcallbackfunctionarg(struct getdns_context_t *foo1, uint16_t foo2) + {UNUSED_PARAM(foo1);UNUSED_PARAM(foo2);} + +int main() +{ + +retregular = getdns_general( + contextarg, + charstararg, + uint16arg, + dictarg, + arrayarg, + txidptrarg, + callbackarg +); + +retregular = getdns_address( + contextarg, + charstararg, + dictarg, + arrayarg, + txidptrarg, + callbackarg +); + +retregular = getdns_hostname( + contextarg, + dictarg, + dictarg, + arrayarg, + txidptrarg, + callbackarg +); + +retregular = getdns_service( + contextarg, + charstararg, + dictarg, + arrayarg, + txidptrarg, + callbackarg +); + +retregular = getdns_context_create( + &contextarg, + boolarg +); + +getdns_context_destroy( + contextarg +); + +retregular = getdns_cancel_callback( + contextarg, + txidarg +); + +retregular = getdns_general_sync( + contextarg, + charstararg, + uint16arg, + dictarg, + uint32ptrarg, + dictarg +); + +retregular = getdns_address_sync( + contextarg, + charstararg, + dictarg, + uint32ptrarg, + dictarg +); + +retregular = getdns_hostname_sync( + contextarg, + dictarg, + dictarg, + uint32ptrarg, + dictarg +); + +retregular = getdns_service_sync( + contextarg, + charstararg, + dictarg, + uint32ptrarg, + dictarg +); + +getdns_free_sync_request_memory( + dictarg +); + +retregular = getdns_list_get_length(listarg, sizetptrarg); +retregular = getdns_list_get_data_type(listarg, sizetarg, datatypeptrarg); +retregular = getdns_list_get_dict(listarg, sizetarg, dictptrarg); +retregular = getdns_list_get_list(listarg, sizetarg, listptrarg); +retregular = getdns_list_get_bindata(listarg, sizetarg, bindataptrarg); +retregular = getdns_list_get_int(listarg, sizetarg, uint32ptrarg); + +retregular = getdns_dict_get_names(dictarg, listptrarg); +retregular = getdns_dict_get_data_type(dictarg, charstararg, datatypeptrarg); +retregular = getdns_dict_get_dict(dictarg, charstararg, dictptrarg); +retregular = getdns_dict_get_list(dictarg, charstararg, listptrarg); +retregular = getdns_dict_get_bindata(dictarg, charstararg, bindataptrarg); +retregular = getdns_dict_get_int(dictarg, charstararg, uint32ptrarg); + +listarg = getdns_list_create(); +getdns_list_destroy(listarg); +retregular = getdns_list_set_dict(listarg, sizetarg, dictarg); +retregular = getdns_list_set_list(listarg, sizetarg, listarg); +retregular = getdns_list_set_bindata(listarg, sizetarg, bindataarg); +retregular = getdns_list_set_int(listarg, sizetarg, uint32arg); + +dictarg = getdns_dict_create(); +getdns_dict_destroy(dictarg); +retregular = getdns_dict_set_dict(dictarg, charstararg, dictarg); +retregular = getdns_dict_set_list(dictarg, charstararg, listarg); +retregular = getdns_dict_set_bindata(dictarg, charstararg, bindataarg); +retregular = getdns_dict_set_int(dictarg, charstararg, uint32arg); + +retcharstar = getdns_convert_fqdn_to_dns_name( + charstararg +); + +retcharstar = getdns_convert_dns_name_to_fqdn( + charstararg +); + +retcharstar = getdns_convert_ulabel_to_alabel( + charstararg +); + +retcharstar = getdns_convert_alabel_to_ulabel( + charstararg +); + +retregular = getdns_validate_dnssec( + bindataarg, + listarg, + listarg +); + +retcharstar = getdns_pretty_print_dict( + dictarg +); + +retcharstar = getdns_display_ip_address( + bindataarg +); + +retregular = getdns_context_set_context_update_callback( + contextarg, + setcallbackfunctionarg +); + +retregular = getdns_context_set_resolution_type( + contextarg, + regulararg +); + +retregular = getdns_context_set_namespaces( + contextarg, + sizetarg, + regularptrarg +); + +retregular = getdns_context_set_dns_transport( + contextarg, + regulararg +); + +retregular = getdns_context_set_limit_outstanding_queries( + contextarg, + uint16arg +); + +retregular = getdns_context_set_timeout( + contextarg, + uint16arg +); + +retregular = getdns_context_set_follow_redirects( + contextarg, + regulararg +); + +retregular = getdns_context_set_dns_root_servers( + contextarg, + listarg +); + +retregular = getdns_context_set_append_name( + contextarg, + regulararg +); + +retregular = getdns_context_set_suffix( + contextarg, + listarg +); + +retregular = getdns_context_set_dnssec_trust_anchors( + contextarg, + listarg +); + +retregular = getdns_context_set_dnssec_allowed_skew( + contextarg, + uint16arg +); + +retregular = getdns_context_set_stub_resolution( + contextarg, + listarg +); + +retregular = getdns_context_set_edns_maximum_udp_payload_size( + contextarg, + uint16arg +); + +retregular = getdns_context_set_edns_extended_rcode( + contextarg, + uint8arg +); + +retregular = getdns_context_set_edns_version( + contextarg, + uint8arg +); + +retregular = getdns_context_set_edns_do_bit( + contextarg, + uint8arg +); + +retregular = getdns_context_set_memory_allocator( + contextarg, + allocfunctionarg +); + +retregular = getdns_context_set_memory_deallocator( + contextarg, + deallocfunctionarg +); + +retregular = getdns_context_set_memory_reallocator( + contextarg, + deallocfunctionarg +); + +return(0); } /* End of main() */ diff --git a/src/src/example-simple-answers.c b/src/src/example-simple-answers.c new file mode 100644 index 00000000..031af9e2 --- /dev/null +++ b/src/src/example-simple-answers.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +#define UNUSED_PARAM(x) ((void)(x)) + +/* Set up the callback function, which will also do the processing of the results */ +void this_callbackfn(struct getdns_context_t *this_context, + uint16_t this_callback_type, + struct getdns_dict *this_response, + void *this_userarg, + getdns_transaction_t this_transaction_id) +{ + UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */ + UNUSED_PARAM(this_context); /* Not looking at the context for this example */ + getdns_return_t this_ret; /* Holder for all function returns */ + if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ + { + /* Be sure the search returned something */ + uint32_t * this_error = NULL; + this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error + if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + { + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + return; + } + struct getdns_list * just_the_addresses_ptr; + this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); + if (this_ret != GETDNS_RETURN_GOOD) // This check is really not needed, but prevents a compiler error under "pedantic" + { + fprintf(stderr, "Trying to get the answers failed: %d", this_ret); + return; + } + size_t * num_addresses_ptr = NULL; + this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + /* Go through each record */ + for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + { + struct getdns_dict * this_address; + this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error + /* Just print the address */ + struct getdns_bindata * this_address_data; + this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error + printf("The address is %s", getdns_display_ip_address(this_address_data)); + } + } + else if (this_callback_type == GETDNS_CALLBACK_CANCEL) + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + else + fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); +} + +int main() +{ + /* Create the DNS context for this call */ + struct getdns_context_t *this_context = NULL; + getdns_return_t context_create_return = getdns_context_create(&this_context, true); + if (context_create_return != GETDNS_RETURN_GOOD) + { + fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + return(GETDNS_RETURN_GENERIC_ERROR); + } + /* Create an event base and put it in the context using the unknown function name */ + struct event_base *this_event_base; + this_event_base = event_base_new(); + if (this_event_base == NULL) + { + fprintf(stderr, "Trying to create the event base failed."); + return(GETDNS_RETURN_GENERIC_ERROR); + } + (void)getdns_extension_set_libevent_base(this_context, this_event_base); + /* Set up the getdns call */ + const char * this_name = "www.example.com"; + char* this_userarg = "somestring"; // Could add things here to help identify this call + getdns_transaction_t this_transaction_id = 0; + + /* Make the call */ + getdns_return_t dns_request_return = getdns_address(this_context, this_name, + NULL, this_userarg, &this_transaction_id, this_callbackfn); + if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) + { + fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + return(GETDNS_RETURN_GENERIC_ERROR); + } + else + { + /* Call the event loop */ + int dispatch_return = event_base_dispatch(this_event_base); + UNUSED_PARAM(dispatch_return); + // TODO: check the return value above + } + /* Clean up */ + getdns_context_destroy(this_context); + /* Assuming we get here, leave gracefully */ + exit(EXIT_SUCCESS); +} diff --git a/src/src/example-synchronous.c b/src/src/example-synchronous.c new file mode 100644 index 00000000..513a3112 --- /dev/null +++ b/src/src/example-synchronous.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + getdns_return_t this_ret; /* Holder for all function returns */ + /* Create the DNS context for this call */ + struct getdns_context_t *this_context = NULL; + getdns_return_t context_create_return = getdns_context_create(&this_context, true); + if (context_create_return != GETDNS_RETURN_GOOD) + { + fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + return(GETDNS_RETURN_GENERIC_ERROR); + } + /* Set up the getdns_sync_request call */ + const char * this_name = "www.example.com"; + uint8_t this_request_type = GETDNS_RRTYPE_A; + /* Get the A and AAAA records */ + struct getdns_dict * this_extensions = getdns_dict_create(); + this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE); + if (this_ret != GETDNS_RETURN_GOOD) + { + fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d", this_ret); + return(GETDNS_RETURN_GENERIC_ERROR); + } + uint32_t this_response_length; + struct getdns_dict * this_response = NULL; + + /* Make the call */ + getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type, + this_extensions, &this_response_length, this_response); + if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) + { + fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + return(GETDNS_RETURN_GENERIC_ERROR); + } + else + { + /* Be sure the search returned something */ + uint32_t * this_error = NULL; + this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error + if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + { + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + return(GETDNS_RETURN_GENERIC_ERROR); + } + struct getdns_list * just_the_addresses_ptr; + this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); // Ignore any error + size_t * num_addresses_ptr = NULL; + this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + /* Go through each record */ + for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + { + struct getdns_dict * this_address; + this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error + /* Just print the address */ + struct getdns_bindata * this_address_data; + this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error + printf("The address is %s", getdns_display_ip_address(this_address_data)); + } + } + /* Clean up */ + getdns_context_destroy(this_context); + getdns_free_sync_request_memory(this_response); + /* Assuming we get here, leave gracefully */ + exit(EXIT_SUCCESS); +} diff --git a/src/src/example-tree.c b/src/src/example-tree.c new file mode 100644 index 00000000..9bda28ec --- /dev/null +++ b/src/src/example-tree.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include + +#define UNUSED_PARAM(x) ((void)(x)) + +/* Set up the callback function, which will also do the processing of the results */ +void this_callbackfn(struct getdns_context_t *this_context, + getdns_return_t this_callback_type, + struct getdns_dict *this_response, + void *this_userarg, + getdns_transaction_t this_transaction_id) +{ + UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */ + UNUSED_PARAM(this_context); /* Not looking at the context for this example */ + getdns_return_t this_ret; /* Holder for all function returns */ + if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ + { + /* Be sure the search returned something */ + uint32_t * this_error = NULL; + this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error + if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + { + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + return; + } + /* Find all the answers returned */ + struct getdns_list * these_answers; + this_ret = getdns_dict_get_list(this_response, "replies-tree", &these_answers); + if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) + { + fprintf(stderr, "Weird: the response had no error, but also no replies-tree. Exiting."); + return; + } + size_t * num_answers_ptr = NULL; + this_ret = getdns_list_get_length(these_answers, num_answers_ptr); + /* Go through each answer */ + for ( size_t rec_count = 0; rec_count <= *num_answers_ptr; ++rec_count ) + { + struct getdns_dict * this_record; + this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record); // Ignore any error + /* Get the answer section */ + struct getdns_list * this_answer; + this_ret = getdns_dict_get_list(this_record, "answer", &this_answer); // Ignore any error + /* Get each RR in the answer section */ + size_t * num_rrs_ptr = NULL; + this_ret = getdns_list_get_length(this_answer, num_rrs_ptr); + for ( size_t rr_count = 0; rr_count <= *num_rrs_ptr; ++rr_count ) + { + struct getdns_dict * this_rr = NULL; + this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr); // Ignore any error + /* Get the RDATA */ + struct getdns_dict * this_rdata = NULL; + this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error + /* Get the RDATA type */ + uint32_t * this_type = NULL; + this_ret = getdns_dict_get_int(this_rdata, "type", this_type); // Ignore any error + /* If it is type A or AAAA, print the value */ + if (*this_type == GETDNS_RRTYPE_A) + { + struct getdns_bindata * this_a_record = NULL; + this_ret = getdns_dict_get_bindata(this_rdata, "ipv4_address", &this_a_record); + if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) + { + fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.", + (int) rr_count, (int) rec_count); + return; + } + printf("The IPv4 address is %s", getdns_display_ip_address(this_a_record)); + } + else if (*this_type == GETDNS_RRTYPE_AAAA) + { + struct getdns_bindata * this_aaaa_record = NULL; + this_ret = getdns_dict_get_bindata(this_rdata, "ipv6_address", &this_aaaa_record); + if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) + { + fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.", + (int) rr_count, (int) rec_count); + return; + } + printf("The IPv6 address is %s", getdns_display_ip_address(this_aaaa_record)); + } + } + } + } + else if (this_callback_type == GETDNS_CALLBACK_CANCEL) + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + else + fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); +} + +int main() +{ + /* Create the DNS context for this call */ + struct getdns_context_t *this_context = NULL; + getdns_return_t context_create_return = getdns_context_create(&this_context, true); + if (context_create_return != GETDNS_RETURN_GOOD) + { + fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + return(GETDNS_RETURN_GENERIC_ERROR); + } + /* Create an event base and put it in the context using the unknown function name */ + struct event_base *this_event_base; + this_event_base = event_base_new(); + if (this_event_base == NULL) + { + fprintf(stderr, "Trying to create the event base failed."); + return(GETDNS_RETURN_GENERIC_ERROR); + } + (void)getdns_extension_set_libevent_base(this_context, this_event_base); + /* Set up the getdns call */ + const char * this_name = "www.example.com"; + char* this_userarg = "somestring"; // Could add things here to help identify this call + getdns_transaction_t this_transaction_id = 0; + + /* Make the call */ + getdns_return_t dns_request_return = getdns_address(this_context, this_name, + NULL, this_userarg, &this_transaction_id, this_callbackfn); + if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) + { + fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + return(GETDNS_RETURN_GENERIC_ERROR); + } + else + { + /* Call the event loop */ + int dispatch_return = event_base_dispatch(this_event_base); + UNUSED_PARAM(dispatch_return); + // TODO: check the return value above + } + /* Clean up */ + getdns_context_destroy(this_context); + /* Assuming we get here, leave gracefully */ + exit(EXIT_SUCCESS); +} diff --git a/src/src/getdns_core_only.c b/src/src/getdns_core_only.c new file mode 100644 index 00000000..60064440 --- /dev/null +++ b/src/src/getdns_core_only.c @@ -0,0 +1,403 @@ +#include + +/* stuff to make it compile pedantically */ +#define UNUSED_PARAM(x) ((void)(x)) + +int main(){ return(0); } + +/* Function definitions */ + +getdns_return_t +getdns_general( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callback +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(request_type); UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); +UNUSED_PARAM(transaction_id); UNUSED_PARAM(callback); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_address( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callback +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); +UNUSED_PARAM(transaction_id); UNUSED_PARAM(callback); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_hostname( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callback +) +{ UNUSED_PARAM(context); UNUSED_PARAM(address); UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); +UNUSED_PARAM(transaction_id); UNUSED_PARAM(callback); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_service( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callback +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); +UNUSED_PARAM(transaction_id); UNUSED_PARAM(callback); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_create( + getdns_context_t *context, + bool set_from_os +) +{ UNUSED_PARAM(context); UNUSED_PARAM(set_from_os); return GETDNS_RETURN_GOOD; } + +void +getdns_context_destroy( + getdns_context_t context +) +{ UNUSED_PARAM(context); } + +getdns_return_t +getdns_cancel_callback( + getdns_context_t context, + getdns_transaction_t transaction_id +) +{ UNUSED_PARAM(context); UNUSED_PARAM(transaction_id); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_general_sync( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(request_type); UNUSED_PARAM(extensions); +UNUSED_PARAM(response_length); UNUSED_PARAM(response); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_address_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(extensions); +UNUSED_PARAM(response_length); UNUSED_PARAM(response); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_hostname_sync( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +) +{ UNUSED_PARAM(context); UNUSED_PARAM(address); UNUSED_PARAM(extensions); +UNUSED_PARAM(response_length); UNUSED_PARAM(response); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_service_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +) +{ UNUSED_PARAM(context); UNUSED_PARAM(name); UNUSED_PARAM(extensions); +UNUSED_PARAM(response_length); UNUSED_PARAM(response); return GETDNS_RETURN_GOOD; } + +void +getdns_free_sync_request_memory( + struct getdns_dict *response +) +{ UNUSED_PARAM(response); } + +getdns_return_t getdns_list_get_length(struct getdns_list *this_list, size_t *answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_get_data_type(struct getdns_list *this_list, size_t index, getdns_data_type *answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index, struct getdns_dict **answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_get_list(struct getdns_list *this_list, size_t index, struct getdns_list **answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_get_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata **answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_get_int(struct getdns_list *this_list, size_t index, uint32_t *answer) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata **answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, uint32_t *answer) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } + +struct getdns_list * getdns_list_create() +{ return NULL; } + +void getdns_list_destroy(struct getdns_list *this_list) +{ UNUSED_PARAM(this_list); } + +getdns_return_t getdns_list_set_dict(struct getdns_list *this_list, size_t index, struct getdns_dict *child_dict) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(child_dict); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_set_list(struct getdns_list *this_list, size_t index, struct getdns_list *child_list) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(child_list); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_set_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata *child_bindata) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(child_bindata); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_list_set_int(struct getdns_list *this_list, size_t index, uint32_t child_uint32) +{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(child_uint32); return GETDNS_RETURN_GOOD; } + +struct getdns_dict * getdns_dict_create() +{ return NULL; } + +void getdns_dict_destroy(struct getdns_dict *this_dict) +{ UNUSED_PARAM(this_dict); } + +getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_dict); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_list); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_bindata); return GETDNS_RETURN_GOOD; } + +getdns_return_t getdns_dict_set_int(struct getdns_dict *this_dict, char *name, uint32_t child_uint32) +{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_uint32); return GETDNS_RETURN_GOOD; } + +char * +getdns_convert_dns_name_to_fqdn( + char *name_from_dns_response +) +{ UNUSED_PARAM(name_from_dns_response); return NULL; } + +char * +getdns_convert_fqdn_to_dns_name( + char *fqdn_as_string +) +{ UNUSED_PARAM(fqdn_as_string); return NULL; } + +char * +getdns_convert_ulabel_to_alabel( + char *ulabel +) +{ UNUSED_PARAM(ulabel); return NULL; } + +char * +getdns_convert_alabel_to_ulabel( + char *alabel +) +{ UNUSED_PARAM(alabel); return NULL; } + +getdns_return_t +getdns_validate_dnssec( + struct getdns_bindata *record_to_validate, + struct getdns_list *bundle_of_support_records, + struct getdns_list *trust_anchor_rdatas +) +{ UNUSED_PARAM(record_to_validate); UNUSED_PARAM(bundle_of_support_records); UNUSED_PARAM(trust_anchor_rdatas); +return GETDNS_RETURN_GOOD; } + + +char * +getdns_pretty_print_dict( + struct getdns_dict *some_dict +) +{ UNUSED_PARAM(some_dict); return NULL; } + +char * +getdns_display_ip_address( + struct getdns_bindata *bindata_of_ipv4_or_ipv6_address +) +{ UNUSED_PARAM(bindata_of_ipv4_or_ipv6_address); return NULL; } + +getdns_return_t +getdns_context_set_context_update_callback( + getdns_context_t context, + void (*value)(getdns_context_t context, uint16_t changed_item) +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_context_update( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_resolution_type( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_namespaces( + getdns_context_t context, + size_t namespace_count, + uint16_t *namespaces +) +{ UNUSED_PARAM(context); UNUSED_PARAM(namespace_count); UNUSED_PARAM(namespaces); +return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_dns_transport( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_limit_outstanding_queries( + getdns_context_t context, + uint16_t limit +) +{ UNUSED_PARAM(context); UNUSED_PARAM(limit); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_timeout( + getdns_context_t context, + uint16_t timeout +) +{ UNUSED_PARAM(context); UNUSED_PARAM(timeout); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_follow_redirects( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_dns_root_servers( + getdns_context_t context, + struct getdns_list *addresses +) +{ UNUSED_PARAM(context); UNUSED_PARAM(addresses); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_append_name( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_suffix( + getdns_context_t context, + struct getdns_list *value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_dnssec_trust_anchors( + getdns_context_t context, + struct getdns_list *value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_dnssec_allowed_skew( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_stub_resolution( + getdns_context_t context, + struct getdns_list *upstream_list +) +{ UNUSED_PARAM(context); UNUSED_PARAM(upstream_list); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_edns_maximum_udp_payload_size( + getdns_context_t context, + uint16_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_edns_extended_rcode( + getdns_context_t context, + uint8_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_edns_version( + getdns_context_t context, + uint8_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_edns_do_bit( + getdns_context_t context, + uint8_t value +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_memory_allocator( + getdns_context_t context, + void (*value)(size_t somesize) +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_memory_deallocator( + getdns_context_t context, + void (*value)(void*) +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_context_set_memory_reallocator( + getdns_context_t context, + void (*value)(void*) +) +{ UNUSED_PARAM(context); UNUSED_PARAM(value); return GETDNS_RETURN_GOOD; } + +getdns_return_t +getdns_extension_set_libevent_base( + getdns_context_t context, + struct event_base *this_event_base +) +{ UNUSED_PARAM(context); UNUSED_PARAM(this_event_base); return GETDNS_RETURN_GOOD; } + diff --git a/src/src/getdns_core_only.h b/src/src/getdns_core_only.h new file mode 100644 index 00000000..33d3bd32 --- /dev/null +++ b/src/src/getdns_core_only.h @@ -0,0 +1,558 @@ +/* Created at 2013-04-02-16-59-04*/ +#ifndef GETDNS_H +#define GETDNS_H + +#include +#include +#include +#include + +#define GETDNS_COMPILATION_COMMENT The API implementation should fill in something here, such as a compilation version string and date, and change it each time the API is compiled. + +/* Return values */ +#define GETDNS_RETURN_GOOD 0 +#define GETDNS_RETURN_GOOD_TEXT Good +#define GETDNS_RETURN_GENERIC_ERROR 1 +#define GETDNS_RETURN_GENERIC_ERROR_TEXT Generic error +#define GETDNS_RETURN_BAD_DOMAIN_NAME 300 +#define GETDNS_RETURN_BAD_DOMAIN_NAME_TEXT Badly-formed domain name in first argument +#define GETDNS_RETURN_BAD_CONTEXT 301 +#define GETDNS_RETURN_BAD_CONTEXT_TEXT Bad value for a context type +#define GETDNS_RETURN_CONTEXT_UPDATE_FAIL 302 +#define GETDNS_RETURN_CONTEXT_UPDATE_FAIL_TEXT Did not update the context +#define GETDNS_RETURN_UNKNOWN_TRANSACTION 303 +#define GETDNS_RETURN_UNKNOWN_TRANSACTION_TEXT An attempt was made to cancel a callback with a transaction_id that is not recognized +#define GETDNS_RETURN_NO_SUCH_LIST_ITEM 304 +#define GETDNS_RETURN_NO_SUCH_LIST_ITEM_TEXT A helper function for lists had an index argument that was too high. +#define GETDNS_RETURN_NO_SUCH_DICT_NAME 305 +#define GETDNS_RETURN_NO_SUCH_DICT_NAME_TEXT A helper function for dicts had a name argument that for a name that is not in the dict. +#define GETDNS_RETURN_WRONG_TYPE_REQUESTED 306 +#define GETDNS_RETURN_WRONG_TYPE_REQUESTED_TEXT A helper function was supposed to return a certain type for an item, but the wrong type was given. +#define GETDNS_RETURN_NO_SUCH_EXTENSION 307 +#define GETDNS_RETURN_NO_SUCH_EXTENSION_TEXT A name in the extensions dict is not a valid extension. +#define GETDNS_RETURN_EXTENSION_MISFORMAT 308 +#define GETDNS_RETURN_EXTENSION_MISFORMAT_TEXT One or more of the extensions is has a bad format. +#define GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED 309 +#define GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED_TEXT A query was made with a context that is using stub resolution and a DNSSEC extension specified. + +/* DNSSEC values */ +#define GETDNS_DNSSEC_SECURE 400 +#define GETDNS_DNSSEC_SECURE_TEXT The record was determined to be secure in DNSSEC +#define GETDNS_DNSSEC_BOGUS 401 +#define GETDNS_DNSSEC_BOGUS_TEXT The record was determined to be bogus in DNSSEC +#define GETDNS_DNSSEC_INDETERMINATE 402 +#define GETDNS_DNSSEC_INDETERMINATE_TEXT The record was not determined to be any state in DNSSEC +#define GETDNS_DNSSEC_INSECURE 403 +#define GETDNS_DNSSEC_INSECURE_TEXT The record was determined to be insecure in DNSSEC +#define GETDNS_DNSSEC_NOT_PERFORMED 404 +#define GETDNS_DNSSEC_NOT_PERFORMED_TEXT DNSSEC validation was not performed (only used for debugging) + +/* Context Variables */ +#define GETDNS_CONTEXT_NAMESPACE_DNS 500 +#define GETDNS_CONTEXT_NAMESPACE_DNS_TEXT See getdns_context_set_namespaces() +#define GETDNS_CONTEXT_NAMESPACE_LOCALNAMES 501 +#define GETDNS_CONTEXT_NAMESPACE_LOCALNAMES_TEXT See getdns_context_set_namespaces() +#define GETDNS_CONTEXT_NAMESPACE_NETBIOS 502 +#define GETDNS_CONTEXT_NAMESPACE_NETBIOS_TEXT See getdns_context_set_namespaces() +#define GETDNS_CONTEXT_NAMESPACE_MDNS 503 +#define GETDNS_CONTEXT_NAMESPACE_MDNS_TEXT See getdns_context_set_namespaces() +#define GETDNS_CONTEXT_NAMESPACE_NIS 504 +#define GETDNS_CONTEXT_NAMESPACE_NIS_TEXT See getdns_context_set_namespaces() +#define GETDNS_CONTEXT_STUB 505 +#define GETDNS_CONTEXT_STUB_TEXT See getdns_context_set_resolution_type() +#define GETDNS_CONTEXT_RECURSING 506 +#define GETDNS_CONTEXT_RECURSING_TEXT See getdns_context_set_resolution_type() +#define GETDNS_CONTEXT_FOLLOW_REDIRECTS 507 +#define GETDNS_CONTEXT_FOLLOW_REDIRECTS_TEXT See getdns_context_set_follow_redirects() +#define GETDNS_CONTEXT_DO_NOT_FOLLOW_REDIRECTS 508 +#define GETDNS_CONTEXT_DO_NOT_FOLLOW_REDIRECTS_TEXT See getdns_context_set_follow_redirects() +#define GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP 509 +#define GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP_TEXT See getdns_context_set_use_udp_tcp() +#define GETDNS_CONTEXT_UDP_ONLY 510 +#define GETDNS_CONTEXT_UDP_ONLY_TEXT See getdns_context_set_use_udp_tcp() +#define GETDNS_CONTEXT_TCP_ONLY 511 +#define GETDNS_CONTEXT_TCP_ONLY_TEXT See getdns_context_set_use_udp_tcp() +#define GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN 512 +#define GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT See getdns_context_set_use_udp_tcp() +#define GETDNS_CONTEXT_APPEND_NAME_ALWAYS 513 +#define GETDNS_CONTEXT_APPEND_NAME_ALWAYS_TEXT See getdns_context_set_append_name() +#define GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE 514 +#define GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE_TEXT See getdns_context_set_append_name() +#define GETDNS_CONTEXT_GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE 515 +#define GETDNS_CONTEXT_GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE_TEXT See getdns_context_set_append_name() +#define GETDNS_CONTEXT_DO_NOT_APPEND_NAMES 516 +#define GETDNS_CONTEXT_DO_NOT_APPEND_NAMES_TEXT See getdns_context_set_append_name() + +/* Context codes */ +#define GETDNS_CONTEXT_CODE_NAMESPACES 600 +#define GETDNS_CONTEXT_CODE_NAMESPACES_TEXT Change related to getdns_context_set_namespaces +#define GETDNS_CONTEXT_CODE_RESOLUTION_TYPE 601 +#define GETDNS_CONTEXT_CODE_RESOLUTION_TYPE_TEXT Change related to getdns_context_set_resolution_type +#define GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS 602 +#define GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS_TEXT Change related to getdns_context_set_follow_redirects +#define GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS 603 +#define GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS_TEXT Change related to getdns_context_set_upstream_recursive_servers +#define GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS 604 +#define GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS_TEXT Change related to getdns_context_set_dns_root_servers +#define GETDNS_CONTEXT_CODE_USE_UDP_TCP 605 +#define GETDNS_CONTEXT_CODE_USE_UDP_TCP_TEXT Change related to getdns_context_set_use_udp_tcp +#define GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES 606 +#define GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES_TEXT Change related to getdns_context_set_limit_outstanding_queries +#define GETDNS_CONTEXT_CODE_APPEND_NAME 607 +#define GETDNS_CONTEXT_CODE_APPEND_NAME_TEXT Change related to getdns_context_set_append_name +#define GETDNS_CONTEXT_CODE_SUFFIX 608 +#define GETDNS_CONTEXT_CODE_SUFFIX_TEXT Change related to getdns_context_set_suffix +#define GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS 609 +#define GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS_TEXT Change related to getdns_context_set_dnssec_trust_anchors +#define GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE 610 +#define GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE_TEXT Change related to getdns_context_set_edns_maximum_udp_payload_size +#define GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE 611 +#define GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE_TEXT Change related to getdns_context_set_edns_extended_rcode +#define GETDNS_CONTEXT_CODE_EDNS_VERSION 612 +#define GETDNS_CONTEXT_CODE_EDNS_VERSION_TEXT Change related to getdns_context_set_edns_version +#define GETDNS_CONTEXT_CODE_EDNS_DO_BIT 613 +#define GETDNS_CONTEXT_CODE_EDNS_DO_BIT_TEXT Change related to getdns_context_set_edns_do_bit +#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW 614 +#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT Change related to getdns_context_set_dnssec_allowed_skew +#define GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR 615 +#define GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR_TEXT Change related to getdns_context_set_memory_allocator +#define GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR 616 +#define GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR_TEXT Change related to getdns_context_set_memory_deallocator +#define GETDNS_CONTEXT_CODE_MEMORY_REALLOCATOR 617 +#define GETDNS_CONTEXT_CODE_MEMORY_REALLOCATOR_TEXT Change related to getdns_context_set_memory_reallocator + +/* Callback Type Variables */ +#define GETDNS_CALLBACK_COMPLETE 700 +#define GETDNS_CALLBACK_COMPLETE_TEXT The response has the requested data in it +#define GETDNS_CALLBACK_CANCEL 701 +#define GETDNS_CALLBACK_CANCEL_TEXT The calling program cancelled the callback; response is NULL +#define GETDNS_CALLBACK_TIMEOUT 702 +#define GETDNS_CALLBACK_TIMEOUT_TEXT The requested action timed out; response is NULL +#define GETDNS_CALLBACK_ERROR 703 +#define GETDNS_CALLBACK_ERROR_TEXT The requested action had an error; response is NULL + +/* Type Of Name Services */ +#define GETDNS_NAMETYPE_DNS 800 +#define GETDNS_NAMETYPE_DNS_TEXT Normal DNS (RFC 1035) +#define GETDNS_NAMETYPE_WINS 801 +#define GETDNS_NAMETYPE_WINS_TEXT The WINS name service (some reference needed) + +/* Status Codes for Responses */ +#define GETDNS_RESPSTATUS_GOOD 900 +#define GETDNS_RESPSTATUS_GOOD_TEXT At least one response was returned +#define GETDNS_RESPSTATUS_NO_NAME 901 +#define GETDNS_RESPSTATUS_NO_NAME_TEXT Queries for the name yielded all negative responses +#define GETDNS_RESPSTATUS_ALL_TIMEOUT 902 +#define GETDNS_RESPSTATUS_ALL_TIMEOUT_TEXT All queries for the name timed out +#define GETDNS_RESPSTATUS_NO_SECURE_ANSWERS 903 +#define GETDNS_RESPSTATUS_NO_SECURE_ANSWERS_TEXT The context setting for getting only secure responses was specified, and at least one DNS response was received, but no DNS response was determined to be secure through DNSSEC. + +/* Values Associated With Extensions */ +#define GETDNS_EXTENSION_TRUE 1000 +#define GETDNS_EXTENSION_TRUE_TEXT Turn on the extension +#define GETDNS_EXTENSION_FALSE 1001 +#define GETDNS_EXTENSION_FALSE_TEXT Do not turn on the extension + +/* Values Associated With DNS Errors Found By The API */ +#define GETDNS_BAD_DNS_CNAME_IN_TARGET 1100 +#define GETDNS_BAD_DNS_CNAME_IN_TARGET_TEXT A DNS query type that does not allow a target to be a CNAME pointed to a CNAME +#define GETDNS_BAD_DNS_ALL_NUMERIC_LABEL 1101 +#define GETDNS_BAD_DNS_ALL_NUMERIC_LABEL_TEXT One or more labels in a returned domain name is all-numeric; this is not legal for a hostname +#define GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE 1102 +#define GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE_TEXT A DNS query for a type other than CNAME returned a CNAME response + +/* Defines for RRtypes (from 2012-12) */ + +#define GETDNS_RRTYPE_A 1 +#define GETDNS_RRTYPE_NS 2 +#define GETDNS_RRTYPE_MD 3 +#define GETDNS_RRTYPE_MF 4 +#define GETDNS_RRTYPE_CNAME 5 +#define GETDNS_RRTYPE_SOA 6 +#define GETDNS_RRTYPE_MB 7 +#define GETDNS_RRTYPE_MG 8 +#define GETDNS_RRTYPE_MR 9 +#define GETDNS_RRTYPE_NULL 10 +#define GETDNS_RRTYPE_WKS 11 +#define GETDNS_RRTYPE_PTR 12 +#define GETDNS_RRTYPE_HINFO 13 +#define GETDNS_RRTYPE_MINFO 14 +#define GETDNS_RRTYPE_MX 15 +#define GETDNS_RRTYPE_TXT 16 +#define GETDNS_RRTYPE_RP 17 +#define GETDNS_RRTYPE_AFSDB 18 +#define GETDNS_RRTYPE_X25 19 +#define GETDNS_RRTYPE_ISDN 20 +#define GETDNS_RRTYPE_RT 21 +#define GETDNS_RRTYPE_NSAP 22 +#define GETDNS_RRTYPE_SIG 24 +#define GETDNS_RRTYPE_KEY 25 +#define GETDNS_RRTYPE_PX 26 +#define GETDNS_RRTYPE_GPOS 27 +#define GETDNS_RRTYPE_AAAA 28 +#define GETDNS_RRTYPE_LOC 29 +#define GETDNS_RRTYPE_NXT 30 +#define GETDNS_RRTYPE_EID 31 +#define GETDNS_RRTYPE_NIMLOC 32 +#define GETDNS_RRTYPE_SRV 33 +#define GETDNS_RRTYPE_ATMA 34 +#define GETDNS_RRTYPE_NAPTR 35 +#define GETDNS_RRTYPE_KX 36 +#define GETDNS_RRTYPE_CERT 37 +#define GETDNS_RRTYPE_A6 38 +#define GETDNS_RRTYPE_DNAME 39 +#define GETDNS_RRTYPE_SINK 40 +#define GETDNS_RRTYPE_OPT 41 +#define GETDNS_RRTYPE_APL 42 +#define GETDNS_RRTYPE_DS 43 +#define GETDNS_RRTYPE_SSHFP 44 +#define GETDNS_RRTYPE_IPSECKEY 45 +#define GETDNS_RRTYPE_RRSIG 46 +#define GETDNS_RRTYPE_NSEC 47 +#define GETDNS_RRTYPE_DNSKEY 48 +#define GETDNS_RRTYPE_DHCID 49 +#define GETDNS_RRTYPE_NSEC3 50 +#define GETDNS_RRTYPE_NSEC3PARAM 51 +#define GETDNS_RRTYPE_TLSA 52 +#define GETDNS_RRTYPE_HIP 55 +#define GETDNS_RRTYPE_NINFO 56 +#define GETDNS_RRTYPE_RKEY 57 +#define GETDNS_RRTYPE_TALINK 58 +#define GETDNS_RRTYPE_CDS 59 +#define GETDNS_RRTYPE_SPF 99 +#define GETDNS_RRTYPE_UINFO 100 +#define GETDNS_RRTYPE_UID 101 +#define GETDNS_RRTYPE_GID 102 +#define GETDNS_RRTYPE_UNSPEC 103 +#define GETDNS_RRTYPE_NID 104 +#define GETDNS_RRTYPE_L32 105 +#define GETDNS_RRTYPE_L64 106 +#define GETDNS_RRTYPE_LP 107 +#define GETDNS_RRTYPE_TKEY 249 +#define GETDNS_RRTYPE_TSIG 250 +#define GETDNS_RRTYPE_IXFR 251 +#define GETDNS_RRTYPE_AXFR 252 +#define GETDNS_RRTYPE_MAILB 253 +#define GETDNS_RRTYPE_MAILA 254 +#define GETDNS_RRTYPE_URI 256 +#define GETDNS_RRTYPE_CAA 257 +#define GETDNS_RRTYPE_TA 32768 +#define GETDNS_RRTYPE_DLV 32769 + +/* Various typedefs */ +typedef struct getdns_context_t *getdns_context_t; +typedef uint16_t getdns_return_t; +typedef uint64_t getdns_transaction_t; +typedef enum some_data_type { + t_dict, t_list, t_int, t_bindata +} getdns_data_type; +typedef struct getdns_bindata { + size_t size; + uint8_t *binary_stuff; +} some_bindata; +typedef struct getdns_dict some_dict; +typedef struct getdns_list some_list; + +/* Helper functions for data structures */ + +/* Lists: get the length, get the data_type of the value at a given + position, and get the data at a given position */ +getdns_return_t getdns_list_get_length(struct getdns_list *this_list, size_t *answer); +getdns_return_t getdns_list_get_data_type(struct getdns_list *this_list, size_t index, getdns_data_type *answer); +getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index, struct getdns_dict **answer); +getdns_return_t getdns_list_get_list(struct getdns_list *this_list, size_t index, struct getdns_list **answer); +getdns_return_t getdns_list_get_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata **answer); +getdns_return_t getdns_list_get_int(struct getdns_list *this_list, size_t index, uint32_t *answer); + +/* Dicts: get the list of names, get the data_type of the + value at a given name, and get the data at a given name */ +getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer); +getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer); +getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer); +getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer); +getdns_return_t getdns_dict_get_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata **answer); +getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, uint32_t *answer); + + +/* Lists: create, destroy, and set the data at a given position */ +struct getdns_list * getdns_list_create(); +void getdns_list_destroy(struct getdns_list *this_list); +getdns_return_t getdns_list_set_dict(struct getdns_list *this_list, size_t index, struct getdns_dict *child_dict); +getdns_return_t getdns_list_set_list(struct getdns_list *this_list, size_t index, struct getdns_list *child_list); +getdns_return_t getdns_list_set_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata *child_bindata); +getdns_return_t getdns_list_set_int(struct getdns_list *this_list, size_t index, uint32_t child_uint32); + +/* Dicts: create, destroy, and set the data at a given name */ +struct getdns_dict * getdns_dict_create(); +void getdns_dict_destroy(struct getdns_dict *this_dict); +getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict); +getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list); +getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata); +getdns_return_t getdns_dict_set_int(struct getdns_dict *this_dict, char *name, uint32_t child_uint32); + +/* Callback arguments */ +typedef void (*getdns_callback_t)( + getdns_context_t context, + uint16_t callback_type, + struct getdns_dict *response, + void *userarg, + getdns_transaction_t transaction_id); + +/* Function definitions */ + +getdns_return_t +getdns_general( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +getdns_return_t +getdns_address( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +getdns_return_t +getdns_hostname( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +getdns_return_t +getdns_service( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); + +getdns_return_t +getdns_context_create( + getdns_context_t *context, + bool set_from_os +); + +void +getdns_context_destroy( + getdns_context_t context +); + +getdns_return_t +getdns_cancel_callback( + getdns_context_t context, + getdns_transaction_t transaction_id +); + +getdns_return_t +getdns_general_sync( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); + +getdns_return_t +getdns_address_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); + +getdns_return_t +getdns_hostname_sync( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); + +getdns_return_t +getdns_service_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); + +void +getdns_free_sync_request_memory( + struct getdns_dict *response +); + +char * +getdns_convert_dns_name_to_fqdn( + char *name_from_dns_response +); + +char * +getdns_convert_fqdn_to_dns_name( + char *fqdn_as_string +); + +char * +getdns_convert_ulabel_to_alabel( + char *ulabel +); + +char * +getdns_convert_alabel_to_ulabel( + char *alabel +); + +getdns_return_t +getdns_validate_dnssec( + struct getdns_bindata *record_to_validate, + struct getdns_list *bundle_of_support_records, + struct getdns_list *trust_anchor_rdatas +); + +char * +getdns_pretty_print_dict( + struct getdns_dict *some_dict +); + +char * +getdns_display_ip_address( + struct getdns_bindata *bindata_of_ipv4_or_ipv6_address +); + +getdns_return_t +getdns_context_set_context_update_callback( + getdns_context_t context, + void (*value)(getdns_context_t context, uint16_t changed_item) +); + +getdns_return_t +getdns_context_set_resolution_type( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_namespaces( + getdns_context_t context, + size_t namespace_count, + uint16_t *namespaces +); + +getdns_return_t +getdns_context_set_dns_transport( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_limit_outstanding_queries( + getdns_context_t context, + uint16_t limit +); + +getdns_return_t +getdns_context_set_timeout( + getdns_context_t context, + uint16_t timeout +); + +getdns_return_t +getdns_context_set_follow_redirects( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_dns_root_servers( + getdns_context_t context, + struct getdns_list *addresses +); + +getdns_return_t +getdns_context_set_append_name( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_suffix( + getdns_context_t context, + struct getdns_list *value +); + +getdns_return_t +getdns_context_set_dnssec_trust_anchors( + getdns_context_t context, + struct getdns_list *value +); + +getdns_return_t +getdns_context_set_dnssec_allowed_skew( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_stub_resolution( + getdns_context_t context, + struct getdns_list *upstream_list +); + +getdns_return_t +getdns_context_set_edns_maximum_udp_payload_size( + getdns_context_t context, + uint16_t value +); + +getdns_return_t +getdns_context_set_edns_extended_rcode( + getdns_context_t context, + uint8_t value +); + +getdns_return_t +getdns_context_set_edns_version( + getdns_context_t context, + uint8_t value +); + +getdns_return_t +getdns_context_set_edns_do_bit( + getdns_context_t context, + uint8_t value +); + +getdns_return_t +getdns_context_set_memory_allocator( + getdns_context_t context, + void (*value)(size_t somesize) +); + +getdns_return_t +getdns_context_set_memory_deallocator( + getdns_context_t context, + void (*value)(void*) +); + +getdns_return_t +getdns_context_set_memory_reallocator( + getdns_context_t context, + void (*value)(void*) +); + +#endif /* GETDNS_H */ diff --git a/src/src/getdns_libevent.h b/src/src/getdns_libevent.h new file mode 100644 index 00000000..fd9effce --- /dev/null +++ b/src/src/getdns_libevent.h @@ -0,0 +1,9 @@ +#include +#include + +/* For libevent, which we are using for these examples */ +getdns_return_t +getdns_extension_set_libevent_base( + getdns_context_t context, + struct event_base *this_event_base +); diff --git a/src/src/index.html b/src/src/index.html new file mode 100644 index 00000000..99c6218c --- /dev/null +++ b/src/src/index.html @@ -0,0 +1,2182 @@ + +DNS API Description + + + + + +

Description of the getdns API

+

Paul Hoffman, Editor

+

Document version: "getdns April 2013"

+ +

This document describes a modern asynchronous DNS API. This new API is intended to be useful to +application developers and operating system distributors as a way of making +all types of DNS information easily available in many types of programs. The major features +of this new API are:

+ +
    +
  • Full support for event-driven programming
  • +
  • Supports DNSSEC in multiple ways
  • +
  • Mirroring of the resolution in getaddrinfo()
  • +
  • Easily supports all RRtypes, even those yet to be defined
  • +
+ +

There is more background into the design and future goals of this API +later in this document.

+ +

This document was discussed on the +getdns-api mailing list; future versions of the API might be discussed there as well. +(If you +want to contact the editor off-list, please send mail to paul.hoffman@vpnc.org.)

+ +

1. The getdns Async Functions

+ +

The API has four async functions:

+ +
    + +
  • getdns_address for doing getaddrinfo()-like address lookups
  • + +
  • getdns_hostname for doing getnameinfo()-like name lookups
  • + +
  • getdns_service for getting results from SRV lookups
  • + +
  • getdns_general for looking up any type of DNS record
  • + +
+ +

1.1 getdns_general()

+ +
getdns_return_t +getdns_general( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +
+ +

context

+

A pointer to the DNS context that is to be used with this call. DNS contexts are +described later in this document. Note that a context must be created +before calling the function.

+ +

*name

+

The ASCII-based domain name to be looked up as a string. This can also be +an IPv4 or IPv6 address for request types that take addresses instead of domain names, +such as PTR. The values here follow the rules in section 2.1 of RFC 4343 +to allow non-ASCII octets and special characters in labels.

+ +

request_type

+

Specifies the RRtype for the query; the RRtype numbers are listed in the IANA +registry. For example, to get the NS records, request_type would be 2. The API also has +defined macros for most of the RRtypes by name; the definition names all start with +"GETDNS_RRTYPE_". For example, to get the NS records, you can also set the +request_type to GETDNS_RRTYPE_NS. +(The full list of request types is always +here.)

+ +

*extensions

+

Specifies the extensions for this request; the value may be NULL if there are no +extensions. See the section below for information on how to specify +the extensions used for a request.

+ +

*userarg

+

A void* that is passed to the function, which the funciton +returns to the callback function untouched. userarg can be used by the callback +function for any user-specific data needed. This can be NULL.

+ +

*transaction_id

+

A pointer to a value that is filled in by the +function to identify the callback being made. +This pointer can be NULL, in which case it is ignored and no value is assigned. +The getdns_cancel_callback() function uses the +transaction_id to determine which callback is to be cancelled. +If the function fails, +transaction_id is set to 0.

+ +

*callbackfn

+

A pointer to a callback function that is defined by the application. +Typically, the callback function will do all the processing on the results from +the API. The parameters of the callback are defined below. This really needs +to be a pointer to a function (and not something like NULL); otherwise, the +results are unpredictable.

+ +

The async getdns functions return GETDNS_RETURN_GOOD if the call was properly formatted. +It returns GETDNS_RETURN_BAD_DOMAIN_NAME if the API determines that the name passed to +the function was bad, GETDNS_RETURN_BAD_CONTEXT if the context pointer is bad, +GETDNS_RETURN_NO_SUCH_EXTENSION if one or more extensions do not exist, or +GETDNS_RETURN_EXTENSION_MISFORMAT if the contents of one or more of the +extensions is incorrect. All of the return values are given later in this document.

+ +

1.2 getdns_address()

+ +
getdns_return_t +getdns_address( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +
+ +

There are three critical differences between getdns_address() and +getdns_general() beyond the missing request_type argument:

+ +
    + +
  • In getdns_address(), the name argument can only take a host name.
  • + +
  • You do not need to include a return_both_v4_and_v6 extension with the call in +getdns_address(): it will always return both IPv4 and IPv6 addresses.
  • + +
  • getdns_address() always uses all of namespaces from the context (to better emulate +getaddrinfo()), while getdns_general() only uses the DNS namespace.
  • + +
+ +

1.3 getdns_hostname()

+ +
getdns_return_t +getdns_hostname( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +
+ +

The address is given as a getdns_dict data structure (defined below). The list must +have two names: address_type (whose value is a bindata; it is currently either "IPv4" +or "IPv6") and address_data (whose value is a bindata).

+ +

1.4 getdns_service()

+ +
getdns_return_t +getdns_service( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callbackfn +); +
+ +

name must be a domain name for an SRV lookup; the call returns the +relevant SRV information for the name.

+ +

1.5 Callback Functions for getdns

+ +

A call to the async getdns functions typically returns before any network or file I/O occurs. After +the API marshalls all the needed information, it calls the callback function that was passed by the +application. The callback function might be called at any time, even before the calling function +has returned. The API guarantees that the callback will be called exactly once unless the calling function +returned an error, in which case the callback function is never called.

+ +

The getdns calling function calls the callback with the parameters defined +as follows:

+
+typedef void (*getdns_callback_t)( + getdns_context_t context, + uint16_t callback_type, + struct getdns_dict *response, + void *userarg, + getdns_transaction_t transaction_id); +
+ +

context

+

The DNS context that was used in the calling function. See below for a description of the basic use of contexts, and later for more advanced use.

+ +

callback_type

+

Supplies the reason for the callback. See below for the codes and reasons.

+ +

*response

+

A response object with the response data. This is described below. The response +object is part of the API's memory space, and will be freed by the API with the callback returns.

+ +

*userarg

+

Identical to the *userarg passed to the calling function.

+ +

transaction_id

+

The transaction identifier that was assigned by the calling function.

+ +

The following are the values for callback_type.

+ +

GETDNS_CALLBACK_COMPLETE

+

The response has the requested data in it

+

GETDNS_CALLBACK_CANCEL

+

The calling program cancelled the callback; response is NULL

+

GETDNS_CALLBACK_TIMEOUT

+

The requested action timed out; response is NULL

+

GETDNS_CALLBACK_ERROR

+

The requested action had an error; response is NULL

+ + +

1.6 Setting Up The DNS Context

+ +

Calls to getdns functions require a DNS context, which is a group of API settings +that affect how DNS calls are made. For most applications, a default context is sufficient.

+ +

To create a new DNS context, use the function:

+ +
getdns_return_t +getdns_context_create( + getdns_context_t *context, + bool set_from_os +); +
+ +

The call to getdns_context_create immediately returns a context that can +be used with other API calls; that context contains the API's default values. Most applications will +want set_from_os set to true.

+ +

To clean up the context, including cleaning up all outstanding transactions that were called +using this context, use the function:

+ +
void +getdns_context_destroy( + getdns_context_t context +); +
+ +

When getdns_context_destroy() returns, the +application knows that all outstanding transactions associated with this +context will have been called; callbacks that had not been called before +getdns_context_destroy() was called will be called with a callback_type of +GETDNS_CALLBACK_CANCEL. getdns_context_destroy() returns after +all of the needed cleanup is done and callbacks are made.

+ +

1.7 Canceling a Callback

+ +

To cancel an outstanding callback, use the following function.

+ +
getdns_return_t +getdns_cancel_callback( + getdns_context_t context, + getdns_transaction_t transaction_id +); +
+ +

This causes the API to call the callback with a callback_type of +GETDNS_CALLBACK_CANCEL if the callback for this transaction_id has not +already been called. The callback code for cancellation should clean up any memory related to the +identified call, such as to deallocate the memory for the userarg. +getdns_cancel_callback() may return immediately, even before the callback finishes its +work and returns. Calling getdns_cancel_callback() with a transaction_id +of a callback that has already been called or an unknown transaction_id returns +GETDNS_RETURN_UNKNOWN_TRANSACTION; otherwise, getdns_cancel_callback() +returns GETDNS_RETURN_GOOD.

+ +

1.8 Event-driven Programs

+ +

Event-driven programs (sometimes called "async programs") require an event +base and event loop (among other things). Different event libraries have +different structures or the event base. Because of this, there is no standard +method to set the event base in the DNS API: those are all added as +extensions. The API is distributed as a core package and one or more sets of +extensions to align with event libraries. It is mandatory to use one of the extension +functions to set the event base in the DNS context; this is required before +calling any event-driven calls like the getdns functions.

+ +

Each implementation of the DNS API will specify an extension function that +tells the DNS context which event base is being used. For example, one +implementation of this API that uses the libevent event library might name +this function "getdns_extension_set_libevent_base()" while +another might name it +"getdns_extension_set_eventbase_for_libevent()"; the two +extension functions could have very different calling patterns and return +values. Thus, the application developer must read the API documentation +(not just this design document) in order to determine what extension function +to use to tell the API the event base to use.

+ +

The structure of a typical event-driven application might look like the following pseudocode. +The code in italics is specific to the event mechanism.

+ +
+Includes for one or more regular C libraries
+An include for the getdns library specific to the event library you use
+Definition of your callback function
+    Get the DNS data from the allocated pointer
+    Process that data
+    Check for errors
+Definition of main()
+    Create context
+    Set up your event base
+    Point the context to your event base
+    Set up the getdns call arguments
+    Make the getdns call
+    Check if the getdns return is good
+    Destroy the context
+    Exit
+
+ +

The API does not have direct support for a polling interface. Instead, the callback interface is +specifically designed to allow an application that wants to process results in polling instead of in +callbacks to be able to create its own polling interface fairly trivially. Such a program would +create a data structure for the calls, including their transaction_id and +userag. The userarg could be the polling data structure or have a pointer to it. +The application would have just +one callback function for all requests, and that function would copy the response into +application memory, update the data structure based on the transaction_id index, +and return from the callback. The polling code could then check the data structure for any updates +at its leisure.

+ +

1.9 Calling the API Synchronously (Without Events)

+ +

Thare are functions parallel to the four getdns async functions, +except that there is no callback. That is, when an application calls one of these +synchronous functions, the +API gathers all the required information and then returns the result. The value returned is exactly the +same as the response returned in the callback if you had used the async version of the function.

+ +
getdns_return_t +getdns_general_sync( + getdns_context_t context, + const char *name, + uint16_t request_type, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); +
+ +
getdns_return_t +getdns_address_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); +
+ +
getdns_return_t +getdns_hostname_sync( + getdns_context_t context, + struct getdns_dict *address, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); +
+ +
getdns_return_t +getdns_service_sync( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + uint32_t *response_length, + struct getdns_dict *response +); +
+ +

When you are done with the data in the response, use the following function so that the API can +free the memory from its internal pool.

+ +
void +getdns_free_sync_request_memory( + struct getdns_dict *response +); +
+ +

2. Data structures in the API

+ +

The API returns data structures. The data structure is not a representational language like JSON: +it is really just a data structure. Data structures can have four types of members:

+ +
    + +
  • list is an ordered list, like JSON and Python lists. +The members of the list can be any of the four data types.
  • + +
  • dict is a name-value pair, like a JSON object or Python dict. The +name is a string literal, and the value can be any of the four data types. The order of the +name-value pairs in a dict is not important.
  • + +
  • int is an integer compatible with uint32_t.
  • + +
  • bindata is a struct to hold binary data. It is defined as +{ size_t size; uint8_t *binary_stuff; }.
  • + +
+ +

The API comes with helper functions to get data from the list and dict data types:

+ +
+/* Lists: get the length, get the data_type of the value at a given + position, and get the data at a given position */ +getdns_return_t getdns_list_get_length(struct getdns_list *this_list, size_t *answer); +getdns_return_t getdns_list_get_data_type(struct getdns_list *this_list, size_t index, getdns_data_type *answer); +getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index, struct getdns_dict **answer); +getdns_return_t getdns_list_get_list(struct getdns_list *this_list, size_t index, struct getdns_list **answer); +getdns_return_t getdns_list_get_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata **answer); +getdns_return_t getdns_list_get_int(struct getdns_list *this_list, size_t index, uint32_t *answer); + +/* Dicts: get the list of names, get the data_type of the + value at a given name, and get the data at a given name */ +getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer); +getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer); +getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer); +getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer); +getdns_return_t getdns_dict_get_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata **answer); +getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, uint32_t *answer); +
+ +

All of these helper getter functions return GETDNS_RETURN_GOOD if the call is successful. +The list functions will return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index argument is +out of range; the dict functions will return GETDNS_RETURN_NO_SUCH_DICT_NAME if the name +argument doesn't exist in the dict. The functions also return GETDNS_RETURN_WRONG_TYPE_REQUESTED +if the requested data type doesn't match the contents of the indexed argument or name.

+ +

This document uses graphical representations of data structures. It is important to note that +this is only a graphical representation; the brackets, commas, quotation marks, comments, and so on +are not part of the data. Also, this document uses macro names instead of some of the int +arguments; of course, the data structures have the actual int in them.

+ +

2.1 Creating Data Structures

+ +

Some of the features of the API require that you create your own data structures to be used in +arguments passed to the API. For example, if you want to use any extensions for the calling functions, +you need to create a dict. The requisite functions are:

+ +
+/* Lists: create, destroy, and set the data at a given position */ +struct getdns_list * getdns_list_create(); +void getdns_list_destroy(struct getdns_list *this_list); +getdns_return_t getdns_list_set_dict(struct getdns_list *this_list, size_t index, struct getdns_dict *child_dict); +getdns_return_t getdns_list_set_list(struct getdns_list *this_list, size_t index, struct getdns_list *child_list); +getdns_return_t getdns_list_set_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata *child_bindata); +getdns_return_t getdns_list_set_int(struct getdns_list *this_list, size_t index, uint32_t child_uint32); + +/* Dicts: create, destroy, and set the data at a given name */ +struct getdns_dict * getdns_dict_create(); +void getdns_dict_destroy(struct getdns_dict *this_dict); +getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict); +getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list); +getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata); +getdns_return_t getdns_dict_set_int(struct getdns_dict *this_dict, char *name, uint32_t child_uint32); +
+ +

These helper setter functions return GETDNS_RETURN_GOOD if the call is successful. +The list functions will return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index argument is +out of range; the dict functions will return GETDNS_RETURN_NO_SUCH_DICT_NAME if the name +argument doesn't exist in the dict. The functions also return GETDNS_RETURN_WRONG_TYPE_REQUESTED +if the requested data type doesn't match the contents of the indexed argument or name.

+ +

3. Extensions

+ +

Extensions are dict data structures. The names in the dict are the names of the extensions. +The definition of each extension describes the value associated with the name. For most extensions, +it is an on-off boolean, and the value is GETDNS_EXTENSION_TRUE. (There is +not currently a good reason to specify an extension name and give it a value of GETDNS_EXTENSION_FALSE, +but that is allowed by the API.)

+ +

For example, to create a dict for extensions and specify the extension to only return +results that have been validated with DNSSEC, you might use:

+ +
+/* . . . */
+struct getdns_dict * this_extensions = getdns_dict_create();
+this_ret = getdns_dict_set_int(this_extensions, "dnssec_return_only_secure", GETDNS_EXTENSION_TRUE);
+/* . . . Do some processing with the extensions and results . . . */
+/* Remember to clean up memory*/
+getdns_dict_destroy(this_extensions);
+
+ +

The extensions described in this section are are: + +

    + +
  • dnssec_return_status
  • + +
  • dnssec_return_only_secure
  • + +
  • dnssec_return_supporting_responses
  • + +
  • return_both_v4_and_v6
  • + +
  • add_opt_parameters
  • + +
  • add_warning_for_bad_dns
  • + +
  • specify_class
  • + +
  • return_api_information
  • + +
  • return_call_debugging
  • + +
+ +

3.1 Extensions for DNSSEC

+ +

If an application wants the API to do DNSSEC validation for a request, it must set one or more +DNSSEC-related extensions. Note that the default is for none of these extensions to be set and +the API will not perform DNSSEC, and thus will return results sooner.

+ +

To return the DNSSEC status for each DNS record in the replies_tree list, use the +dnssec_return_status extension. The extension's value (an int) is set to +GETDNS_EXTENSION_TRUE to cause the returned status to have the name +dnssec_status (an int) added to the other names in the record's dict ("header", +"question", and so on). The values for that name are GETDNS_DNSSEC_SECURE, +GETDNS_DNSSEC_BOGUS, GETDNS_DNSSEC_INDETERMINATE, and +GETDNS_DNSSEC_INSECURE. Thus, a reply might look like:

+ +
+    {     # This is the first reply
+      "dnssec_status": GETDNS_DNSSEC_INDETERMINATE,
+      "header": { "id": 23456, "qr": 1, "opcode": 0, ... },
+      . . .
+
+ +

If instead of returning the status, you want to only see secure results, use the +dnssec_return_only_secure extension. The extension's value (an int) is set to +GETDNS_EXTENSION_TRUE to cause only records that the API can validate as secure with +DNSSEC to be returned in the replies_tree and replies_full lists. No +additional names are added to the dict of the record; the change is that some records might not +appear in the results. When this context option is set, if the API receives DNS replies but none +are determined to be secure, the error code at the top level of the response object is +GETDNS_RESPSTATUS_NO_SECURE_ANSWERS.

+ +

Applications that want to do their own validation will want to have the DNSSEC-related records +for a particular response. Use the dnssec_return_supporting_responses extension. The +extension's value (an int) is set to GETDNS_EXTENSION_TRUE to cause a set +of additional DNSSEC-related records needed for validation to be returned in the response object. +This set comes as additional_dnssec (a list) at the top level of the response object. +This list includes any trust anchors needed for the validation. Thus, a reply might look like:

+ +
+{     # This is the response object
+  "additional_dnssec": [ <bindata of the first DNSSEC record>, <bindata of the second DNSSEC record> ... ],
+  "replies_tree":
+  [
+  . . .
+
+ +

If a request is using a context in which stub resolution is set, and that request also has +any of the dnssec_return_status, dnssec_return_only_secure, or +dnssec_return_supporting_responses extensions specified, the API will not perform +the request and will instead return an error of GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED.

+ +

3.2 Returning Both IPv4 and IPv6 Responses

+ +

Many applications want to get both IPv4 and IPv6 addresses in a single call so that the results +can be processed together. The getdns_address and getdns_address_sync +functions are able to do this automatically. If you are using the getdns_general or +getdns_general_sync function, you can enable this with the +return_both_v4_and_v6 extension. The extension's value (an int) is set to +GETDNS_EXTENSION_TRUE to cause the results to be the lookup of either A or AAAA records +to include any A and AAAA records for the queried name (otherwise, the extension does nothing). +These results are expected to be used with Happy Eyeballs systems that will find the best socket for +an application.

+ +

3.3 Setting Up OPT Resource Records

+ +

For lookups that need an OPT resource record in the Additional Data section, use the +add_opt_parameters extension. The extension's value (a dict) contains the +parameters; these are described in more detail in RFC 2671. They are:

+ +
    + +
  • maximum_udp_payload_size (an int), a value between 512 and 65535; if not specified, +this defaults to those from the DNS context
  • + +
  • extended_rcode (an int), a value between 0 and 255; if not specified, +this defaults to those from the DNS context
  • + +
  • version (an int), a value between 0 and 255; if not specified, this +defaults to 0
  • + +
  • do_bit (an int), a value between 0 and 1; if not specified, this defaults +to those from the DNS context
  • + +
  • options (a list) contains dicts for each option to be specified. +Each list time contains two names: option_code (an int) and option_data +(a bindata). The API marshalls the entire set of options into a properly-formatted RDATA +for the resource record.
  • + +
+ +

It is very important to note that the OPT resource record specified in the +add_opt_parameters extension might not be the same the one that the API sends in the +query. For example, if the application also includes any of the DNSSEC extensions, the API will make +sure that the OPT resource record sets the resource record appropriately, making the needed changes +to the settings from the add_opt_parameters extension.

+ +

The use of this extension can conflict with the values in the DNS context. For example, +the default for an OS might be a maximum payload size of 65535, but the extension might specify +1550. In such a case, the API will honor the values stated in the extension, but will honor the +values from the DNS context if values are not given in the extension.

+ +

3.4 Getting Warnings for Responses that Violate the DNS Standard

+ +

To receive a warning if a particular response violates some parts of the DNS standard, use +the add_warning_for_bad_dns extension. The extension's value (an int) is set to +GETDNS_EXTENSION_TRUE to cause each reply in the replies_tree +to contain an additional name, bad_dns (a list). The list is zero or more +ints that indicate types of bad DNS found in that reply. The list of values is: + +

GETDNS_BAD_DNS_CNAME_IN_TARGET

+

A DNS query type that does not allow a target to be a CNAME pointed to a CNAME

+

GETDNS_BAD_DNS_ALL_NUMERIC_LABEL

+

One or more labels in a returned domain name is all-numeric; this is not legal for a hostname

+

GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE

+

A DNS query for a type other than CNAME returned a CNAME response

+ + +

3.5 Using Other Class Types

+ +

The vast majority of DNS requests are made with the Internet (IN) class. To make a request in a +different DNS class, use, the specify_class extension. The extension's value (an int) +contains the class number. Few applications will ever use this extension.

+ +

3.6 Extensions Relating to the API

+ +

An application might want to see information about the API itself. Use the +return_api_information extension. An application that wants to get this information +before a "real" query is issued can add this extension to a PTR query for 127.0.0.1. +The extension's value (an int) is set to +GETDNS_EXTENSION_TRUE to add the following to the top level of the response object:

+ +
    + +
  • version_string (a bindata) represents the version string for this version of the DNS +API.
  • + +
  • implementation_string (a bindata) is a string set by the API implementer. It might +be human-readable, and it might have information in it useful to an application developer (but it doesn't +have to).
  • + +
  • resolver_type (an int) is the type of resolver that the API is acting as in this context: +GETDNS_CONTEXT_RECURSING or GETDNS_CONTEXT_STUB (it will be +a recursing resolver unless the application changed this in a context.
  • + +
  • all_context (a dict) with names for all the types of context. This can be used with +getdns_pretty_print_dict() for debugging.
  • + +
+ +

An application might want to see debugging information for queries such as the length of time it +takes for each query to return to the API. Use the return_call_debugging extension. The +extension's value (an int) is set to GETDNS_EXTENSION_TRUE to add the name +call_debugging (a list) to the top level of the response object. Each member of the +list is a dict that represents one call made for the call to the API. Each member has the following +names:

+ +
    +
  • query_name (a bindata) is the name that was sent
  • +
  • query_type (an int) is the type that was queried for
  • +
  • query_to (a bindata) is the address to which the query was sent
  • +
  • start_time (a bindata) is the time the query started in milliseconds since the epoch, +represented as a uint64_t
  • +
  • end_time (a bindata) is the time the query was received in milliseconds since the epoch, +represented as a uint64_t
  • +
  • entire_reply (a bindata) is the entire response received
  • +
  • dnssec_result (an int) is the DNSSEC status, or GETDNS_DNSSEC_NOT_PERFORMED +if DNSSEC validation was not performed
  • +
+ +

4. Response Data from Queries

+ +

The callback function contains a pointer to a response object. +A response object is always a dict. The response +object always contains at least three names: replies_full (a list) and +replies_tree (a list), and status (an int). +replies_full is a list of DNS replies (each is bindata) as they appear on the wire. +replies_tree is a list of DNS replies (each is a dict) with the various part of the +reply parsed out. status is a status code for the query.

+ +

Because the API might be extended in the future, a response object might also contain names other +than replies_full, replies_tree, and status. Similarly, any +of the dicts described here might be extended in later versions of the API. Thus, an application +using the API must not assume that it knows all possible names in a dict.

+ +

The following lists the status codes for response objects. Note that, if the status is that there +are no responses for the query, the lists in replies_full and replies_tree +will have zero length.

+ +

GETDNS_RESPSTATUS_GOOD

+

At least one response was returned

+

GETDNS_RESPSTATUS_NO_NAME

+

Queries for the name yielded all negative responses

+

GETDNS_RESPSTATUS_ALL_TIMEOUT

+

All queries for the name timed out

+

GETDNS_RESPSTATUS_NO_SECURE_ANSWERS

+

The context setting for getting only secure responses was specified, and at least one DNS response was received, but no DNS response was determined to be secure through DNSSEC.

+ + +

The top level of replies_tree can optionally have the following names: canonical_name (a +bindata), intermediate_aliases (a list), answer_ipv4_address (a bindata), +answer_ipv6_address (a bindata), and answer_type (an int).

+ +
    + +
  • The value of canonical_name is the name that the API used for its lookup. It is in +FQDN presentation format.
  • + +
  • The values in the intermediate_aliases list are domain names from any CNAME or +unsynthesized DNAME found when resolving the original query. The list might have zero entries +if there were no CNAMEs in the path. These may be useful, for example, for name comparisons +when following the rules in RFC 6125.
  • + +
  • The value of answer_ipv4_address and answer_ipv6_address are +the addresses of the server from which the answer was received.
  • + +
  • The value of answer_type is the type of name service that generated the response. +The values are:
  • + +
+ +

GETDNS_NAMETYPE_DNS

+

Normal DNS (RFC 1035)

+

GETDNS_NAMETYPE_WINS

+

The WINS name service (some reference needed)

+ + +

If the call was getdns_address or getdns_address_sync, the top level +of replies_tree has an additional name, just_address_answers (a list). +The value of just_address_answers is a list that contains all of the A and AAAA +records from the answer sections of any of the replies, in the order they appear in the replies. +Each item in the list is a dict with at least two names: address_type (whose value is +a bindata; it is currently either "IPv4" or "IPv6") and address_data (whose value is a bindata). +Note that the dnssec_return_only_secure extension affects +what will appear in the just_address_answers list. Also note if later versions of the +DNS return other address types, those types will appear in this list as well.

+ +

The API can make service discovery through SRV records easier. If +the call was getdns_service or getdns_service_sync, +the top level of replies_tree has an additional name, +srv_addresses (a list). +The list is ordered by priority and weight based on the weighting +algorithm in RFC 2782, lowest priority value first. Each element +of the list is dict has at least two names: port and domain_name. If the +API was able to determine the address of the target domain name (such as from its cache or from the +Additional section of responses), the dict for an element will also contain +address_type (whose value is a bindata; it is currently either "IPv4" or "IPv6") and +address_data (whose value is a bindata). Note that the +dnssec_return_only_secure extension affects what will appear in the +srv_addresses list.

+ +

4.1 Structure of DNS replies_tree

+ +

The names in each entry in the the replies_tree list for DNS responses include +header (a dict), question (a dict), answer (a list), +authority (a list), and additional (a list), corresponding to the sections +in the DNS message format. The answer, authority, and additional lists each contain zero or more +dicts, with each dict in each list representing a resource record.

+ +

The names in the header dict are all the fields from Section 4.1.1. of RFC 1035. +They are: id, qr, opcode, aa, tc, +rd, ra, z, rcode, qdcount, +ancount, nscount, and arcount. All are ints.

+ +

The names in the question dict are the three fields from Section 4.1.2. of RFC 1035: +qname (a bindata), qtype (an int), and qclass (an int).

+ +

Resource records are a bit different than headers and question sections in that the RDATA portion +often has its own structure. The other names in the resource record dicts are name (a +bindata), type (an int), class (an int), ttl (an int) and +rdata (a dict); there is no name equivalent to the RDLENGTH field.

+ +

The rdata dict has different names for each response type. There is a complete list of the types defined in the API. For names that end in +"-obsolete" or "-unknown", the bindata is the entire RDATA field. For example, the +rdata for an A record has a name ipv4_address (a bindata); the +rdata for an SRV record has the names priority (an int), +weight (an int), port (an int), and target (a bindata).

+ +

Each rdata dict also has a rdata_raw field (a bindata). This is useful +for types not defined in this version of the API. It also might be of value if a later version of +the API allows for additional parsers. Thus, doing a query for types not known by the API still will +return a result: an rdata with just a rdata_raw.

+ +

It is expected that later extensions to the API will give some DNS types different names. It is +also possible that later extensions will change the names for some of the DNS types listed above.

+ +

For example, a response to a getdns_address() call for www.example.com would +look something like this:

+ +
+{     # This is the response object
+  "replies_full": [ <bindata of the first response>, <bindata of the second response> ],
+  "just_address_answers": [ <bindata of 0x0a0b0c01>, <bindata of 0x33445566334455663344556633445566> ],
+  "canonical_name": <bindata for "www.example.com">,
+  "answer_type": GETDNS_NAMETYPE_DNS,
+  "intermediate_aliases": [],
+  "replies_tree":
+  [
+    {     # This is the first reply
+      "header": { "id": 23456, "qr": 1, "opcode": 0, ... },
+      "question": { "qname": <bindata for "www.example.com">, "qtype": 1, "qclass": 1 },
+      "answer":
+      [
+        {
+          "name": <bindata for "www.example.com">,
+          "type": 1,
+          "class": 1,
+          "ttl": 33000,
+          "rdata":
+          {
+            "ipv4_address": <bindata of 0x0a0b0c01>
+            "rdata_raw": <bindata of 0x0a0b0c01>
+          }
+        }
+      ],
+      "authority":
+      [
+        {
+          "name": <bindata for "ns1.example.com">,
+          "type": 1,
+          "class": 1,
+          "ttl": 600,
+          "rdata":
+          {
+            "ipv4_address": <bindata of 0x65439876>
+            "rdata_raw": <bindata of 0x65439876>
+          }
+        }
+      ]
+      "additional": [],
+      "canonical_name": <bindata for "www.example.com">,
+      "answer_type": GETDNS_NAMETYPE_DNS
+    },
+    {     # This is the second reply
+      "header": { "id": 47809, "qr": 1, "opcode": 0, ... },
+      "question": { "qname": <bindata for "www.example.com">, "qtype": 28, "qclass": 1 },
+      "answer":
+      [
+        {
+          "name": <bindata for "www.example.com">,
+          "type": 28,
+          "class": 1,
+          "ttl": 1000,
+          "rdata":
+          {
+            "ipv6_address": <bindata of 0x33445566334455663344556633445566>
+            "rdata_raw": <bindata of 0x33445566334455663344556633445566>
+          }
+       }
+      ],
+      "authority": [  # Same as for other record... ]
+      "additional": [],
+    },
+  ]
+}
+
+ +

In DNS responses, domain names are treated special. RFC 1035 describes a form of name compression +that requires that the entire record be available for analysis. The API deals with this by +converting compressed names into full names when returning names in the replies_tree. +This conversion happens for qname in question; name in the +answer, authority, and additional; and in domain names in the +data in names under rdata where the response type is AFSDB, CNAME, MX, NS, PTR, RP, RT, and SOA.

+ +

4.2 Converting Domain Names

+ +

Names in DNS fields are stored in a fashion very different from the normal presentation format +normally used in applications. The DNS format is described in the first paragraph in Section 3.1 of +RFC 1035; the presentation format here is a null-terminated string with interior dots. These helper +functions only work with names in the DNS format that are not compressed. They are useful for +converting domain names in the replies_tree to and from the FQDN presentation +format.

+ +

getdns_convert_dns_name_to_fqdn() converts a domain name in DNS format to the +presentation format. For example, the hex sequence 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 +6f 6d 00 would be converted to "www.example.com". +getdns_convert_fqdn_to_dns_name() does the reverse: it converts a null-terminated +string in FQDN format to bytes in DNS format.

+ +
+char * +getdns_convert_dns_name_to_fqdn( + char *name_from_dns_response +); + +char * +getdns_convert_fqdn_to_dns_name( + char *fqdn_as_string +); +
+ +

5. Additional Definitions and Descriptions

+ +

5.1 A Few Needed Definitions

+ +
typedef struct getdns_context_t *getdns_context_t; +typedef uint16_t getdns_return_t; +typedef uint64_t getdns_transaction_t; +typedef enum some_data_type { + t_dict, t_list, t_int, t_bindata +} getdns_data_type; +typedef struct getdns_bindata { + size_t size; + uint8_t *binary_stuff; +} some_bindata; +typedef struct getdns_dict some_dict; +typedef struct getdns_list some_list; +
+ +

5.2 Return Codes

+ +

The return codes for all the functions are:

+ +

GETDNS_RETURN_GOOD

+

Good

+

GETDNS_RETURN_GENERIC_ERROR

+

Generic error

+

GETDNS_RETURN_BAD_DOMAIN_NAME

+

Badly-formed domain name in first argument

+

GETDNS_RETURN_BAD_CONTEXT

+

Bad value for a context type

+

GETDNS_RETURN_CONTEXT_UPDATE_FAIL

+

Did not update the context

+

GETDNS_RETURN_UNKNOWN_TRANSACTION

+

An attempt was made to cancel a callback with a transaction_id that is not recognized

+

GETDNS_RETURN_NO_SUCH_LIST_ITEM

+

A helper function for lists had an index argument that was too high.

+

GETDNS_RETURN_NO_SUCH_DICT_NAME

+

A helper function for dicts had a name argument that for a name that is not in the dict.

+

GETDNS_RETURN_WRONG_TYPE_REQUESTED

+

A helper function was supposed to return a certain type for an item, but the wrong type was given.

+

GETDNS_RETURN_NO_SUCH_EXTENSION

+

A name in the extensions dict is not a valid extension.

+

GETDNS_RETURN_EXTENSION_MISFORMAT

+

One or more of the extensions is has a bad format.

+

GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED

+

A query was made with a context that is using stub resolution and a DNSSEC extension specified.

+ + +

5.3 Types of RDATA Returned in the API

+ +

The names in the rdata dicts in replies are:

+ + +

A (1)

+

ipv4_address (a bindata)

+ +

NS (2)

+

nsdname (a bindata)

+ +

MD (3)

+

madname (a bindata)

+ +

MF (4)

+

madname (a bindata)

+ +

CNAME (5)

+

cname (a bindata)

+ +

SOA (6)

+

mname (a bindata), rname (a bindata), +serial (an int), refresh (an int), refresh (an int), +retry (an int), and expire (an int)

+ +

MB (7)

+

madname (a bindata)

+ +

MG (8)

+

mgmname (a bindata)

+ +

MR (9)

+

newname (a bindata)

+ +

NULL (10)

+

anything (a bindata)

+ +

WKS (11)

+

address (a bindata), protocol (an int), +and bitmap (a bindata)

+ +

PTR (12)

+

ptrdname (a bindata)

+ +

HINFO (13)

+

cpu (a bindata) and os (a bindata)

+ +

MINFO (14)

+

rmailbx (a bindata) and emailbx (a bindata)

+ +

MX (15)

+

preference (an int) and exchange (a bindata)

+ +

TXT (16)

+

txt_strings (a list) which contains zero or more bindata elements +that are text strings

+ +

RP (17)

+

mbox_dname (a bindata) and txt_dname (a bindata)

+ +

AFSDB (18)

+

subtype (an int) and hostname (a bindata)

+ +

X25 (19)

+

psdn_address (a bindata)

+ +

ISDN (20)

+

isdn_address (a bindata) and sa (a bindata)

+ +

RT (21)

+

preference (an int) and intermediate_host (a bindata)

+ +

NSAP (22)

+

nsap (a bindata)

+ +

SIG (24)

+

sig_obsolete (a bindata)

+ +

KEY (25)

+

key_obsolete (a bindata)

+ +

PX (26)

+

preference (an int), map822 (a bindata), and mapx400 (a bindata)

+ +

GPOS (27)

+

longitude (a bindata), latitude (a bindata), and altitude (a bindata)

+ +

AAAA (28)

+

ipv6_address (a bindata)

+ +

LOC (29)

+

loc_obsolete (a bindata)

+ +

NXT (30)

+

nxt_obsolete (a bindata)

+ +

EID (31)

+

eid_unknown (a bindata)

+ +

NIMLOC (32)

+

nimloc_unknown (a bindata)

+ +

SRV (33)

+

priority (an int), weight (an int), +port (an int), and target (a bindata)

+ +

ATMA (34)

+

format (an int) and address (a bindata)

+ +

NAPTR (35)

+

order (an int), preference (an int), flags +(a bindata), service (a bindata), regexp (a bindata), and +replacement (a bindata).

+ +

KX (36)

+

preference (an int) and exchanger (a bindata)

+ +

CERT (37)

+

type (an int), key_tag (an int), algorithm (an int), +and certificate_or_crl (a bindata)

+ +

A6 (38)

+

a6_obsolete (a bindata)

+ +

DNAME (39)

+

target (a bindata)

+ +

SINK (40)

+

sink_unknown (a bindata)

+ +

OPT (41)

+

options (a list). Each element of the options list is a +dict with two names: option_code (an int) and option_data (a bindata).

+ +

APL (42)

+

address_family (an int), prefix (an int), +n (an int), and afdpart (a bindata)

+ +

DS (43)

+

key_tag (an int), algorithm (an int), digest_type (an int), +and digest (a bindata)

+ +

SSHFP (44)

+

algorithm (an int), fp_type (an int), +and fingerprint (a bindata)

+ +

IPSECKEY (45)

+

algorithm (an int), gateway_type (an int), precedence (an int), +gateway, and public_key (a bindata)

+ +

RRSIG (46)

+

type_covered (an int), algorithm (an int), +labels (an int), original_ttl (an int), signature_expiration +(an int), signature_inception (an int), key_tag (an int), +signers_name (a bindata), and signature (a bindata)

+ +

NSEC (47)

+

next_domain_name (a bindata) and type_bit_maps (a bindata)

+ +

DNSKEY (48)

+

flags (an int), protocol (an int), algorithm (an int), +and public_key (a bindata)

+ +

DHCID (49)

+

dhcid_opaque (a bindata)

+ +

NSEC3 (50)

+

hash_algorithm (an int), flags (an int), +iterations (an int), salt_length (an int), salt (a bindata), +hash_length (an int), next_hashed_owner_name (a bindata), and +type_bit_maps (a bindata)

+ +

NSEC3PARAM (51)

+

hash_algorithm (an int), flags (an int), +iterations (an int), salt_length (an int), and +salt (a bindata)

+ +

TLSA (52)

+

certificate_usage (an int), selector (an int), +matching_type (an int), and certificate_association_data (a +bindata).

+ +

HIP (55)

+

hit_length (an int), pk_algorithm (an int), +pk_length (an int), hit (a bindata), public_key +(a bindata), and rendezvous_servers (a bindata)

+ +

NINFO (56)

+

ninfo_unknown (a bindata)

+ +

RKEY (57)

+

rkey_unknown (a bindata)

+ +

TALINK (58)

+

talink_unknown (a bindata)

+ +

CDS (59)

+

cds_unknown (a bindata)

+ +

SPF (99)

+

text (a bindata)

+ +

UINFO (100)

+

uinfo_unknown (a bindata)

+ +

UID (101)

+

uid_unknown (a bindata)

+ +

GID (102)

+

gid_unknown (a bindata)

+ +

UNSPEC (103)

+

unspec_unknown (a bindata)

+ +

NID (104)

+

preference (an int) and +node_id (a bindata)

+ +

L32 (105)

+

preference (an int), locator32_msbs (a bindata), +and locator64_lsbs (a bindata)

+ +

L64 (106)

+

preference (an int) and locator64 (a bindata)

+ +

LP (107)

+

preference (an int) and fqdn (a bindata)

+ +

TKEY (249)

+

algorithm (a bindata), inception (an int), +expiration (an int), mode (an int), error (an int), +key_data (a bindata), and other_data (a bindata)

+ +

TSIG (250)

+

algorithm (a bindata), time_signed (a bindata), +fudge (an int), mac (a bindata), original_id (an int), +error (an int), and other_data (a bindata)

+ +

IXFR (251)

+

zones (a bindata)

+ +

AXFR (252)

+

zones (a bindata)

+ +

MAILB (253)

+

mailb-unknown (a bindata)

+ +

MAILA (254)

+

maila-unknown (a bindata)

+ +

URI (256)

+

priority (an int), weight (an int), +and target (a bindata)

+ +

CAA (257)

+

flags (an int), tag (a bindata), and value (a bindata)

+ +

TA (32768)

+

ta_unknown (a bindata)

+ +

DLV (32769)

+

Identical to DS (43)

+ + +

6. Examples

+ +

This section gives examples of code that calls the API to do many common tasks. +The purpose of the code here is to give application developers a quick hands-on +demo of using the API.

+ +

Note that the examples here all use getdns_libevent.h as the include that will call in the API +code as well as calling in libevent as the event library. They also use +getdns_context_set_libevent_base() as the name of the function to set the event base in +the DNS context. If you are using a different event library, you will of course use a different +#include at the beginning of your code, and a different name for the event base +function.

+ +

6.1 Get Both IPv4 and IPv6 Addresses for a Domain Name Using Quick Results

+ +

This is an example of a common call to getdns_address().

+ +
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <getdns_libevent.h>
+
+#define UNUSED_PARAM(x) ((void)(x))
+
+/* Set up the callback function, which will also do the processing of the results */
+void this_callbackfn(struct getdns_context_t *this_context,
+                     uint16_t     this_callback_type,
+                     struct getdns_dict *this_response, 
+                     void *this_userarg,
+                     getdns_transaction_t this_transaction_id)
+{
+    UNUSED_PARAM(this_userarg);  /* Not looking at the userarg for this example */
+    UNUSED_PARAM(this_context);  /* Not looking at the context for this example */
+    getdns_return_t this_ret;  /* Holder for all function returns */
+    if (this_callback_type == GETDNS_CALLBACK_COMPLETE)  /* This is a callback with data */
+    {
+        /* Be sure the search returned something */
+        uint32_t * this_error = NULL;
+        this_ret = getdns_dict_get_int(this_response, "status", this_error);  // Ignore any error
+        if (*this_error != GETDNS_RESPSTATUS_GOOD)  // If the search didn't return "good"
+        {
+            fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error);
+            return;
+        }
+        struct getdns_list * just_the_addresses_ptr;
+        this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr);
+        if (this_ret != GETDNS_RETURN_GOOD)  // This check is really not needed, but prevents a compiler error under "pedantic"
+        {
+            fprintf(stderr, "Trying to get the answers failed: %d", this_ret);
+            return;
+        }
+        size_t * num_addresses_ptr = NULL;
+        this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr);  // Ignore any error
+        /* Go through each record */
+        for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count )
+        {
+            struct getdns_dict * this_address;
+            this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address);  // Ignore any error
+            /* Just print the address */
+            struct getdns_bindata * this_address_data;
+            this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
+            printf("The address is %s", getdns_display_ip_address(this_address_data));
+        }
+    }
+    else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
+        fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id);
+    else
+        fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type);
+}
+
+int main()
+{
+    /* Create the DNS context for this call */
+    struct getdns_context_t *this_context = NULL;
+    getdns_return_t context_create_return = getdns_context_create(&this_context, true);
+    if (context_create_return != GETDNS_RETURN_GOOD)
+    {
+        fprintf(stderr, "Trying to create the context failed: %d", context_create_return);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    /* Create an event base and put it in the context using the unknown function name */
+    struct event_base *this_event_base;
+    this_event_base = event_base_new();
+    if (this_event_base == NULL)
+    {
+        fprintf(stderr, "Trying to create the event base failed.");
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    (void)getdns_extension_set_libevent_base(this_context, this_event_base);
+    /* Set up the getdns call */
+    const char * this_name  = "www.example.com";
+    char* this_userarg = "somestring"; // Could add things here to help identify this call
+    getdns_transaction_t this_transaction_id = 0;
+
+    /* Make the call */
+    getdns_return_t dns_request_return = getdns_address(this_context, this_name,
+        NULL, this_userarg, &this_transaction_id, this_callbackfn);
+    if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
+    {
+        fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    else
+    {
+        /* Call the event loop */
+        int dispatch_return = event_base_dispatch(this_event_base);
+        UNUSED_PARAM(dispatch_return);
+        // TODO: check the return value above
+    }
+    /* Clean up */
+    getdns_context_destroy(this_context);
+    /* Assuming we get here, leave gracefully */
+    exit(EXIT_SUCCESS);
+}
+
+ + + +

6.2 Get IPv4 and IPv6 Addresses for a Domain Name

+ +

This example is similar to the previous one, except that it retrieves more information than just +the addresses, so it traverses the replies_tree. In this case, it gets both the addresses and +their TTLs.

+ +
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <getdns_libevent.h>
+
+#define UNUSED_PARAM(x) ((void)(x))
+
+/* Set up the callback function, which will also do the processing of the results */
+void this_callbackfn(struct getdns_context_t *this_context,
+                     getdns_return_t this_callback_type,
+                     struct getdns_dict *this_response, 
+                     void *this_userarg,
+                     getdns_transaction_t this_transaction_id)
+{
+    UNUSED_PARAM(this_userarg);  /* Not looking at the userarg for this example */
+    UNUSED_PARAM(this_context);  /* Not looking at the context for this example */
+    getdns_return_t this_ret;  /* Holder for all function returns */
+    if (this_callback_type == GETDNS_CALLBACK_COMPLETE)  /* This is a callback with data */
+    {
+        /* Be sure the search returned something */
+        uint32_t * this_error = NULL;
+        this_ret = getdns_dict_get_int(this_response, "status", this_error);  // Ignore any error
+        if (*this_error != GETDNS_RESPSTATUS_GOOD)  // If the search didn't return "good"
+        {
+            fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error);
+            return;
+        }
+        /* Find all the answers returned */
+        struct getdns_list * these_answers;
+        this_ret = getdns_dict_get_list(this_response, "replies-tree", &these_answers);
+        if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
+        {
+            fprintf(stderr, "Weird: the response had no error, but also no replies-tree. Exiting.");
+            return;
+        }
+        size_t * num_answers_ptr = NULL;
+        this_ret = getdns_list_get_length(these_answers, num_answers_ptr);
+        /* Go through each answer */
+        for ( size_t rec_count = 0; rec_count <= *num_answers_ptr; ++rec_count )
+        {
+            struct getdns_dict * this_record;
+            this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record);  // Ignore any error
+            /* Get the answer section */
+            struct getdns_list * this_answer;
+            this_ret = getdns_dict_get_list(this_record, "answer", &this_answer);  // Ignore any error
+            /* Get each RR in the answer section */
+            size_t * num_rrs_ptr = NULL;
+            this_ret = getdns_list_get_length(this_answer, num_rrs_ptr);
+            for ( size_t rr_count = 0; rr_count <= *num_rrs_ptr; ++rr_count )
+            {
+                struct getdns_dict * this_rr = NULL;
+                this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr);  // Ignore any error
+                /* Get the RDATA */
+                struct getdns_dict * this_rdata = NULL;
+                this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata);  // Ignore any error
+                /* Get the RDATA type */
+                uint32_t * this_type = NULL;
+                this_ret = getdns_dict_get_int(this_rdata, "type", this_type);  // Ignore any error
+                /* If it is type A or AAAA, print the value */
+                if (*this_type == GETDNS_RRTYPE_A)
+                {
+                    struct getdns_bindata * this_a_record = NULL;
+                    this_ret = getdns_dict_get_bindata(this_rdata, "ipv4_address", &this_a_record);
+                    if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
+                    {
+                        fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.",
+                            (int) rr_count, (int) rec_count);
+                        return;
+                    }
+                    printf("The IPv4 address is %s", getdns_display_ip_address(this_a_record));
+                }
+                else if (*this_type == GETDNS_RRTYPE_AAAA)
+                {
+                    struct getdns_bindata * this_aaaa_record = NULL;
+                    this_ret = getdns_dict_get_bindata(this_rdata, "ipv6_address", &this_aaaa_record);
+                    if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
+                    {
+                        fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.",
+                            (int) rr_count, (int) rec_count);
+                        return;
+                    }
+                    printf("The IPv6 address is %s", getdns_display_ip_address(this_aaaa_record));
+                }
+            }
+        }
+    }
+    else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
+        fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id);
+    else
+        fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type);
+}
+
+int main()
+{
+    /* Create the DNS context for this call */
+    struct getdns_context_t *this_context = NULL;
+    getdns_return_t context_create_return = getdns_context_create(&this_context, true);
+    if (context_create_return != GETDNS_RETURN_GOOD)
+    {
+        fprintf(stderr, "Trying to create the context failed: %d", context_create_return);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    /* Create an event base and put it in the context using the unknown function name */
+    struct event_base *this_event_base;
+    this_event_base = event_base_new();
+    if (this_event_base == NULL)
+    {
+        fprintf(stderr, "Trying to create the event base failed.");
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    (void)getdns_extension_set_libevent_base(this_context, this_event_base);
+    /* Set up the getdns call */
+    const char * this_name  = "www.example.com";
+    char* this_userarg = "somestring"; // Could add things here to help identify this call
+    getdns_transaction_t this_transaction_id = 0;
+
+    /* Make the call */
+    getdns_return_t dns_request_return = getdns_address(this_context, this_name,
+        NULL, this_userarg, &this_transaction_id, this_callbackfn);
+    if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
+    {
+        fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    else
+    {
+        /* Call the event loop */
+        int dispatch_return = event_base_dispatch(this_event_base);
+        UNUSED_PARAM(dispatch_return);
+        // TODO: check the return value above
+    }
+    /* Clean up */
+    getdns_context_destroy(this_context);
+    /* Assuming we get here, leave gracefully */
+    exit(EXIT_SUCCESS);
+}
+
+ + + +

6.3 Get Addresses for a Domain Name And Their Associated DNSSEC Validation Status

+ +

This example shows how to check for secure DNSSEC results using the +dnssec_return_status extension. In the innermost loop of the +callback function, add a check for the DNSSEC status. It shows how to add two +extensions to the extensions argument of the call.

+ +
+struct getdns_dict * this_extensions = getdns_dict_create();
+this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
+this_ret = getdns_dict_set_int(this_extensions, "dnssec_return_status", GETDNS_EXTENSION_TRUE);
+. . .
+if (*this_type == GETDNS_RRTYPE_A)
+{
+    uint32_t * this_dnssec_status;
+    this_ret = getdns_dict_get_int(this_rdata, "dnssec_status", this_dnssec_status);
+    if (&this_dnssec_status != GETDNS_DNSSEC_SECURE)
+    {
+        // Log the DNSSEC status somewhere
+    }
+    else
+    {
+        // Deal with the record however you were going to
+    }
+}
+. . .
+
+ +

You can put the DNSSEC status check outside the check for the particular type of record you care about, but +you will then get log messages for bad status on records you might not care about as well.

+ +

6.4 Using the API Synchronously with getdns_sync_request()

+ +

This example is the same as the earlier examples, but uses getdns_general_sync() +and thus does not use the async code. Note that the processing of the answers is essentially the same +as it is for the synchronous example, it is just done in main().

+ +
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <getdns_core_only.h>
+
+int main()
+{
+    getdns_return_t this_ret;  /* Holder for all function returns */
+    /* Create the DNS context for this call */
+    struct getdns_context_t *this_context = NULL;
+    getdns_return_t context_create_return = getdns_context_create(&this_context, true);
+    if (context_create_return != GETDNS_RETURN_GOOD)
+    {
+        fprintf(stderr, "Trying to create the context failed: %d", context_create_return);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    /* Set up the getdns_sync_request call */
+    const char * this_name  = "www.example.com";
+    uint8_t this_request_type = GETDNS_RRTYPE_A;
+    /* Get the A and AAAA records */
+    struct getdns_dict * this_extensions = getdns_dict_create();
+    this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
+    if (this_ret != GETDNS_RETURN_GOOD)
+    {
+        fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d", this_ret);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    uint32_t this_response_length;
+    struct getdns_dict * this_response = NULL;
+
+    /* Make the call */
+    getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type,
+        this_extensions, &this_response_length, this_response);
+    if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
+    {
+        fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name);
+        return(GETDNS_RETURN_GENERIC_ERROR);
+    }
+    else
+    {
+        /* Be sure the search returned something */
+        uint32_t * this_error = NULL;
+        this_ret = getdns_dict_get_int(this_response, "status", this_error);  // Ignore any error
+        if (*this_error != GETDNS_RESPSTATUS_GOOD)  // If the search didn't return "good"
+        {
+            fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error);
+            return(GETDNS_RETURN_GENERIC_ERROR);
+        }
+        struct getdns_list * just_the_addresses_ptr;
+        this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr);  // Ignore any error
+        size_t * num_addresses_ptr = NULL;
+        this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr);  // Ignore any error
+        /* Go through each record */
+        for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count )
+        {
+            struct getdns_dict * this_address;
+            this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address);  // Ignore any error
+            /* Just print the address */
+            struct getdns_bindata * this_address_data;
+            this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
+            printf("The address is %s", getdns_display_ip_address(this_address_data));
+        }
+    }
+    /* Clean up */
+    getdns_context_destroy(this_context);
+    getdns_free_sync_request_memory(this_response); 
+    /* Assuming we get here, leave gracefully */
+    exit(EXIT_SUCCESS);
+}
+
+ + + +

7. More Helper Functions

+ +

The following two functions convert individual labels of IDNs between their Unicode +encoding and their ASCII encoding. They follow the rules for IDNA 2008 described in +RFC 5890-5892.

+
char * +getdns_convert_ulabel_to_alabel( + char *ulabel +); +
+
char * +getdns_convert_alabel_to_ulabel( + char *alabel +); +
+ +

If an application wants the API do perform DNSSEC validation without using the extensions, it +can use the getdns_validate_dnssec() helper function.

+
getdns_return_t +getdns_validate_dnssec( + struct getdns_bindata *record_to_validate, + struct getdns_list *bundle_of_support_records, + struct getdns_list *trust_anchor_rdatas +); +
+

The record_to_validate is the resource record being validated. The API +will use the resource records in bundle_of_support_records and the RDATAs in the +trust_ancor_rdatas as trust anchors. The function returns one of +GETDNS_DNSSEC_SECURE, GETDNS_DNSSEC_BOGUS, +GETDNS_DNSSEC_INDETERMINATE, or GETDNS_DNSSEC_INSECURE.

+ +

There are two functions that help process data:

+ +
+char * +getdns_pretty_print_dict( + struct getdns_dict *some_dict +); +
+

This returns a string that is the nicely-formatted version +of the dict and all of the named elements in it.

+ +
+char * +getdns_display_ip_address( + struct getdns_bindata *bindata_of_ipv4_or_ipv6_address +); +
+

This returns a string that is the nicely-formatted version +of the IPv4 or IPv6 address in it. The API determines they type of address +by the length given in the bindata.

+ +

8. DNS Contexts

+ +

Many calls in the DNS API require a DNS context. A DNS +context contains the information that the API needs in order to process DNS calls, such as the +locations of upstream DNS servers, DNSSEC trust anchors, and so on. The internal structure of the +DNS context is opaque, and might be different on each OS. When a context is passed to any function, +it must be an allocated context; the context must not be NULL.

+ +

A typical application using this API doesn't need to know anything about contexts. Basically, +the application creates a default context, uses it in the functions that require a context, and +then deallocates it when done. Context manipulation is available for more DNS-aware programs, +but is unlikely to be of interest to applications that just want the results of lookups for +A, AAAA, SRV, and PTR records.

+ +

It is expected that contexts in implementations of the API will not necessarily be thread-safe, +but they will not be thread-hostile. A context should not be used by multiple threads: create a new +context for use on a different thread. It is just fine for an application to have many contexts, +and some DNS-heavy applications will certainly want to have many even if the application uses +a single thread.

+ +

See above for the method for creating and destroying +contexts. When the context is used in the API for the first time and set_from_os is +true, the API starts replacing some of the values with values from the OS, such as +those that would be found in res_query(3), /etc/resolv.conf, and so on, then proceeds with the new +function. Some advanced users will not want the API to change the values to the OS's defaults; if +set_from_os is false, the API will not do any updates to the initial +values based on changes in the OS. For example, this might be useful if the API is acting +as a stub resolver that is using a specific upstream recursive resolver chosen by the +application, not the one that might come back from DHCP.

+ +

8.1 Updating the Context Automatically

+ +

The context returned by getdns_context_create() is updated by the API by default, +such as when changes are made to /etc/resolv.conf. When there is a change, the callback function +that is set in getdns_context_set_context_update_callback() (described below) is +called.

+ +

Many of the defaults for a context come from the operating system under which the API is running. +In specific, it is important that the implementation should try to replicate as best as possible the +logic of a local getaddrinfo() when creating a new context. This includes making +lookups in WINS for NetBIOS, mDNS lookups, nis names, and any other name lookup that +getaddrinfo() normally does automatically. The API should look at nsswitch, the Windows +resolver, and so on.

+ +

In the function definitions below, the choice listed in bold is the one used +for the API default context.

+ +

8.2 Updating the Context Manually

+ +

Setting specific values in a context are done with value-specific +functions shown here. The setting functions all return either GETDNS_RETURN_GOOD for +success, GETDNS_RETURN_BAD_CONTEXT for trying to set a type with a value that +is not allowed, or GETDNS_RETURN_CONTEXT_UPDATE_FAIL for a failure to update the context.

+ +

An application can be notified when the context is changed.

+ +
+getdns_return_t +getdns_context_set_context_update_callback( + getdns_context_t context, + void (*value)(getdns_context_t context, uint16_t changed_item) +);
+

The value is a pointer to the callback function that will be +called when any context is changed. Such changes might be from automatic +changes from the API (such as changes to /etc/resolv.conf), or might be from any of the +API functions in this section being called. The second argument to the callback function +specifies which of the context changed; the context codes are listed +later in this document.

+ +

8.3 Contexts for Basic Resolution

+ +
+getdns_return_t +getdns_context_set_resolution_type( + getdns_context_t context, + uint16_t value +);
+

Specifies whether DNS queries are performed with nonrecurive lookups or +as a stub resolver. The value is GETDNS_CONTEXT_RECURSING or +GETDNS_CONTEXT_STUB.

+ +

All implementations of this API can act as recursive resolvers, and that must be the +default mode of the default context. +Some implementations of this API are expected to also be able to act as stub resolvers. +If an +implementation of this API is only able to act as a recursive resolver, a call to +getdns_context_set_resolution_type(somecontext, GETDNS_CONTEXT_STUB) will +return GETDNS_RETURN_CONTEXT_UPDATE_FAIL.

+ +
+getdns_return_t +getdns_context_set_namespaces( + getdns_context_t context, + size_t namespace_count, + uint16_t *namespaces +);
+

The namespaces array contains an ordered list +of namespaces that will be queried. +Important: this context setting is ignored for the getdns_general and +getdns_general_sync functions; it is used for the other funtions. +The values +are GETDNS_CONTEXT_NAMESPACE_DNS, +GETDNS_CONTEXT_NAMESPACE_LOCALNAMES, +GETDNS_CONTEXT_NAMESPACE_NETBIOS, +GETDNS_CONTEXT_NAMESPACE_MDNS, and +GETDNS_CONTEXT_NAMESPACE_NIS. When a normal lookup is done, +the API does the lookups in the order given and stops when it gets the +first result; a different method with the same result would be to run +the queries in parallel and return when it gets the first result. +Because lookups might be done over different mechanisms because of the +different namespaces, there can be information leakage that is similar +to that seen with getaddrinfo(). The +default is determined by the OS.

+ +
+getdns_return_t +getdns_context_set_dns_transport( + getdns_context_t context, + uint16_t value +);
+

Specifies what transport is used for DNS lookups. +The value is +GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP, +GETDNS_CONTEXT_UDP_ONLY, +GETDNS_CONTEXT_TCP_ONLY, or +GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN.

+ +
+getdns_return_t +getdns_context_set_limit_outstanding_queries( + getdns_context_t context, + uint16_t limit +);
+

Specifies limit the number of outstanding DNS queries. +The API will block itself from sending more queries if it is about to exceed +this value, and instead keep those queries in an internal queue. +The a value of 0 indicates that +the number of outstanding DNS queries is unlimited.

+ +
+getdns_return_t +getdns_context_set_timeout( + getdns_context_t context, + uint16_t timeout +);
+

Specifies number of seconds the API will wait for request to return. +The default is not specified.

+ +

8.4 Context for Recursive Resolvers

+ +
+getdns_return_t +getdns_context_set_follow_redirects( + getdns_context_t context, + uint16_t value +);
+

Specifies whether or not DNS queries follow redirects. +The value is GETDNS_CONTEXT_FOLLOW_REDIRECTS for normal +following of redirects though CNAME and DNAME; or +GETDNS_CONTEXT_DO_NOT_FOLLOW_REDIRECTS to cause any lookups that would have gone +through CNAME and DNAME to return the CNAME or DNAME, not the eventual target.

+ +
+getdns_return_t +getdns_context_set_dns_root_servers( + getdns_context_t context, + struct getdns_list *addresses +);
+

The list contains dicts that are addresses to be used for looking up top-level +domains; the default is the list of "normal" IANA root servers. Each dict in the list +contains at least two names: address_type (whose value is a bindata; it is currently +either "IPv4" or "IPv6") and address_data (whose value is a bindata).

+ +

8.5 Context for Local Naming

+ +
+getdns_return_t +getdns_context_set_append_name( + getdns_context_t context, + uint16_t value +);
+

Specifies whether to append a suffix to the query string +before the API starts resolving a name. +The value is +GETDNS_CONTEXT_APPEND_NAME_ALWAYS, +GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE, +GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE, +or GETDNS_CONTEXT_DO_NOT_APPEND_NAMES. This controls +whether or not to append the suffix given by getdns_context_set_suffix

+ +
+getdns_return_t +getdns_context_set_suffix( + getdns_context_t context, + struct getdns_list *value +);
+

The value is a list of bindatas that are strings that are +to be appended based on getdns_context_set_append_name; the default is an empty list. The values here follow the rules in section 2.1 of RFC 4343 +to allow non-ASCII octets and special characters in labels.

+ +

8.6 Context for DNSSEC

+ +

These context settings affect queries that have extensions that specify the use of DNSSEC.

+ +

Applications that need to specify the DNSSEC trust anchors can use:

+
+getdns_return_t +getdns_context_set_dnssec_trust_anchors( + getdns_context_t context, + struct getdns_list *value +);
+

The value is a list of bindatas that are the DNSSEC trust anchors. The default +is the trust anchors from the IANA root. The trust anchors +are expressed as RDATAs from DNSKEY resource records.

+ +

In the rare case that an application needs to set the DNSSEC skew, it can:

+
+getdns_return_t +getdns_context_set_dnssec_allowed_skew( + getdns_context_t context, + uint16_t value +);
+

The value is the number of seconds of skew that is allowed in either direction when +checking an RRSIG's Expiration and Inception fields. The default +is 0.

+ +

8.7 Context Specific to Stub Resolvers

+ +

An application can change the quering mechanism of a context to be to act as a stub +resolver. Such an application might first get the default information to make this change +from the operating system, probably through DHCP.

+ +

Note that if a context is changed to being a stub resolver, this automatically prevents the application +from using the extenstions for DNSSEC. An application that wants to both do DNSSEC and stub resolution +must do its own DNSSEC processing, possibly with the getdns_validate_dnssec() function.

+ +
+getdns_return_t +getdns_context_set_stub_resolution( + getdns_context_t context, + struct getdns_list *upstream_list +);
+

The list of dicts define where a stub resolver will send queries. Each dict contains +at least two names: address_type (whose value is a bindata; it is currently either +"IPv4" or "IPv6") and address_data (whose value is a bindata). It might also contain +port to specify which port to use to contact these DNS servers; the default is 53. If +the stub and a recursive resolver both support TSIG (RFC 2845), the upstream_list entry +can also contain tsig_algorithm (a bindata) that is the name of the TSIG hash +algorithm, and tsig_secret (a bindata) that is the TSIG key.

+ +

8.8 Context for EDNS

+ +

These context settings affect queries that have extensions that specify the use of OPT resource records. +These come from RFC 2671.

+ +
+getdns_return_t +getdns_context_set_edns_maximum_udp_payload_size( + getdns_context_t context, + uint16_t value +);
+

The value is between 512 and 65535; the default +is 512.

+ +
+getdns_return_t +getdns_context_set_edns_extended_rcode( + getdns_context_t context, + uint8_t value +);
+

The value is between 0 and 256; the default +is 0.

+ +
+getdns_return_t +getdns_context_set_edns_version( + getdns_context_t context, + uint8_t value +);
+

The value is between 0 and 256; the default +is 0.

+ +
+getdns_return_t +getdns_context_set_edns_do_bit( + getdns_context_t context, + uint8_t value +);
+

The value is between 0 and 1; the default +is 0.

+ +

8.9 Context Use of C Functions

+ +
+getdns_return_t +getdns_context_set_memory_allocator( + getdns_context_t context, + void (*value)(size_t somesize) +);
+

The value is a function pointer to the memory allocator; the +default is the malloc function.

+ +
+getdns_return_t +getdns_context_set_memory_deallocator( + getdns_context_t context, + void (*value)(void*) +);
+

The value is a function pointer to the memory deallocator; the +default is the free function.

+ +
+getdns_return_t +getdns_context_set_memory_reallocator( + getdns_context_t context, + void (*value)(void*) +);
+

The value is a function pointer to the memory reallocator; the +default is the realloc function.

+ +

8.10 Context Codes

+ +

The context codes for getdns_context_set_context_update_callback() are:

+ +

GETDNS_CONTEXT_CODE_NAMESPACES

+

Change related to getdns_context_set_namespaces

+

GETDNS_CONTEXT_CODE_RESOLUTION_TYPE

+

Change related to getdns_context_set_resolution_type

+

GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS

+

Change related to getdns_context_set_follow_redirects

+

GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS

+

Change related to getdns_context_set_upstream_recursive_servers

+

GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS

+

Change related to getdns_context_set_dns_root_servers

+

GETDNS_CONTEXT_CODE_USE_UDP_TCP

+

Change related to getdns_context_set_use_udp_tcp

+

GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES

+

Change related to getdns_context_set_limit_outstanding_queries

+

GETDNS_CONTEXT_CODE_APPEND_NAME

+

Change related to getdns_context_set_append_name

+

GETDNS_CONTEXT_CODE_SUFFIX

+

Change related to getdns_context_set_suffix

+

GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS

+

Change related to getdns_context_set_dnssec_trust_anchors

+

GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE

+

Change related to getdns_context_set_edns_maximum_udp_payload_size

+

GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE

+

Change related to getdns_context_set_edns_extended_rcode

+

GETDNS_CONTEXT_CODE_EDNS_VERSION

+

Change related to getdns_context_set_edns_version

+

GETDNS_CONTEXT_CODE_EDNS_DO_BIT

+

Change related to getdns_context_set_edns_do_bit

+

GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW

+

Change related to getdns_context_set_dnssec_allowed_skew

+

GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR

+

Change related to getdns_context_set_memory_allocator

+

GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR

+

Change related to getdns_context_set_memory_deallocator

+

GETDNS_CONTEXT_CODE_MEMORY_REALLOCATOR

+

Change related to getdns_context_set_memory_reallocator

+ + +

9. The Generated Files

+ +

There is a tarball that includes the .h files, +the examples, and so on. The examples all make, even though there is no API implementation, based +on a pseudo-implementation in the tarball; see make-examples-PLATFORM.sh. Note that this currently builds fine +on the Macintosh and Ubuntu; help is definitely appreciated on making the build process +work on more platforms if it fails there.

+ +

10. Commentary

+ +

The following description of the API may be of value to those who might implement the design, and +those who are using an implementation of the design.

+ +

10.1 API Design Considerations

+ +

The genesis of this DNS API design was seeing other DNS API designs flounder. There are other +DNS APIs already available (such as draft-hayatnagarkar-dnsext-validator-api, as well +as DNSSEC APIs in BIND and Unbound), but there has been very little uptake of them. In talking to +application developers, there was a consistent story: that they felt that the APIs were developed by and +for DNS people, not applications developers.

+ +

This API design comes from talking to a small handful of applications developers about what they +would want to see in a modern DNS API. Now that the API is public, it would be great to hear from many +more application developers about whether it would meet their needs if it was implemented. My goal +is to create a design that is a natural follow-on to getaddrinfo() that has all the +capabilities that most application developers might want now or in the next few years: access to all +types of DNS records (including those which are yet to be defined), full DNSSEC awareness, IDN +handling, and parity for IPv4 and IPv6 addresses.

+ +

Note that this is just a design for a new API: there is no implementation of the design yet, but +at least one is being worked on. The process of designing the API without implementing it at the +same time has the huge advantage that major design changes could be made without any worry about +"but we already coded it the other way". In the early revisions of this document, many fundamental +design choices changed over and over, and even bike-shedding-like changes were allowed because they +didn't involve any programming effort.

+ +

This work was done independently, not through the IETF because the IETF generally doesn't take on +API work, and has explicitly avoided DNS API work in the past.

+ +

This API design has a Creative Commons license so that it can be +used widely by potential API implementers. This also allows other people who want to fork the design +to do so cleanly. Of course, any implementation of this API can choose whatever kind of license the +API implementer wishes, but it would be fabulous if one or more such implementations had Creative +Commons or BSD-ish licenses.

+ +

The API relies heavily on C macros and hopefully has no magic numbers.

+ +

10.2 API Implementation Considerations

+ +

All implementations of this API must act as recursive resolvers, and some might choose not to be +able to act as stub resolvers. Note that all implementations of this API must be DNSSEC validators.

+ +

Because there are many C event libraries available, and they have different calling routines, +it is the implementation of an API that determines which event library is used. This is certainly +not optimal for C programmers, but they appear to have gotten used to is so far. All implementations +of this API must support synchronous calls with getdns_sync_request().

+ +

Versions are differentiated by version strings instead of version numbers. The version string for +this API is "getdns April 2013". Each implementation is free to set the implementation string as it +feels fit.

+ +

The API's .h file contains a macro called GETDNS_COMPILATION_COMMENT. This can be useful +to an application which will use the API because it can check the string without calling any +functions. Each time the API implementation is compiled, this string should be updated with unique +information about the implementation build.

+ +

The implementation of both the async and sync getdns functions will +copy all the values of the parameters into local memory, in case the application changes or +deallocates them.

+ +
+ +

Creative
+Commons License
This work is licensed under a Creative Commons Attribution 3.0 +Unported License.

+ + diff --git a/src/src/install-sh b/src/src/install-sh new file mode 100755 index 00000000..6781b987 --- /dev/null +++ b/src/src/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/src/make-examples-linux.sh b/src/src/make-examples-linux.sh new file mode 100755 index 00000000..ca56726d --- /dev/null +++ b/src/src/make-examples-linux.sh @@ -0,0 +1,22 @@ +rm -rf *.o *.dylib +gcc -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c getdns_core_only.c +gcc -std=c89 -shared -fPIC -levent_core -o libgetdns.so getdns_core_only.o +gcc -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-all-functions.c +gcc -std=c89 -fPIC -L./ example-all-functions.o -levent_core -lgetdns -o example-all-functions +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-simple-answers.c +gcc -std=c99 -fPIC -L./ example-simple-answers.o -levent_core -lgetdns -o example-simple-answers +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-tree.c +gcc -std=c99 -fPIC -L./ example-tree.o -levent_core -lgetdns -o example-tree +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-synchronous.c +gcc -std=c99 -fPIC -L./ example-synchronous.o -levent_core -lgetdns -o example-synchronous +rm -rf *.o *.dylib +clang -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c getdns_core_only.c +clang -std=c89 -shared -fPIC -levent_core -o libgetdns.so getdns_core_only.o +clang -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-all-functions.c +clang -std=c89 -fPIC -L./ example-all-functions.o -levent_core -lgetdns -o example-all-functions +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-simple-answers.c +clang -std=c99 -fPIC -L./ example-simple-answers.o -levent_core -lgetdns -o example-simple-answers +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-tree.c +clang -std=c99 -fPIC -L./ example-tree.o -levent_core -lgetdns -o example-tree +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-synchronous.c +clang -std=c99 -fPIC -L./ example-synchronous.o -levent_core -lgetdns -o example-synchronous diff --git a/src/src/make-examples-mac.sh b/src/src/make-examples-mac.sh new file mode 100755 index 00000000..02c91eb0 --- /dev/null +++ b/src/src/make-examples-mac.sh @@ -0,0 +1,22 @@ +rm -rf *.o *.dylib +gcc -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c getdns_core_only.c +gcc -std=c89 -dynamiclib -fPIC -levent_core -o libgetdns.dylib getdns_core_only.o +gcc -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-all-functions.c +gcc -std=c89 -fPIC -L./ example-all-functions.o -levent_core -lgetdns -o example-all-functions +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-simple-answers.c +gcc -std=c99 -fPIC -L./ example-simple-answers.o -levent_core -lgetdns -o example-simple-answers +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-tree.c +gcc -std=c99 -fPIC -L./ example-tree.o -levent_core -lgetdns -o example-tree +gcc -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-synchronous.c +gcc -std=c99 -fPIC -L./ example-synchronous.o -levent_core -lgetdns -o example-synchronous +rm -rf *.o *.dylib +clang -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c getdns_core_only.c +clang -std=c89 -dynamiclib -fPIC -levent_core -o libgetdns.dylib getdns_core_only.o +clang -std=c89 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-all-functions.c +clang -std=c89 -fPIC -L./ example-all-functions.o -levent_core -lgetdns -o example-all-functions +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-simple-answers.c +clang -std=c99 -fPIC -L./ example-simple-answers.o -levent_core -lgetdns -o example-simple-answers +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-tree.c +clang -std=c99 -fPIC -L./ example-tree.o -levent_core -lgetdns -o example-tree +clang -std=c99 -c -fPIC -pedantic -g -I./ -Werror -Wall -Wextra -c example-synchronous.c +clang -std=c99 -fPIC -L./ example-synchronous.o -levent_core -lgetdns -o example-synchronous diff --git a/src/src/missing b/src/src/missing new file mode 100755 index 00000000..28055d2a --- /dev/null +++ b/src/src/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: