diff options
Diffstat (limited to 'lib/isccc')
-rw-r--r-- | lib/isccc/Makefile.am | 38 | ||||
-rw-r--r-- | lib/isccc/Makefile.in | 956 | ||||
-rw-r--r-- | lib/isccc/alist.c | 320 | ||||
-rw-r--r-- | lib/isccc/base64.c | 74 | ||||
-rw-r--r-- | lib/isccc/cc.c | 1057 | ||||
-rw-r--r-- | lib/isccc/ccmsg.c | 185 | ||||
-rw-r--r-- | lib/isccc/include/isccc/alist.h | 86 | ||||
-rw-r--r-- | lib/isccc/include/isccc/base64.h | 79 | ||||
-rw-r--r-- | lib/isccc/include/isccc/cc.h | 131 | ||||
-rw-r--r-- | lib/isccc/include/isccc/ccmsg.h | 137 | ||||
-rw-r--r-- | lib/isccc/include/isccc/events.h | 43 | ||||
-rw-r--r-- | lib/isccc/include/isccc/sexpr.h | 119 | ||||
-rw-r--r-- | lib/isccc/include/isccc/symtab.h | 133 | ||||
-rw-r--r-- | lib/isccc/include/isccc/symtype.h | 37 | ||||
-rw-r--r-- | lib/isccc/include/isccc/types.h | 52 | ||||
-rw-r--r-- | lib/isccc/include/isccc/util.h | 208 | ||||
-rw-r--r-- | lib/isccc/sexpr.c | 317 | ||||
-rw-r--r-- | lib/isccc/symtab.c | 293 |
18 files changed, 4265 insertions, 0 deletions
diff --git a/lib/isccc/Makefile.am b/lib/isccc/Makefile.am new file mode 100644 index 0000000..7877bfb --- /dev/null +++ b/lib/isccc/Makefile.am @@ -0,0 +1,38 @@ +include $(top_srcdir)/Makefile.top + +lib_LTLIBRARIES = libisccc.la + +libisccc_ladir = $(includedir)/isccc +libisccc_la_HEADERS = \ + include/isccc/alist.h \ + include/isccc/base64.h \ + include/isccc/cc.h \ + include/isccc/ccmsg.h \ + include/isccc/events.h \ + include/isccc/sexpr.h \ + include/isccc/symtab.h \ + include/isccc/symtype.h \ + include/isccc/types.h \ + include/isccc/util.h + +libisccc_la_SOURCES = \ + $(libisccc_la_HEADERS) \ + alist.c \ + base64.c \ + cc.c \ + ccmsg.c \ + sexpr.c \ + symtab.c + +libisccc_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(LIBISC_CFLAGS) \ + $(LIBDNS_CFLAGS) \ + $(LIBISCCC_CFLAGS) + +libisccc_la_LIBADD = \ + $(LIBISC_LIBS) + +libisccc_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -release "$(PACKAGE_VERSION)" diff --git a/lib/isccc/Makefile.in b/lib/isccc/Makefile.in new file mode 100644 index 0000000..3fee7ca --- /dev/null +++ b/lib/isccc/Makefile.in @@ -0,0 +1,956 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in 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. + +@SET_MAKE@ + +# Hey Emacs, this is -*- makefile-automake -*- file! +# vim: filetype=automake + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@HOST_MACOS_TRUE@am__append_1 = \ +@HOST_MACOS_TRUE@ -Wl,-flat_namespace + +subdir = lib/isccc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_check_openssl.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_jemalloc.m4 \ + $(top_srcdir)/m4/ax_lib_lmdb.m4 \ + $(top_srcdir)/m4/ax_perl_module.m4 \ + $(top_srcdir)/m4/ax_posix_shell.m4 \ + $(top_srcdir)/m4/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/ax_python_module.m4 \ + $(top_srcdir)/m4/ax_restore_flags.m4 \ + $(top_srcdir)/m4/ax_save_flags.m4 $(top_srcdir)/m4/ax_tls.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(libisccc_la_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libisccc_ladir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libisccc_la_DEPENDENCIES = $(LIBISC_LIBS) +am__objects_1 = +am_libisccc_la_OBJECTS = $(am__objects_1) libisccc_la-alist.lo \ + libisccc_la-base64.lo libisccc_la-cc.lo libisccc_la-ccmsg.lo \ + libisccc_la-sexpr.lo libisccc_la-symtab.lo +libisccc_la_OBJECTS = $(am_libisccc_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libisccc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libisccc_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libisccc_la-alist.Plo \ + ./$(DEPDIR)/libisccc_la-base64.Plo \ + ./$(DEPDIR)/libisccc_la-cc.Plo \ + ./$(DEPDIR)/libisccc_la-ccmsg.Plo \ + ./$(DEPDIR)/libisccc_la-sexpr.Plo \ + ./$(DEPDIR)/libisccc_la-symtab.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libisccc_la_SOURCES) +DIST_SOURCES = $(libisccc_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(libisccc_la_HEADERS) +am__extra_recursive_targets = test-recursive unit-recursive \ + doc-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/Makefile.top \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ +CMOCKA_LIBS = @CMOCKA_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CURL = @CURL@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEVELOPER_MODE = @DEVELOPER_MODE@ +DLLTOOL = @DLLTOOL@ +DNSTAP_CFLAGS = @DNSTAP_CFLAGS@ +DNSTAP_LIBS = @DNSTAP_LIBS@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FSTRM_CAPTURE = @FSTRM_CAPTURE@ +FUZZ_LDFLAGS = @FUZZ_LDFLAGS@ +FUZZ_LOG_COMPILER = @FUZZ_LOG_COMPILER@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@ +JEMALLOC_LIBS = @JEMALLOC_LIBS@ +JSON_C_CFLAGS = @JSON_C_CFLAGS@ +JSON_C_LIBS = @JSON_C_LIBS@ +KRB5_CFLAGS = @KRB5_CFLAGS@ +KRB5_CONFIG = @KRB5_CONFIG@ +KRB5_LIBS = @KRB5_LIBS@ +LATEXMK = @LATEXMK@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBCAP_LIBS = @LIBCAP_LIBS@ +LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@ +LIBIDN2_LIBS = @LIBIDN2_LIBS@ +LIBNGHTTP2_CFLAGS = @LIBNGHTTP2_CFLAGS@ +LIBNGHTTP2_LIBS = @LIBNGHTTP2_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUV_CFLAGS = @LIBUV_CFLAGS@ +LIBUV_LIBS = @LIBUV_LIBS@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LMDB_CFLAGS = @LMDB_CFLAGS@ +LMDB_LIBS = @LMDB_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MAXMINDDB_CFLAGS = @MAXMINDDB_CFLAGS@ +MAXMINDDB_LIBS = @MAXMINDDB_LIBS@ +MAXMINDDB_PREFIX = @MAXMINDDB_PREFIX@ +MKDIR_P = @MKDIR_P@ +NC = @NC@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTOC_C = @PROTOC_C@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTEST = @PYTEST@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +READLINE_CFLAGS = @READLINE_CFLAGS@ +READLINE_LIBS = @READLINE_LIBS@ +RELEASE_DATE = @RELEASE_DATE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX_BUILD = @SPHINX_BUILD@ +STD_CFLAGS = @STD_CFLAGS@ +STD_CPPFLAGS = @STD_CPPFLAGS@ +STD_LDFLAGS = @STD_LDFLAGS@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +VERSION = @VERSION@ +XELATEX = @XELATEX@ +XSLTPROC = @XSLTPROC@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4 +AM_CFLAGS = \ + $(STD_CFLAGS) + +AM_CPPFLAGS = \ + $(STD_CPPFLAGS) \ + -include $(top_builddir)/config.h \ + -I$(srcdir)/include + +AM_LDFLAGS = $(STD_LDFLAGS) $(am__append_1) +LDADD = +LIBISC_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib/isc/include \ + -I$(top_builddir)/lib/isc/include + +LIBISC_LIBS = $(top_builddir)/lib/isc/libisc.la +LIBDNS_CFLAGS = \ + -I$(top_srcdir)/lib/dns/include \ + -I$(top_builddir)/lib/dns/include + +LIBDNS_LIBS = \ + $(top_builddir)/lib/dns/libdns.la + +LIBNS_CFLAGS = \ + -I$(top_srcdir)/lib/ns/include + +LIBNS_LIBS = \ + $(top_builddir)/lib/ns/libns.la + +LIBIRS_CFLAGS = \ + -I$(top_srcdir)/lib/irs/include + +LIBIRS_LIBS = \ + $(top_builddir)/lib/irs/libirs.la + +LIBISCCFG_CFLAGS = \ + -I$(top_srcdir)/lib/isccfg/include + +LIBISCCFG_LIBS = \ + $(top_builddir)/lib/isccfg/libisccfg.la + +LIBISCCC_CFLAGS = \ + -I$(top_srcdir)/lib/isccc/include/ + +LIBISCCC_LIBS = \ + $(top_builddir)/lib/isccc/libisccc.la + +LIBBIND9_CFLAGS = \ + -I$(top_srcdir)/lib/bind9/include + +LIBBIND9_LIBS = \ + $(top_builddir)/lib/bind9/libbind9.la + +lib_LTLIBRARIES = libisccc.la +libisccc_ladir = $(includedir)/isccc +libisccc_la_HEADERS = \ + include/isccc/alist.h \ + include/isccc/base64.h \ + include/isccc/cc.h \ + include/isccc/ccmsg.h \ + include/isccc/events.h \ + include/isccc/sexpr.h \ + include/isccc/symtab.h \ + include/isccc/symtype.h \ + include/isccc/types.h \ + include/isccc/util.h + +libisccc_la_SOURCES = \ + $(libisccc_la_HEADERS) \ + alist.c \ + base64.c \ + cc.c \ + ccmsg.c \ + sexpr.c \ + symtab.c + +libisccc_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(LIBISC_CFLAGS) \ + $(LIBDNS_CFLAGS) \ + $(LIBISCCC_CFLAGS) + +libisccc_la_LIBADD = \ + $(LIBISC_LIBS) + +libisccc_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -release "$(PACKAGE_VERSION)" + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.top $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/isccc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/isccc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.top $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libisccc.la: $(libisccc_la_OBJECTS) $(libisccc_la_DEPENDENCIES) $(EXTRA_libisccc_la_DEPENDENCIES) + $(AM_V_CCLD)$(libisccc_la_LINK) -rpath $(libdir) $(libisccc_la_OBJECTS) $(libisccc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-alist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-base64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-cc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-ccmsg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-sexpr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisccc_la-symtab.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libisccc_la-alist.lo: alist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-alist.lo -MD -MP -MF $(DEPDIR)/libisccc_la-alist.Tpo -c -o libisccc_la-alist.lo `test -f 'alist.c' || echo '$(srcdir)/'`alist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-alist.Tpo $(DEPDIR)/libisccc_la-alist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alist.c' object='libisccc_la-alist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-alist.lo `test -f 'alist.c' || echo '$(srcdir)/'`alist.c + +libisccc_la-base64.lo: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-base64.lo -MD -MP -MF $(DEPDIR)/libisccc_la-base64.Tpo -c -o libisccc_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-base64.Tpo $(DEPDIR)/libisccc_la-base64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='libisccc_la-base64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +libisccc_la-cc.lo: cc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-cc.lo -MD -MP -MF $(DEPDIR)/libisccc_la-cc.Tpo -c -o libisccc_la-cc.lo `test -f 'cc.c' || echo '$(srcdir)/'`cc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-cc.Tpo $(DEPDIR)/libisccc_la-cc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cc.c' object='libisccc_la-cc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-cc.lo `test -f 'cc.c' || echo '$(srcdir)/'`cc.c + +libisccc_la-ccmsg.lo: ccmsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-ccmsg.lo -MD -MP -MF $(DEPDIR)/libisccc_la-ccmsg.Tpo -c -o libisccc_la-ccmsg.lo `test -f 'ccmsg.c' || echo '$(srcdir)/'`ccmsg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-ccmsg.Tpo $(DEPDIR)/libisccc_la-ccmsg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ccmsg.c' object='libisccc_la-ccmsg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-ccmsg.lo `test -f 'ccmsg.c' || echo '$(srcdir)/'`ccmsg.c + +libisccc_la-sexpr.lo: sexpr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-sexpr.lo -MD -MP -MF $(DEPDIR)/libisccc_la-sexpr.Tpo -c -o libisccc_la-sexpr.lo `test -f 'sexpr.c' || echo '$(srcdir)/'`sexpr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-sexpr.Tpo $(DEPDIR)/libisccc_la-sexpr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sexpr.c' object='libisccc_la-sexpr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-sexpr.lo `test -f 'sexpr.c' || echo '$(srcdir)/'`sexpr.c + +libisccc_la-symtab.lo: symtab.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisccc_la-symtab.lo -MD -MP -MF $(DEPDIR)/libisccc_la-symtab.Tpo -c -o libisccc_la-symtab.lo `test -f 'symtab.c' || echo '$(srcdir)/'`symtab.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisccc_la-symtab.Tpo $(DEPDIR)/libisccc_la-symtab.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='symtab.c' object='libisccc_la-symtab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisccc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisccc_la-symtab.lo `test -f 'symtab.c' || echo '$(srcdir)/'`symtab.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-libisccc_laHEADERS: $(libisccc_la_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libisccc_la_HEADERS)'; test -n "$(libisccc_ladir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libisccc_ladir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libisccc_ladir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libisccc_ladir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libisccc_ladir)" || exit $$?; \ + done + +uninstall-libisccc_laHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libisccc_la_HEADERS)'; test -n "$(libisccc_ladir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libisccc_ladir)'; $(am__uninstall_files_from_dir) +test-local: +unit-local: +doc-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libisccc_ladir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo + -rm -f ./$(DEPDIR)/libisccc_la-base64.Plo + -rm -f ./$(DEPDIR)/libisccc_la-cc.Plo + -rm -f ./$(DEPDIR)/libisccc_la-ccmsg.Plo + -rm -f ./$(DEPDIR)/libisccc_la-sexpr.Plo + -rm -f ./$(DEPDIR)/libisccc_la-symtab.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +doc: doc-am + +doc-am: doc-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-libisccc_laHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo + -rm -f ./$(DEPDIR)/libisccc_la-base64.Plo + -rm -f ./$(DEPDIR)/libisccc_la-cc.Plo + -rm -f ./$(DEPDIR)/libisccc_la-ccmsg.Plo + -rm -f ./$(DEPDIR)/libisccc_la-sexpr.Plo + -rm -f ./$(DEPDIR)/libisccc_la-symtab.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +test: test-am + +test-am: test-local + +uninstall-am: uninstall-libLTLIBRARIES uninstall-libisccc_laHEADERS + +unit: unit-am + +unit-am: unit-local + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir doc-am doc-local dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-libisccc_laHEADERS install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am test-am test-local uninstall uninstall-am \ + uninstall-libLTLIBRARIES uninstall-libisccc_laHEADERS unit-am \ + unit-local + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/isccc/alist.c b/lib/isccc/alist.c new file mode 100644 index 0000000..182ada0 --- /dev/null +++ b/lib/isccc/alist.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <isc/assertions.h> +#include <isc/print.h> +#include <isc/result.h> + +#include <isccc/alist.h> +#include <isccc/sexpr.h> +#include <isccc/util.h> + +#define CAR(s) (s)->value.as_dottedpair.car +#define CDR(s) (s)->value.as_dottedpair.cdr + +#define ALIST_TAG "*alist*" +#define MAX_INDENT 64 + +static char spaces[MAX_INDENT + 1] = " " + " "; + +isccc_sexpr_t * +isccc_alist_create(void) { + isccc_sexpr_t *alist, *tag; + + tag = isccc_sexpr_fromstring(ALIST_TAG); + if (tag == NULL) { + return (NULL); + } + alist = isccc_sexpr_cons(tag, NULL); + if (alist == NULL) { + isccc_sexpr_free(&tag); + return (NULL); + } + + return (alist); +} + +bool +isccc_alist_alistp(isccc_sexpr_t *alist) { + isccc_sexpr_t *car; + + if (alist == NULL || alist->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) { + return (false); + } + car = CAR(alist); + if (car == NULL || car->type != ISCCC_SEXPRTYPE_STRING) { + return (false); + } + if (strcmp(car->value.as_string, ALIST_TAG) != 0) { + return (false); + } + return (true); +} + +bool +isccc_alist_emptyp(isccc_sexpr_t *alist) { + REQUIRE(isccc_alist_alistp(alist)); + + if (CDR(alist) == NULL) { + return (true); + } + return (false); +} + +isccc_sexpr_t * +isccc_alist_first(isccc_sexpr_t *alist) { + REQUIRE(isccc_alist_alistp(alist)); + + return (CDR(alist)); +} + +isccc_sexpr_t * +isccc_alist_assq(isccc_sexpr_t *alist, const char *key) { + isccc_sexpr_t *car, *caar; + + REQUIRE(isccc_alist_alistp(alist)); + + /* + * Skip alist type tag. + */ + alist = CDR(alist); + + while (alist != NULL) { + INSIST(alist->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + car = CAR(alist); + INSIST(car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + caar = CAR(car); + if (caar->type == ISCCC_SEXPRTYPE_STRING && + strcmp(caar->value.as_string, key) == 0) + { + return (car); + } + alist = CDR(alist); + } + + return (NULL); +} + +void +isccc_alist_delete(isccc_sexpr_t *alist, const char *key) { + isccc_sexpr_t *car, *caar, *rest, *prev; + + REQUIRE(isccc_alist_alistp(alist)); + + prev = alist; + rest = CDR(alist); + while (rest != NULL) { + INSIST(rest->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + car = CAR(rest); + INSIST(car != NULL && car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + caar = CAR(car); + if (caar->type == ISCCC_SEXPRTYPE_STRING && + strcmp(caar->value.as_string, key) == 0) + { + CDR(prev) = CDR(rest); + CDR(rest) = NULL; + isccc_sexpr_free(&rest); + break; + } + prev = rest; + rest = CDR(rest); + } +} + +isccc_sexpr_t * +isccc_alist_define(isccc_sexpr_t *alist, const char *key, + isccc_sexpr_t *value) { + isccc_sexpr_t *kv, *k, *elt; + + kv = isccc_alist_assq(alist, key); + if (kv == NULL) { + /* + * New association. + */ + k = isccc_sexpr_fromstring(key); + if (k == NULL) { + return (NULL); + } + kv = isccc_sexpr_cons(k, value); + if (kv == NULL) { + isccc_sexpr_free(&kv); + return (NULL); + } + elt = isccc_sexpr_addtolist(&alist, kv); + if (elt == NULL) { + isccc_sexpr_free(&kv); + return (NULL); + } + } else { + /* + * We've already got an entry for this key. Replace it. + */ + isccc_sexpr_free(&CDR(kv)); + CDR(kv) = value; + } + + return (kv); +} + +isccc_sexpr_t * +isccc_alist_definestring(isccc_sexpr_t *alist, const char *key, + const char *str) { + isccc_sexpr_t *v, *kv; + + v = isccc_sexpr_fromstring(str); + if (v == NULL) { + return (NULL); + } + kv = isccc_alist_define(alist, key, v); + if (kv == NULL) { + isccc_sexpr_free(&v); + } + + return (kv); +} + +isccc_sexpr_t * +isccc_alist_definebinary(isccc_sexpr_t *alist, const char *key, + isccc_region_t *r) { + isccc_sexpr_t *v, *kv; + + v = isccc_sexpr_frombinary(r); + if (v == NULL) { + return (NULL); + } + kv = isccc_alist_define(alist, key, v); + if (kv == NULL) { + isccc_sexpr_free(&v); + } + + return (kv); +} + +isccc_sexpr_t * +isccc_alist_lookup(isccc_sexpr_t *alist, const char *key) { + isccc_sexpr_t *kv; + + kv = isccc_alist_assq(alist, key); + if (kv != NULL) { + return (CDR(kv)); + } + return (NULL); +} + +isc_result_t +isccc_alist_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp) { + isccc_sexpr_t *kv, *v; + + kv = isccc_alist_assq(alist, key); + if (kv != NULL) { + v = CDR(kv); + if (isccc_sexpr_stringp(v)) { + if (strp != NULL) { + *strp = isccc_sexpr_tostring(v); + } + return (ISC_R_SUCCESS); + } else { + return (ISC_R_EXISTS); + } + } + + return (ISC_R_NOTFOUND); +} + +isc_result_t +isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, + isccc_region_t **r) { + isccc_sexpr_t *kv, *v; + + kv = isccc_alist_assq(alist, key); + if (kv != NULL) { + v = CDR(kv); + if (isccc_sexpr_binaryp(v)) { + if (r != NULL) { + *r = isccc_sexpr_tobinary(v); + } + return (ISC_R_SUCCESS); + } else { + return (ISC_R_EXISTS); + } + } + + return (ISC_R_NOTFOUND); +} + +void +isccc_alist_prettyprint(isccc_sexpr_t *sexpr, unsigned int indent, + FILE *stream) { + isccc_sexpr_t *elt, *kv, *k, *v; + + if (isccc_alist_alistp(sexpr)) { + fprintf(stream, "{\n"); + indent += 4; + for (elt = isccc_alist_first(sexpr); elt != NULL; + elt = CDR(elt)) + { + kv = CAR(elt); + INSIST(isccc_sexpr_listp(kv)); + k = CAR(kv); + v = CDR(kv); + INSIST(isccc_sexpr_stringp(k)); + fprintf(stream, "%.*s%s => ", (int)indent, spaces, + isccc_sexpr_tostring(k)); + isccc_alist_prettyprint(v, indent, stream); + if (CDR(elt) != NULL) { + fprintf(stream, ","); + } + fprintf(stream, "\n"); + } + indent -= 4; + fprintf(stream, "%.*s}", (int)indent, spaces); + } else if (isccc_sexpr_listp(sexpr)) { + fprintf(stream, "(\n"); + indent += 4; + for (elt = sexpr; elt != NULL; elt = CDR(elt)) { + fprintf(stream, "%.*s", (int)indent, spaces); + isccc_alist_prettyprint(CAR(elt), indent, stream); + if (CDR(elt) != NULL) { + fprintf(stream, ","); + } + fprintf(stream, "\n"); + } + indent -= 4; + fprintf(stream, "%.*s)", (int)indent, spaces); + } else { + isccc_sexpr_print(sexpr, stream); + } +} diff --git a/lib/isccc/base64.c b/lib/isccc/base64.c new file mode 100644 index 0000000..fd0f381 --- /dev/null +++ b/lib/isccc/base64.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <isc/base64.h> +#include <isc/buffer.h> +#include <isc/region.h> +#include <isc/result.h> + +#include <isccc/base64.h> +#include <isccc/util.h> + +isc_result_t +isccc_base64_encode(isccc_region_t *source, int wordlength, + const char *wordbreak, isccc_region_t *target) { + isc_region_t sr; + isc_buffer_t tb; + isc_result_t result; + + sr.base = source->rstart; + sr.length = (unsigned int)(source->rend - source->rstart); + isc_buffer_init(&tb, target->rstart, + (unsigned int)(target->rend - target->rstart)); + + result = isc_base64_totext(&sr, wordlength, wordbreak, &tb); + if (result != ISC_R_SUCCESS) { + return (result); + } + source->rstart = source->rend; + target->rstart = isc_buffer_used(&tb); + return (ISC_R_SUCCESS); +} + +isc_result_t +isccc_base64_decode(const char *cstr, isccc_region_t *target) { + isc_buffer_t b; + isc_result_t result; + + isc_buffer_init(&b, target->rstart, + (unsigned int)(target->rend - target->rstart)); + result = isc_base64_decodestring(cstr, &b); + if (result != ISC_R_SUCCESS) { + return (result); + } + target->rstart = isc_buffer_used(&b); + return (ISC_R_SUCCESS); +} diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c new file mode 100644 index 0000000..cbd9bad --- /dev/null +++ b/lib/isccc/cc.c @@ -0,0 +1,1057 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <errno.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <isc/assertions.h> +#include <isc/hmac.h> +#include <isc/print.h> +#include <isc/result.h> +#include <isc/safe.h> + +#include <isccc/alist.h> +#include <isccc/base64.h> +#include <isccc/cc.h> +#include <isccc/sexpr.h> +#include <isccc/symtab.h> +#include <isccc/symtype.h> +#include <isccc/util.h> + +#define MAX_TAGS 256 +#define DUP_LIFETIME 900 +#ifndef ISCCC_MAXDEPTH +#define ISCCC_MAXDEPTH \ + 10 /* Big enough for rndc which just sends a string each way. */ +#endif + +typedef isccc_sexpr_t *sexpr_ptr; + +static unsigned char auth_hmd5[] = { + 0x05, 0x5f, 0x61, 0x75, 0x74, 0x68, /*%< len + _auth */ + ISCCC_CCMSGTYPE_TABLE, /*%< message type */ + 0x00, 0x00, 0x00, 0x20, /*%< length == 32 */ + 0x04, 0x68, 0x6d, 0x64, 0x35, /*%< len + hmd5 */ + ISCCC_CCMSGTYPE_BINARYDATA, /*%< message type */ + 0x00, 0x00, 0x00, 0x16, /*%< length == 22 */ + /* + * The base64 encoding of one of our HMAC-MD5 signatures is + * 22 bytes. + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#define HMD5_OFFSET 21 /*%< 21 = 6 + 1 + 4 + 5 + 1 + 4 */ +#define HMD5_LENGTH 22 + +static unsigned char auth_hsha[] = { + 0x05, 0x5f, 0x61, 0x75, 0x74, 0x68, /*%< len + _auth */ + ISCCC_CCMSGTYPE_TABLE, /*%< message type */ + 0x00, 0x00, 0x00, 0x63, /*%< length == 99 */ + 0x04, 0x68, 0x73, 0x68, 0x61, /*%< len + hsha */ + ISCCC_CCMSGTYPE_BINARYDATA, /*%< message type */ + 0x00, 0x00, 0x00, 0x59, /*%< length == 89 */ + 0x00, /*%< algorithm */ + /* + * The base64 encoding of one of our HMAC-SHA* signatures is + * 88 bytes. + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +#define HSHA_OFFSET 22 /*%< 21 = 6 + 1 + 4 + 5 + 1 + 4 + 1 */ +#define HSHA_LENGTH 88 + +static isc_result_t +table_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer); + +static isc_result_t +list_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer); + +static isc_result_t +value_towire(isccc_sexpr_t *elt, isc_buffer_t **buffer) { + unsigned int len; + isccc_region_t *vr; + isc_result_t result; + + if (isccc_sexpr_binaryp(elt)) { + vr = isccc_sexpr_tobinary(elt); + len = REGION_SIZE(*vr); + result = isc_buffer_reserve(buffer, 1 + 4); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_BINARYDATA); + isc_buffer_putuint32(*buffer, len); + + result = isc_buffer_reserve(buffer, len); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + isc_buffer_putmem(*buffer, vr->rstart, len); + } else if (isccc_alist_alistp(elt)) { + unsigned int used; + isc_buffer_t b; + + result = isc_buffer_reserve(buffer, 1 + 4); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_TABLE); + /* + * Emit a placeholder length. + */ + used = (*buffer)->used; + isc_buffer_putuint32(*buffer, 0); + + /* + * Emit the table. + */ + result = table_towire(elt, buffer); + if (result != ISC_R_SUCCESS) { + return (result); + } + + len = (*buffer)->used - used; + /* + * 'len' is 4 bytes too big, since it counts + * the placeholder length too. Adjust and + * emit. + */ + INSIST(len >= 4U); + len -= 4; + + isc_buffer_init(&b, (unsigned char *)(*buffer)->base + used, 4); + isc_buffer_putuint32(&b, len); + } else if (isccc_sexpr_listp(elt)) { + unsigned int used; + isc_buffer_t b; + + result = isc_buffer_reserve(buffer, 1 + 4); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_LIST); + /* + * Emit a placeholder length. + */ + used = (*buffer)->used; + isc_buffer_putuint32(*buffer, 0); + + /* + * Emit the list. + */ + result = list_towire(elt, buffer); + if (result != ISC_R_SUCCESS) { + return (result); + } + + len = (*buffer)->used - used; + /* + * 'len' is 4 bytes too big, since it counts + * the placeholder length too. Adjust and + * emit. + */ + INSIST(len >= 4U); + len -= 4; + + isc_buffer_init(&b, (unsigned char *)(*buffer)->base + used, 4); + isc_buffer_putuint32(&b, len); + } + + return (ISC_R_SUCCESS); +} + +static isc_result_t +table_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer) { + isccc_sexpr_t *kv, *elt, *k, *v; + char *ks; + isc_result_t result; + unsigned int len; + + for (elt = isccc_alist_first(alist); elt != NULL; + elt = ISCCC_SEXPR_CDR(elt)) + { + kv = ISCCC_SEXPR_CAR(elt); + k = ISCCC_SEXPR_CAR(kv); + ks = isccc_sexpr_tostring(k); + v = ISCCC_SEXPR_CDR(kv); + len = (unsigned int)strlen(ks); + INSIST(len <= 255U); + /* + * Emit the key name. + */ + result = isc_buffer_reserve(buffer, 1 + len); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + isc_buffer_putuint8(*buffer, (uint8_t)len); + isc_buffer_putmem(*buffer, (const unsigned char *)ks, len); + /* + * Emit the value. + */ + result = value_towire(v, buffer); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + return (ISC_R_SUCCESS); +} + +static isc_result_t +list_towire(isccc_sexpr_t *list, isc_buffer_t **buffer) { + isc_result_t result; + + while (list != NULL) { + result = value_towire(ISCCC_SEXPR_CAR(list), buffer); + if (result != ISC_R_SUCCESS) { + return (result); + } + list = ISCCC_SEXPR_CDR(list); + } + + return (ISC_R_SUCCESS); +} + +static isc_result_t +sign(unsigned char *data, unsigned int length, unsigned char *hmac, + uint32_t algorithm, isccc_region_t *secret) { + const isc_md_type_t *md_type; + isc_result_t result; + isccc_region_t source, target; + unsigned char digest[ISC_MAX_MD_SIZE]; + unsigned int digestlen = sizeof(digest); + unsigned char digestb64[HSHA_LENGTH + 4]; + + source.rstart = digest; + + switch (algorithm) { + case ISCCC_ALG_HMACMD5: + md_type = ISC_MD_MD5; + break; + case ISCCC_ALG_HMACSHA1: + md_type = ISC_MD_SHA1; + break; + case ISCCC_ALG_HMACSHA224: + md_type = ISC_MD_SHA224; + break; + case ISCCC_ALG_HMACSHA256: + md_type = ISC_MD_SHA256; + break; + case ISCCC_ALG_HMACSHA384: + md_type = ISC_MD_SHA384; + break; + case ISCCC_ALG_HMACSHA512: + md_type = ISC_MD_SHA512; + break; + default: + return (ISC_R_NOTIMPLEMENTED); + } + + result = isc_hmac(md_type, secret->rstart, REGION_SIZE(*secret), data, + length, digest, &digestlen); + if (result != ISC_R_SUCCESS) { + return (result); + } + source.rend = digest + digestlen; + + memset(digestb64, 0, sizeof(digestb64)); + target.rstart = digestb64; + target.rend = digestb64 + sizeof(digestb64); + result = isccc_base64_encode(&source, 64, "", &target); + if (result != ISC_R_SUCCESS) { + return (result); + } + if (algorithm == ISCCC_ALG_HMACMD5) { + PUT_MEM(digestb64, HMD5_LENGTH, hmac); + } else { + PUT_MEM(digestb64, HSHA_LENGTH, hmac); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +isccc_cc_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer, uint32_t algorithm, + isccc_region_t *secret) { + unsigned int hmac_base, signed_base; + isc_result_t result; + + result = isc_buffer_reserve(buffer, + 4 + ((algorithm == ISCCC_ALG_HMACMD5) + ? sizeof(auth_hmd5) + : sizeof(auth_hsha))); + if (result != ISC_R_SUCCESS) { + return (ISC_R_NOSPACE); + } + + /* + * Emit protocol version. + */ + isc_buffer_putuint32(*buffer, 1); + + if (secret != NULL) { + /* + * Emit _auth section with zeroed HMAC signature. + * We'll replace the zeros with the real signature once + * we know what it is. + */ + if (algorithm == ISCCC_ALG_HMACMD5) { + hmac_base = (*buffer)->used + HMD5_OFFSET; + isc_buffer_putmem(*buffer, auth_hmd5, + sizeof(auth_hmd5)); + } else { + unsigned char *hmac_alg; + + hmac_base = (*buffer)->used + HSHA_OFFSET; + hmac_alg = (unsigned char *)isc_buffer_used(*buffer) + + HSHA_OFFSET - 1; + isc_buffer_putmem(*buffer, auth_hsha, + sizeof(auth_hsha)); + *hmac_alg = algorithm; + } + } else { + hmac_base = 0; + } + signed_base = (*buffer)->used; + /* + * Delete any existing _auth section so that we don't try + * to encode it. + */ + isccc_alist_delete(alist, "_auth"); + /* + * Emit the message. + */ + result = table_towire(alist, buffer); + if (result != ISC_R_SUCCESS) { + return (result); + } + if (secret != NULL) { + return (sign((unsigned char *)(*buffer)->base + signed_base, + (*buffer)->used - signed_base, + (unsigned char *)(*buffer)->base + hmac_base, + algorithm, secret)); + } + return (ISC_R_SUCCESS); +} + +static isc_result_t +verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, + uint32_t algorithm, isccc_region_t *secret) { + const isc_md_type_t *md_type; + isccc_region_t source; + isccc_region_t target; + isc_result_t result; + isccc_sexpr_t *_auth, *hmac; + unsigned char digest[ISC_MAX_MD_SIZE]; + unsigned int digestlen = sizeof(digest); + unsigned char digestb64[HSHA_LENGTH * 4]; + + /* + * Extract digest. + */ + _auth = isccc_alist_lookup(alist, "_auth"); + if (!isccc_alist_alistp(_auth)) { + return (ISC_R_FAILURE); + } + if (algorithm == ISCCC_ALG_HMACMD5) { + hmac = isccc_alist_lookup(_auth, "hmd5"); + } else { + hmac = isccc_alist_lookup(_auth, "hsha"); + } + if (!isccc_sexpr_binaryp(hmac)) { + return (ISC_R_FAILURE); + } + /* + * Compute digest. + */ + source.rstart = digest; + + switch (algorithm) { + case ISCCC_ALG_HMACMD5: + md_type = ISC_MD_MD5; + break; + case ISCCC_ALG_HMACSHA1: + md_type = ISC_MD_SHA1; + break; + case ISCCC_ALG_HMACSHA224: + md_type = ISC_MD_SHA224; + break; + case ISCCC_ALG_HMACSHA256: + md_type = ISC_MD_SHA256; + break; + case ISCCC_ALG_HMACSHA384: + md_type = ISC_MD_SHA384; + break; + case ISCCC_ALG_HMACSHA512: + md_type = ISC_MD_SHA512; + break; + default: + return (ISC_R_NOTIMPLEMENTED); + } + + result = isc_hmac(md_type, secret->rstart, REGION_SIZE(*secret), data, + length, digest, &digestlen); + if (result != ISC_R_SUCCESS) { + return (result); + } + source.rend = digest + digestlen; + + target.rstart = digestb64; + target.rend = digestb64 + sizeof(digestb64); + memset(digestb64, 0, sizeof(digestb64)); + result = isccc_base64_encode(&source, 64, "", &target); + if (result != ISC_R_SUCCESS) { + return (result); + } + + /* + * Verify. + */ + if (algorithm == ISCCC_ALG_HMACMD5) { + isccc_region_t *region; + unsigned char *value; + + region = isccc_sexpr_tobinary(hmac); + if ((region->rend - region->rstart) != HMD5_LENGTH) { + return (ISCCC_R_BADAUTH); + } + value = region->rstart; + if (!isc_safe_memequal(value, digestb64, HMD5_LENGTH)) { + return (ISCCC_R_BADAUTH); + } + } else { + isccc_region_t *region; + unsigned char *value; + uint32_t valalg; + + region = isccc_sexpr_tobinary(hmac); + + /* + * Note: with non-MD5 algorithms, there's an extra octet + * to identify which algorithm is in use. + */ + if ((region->rend - region->rstart) != HSHA_LENGTH + 1) { + return (ISCCC_R_BADAUTH); + } + value = region->rstart; + GET8(valalg, value); + if ((valalg != algorithm) || + !isc_safe_memequal(value, digestb64, HSHA_LENGTH)) + { + return (ISCCC_R_BADAUTH); + } + } + + return (ISC_R_SUCCESS); +} + +static isc_result_t +table_fromwire(isccc_region_t *source, isccc_region_t *secret, + uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp); + +static isc_result_t +list_fromwire(isccc_region_t *source, unsigned int depth, + isccc_sexpr_t **listp); + +static isc_result_t +value_fromwire(isccc_region_t *source, unsigned int depth, + isccc_sexpr_t **valuep) { + unsigned int msgtype; + uint32_t len; + isccc_sexpr_t *value; + isccc_region_t active; + isc_result_t result; + + if (depth > ISCCC_MAXDEPTH) { + return (ISCCC_R_MAXDEPTH); + } + + if (REGION_SIZE(*source) < 1 + 4) { + return (ISC_R_UNEXPECTEDEND); + } + GET8(msgtype, source->rstart); + GET32(len, source->rstart); + if (REGION_SIZE(*source) < len) { + return (ISC_R_UNEXPECTEDEND); + } + active.rstart = source->rstart; + active.rend = active.rstart + len; + source->rstart = active.rend; + if (msgtype == ISCCC_CCMSGTYPE_BINARYDATA) { + value = isccc_sexpr_frombinary(&active); + if (value != NULL) { + *valuep = value; + result = ISC_R_SUCCESS; + } else { + result = ISC_R_NOMEMORY; + } + } else if (msgtype == ISCCC_CCMSGTYPE_TABLE) { + result = table_fromwire(&active, NULL, 0, depth + 1, valuep); + } else if (msgtype == ISCCC_CCMSGTYPE_LIST) { + result = list_fromwire(&active, depth + 1, valuep); + } else { + result = ISCCC_R_SYNTAX; + } + + return (result); +} + +static isc_result_t +table_fromwire(isccc_region_t *source, isccc_region_t *secret, + uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp) { + char key[256]; + uint32_t len; + isc_result_t result; + isccc_sexpr_t *alist, *value; + bool first_tag; + unsigned char *checksum_rstart; + + REQUIRE(alistp != NULL && *alistp == NULL); + + if (depth > ISCCC_MAXDEPTH) { + return (ISCCC_R_MAXDEPTH); + } + + checksum_rstart = NULL; + first_tag = true; + alist = isccc_alist_create(); + if (alist == NULL) { + return (ISC_R_NOMEMORY); + } + + while (!REGION_EMPTY(*source)) { + GET8(len, source->rstart); + if (REGION_SIZE(*source) < len) { + result = ISC_R_UNEXPECTEDEND; + goto bad; + } + GET_MEM(key, len, source->rstart); + key[len] = '\0'; /* Ensure NUL termination. */ + value = NULL; + result = value_fromwire(source, depth + 1, &value); + if (result != ISC_R_SUCCESS) { + goto bad; + } + if (isccc_alist_define(alist, key, value) == NULL) { + result = ISC_R_NOMEMORY; + goto bad; + } + if (first_tag && secret != NULL && strcmp(key, "_auth") == 0) { + checksum_rstart = source->rstart; + } + first_tag = false; + } + + if (secret != NULL) { + if (checksum_rstart != NULL) { + result = verify( + alist, checksum_rstart, + (unsigned int)(source->rend - checksum_rstart), + algorithm, secret); + } else { + result = ISCCC_R_BADAUTH; + } + } else { + result = ISC_R_SUCCESS; + } + +bad: + if (result == ISC_R_SUCCESS) { + *alistp = alist; + } else { + isccc_sexpr_free(&alist); + } + + return (result); +} + +static isc_result_t +list_fromwire(isccc_region_t *source, unsigned int depth, + isccc_sexpr_t **listp) { + isccc_sexpr_t *list, *value; + isc_result_t result; + + if (depth > ISCCC_MAXDEPTH) { + return (ISCCC_R_MAXDEPTH); + } + + list = NULL; + while (!REGION_EMPTY(*source)) { + value = NULL; + result = value_fromwire(source, depth + 1, &value); + if (result != ISC_R_SUCCESS) { + isccc_sexpr_free(&list); + return (result); + } + if (isccc_sexpr_addtolist(&list, value) == NULL) { + isccc_sexpr_free(&value); + isccc_sexpr_free(&list); + return (ISC_R_NOMEMORY); + } + } + + *listp = list; + + return (ISC_R_SUCCESS); +} + +isc_result_t +isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp, + uint32_t algorithm, isccc_region_t *secret) { + unsigned int size; + uint32_t version; + + size = REGION_SIZE(*source); + if (size < 4) { + return (ISC_R_UNEXPECTEDEND); + } + GET32(version, source->rstart); + if (version != 1) { + return (ISCCC_R_UNKNOWNVERSION); + } + + return (table_fromwire(source, secret, algorithm, 0, alistp)); +} + +static isc_result_t +createmessage(uint32_t version, const char *from, const char *to, + uint32_t serial, isccc_time_t now, isccc_time_t expires, + isccc_sexpr_t **alistp, bool want_expires) { + isccc_sexpr_t *alist, *_ctrl, *_data; + isc_result_t result; + + REQUIRE(alistp != NULL && *alistp == NULL); + + if (version != 1) { + return (ISCCC_R_UNKNOWNVERSION); + } + + alist = isccc_alist_create(); + if (alist == NULL) { + return (ISC_R_NOMEMORY); + } + + result = ISC_R_NOMEMORY; + + _ctrl = isccc_alist_create(); + if (_ctrl == NULL) { + goto bad; + } + if (isccc_alist_define(alist, "_ctrl", _ctrl) == NULL) { + isccc_sexpr_free(&_ctrl); + goto bad; + } + + _data = isccc_alist_create(); + if (_data == NULL) { + goto bad; + } + if (isccc_alist_define(alist, "_data", _data) == NULL) { + isccc_sexpr_free(&_data); + goto bad; + } + + if (isccc_cc_defineuint32(_ctrl, "_ser", serial) == NULL || + isccc_cc_defineuint32(_ctrl, "_tim", now) == NULL || + (want_expires && + isccc_cc_defineuint32(_ctrl, "_exp", expires) == NULL)) + { + goto bad; + } + if (from != NULL && isccc_cc_definestring(_ctrl, "_frm", from) == NULL) + { + goto bad; + } + if (to != NULL && isccc_cc_definestring(_ctrl, "_to", to) == NULL) { + goto bad; + } + + *alistp = alist; + + return (ISC_R_SUCCESS); + +bad: + isccc_sexpr_free(&alist); + + return (result); +} + +isc_result_t +isccc_cc_createmessage(uint32_t version, const char *from, const char *to, + uint32_t serial, isccc_time_t now, isccc_time_t expires, + isccc_sexpr_t **alistp) { + return (createmessage(version, from, to, serial, now, expires, alistp, + true)); +} + +isc_result_t +isccc_cc_createack(isccc_sexpr_t *message, bool ok, isccc_sexpr_t **ackp) { + char *_frm, *_to; + uint32_t serial; + isccc_sexpr_t *ack, *_ctrl; + isc_result_t result; + isccc_time_t t; + + REQUIRE(ackp != NULL && *ackp == NULL); + + _ctrl = isccc_alist_lookup(message, "_ctrl"); + if (!isccc_alist_alistp(_ctrl) || + isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS || + isccc_cc_lookupuint32(_ctrl, "_tim", &t) != ISC_R_SUCCESS) + { + return (ISC_R_FAILURE); + } + /* + * _frm and _to are optional. + */ + _frm = NULL; + (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm); + _to = NULL; + (void)isccc_cc_lookupstring(_ctrl, "_to", &_to); + /* + * Create the ack. + */ + ack = NULL; + result = createmessage(1, _to, _frm, serial, t, 0, &ack, false); + if (result != ISC_R_SUCCESS) { + return (result); + } + + _ctrl = isccc_alist_lookup(ack, "_ctrl"); + if (_ctrl == NULL) { + result = ISC_R_FAILURE; + goto bad; + } + if (isccc_cc_definestring(ack, "_ack", (ok) ? "1" : "0") == NULL) { + result = ISC_R_NOMEMORY; + goto bad; + } + + *ackp = ack; + + return (ISC_R_SUCCESS); + +bad: + isccc_sexpr_free(&ack); + + return (result); +} + +bool +isccc_cc_isack(isccc_sexpr_t *message) { + isccc_sexpr_t *_ctrl; + + _ctrl = isccc_alist_lookup(message, "_ctrl"); + if (!isccc_alist_alistp(_ctrl)) { + return (false); + } + if (isccc_cc_lookupstring(_ctrl, "_ack", NULL) == ISC_R_SUCCESS) { + return (true); + } + return (false); +} + +bool +isccc_cc_isreply(isccc_sexpr_t *message) { + isccc_sexpr_t *_ctrl; + + _ctrl = isccc_alist_lookup(message, "_ctrl"); + if (!isccc_alist_alistp(_ctrl)) { + return (false); + } + if (isccc_cc_lookupstring(_ctrl, "_rpl", NULL) == ISC_R_SUCCESS) { + return (true); + } + return (false); +} + +isc_result_t +isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, + isccc_time_t expires, isccc_sexpr_t **alistp) { + char *_frm, *_to, *type = NULL; + uint32_t serial; + isccc_sexpr_t *alist, *_ctrl, *_data; + isc_result_t result; + + REQUIRE(alistp != NULL && *alistp == NULL); + + _ctrl = isccc_alist_lookup(message, "_ctrl"); + _data = isccc_alist_lookup(message, "_data"); + if (!isccc_alist_alistp(_ctrl) || !isccc_alist_alistp(_data) || + isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS || + isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS) + { + return (ISC_R_FAILURE); + } + /* + * _frm and _to are optional. + */ + _frm = NULL; + (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm); + _to = NULL; + (void)isccc_cc_lookupstring(_ctrl, "_to", &_to); + /* + * Create the response. + */ + alist = NULL; + result = isccc_cc_createmessage(1, _to, _frm, serial, now, expires, + &alist); + if (result != ISC_R_SUCCESS) { + return (result); + } + + _ctrl = isccc_alist_lookup(alist, "_ctrl"); + if (_ctrl == NULL) { + result = ISC_R_FAILURE; + goto bad; + } + + _data = isccc_alist_lookup(alist, "_data"); + if (_data == NULL) { + result = ISC_R_FAILURE; + goto bad; + } + + if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL || + isccc_cc_definestring(_data, "type", type) == NULL) + { + result = ISC_R_NOMEMORY; + goto bad; + } + + *alistp = alist; + + return (ISC_R_SUCCESS); + +bad: + isccc_sexpr_free(&alist); + return (result); +} + +isccc_sexpr_t * +isccc_cc_definestring(isccc_sexpr_t *alist, const char *key, const char *str) { + size_t len; + isccc_region_t r; + + len = strlen(str); + DE_CONST(str, r.rstart); + r.rend = r.rstart + len; + + return (isccc_alist_definebinary(alist, key, &r)); +} + +isccc_sexpr_t * +isccc_cc_defineuint32(isccc_sexpr_t *alist, const char *key, uint32_t i) { + char b[100]; + size_t len; + isccc_region_t r; + + snprintf(b, sizeof(b), "%u", i); + len = strlen(b); + r.rstart = (unsigned char *)b; + r.rend = (unsigned char *)b + len; + + return (isccc_alist_definebinary(alist, key, &r)); +} + +isc_result_t +isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp) { + isccc_sexpr_t *kv, *v; + + REQUIRE(strp == NULL || *strp == NULL); + + kv = isccc_alist_assq(alist, key); + if (kv != NULL) { + v = ISCCC_SEXPR_CDR(kv); + if (isccc_sexpr_binaryp(v)) { + if (strp != NULL) { + *strp = isccc_sexpr_tostring(v); + } + return (ISC_R_SUCCESS); + } else { + return (ISC_R_EXISTS); + } + } + + return (ISC_R_NOTFOUND); +} + +isc_result_t +isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key, uint32_t *uintp) { + isccc_sexpr_t *kv, *v; + + kv = isccc_alist_assq(alist, key); + if (kv != NULL) { + v = ISCCC_SEXPR_CDR(kv); + if (isccc_sexpr_binaryp(v)) { + if (uintp != NULL) { + *uintp = (uint32_t)strtoul( + isccc_sexpr_tostring(v), NULL, 10); + } + return (ISC_R_SUCCESS); + } else { + return (ISC_R_EXISTS); + } + } + + return (ISC_R_NOTFOUND); +} + +static void +symtab_undefine(char *key, unsigned int type, isccc_symvalue_t value, + void *arg) { + UNUSED(type); + UNUSED(value); + UNUSED(arg); + + free(key); +} + +static bool +symtab_clean(char *key, unsigned int type, isccc_symvalue_t value, void *arg) { + isccc_time_t *now; + + UNUSED(key); + UNUSED(type); + + now = arg; + + if (*now < value.as_uinteger) { + return (false); + } + if ((*now - value.as_uinteger) < DUP_LIFETIME) { + return (false); + } + return (true); +} + +isc_result_t +isccc_cc_createsymtab(isccc_symtab_t **symtabp) { + return (isccc_symtab_create(11897, symtab_undefine, NULL, false, + symtabp)); +} + +void +isccc_cc_cleansymtab(isccc_symtab_t *symtab, isccc_time_t now) { + isccc_symtab_foreach(symtab, symtab_clean, &now); +} + +static bool +has_whitespace(const char *str) { + char c; + + if (str == NULL) { + return (false); + } + while ((c = *str++) != '\0') { + if (c == ' ' || c == '\t' || c == '\n') { + return (true); + } + } + return (false); +} + +isc_result_t +isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, + isccc_time_t now) { + const char *_frm; + const char *_to; + char *_ser = NULL, *_tim = NULL, *tmp; + isc_result_t result; + char *key; + size_t len; + isccc_symvalue_t value; + isccc_sexpr_t *_ctrl; + + _ctrl = isccc_alist_lookup(message, "_ctrl"); + if (!isccc_alist_alistp(_ctrl) || + isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS || + isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS) + { + return (ISC_R_FAILURE); + } + + INSIST(_ser != NULL); + INSIST(_tim != NULL); + + /* + * _frm and _to are optional. + */ + tmp = NULL; + if (isccc_cc_lookupstring(_ctrl, "_frm", &tmp) != ISC_R_SUCCESS) { + _frm = ""; + } else { + _frm = tmp; + } + tmp = NULL; + if (isccc_cc_lookupstring(_ctrl, "_to", &tmp) != ISC_R_SUCCESS) { + _to = ""; + } else { + _to = tmp; + } + /* + * Ensure there is no newline in any of the strings. This is so + * we can write them to a file later. + */ + if (has_whitespace(_frm) || has_whitespace(_to) || + has_whitespace(_ser) || has_whitespace(_tim)) + { + return (ISC_R_FAILURE); + } + len = strlen(_frm) + strlen(_to) + strlen(_ser) + strlen(_tim) + 4; + key = malloc(len); + if (key == NULL) { + return (ISC_R_NOMEMORY); + } + snprintf(key, len, "%s;%s;%s;%s", _frm, _to, _ser, _tim); + value.as_uinteger = now; + result = isccc_symtab_define(symtab, key, ISCCC_SYMTYPE_CCDUP, value, + isccc_symexists_reject); + if (result != ISC_R_SUCCESS) { + free(key); + return (result); + } + + return (ISC_R_SUCCESS); +} diff --git a/lib/isccc/ccmsg.c b/lib/isccc/ccmsg.c new file mode 100644 index 0000000..9ee48ab --- /dev/null +++ b/lib/isccc/ccmsg.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <inttypes.h> + +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/result.h> +#include <isc/string.h> +#include <isc/util.h> + +#include <isccc/ccmsg.h> +#include <isccc/events.h> + +#define CCMSG_MAGIC ISC_MAGIC('C', 'C', 'm', 's') +#define VALID_CCMSG(foo) ISC_MAGIC_VALID(foo, CCMSG_MAGIC) + +static void +recv_data(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, + void *arg) { + isccc_ccmsg_t *ccmsg = arg; + size_t size; + + INSIST(VALID_CCMSG(ccmsg)); + + switch (eresult) { + case ISC_R_SHUTTINGDOWN: + case ISC_R_CANCELED: + case ISC_R_EOF: + ccmsg->result = eresult; + goto done; + case ISC_R_SUCCESS: + if (region == NULL) { + ccmsg->result = ISC_R_EOF; + goto done; + } + ccmsg->result = ISC_R_SUCCESS; + break; + default: + ccmsg->result = eresult; + goto done; + } + + if (!ccmsg->length_received) { + if (region->length < sizeof(uint32_t)) { + ccmsg->result = ISC_R_UNEXPECTEDEND; + goto done; + } + + ccmsg->size = ntohl(*(uint32_t *)region->base); + + if (ccmsg->size == 0) { + ccmsg->result = ISC_R_UNEXPECTEDEND; + goto done; + } + if (ccmsg->size > ccmsg->maxsize) { + ccmsg->result = ISC_R_RANGE; + goto done; + } + + isc_region_consume(region, sizeof(uint32_t)); + isc_buffer_allocate(ccmsg->mctx, &ccmsg->buffer, ccmsg->size); + + ccmsg->length_received = true; + } + + /* + * If there's no more data, wait for more + */ + if (region->length == 0) { + return; + } + + /* We have some data in the buffer, read it */ + + size = ISC_MIN(isc_buffer_availablelength(ccmsg->buffer), + region->length); + isc_buffer_putmem(ccmsg->buffer, region->base, size); + isc_region_consume(region, size); + + if (isc_buffer_usedlength(ccmsg->buffer) == ccmsg->size) { + ccmsg->result = ISC_R_SUCCESS; + goto done; + } + + /* Wait for more data to come */ + return; + +done: + isc_nm_pauseread(handle); + ccmsg->cb(handle, ccmsg->result, ccmsg->cbarg); +} + +void +isccc_ccmsg_init(isc_mem_t *mctx, isc_nmhandle_t *handle, + isccc_ccmsg_t *ccmsg) { + REQUIRE(mctx != NULL); + REQUIRE(handle != NULL); + REQUIRE(ccmsg != NULL); + + *ccmsg = (isccc_ccmsg_t){ + .magic = CCMSG_MAGIC, + .maxsize = 0xffffffffU, /* Largest message possible. */ + .mctx = mctx, + .handle = handle, + .result = ISC_R_UNEXPECTED /* None yet. */ + }; +} + +void +isccc_ccmsg_setmaxsize(isccc_ccmsg_t *ccmsg, unsigned int maxsize) { + REQUIRE(VALID_CCMSG(ccmsg)); + + ccmsg->maxsize = maxsize; +} + +void +isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_nm_cb_t cb, void *cbarg) { + REQUIRE(VALID_CCMSG(ccmsg)); + + if (ccmsg->buffer != NULL) { + isc_buffer_free(&ccmsg->buffer); + } + + ccmsg->cb = cb; + ccmsg->cbarg = cbarg; + ccmsg->result = ISC_R_UNEXPECTED; /* unknown right now */ + ccmsg->length_received = false; + + if (ccmsg->reading) { + isc_nm_resumeread(ccmsg->handle); + } else { + isc_nm_read(ccmsg->handle, recv_data, ccmsg); + ccmsg->reading = true; + } +} + +void +isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg) { + REQUIRE(VALID_CCMSG(ccmsg)); + + if (ccmsg->reading) { + isc_nm_cancelread(ccmsg->handle); + ccmsg->reading = false; + } +} + +void +isccc_ccmsg_invalidate(isccc_ccmsg_t *ccmsg) { + REQUIRE(VALID_CCMSG(ccmsg)); + + ccmsg->magic = 0; + + if (ccmsg->buffer != NULL) { + isc_buffer_free(&ccmsg->buffer); + } +} diff --git a/lib/isccc/include/isccc/alist.h b/lib/isccc/include/isccc/alist.h new file mode 100644 index 0000000..dc70044 --- /dev/null +++ b/lib/isccc/include/isccc/alist.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/alist.h */ + +#include <stdbool.h> +#include <stdio.h> + +#include <isc/lang.h> + +#include <isccc/types.h> + +ISC_LANG_BEGINDECLS + +isccc_sexpr_t * +isccc_alist_create(void); + +bool +isccc_alist_alistp(isccc_sexpr_t *alist); + +bool +isccc_alist_emptyp(isccc_sexpr_t *alist); + +isccc_sexpr_t * +isccc_alist_first(isccc_sexpr_t *alist); + +isccc_sexpr_t * +isccc_alist_assq(isccc_sexpr_t *alist, const char *key); + +void +isccc_alist_delete(isccc_sexpr_t *alist, const char *key); + +isccc_sexpr_t * +isccc_alist_define(isccc_sexpr_t *alist, const char *key, isccc_sexpr_t *value); + +isccc_sexpr_t * +isccc_alist_definestring(isccc_sexpr_t *alist, const char *key, + const char *str); + +isccc_sexpr_t * +isccc_alist_definebinary(isccc_sexpr_t *alist, const char *key, + isccc_region_t *r); + +isccc_sexpr_t * +isccc_alist_lookup(isccc_sexpr_t *alist, const char *key); + +isc_result_t +isccc_alist_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp); + +isc_result_t +isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, + isccc_region_t **r); + +void +isccc_alist_prettyprint(isccc_sexpr_t *sexpr, unsigned int indent, + FILE *stream); + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/base64.h b/lib/isccc/include/isccc/base64.h new file mode 100644 index 0000000..641dd4e --- /dev/null +++ b/lib/isccc/include/isccc/base64.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/base64.h */ + +#include <isc/lang.h> + +#include <isccc/types.h> + +ISC_LANG_BEGINDECLS + +/*** + *** Functions + ***/ + +isc_result_t +isccc_base64_encode(isccc_region_t *source, int wordlength, + const char *wordbreak, isccc_region_t *target); +/*%< + * Convert data into base64 encoded text. + * + * Notes: + *\li The base64 encoded text in 'target' will be divided into + * words of at most 'wordlength' characters, separated by + * the 'wordbreak' string. No parentheses will surround + * the text. + * + * Requires: + *\li 'source' is a region containing binary data. + *\li 'target' is a text region containing available space. + *\li 'wordbreak' points to a null-terminated string of + * zero or more whitespace characters. + */ + +isc_result_t +isccc_base64_decode(const char *cstr, isccc_region_t *target); +/*%< + * Decode a null-terminated base64 string. + * + * Requires: + *\li 'cstr' is non-null. + *\li 'target' is a valid region. + * + * Returns: + *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' + * fit in 'target'. + *\li #ISC_R_BADBASE64 -- 'cstr' is not a valid base64 encoding. + *\li #ISC_R_NOSPACE -- 'target' is not big enough. + */ + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/cc.h b/lib/isccc/include/isccc/cc.h new file mode 100644 index 0000000..f597276 --- /dev/null +++ b/lib/isccc/include/isccc/cc.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/cc.h */ + +#include <inttypes.h> +#include <stdbool.h> + +#include <isc/buffer.h> +#include <isc/lang.h> + +#include <dst/dst.h> +#include <isccc/types.h> + +ISC_LANG_BEGINDECLS + +/*% + * The HMAC algorithms supported by isccc_cc_fromwire and + * isccc_cc_towire as implemented in DST. + */ +#define ISCCC_ALG_UNKNOWN 0 +#define ISCCC_ALG_HMACMD5 DST_ALG_HMACMD5 +#define ISCCC_ALG_HMACSHA1 DST_ALG_HMACSHA1 +#define ISCCC_ALG_HMACSHA224 DST_ALG_HMACSHA224 +#define ISCCC_ALG_HMACSHA256 DST_ALG_HMACSHA256 +#define ISCCC_ALG_HMACSHA384 DST_ALG_HMACSHA384 +#define ISCCC_ALG_HMACSHA512 DST_ALG_HMACSHA512 + +/*% Maximum Datagram Package */ +#define ISCCC_CC_MAXDGRAMPACKET 4096 + +/*% Message Type String */ +#define ISCCC_CCMSGTYPE_STRING 0x00 +/*% Message Type Binary Data */ +#define ISCCC_CCMSGTYPE_BINARYDATA 0x01 +/*% Message Type Table */ +#define ISCCC_CCMSGTYPE_TABLE 0x02 +/*% Message Type List */ +#define ISCCC_CCMSGTYPE_LIST 0x03 + +/*% Send to Wire */ +isc_result_t +isccc_cc_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer, uint32_t algorithm, + isccc_region_t *secret); + +/*% Get From Wire */ +isc_result_t +isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp, + uint32_t algorithm, isccc_region_t *secret); + +/*% Create Message */ +isc_result_t +isccc_cc_createmessage(uint32_t version, const char *from, const char *to, + uint32_t serial, isccc_time_t now, isccc_time_t expires, + isccc_sexpr_t **alistp); + +/*% Create Acknowledgment */ +isc_result_t +isccc_cc_createack(isccc_sexpr_t *message, bool ok, isccc_sexpr_t **ackp); + +/*% Is Ack? */ +bool +isccc_cc_isack(isccc_sexpr_t *message); + +/*% Is Reply? */ +bool +isccc_cc_isreply(isccc_sexpr_t *message); + +/*% Create Response */ +isc_result_t +isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, + isccc_time_t expires, isccc_sexpr_t **alistp); + +/*% Define String */ +isccc_sexpr_t * +isccc_cc_definestring(isccc_sexpr_t *alist, const char *key, const char *str); + +/*% Define uint 32 */ +isccc_sexpr_t * +isccc_cc_defineuint32(isccc_sexpr_t *alist, const char *key, uint32_t i); + +/*% Lookup String */ +isc_result_t +isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp); + +/*% Lookup uint 32 */ +isc_result_t +isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key, uint32_t *uintp); + +/*% Create Symbol Table */ +isc_result_t +isccc_cc_createsymtab(isccc_symtab_t **symtabp); + +/*% Clean up Symbol Table */ +void +isccc_cc_cleansymtab(isccc_symtab_t *symtab, isccc_time_t now); + +/*% Check for Duplicates */ +isc_result_t +isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, + isccc_time_t now); + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/ccmsg.h b/lib/isccc/include/isccc/ccmsg.h new file mode 100644 index 0000000..a648226 --- /dev/null +++ b/lib/isccc/include/isccc/ccmsg.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/ccmsg.h */ + +#include <inttypes.h> + +#include <isc/buffer.h> +#include <isc/lang.h> +#include <isc/netmgr.h> +#include <isc/sockaddr.h> + +/*% ISCCC Message Structure */ +typedef struct isccc_ccmsg { + /* private (don't touch!) */ + unsigned int magic; + uint32_t size; + bool length_received; + isc_buffer_t *buffer; + unsigned int maxsize; + isc_mem_t *mctx; + isc_nmhandle_t *handle; + isc_nm_cb_t cb; + void *cbarg; + bool reading; + /* public (read-only) */ + isc_result_t result; +} isccc_ccmsg_t; + +ISC_LANG_BEGINDECLS + +void +isccc_ccmsg_init(isc_mem_t *mctx, isc_nmhandle_t *handle, isccc_ccmsg_t *ccmsg); +/*% + * Associate a cc message state with a given memory context and + * netmgr handle. (Note that the caller must hold a reference to + * the handle during asynchronous ccmsg operations; the ccmsg code + * does not hold the reference itself.) + * + * Requires: + * + *\li "mctx" be a valid memory context. + * + *\li "handle" be a netmgr handle for a stream socket. + * + *\li "ccmsg" be non-NULL and an uninitialized or invalidated structure. + * + * Ensures: + * + *\li "ccmsg" is a valid structure. + */ + +void +isccc_ccmsg_setmaxsize(isccc_ccmsg_t *ccmsg, unsigned int maxsize); +/*% + * Set the maximum packet size to "maxsize" + * + * Requires: + * + *\li "ccmsg" be valid. + * + *\li 512 <= "maxsize" <= 4294967296 + */ + +void +isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_nm_cb_t cb, void *cbarg); +/*% + * Schedule an event to be delivered when a command channel message is + * readable, or when an error occurs on the socket. + * + * Requires: + * + *\li "ccmsg" be valid. + * + * Notes: + * + *\li The event delivered is a fully generic event. It will contain no + * actual data. The sender will be a pointer to the isccc_ccmsg_t. + * The result code inside that structure should be checked to see + * what the final result was. + */ + +void +isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg); +/*% + * Cancel a readmessage() call. The event will still be posted with a + * CANCELED result code. + * + * Requires: + * + *\li "ccmsg" be valid. + */ + +void +isccc_ccmsg_invalidate(isccc_ccmsg_t *ccmsg); +/*% + * Clean up all allocated state, and invalidate the structure. + * + * Requires: + * + *\li "ccmsg" be valid. + * + * Ensures: + * + *\li "ccmsg" is invalidated and disassociated with all memory contexts, + * sockets, etc. + */ + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/events.h b/lib/isccc/include/isccc/events.h new file mode 100644 index 0000000..0461a8a --- /dev/null +++ b/lib/isccc/include/isccc/events.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/events.h */ + +#include <isc/eventclass.h> + +/*% + * Registry of ISCCC event numbers. + */ + +#define ISCCC_EVENT_CCMSG (ISC_EVENTCLASS_ISCCC + 0) + +#define ISCCC_EVENT_FIRSTEVENT (ISC_EVENTCLASS_ISCCC + 0) +#define ISCCC_EVENT_LASTEVENT (ISC_EVENTCLASS_ISCCC + 65535) diff --git a/lib/isccc/include/isccc/sexpr.h b/lib/isccc/include/isccc/sexpr.h new file mode 100644 index 0000000..133d06d --- /dev/null +++ b/lib/isccc/include/isccc/sexpr.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/sexpr.h */ + +#include <stdbool.h> +#include <stdio.h> + +#include <isc/lang.h> + +#include <isccc/types.h> + +ISC_LANG_BEGINDECLS + +/*% dotted pair structure */ +struct isccc_dottedpair { + isccc_sexpr_t *car; + isccc_sexpr_t *cdr; +}; + +/*% iscc_sexpr structure */ +struct isccc_sexpr { + unsigned int type; + union { + char *as_string; + isccc_dottedpair_t as_dottedpair; + isccc_region_t as_region; + } value; +}; + +#define ISCCC_SEXPRTYPE_NONE 0x00 /*%< Illegal. */ +#define ISCCC_SEXPRTYPE_T 0x01 +#define ISCCC_SEXPRTYPE_STRING 0x02 +#define ISCCC_SEXPRTYPE_DOTTEDPAIR 0x03 +#define ISCCC_SEXPRTYPE_BINARY 0x04 + +#define ISCCC_SEXPR_CAR(s) (s)->value.as_dottedpair.car +#define ISCCC_SEXPR_CDR(s) (s)->value.as_dottedpair.cdr + +isccc_sexpr_t * +isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr); + +isccc_sexpr_t * +isccc_sexpr_tconst(void); + +isccc_sexpr_t * +isccc_sexpr_fromstring(const char *str); + +isccc_sexpr_t * +isccc_sexpr_frombinary(const isccc_region_t *region); + +void +isccc_sexpr_free(isccc_sexpr_t **sexprp); + +void +isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream); + +isccc_sexpr_t * +isccc_sexpr_car(isccc_sexpr_t *list); + +isccc_sexpr_t * +isccc_sexpr_cdr(isccc_sexpr_t *list); + +void +isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car); + +void +isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr); + +isccc_sexpr_t * +isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2); + +bool +isccc_sexpr_listp(isccc_sexpr_t *sexpr); + +bool +isccc_sexpr_emptyp(isccc_sexpr_t *sexpr); + +bool +isccc_sexpr_stringp(isccc_sexpr_t *sexpr); + +bool +isccc_sexpr_binaryp(isccc_sexpr_t *sexpr); + +char * +isccc_sexpr_tostring(isccc_sexpr_t *sexpr); + +isccc_region_t * +isccc_sexpr_tobinary(isccc_sexpr_t *sexpr); + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/symtab.h b/lib/isccc/include/isccc/symtab.h new file mode 100644 index 0000000..a156c06 --- /dev/null +++ b/lib/isccc/include/isccc/symtab.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/***** +***** Module Info +*****/ + +/*! \file isccc/symtab.h + * \brief + * Provides a simple memory-based symbol table. + * + * Keys are C strings. A type may be specified when looking up, + * defining, or undefining. A type value of 0 means "match any type"; + * any other value will only match the given type. + * + * It's possible that a client will attempt to define a <key, type, + * value> tuple when a tuple with the given key and type already + * exists in the table. What to do in this case is specified by the + * client. Possible policies are: + * + *\li isccc_symexists_reject Disallow the define, returning #ISC_R_EXISTS + *\li isccc_symexists_replace Replace the old value with the new. The + * undefine action (if provided) will be called + * with the old <key, type, value> tuple. + *\li isccc_symexists_add Add the new tuple, leaving the old tuple in + * the table. Subsequent lookups will retrieve + * the most-recently-defined tuple. + * + * A lookup of a key using type 0 will return the most-recently + * defined symbol with that key. An undefine of a key using type 0 + * will undefine the most-recently defined symbol with that key. + * Trying to define a key with type 0 is illegal. + * + * The symbol table library does not make a copy the key field, so the + * caller must ensure that any key it passes to isccc_symtab_define() + * will not change until it calls isccc_symtab_undefine() or + * isccc_symtab_destroy(). + * + * A user-specified action will be called (if provided) when a symbol + * is undefined. It can be used to free memory associated with keys + * and/or values. + */ + +/*** + *** Imports. + ***/ + +#include <stdbool.h> + +#include <isc/lang.h> + +#include <isccc/types.h> + +/*** + *** Symbol Tables. + ***/ + +typedef union isccc_symvalue { + void *as_pointer; + int as_integer; + unsigned int as_uinteger; +} isccc_symvalue_t; + +typedef void (*isccc_symtabundefaction_t)(char *key, unsigned int type, + isccc_symvalue_t value, + void *userarg); + +typedef bool (*isccc_symtabforeachaction_t)(char *key, unsigned int type, + isccc_symvalue_t value, + void *userarg); + +typedef enum { + isccc_symexists_reject = 0, + isccc_symexists_replace = 1, + isccc_symexists_add = 2 +} isccc_symexists_t; + +ISC_LANG_BEGINDECLS + +isc_result_t +isccc_symtab_create(unsigned int size, + isccc_symtabundefaction_t undefine_action, + void *undefine_arg, bool case_sensitive, + isccc_symtab_t **symtabp); + +void +isccc_symtab_destroy(isccc_symtab_t **symtabp); + +isc_result_t +isccc_symtab_lookup(isccc_symtab_t *symtab, const char *key, unsigned int type, + isccc_symvalue_t *value); + +isc_result_t +isccc_symtab_define(isccc_symtab_t *symtab, char *key, unsigned int type, + isccc_symvalue_t value, isccc_symexists_t exists_policy); + +isc_result_t +isccc_symtab_undefine(isccc_symtab_t *symtab, const char *key, + unsigned int type); + +void +isccc_symtab_foreach(isccc_symtab_t *symtab, isccc_symtabforeachaction_t action, + void *arg); + +ISC_LANG_ENDDECLS diff --git a/lib/isccc/include/isccc/symtype.h b/lib/isccc/include/isccc/symtype.h new file mode 100644 index 0000000..8e67eda --- /dev/null +++ b/lib/isccc/include/isccc/symtype.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/symtype.h */ + +#define ISCCC_SYMTYPE_ZONESTATS 0x0001 +#define ISCCC_SYMTYPE_CCDUP 0x0002 +#define ISCCC_SYMTYPE_TELLSERVICE 0x0003 +#define ISCCC_SYMTYPE_TELLRESPONSE 0x0004 diff --git a/lib/isccc/include/isccc/types.h b/lib/isccc/include/isccc/types.h new file mode 100644 index 0000000..f2032a7 --- /dev/null +++ b/lib/isccc/include/isccc/types.h @@ -0,0 +1,52 @@ +/* + * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +/*! \file isccc/types.h */ + +#include <inttypes.h> + +#include <isc/result.h> + +/*% isccc_time_t typedef */ +typedef uint32_t isccc_time_t; + +/*% isccc_sexpr_t typedef */ +typedef struct isccc_sexpr isccc_sexpr_t; +/*% isccc_dottedpair_t typedef */ +typedef struct isccc_dottedpair isccc_dottedpair_t; +/*% isccc_symtab_t typedef */ +typedef struct isccc_symtab isccc_symtab_t; + +/*% iscc region structure */ +typedef struct isccc_region { + unsigned char *rstart; + unsigned char *rend; +} isccc_region_t; diff --git a/lib/isccc/include/isccc/util.h b/lib/isccc/include/isccc/util.h new file mode 100644 index 0000000..546b633 --- /dev/null +++ b/lib/isccc/include/isccc/util.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#include <inttypes.h> + +#include <isc/util.h> + +/*! \file isccc/util.h + * \brief + * Macros for dealing with unaligned numbers. + * + * \note no side effects are allowed when invoking these macros! + */ + +#define GET8(v, w) \ + do { \ + v = *w; \ + w++; \ + } while (0) + +#define GET16(v, w) \ + do { \ + v = (unsigned int)w[0] << 8; \ + v |= (unsigned int)w[1]; \ + w += 2; \ + } while (0) + +#define GET24(v, w) \ + do { \ + v = (unsigned int)w[0] << 16; \ + v |= (unsigned int)w[1] << 8; \ + v |= (unsigned int)w[2]; \ + w += 3; \ + } while (0) + +#define GET32(v, w) \ + do { \ + v = (unsigned int)w[0] << 24; \ + v |= (unsigned int)w[1] << 16; \ + v |= (unsigned int)w[2] << 8; \ + v |= (unsigned int)w[3]; \ + w += 4; \ + } while (0) + +#define GET64(v, w) \ + do { \ + v = (uint64_t)w[0] << 56; \ + v |= (uint64_t)w[1] << 48; \ + v |= (uint64_t)w[2] << 40; \ + v |= (uint64_t)w[3] << 32; \ + v |= (uint64_t)w[4] << 24; \ + v |= (uint64_t)w[5] << 16; \ + v |= (uint64_t)w[6] << 8; \ + v |= (uint64_t)w[7]; \ + w += 8; \ + } while (0) + +#define GETC16(v, w, d) \ + do { \ + GET8(v, w); \ + if (v == 0) { \ + d = ISCCC_TRUE; \ + } else { \ + d = ISCCC_FALSE; \ + if (v == 255) \ + GET16(v, w); \ + } \ + } while (0) + +#define GETC32(v, w) \ + do { \ + GET24(v, w); \ + if (v == 0xffffffu) { \ + GET32(v, w); \ + } \ + } while (0) + +#define GET_OFFSET(v, w) GET32(v, w) + +#define GET_MEM(v, c, w) \ + do { \ + memmove(v, w, c); \ + w += c; \ + } while (0) + +#define GET_TYPE(v, w) \ + do { \ + GET8(v, w); \ + if (v > 127) { \ + if (v < 255) { \ + v = ((v & 0x7f) << 16) | ISCCC_RDATATYPE_SIG; \ + } else { \ + GET32(v, w); \ + } \ + } \ + } while (0) + +#define PUT8(v, w) \ + do { \ + *w = (v & 0x000000ffU); \ + w++; \ + } while (0) + +#define PUT16(v, w) \ + do { \ + w[0] = (v & 0x0000ff00U) >> 8; \ + w[1] = (v & 0x000000ffU); \ + w += 2; \ + } while (0) + +#define PUT24(v, w) \ + do { \ + w[0] = (v & 0x00ff0000U) >> 16; \ + w[1] = (v & 0x0000ff00U) >> 8; \ + w[2] = (v & 0x000000ffU); \ + w += 3; \ + } while (0) + +#define PUT32(v, w) \ + do { \ + w[0] = (v & 0xff000000U) >> 24; \ + w[1] = (v & 0x00ff0000U) >> 16; \ + w[2] = (v & 0x0000ff00U) >> 8; \ + w[3] = (v & 0x000000ffU); \ + w += 4; \ + } while (0) + +#define PUT64(v, w) \ + do { \ + w[0] = (v & 0xff00000000000000ULL) >> 56; \ + w[1] = (v & 0x00ff000000000000ULL) >> 48; \ + w[2] = (v & 0x0000ff0000000000ULL) >> 40; \ + w[3] = (v & 0x000000ff00000000ULL) >> 32; \ + w[4] = (v & 0x00000000ff000000ULL) >> 24; \ + w[5] = (v & 0x0000000000ff0000ULL) >> 16; \ + w[6] = (v & 0x000000000000ff00ULL) >> 8; \ + w[7] = (v & 0x00000000000000ffULL); \ + w += 8; \ + } while (0) + +#define PUTC16(v, w) \ + do { \ + if (v > 0 && v < 255) { \ + PUT8(v, w); \ + } else { \ + PUT8(255, w); \ + PUT16(v, w); \ + } \ + } while (0) + +#define PUTC32(v, w) \ + do { \ + if (v < 0xffffffU) { \ + PUT24(v, w); \ + } else { \ + PUT24(0xffffffU, w); \ + PUT32(v, w); \ + } \ + } while (0) + +#define PUT_OFFSET(v, w) PUT32(v, w) + +#include <string.h> + +#define PUT_MEM(s, c, w) \ + do { \ + memmove(w, s, c); \ + w += c; \ + } while (0) + +/* + * Regions. + */ +#define REGION_SIZE(r) ((unsigned int)((r).rend - (r).rstart)) +#define REGION_EMPTY(r) ((r).rstart == (r).rend) +#define REGION_FROMSTRING(r, s) \ + do { \ + (r).rstart = (unsigned char *)s; \ + (r).rend = (r).rstart + strlen(s); \ + } while (0) diff --git a/lib/isccc/sexpr.c b/lib/isccc/sexpr.c new file mode 100644 index 0000000..62c80c4 --- /dev/null +++ b/lib/isccc/sexpr.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <ctype.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <isc/assertions.h> +#include <isc/print.h> + +#include <isccc/sexpr.h> +#include <isccc/util.h> + +static isccc_sexpr_t sexpr_t = { ISCCC_SEXPRTYPE_T, { NULL } }; + +#define CAR(s) (s)->value.as_dottedpair.car +#define CDR(s) (s)->value.as_dottedpair.cdr + +isccc_sexpr_t * +isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr) { + isccc_sexpr_t *sexpr; + + sexpr = malloc(sizeof(*sexpr)); + if (sexpr == NULL) { + return (NULL); + } + sexpr->type = ISCCC_SEXPRTYPE_DOTTEDPAIR; + CAR(sexpr) = car; + CDR(sexpr) = cdr; + + return (sexpr); +} + +isccc_sexpr_t * +isccc_sexpr_tconst(void) { + return (&sexpr_t); +} + +isccc_sexpr_t * +isccc_sexpr_fromstring(const char *str) { + isccc_sexpr_t *sexpr; + + sexpr = malloc(sizeof(*sexpr)); + if (sexpr == NULL) { + return (NULL); + } + sexpr->type = ISCCC_SEXPRTYPE_STRING; + sexpr->value.as_string = strdup(str); + if (sexpr->value.as_string == NULL) { + free(sexpr); + return (NULL); + } + + return (sexpr); +} + +isccc_sexpr_t * +isccc_sexpr_frombinary(const isccc_region_t *region) { + isccc_sexpr_t *sexpr; + unsigned int region_size; + + sexpr = malloc(sizeof(*sexpr)); + if (sexpr == NULL) { + return (NULL); + } + sexpr->type = ISCCC_SEXPRTYPE_BINARY; + region_size = REGION_SIZE(*region); + /* + * We add an extra byte when we malloc so we can NUL terminate + * the binary data. This allows the caller to use it as a C + * string. It's up to the caller to ensure this is safe. We don't + * add 1 to the length of the binary region, because the NUL is + * not part of the binary data. + */ + sexpr->value.as_region.rstart = malloc(region_size + 1); + if (sexpr->value.as_region.rstart == NULL) { + free(sexpr); + return (NULL); + } + sexpr->value.as_region.rend = sexpr->value.as_region.rstart + + region_size; + memmove(sexpr->value.as_region.rstart, region->rstart, region_size); + /* + * NUL terminate. + */ + sexpr->value.as_region.rstart[region_size] = '\0'; + + return (sexpr); +} + +void +isccc_sexpr_free(isccc_sexpr_t **sexprp) { + isccc_sexpr_t *sexpr; + isccc_sexpr_t *item; + + sexpr = *sexprp; + *sexprp = NULL; + if (sexpr == NULL) { + return; + } + switch (sexpr->type) { + case ISCCC_SEXPRTYPE_STRING: + free(sexpr->value.as_string); + break; + case ISCCC_SEXPRTYPE_DOTTEDPAIR: + item = CAR(sexpr); + if (item != NULL) { + isccc_sexpr_free(&item); + } + item = CDR(sexpr); + if (item != NULL) { + isccc_sexpr_free(&item); + } + break; + case ISCCC_SEXPRTYPE_BINARY: + free(sexpr->value.as_region.rstart); + break; + } + free(sexpr); +} + +static bool +printable(isccc_region_t *r) { + unsigned char *curr; + + curr = r->rstart; + while (curr != r->rend) { + if (!isprint(*curr)) { + return (false); + } + curr++; + } + + return (true); +} + +void +isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream) { + isccc_sexpr_t *cdr; + unsigned int size, i; + unsigned char *curr; + + if (sexpr == NULL) { + fprintf(stream, "nil"); + return; + } + + switch (sexpr->type) { + case ISCCC_SEXPRTYPE_T: + fprintf(stream, "t"); + break; + case ISCCC_SEXPRTYPE_STRING: + fprintf(stream, "\"%s\"", sexpr->value.as_string); + break; + case ISCCC_SEXPRTYPE_DOTTEDPAIR: + fprintf(stream, "("); + do { + isccc_sexpr_print(CAR(sexpr), stream); + cdr = CDR(sexpr); + if (cdr != NULL) { + fprintf(stream, " "); + if (cdr->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) { + fprintf(stream, ". "); + isccc_sexpr_print(cdr, stream); + cdr = NULL; + } + } + sexpr = cdr; + } while (sexpr != NULL); + fprintf(stream, ")"); + break; + case ISCCC_SEXPRTYPE_BINARY: + size = REGION_SIZE(sexpr->value.as_region); + curr = sexpr->value.as_region.rstart; + if (printable(&sexpr->value.as_region)) { + fprintf(stream, "'%.*s'", (int)size, curr); + } else { + fprintf(stream, "0x"); + for (i = 0; i < size; i++) { + fprintf(stream, "%02x", *curr++); + } + } + break; + default: + UNREACHABLE(); + } +} + +isccc_sexpr_t * +isccc_sexpr_car(isccc_sexpr_t *list) { + REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + + return (CAR(list)); +} + +isccc_sexpr_t * +isccc_sexpr_cdr(isccc_sexpr_t *list) { + REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + + return (CDR(list)); +} + +void +isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car) { + REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + + CAR(pair) = car; +} + +void +isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr) { + REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + + CDR(pair) = cdr; +} + +isccc_sexpr_t * +isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2) { + isccc_sexpr_t *last, *elt, *l1; + + REQUIRE(l1p != NULL); + l1 = *l1p; + REQUIRE(l1 == NULL || l1->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); + + elt = isccc_sexpr_cons(l2, NULL); + if (elt == NULL) { + return (NULL); + } + if (l1 == NULL) { + *l1p = elt; + return (elt); + } + for (last = l1; CDR(last) != NULL; last = CDR(last)) { + /* Nothing */ + } + CDR(last) = elt; + + return (elt); +} + +bool +isccc_sexpr_listp(isccc_sexpr_t *sexpr) { + if (sexpr == NULL || sexpr->type == ISCCC_SEXPRTYPE_DOTTEDPAIR) { + return (true); + } + return (false); +} + +bool +isccc_sexpr_emptyp(isccc_sexpr_t *sexpr) { + if (sexpr == NULL) { + return (true); + } + return (false); +} + +bool +isccc_sexpr_stringp(isccc_sexpr_t *sexpr) { + if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_STRING) { + return (true); + } + return (false); +} + +bool +isccc_sexpr_binaryp(isccc_sexpr_t *sexpr) { + if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY) { + return (true); + } + return (false); +} + +char * +isccc_sexpr_tostring(isccc_sexpr_t *sexpr) { + REQUIRE(sexpr != NULL && (sexpr->type == ISCCC_SEXPRTYPE_STRING || + sexpr->type == ISCCC_SEXPRTYPE_BINARY)); + + if (sexpr->type == ISCCC_SEXPRTYPE_BINARY) { + return ((char *)sexpr->value.as_region.rstart); + } + return (sexpr->value.as_string); +} + +isccc_region_t * +isccc_sexpr_tobinary(isccc_sexpr_t *sexpr) { + REQUIRE(sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY); + return (&sexpr->value.as_region); +} diff --git a/lib/isccc/symtab.c b/lib/isccc/symtab.c new file mode 100644 index 0000000..62e4614 --- /dev/null +++ b/lib/isccc/symtab.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 AND ISC + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Copyright (C) 2001 Nominum, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*! \file */ + +#include <ctype.h> +#include <stdbool.h> +#include <stdlib.h> + +#include <isc/assertions.h> +#include <isc/magic.h> +#include <isc/result.h> +#include <isc/string.h> + +#include <isccc/symtab.h> +#include <isccc/util.h> + +typedef struct elt { + char *key; + unsigned int type; + isccc_symvalue_t value; + ISC_LINK(struct elt) link; +} elt_t; + +typedef ISC_LIST(elt_t) eltlist_t; + +#define SYMTAB_MAGIC ISC_MAGIC('S', 'y', 'm', 'T') +#define VALID_SYMTAB(st) ISC_MAGIC_VALID(st, SYMTAB_MAGIC) + +struct isccc_symtab { + unsigned int magic; + unsigned int size; + eltlist_t *table; + isccc_symtabundefaction_t undefine_action; + void *undefine_arg; + bool case_sensitive; +}; + +isc_result_t +isccc_symtab_create(unsigned int size, + isccc_symtabundefaction_t undefine_action, + void *undefine_arg, bool case_sensitive, + isccc_symtab_t **symtabp) { + isccc_symtab_t *symtab; + unsigned int i; + + REQUIRE(symtabp != NULL && *symtabp == NULL); + REQUIRE(size > 0); /* Should be prime. */ + + symtab = malloc(sizeof(*symtab)); + if (symtab == NULL) { + return (ISC_R_NOMEMORY); + } + symtab->table = malloc(size * sizeof(eltlist_t)); + if (symtab->table == NULL) { + free(symtab); + return (ISC_R_NOMEMORY); + } + for (i = 0; i < size; i++) { + ISC_LIST_INIT(symtab->table[i]); + } + symtab->size = size; + symtab->undefine_action = undefine_action; + symtab->undefine_arg = undefine_arg; + symtab->case_sensitive = case_sensitive; + symtab->magic = SYMTAB_MAGIC; + + *symtabp = symtab; + + return (ISC_R_SUCCESS); +} + +static void +free_elt(isccc_symtab_t *symtab, unsigned int bucket, elt_t *elt) { + ISC_LIST_UNLINK(symtab->table[bucket], elt, link); + if (symtab->undefine_action != NULL) { + (symtab->undefine_action)(elt->key, elt->type, elt->value, + symtab->undefine_arg); + } + free(elt); +} + +void +isccc_symtab_destroy(isccc_symtab_t **symtabp) { + isccc_symtab_t *symtab; + unsigned int i; + elt_t *elt, *nelt; + + REQUIRE(symtabp != NULL); + symtab = *symtabp; + *symtabp = NULL; + REQUIRE(VALID_SYMTAB(symtab)); + + for (i = 0; i < symtab->size; i++) { + for (elt = ISC_LIST_HEAD(symtab->table[i]); elt != NULL; + elt = nelt) + { + nelt = ISC_LIST_NEXT(elt, link); + free_elt(symtab, i, elt); + } + } + free(symtab->table); + symtab->magic = 0; + free(symtab); +} + +static unsigned int +hash(const char *key, bool case_sensitive) { + const char *s; + unsigned int h = 0; + unsigned int g; + int c; + + /* + * P. J. Weinberger's hash function, adapted from p. 436 of + * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi + * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6. + */ + + if (case_sensitive) { + for (s = key; *s != '\0'; s++) { + h = (h << 4) + *s; + if ((g = (h & 0xf0000000)) != 0) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + } else { + for (s = key; *s != '\0'; s++) { + c = *s; + c = tolower((unsigned char)c); + h = (h << 4) + c; + if ((g = (h & 0xf0000000)) != 0) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + } + + return (h); +} + +#define FIND(s, k, t, b, e) \ + b = hash((k), (s)->case_sensitive) % (s)->size; \ + if ((s)->case_sensitive) { \ + for (e = ISC_LIST_HEAD((s)->table[b]); e != NULL; \ + e = ISC_LIST_NEXT(e, link)) \ + { \ + if (((t) == 0 || e->type == (t)) && \ + strcmp(e->key, (k)) == 0) \ + break; \ + } \ + } else { \ + for (e = ISC_LIST_HEAD((s)->table[b]); e != NULL; \ + e = ISC_LIST_NEXT(e, link)) \ + { \ + if (((t) == 0 || e->type == (t)) && \ + strcasecmp(e->key, (k)) == 0) \ + break; \ + } \ + } + +isc_result_t +isccc_symtab_lookup(isccc_symtab_t *symtab, const char *key, unsigned int type, + isccc_symvalue_t *value) { + unsigned int bucket; + elt_t *elt; + + REQUIRE(VALID_SYMTAB(symtab)); + REQUIRE(key != NULL); + + FIND(symtab, key, type, bucket, elt); + + if (elt == NULL) { + return (ISC_R_NOTFOUND); + } + + if (value != NULL) { + *value = elt->value; + } + + return (ISC_R_SUCCESS); +} + +isc_result_t +isccc_symtab_define(isccc_symtab_t *symtab, char *key, unsigned int type, + isccc_symvalue_t value, isccc_symexists_t exists_policy) { + unsigned int bucket; + elt_t *elt; + + REQUIRE(VALID_SYMTAB(symtab)); + REQUIRE(key != NULL); + REQUIRE(type != 0); + + FIND(symtab, key, type, bucket, elt); + + if (exists_policy != isccc_symexists_add && elt != NULL) { + if (exists_policy == isccc_symexists_reject) { + return (ISC_R_EXISTS); + } + INSIST(exists_policy == isccc_symexists_replace); + ISC_LIST_UNLINK(symtab->table[bucket], elt, link); + if (symtab->undefine_action != NULL) { + (symtab->undefine_action)(elt->key, elt->type, + elt->value, + symtab->undefine_arg); + } + } else { + elt = malloc(sizeof(*elt)); + if (elt == NULL) { + return (ISC_R_NOMEMORY); + } + ISC_LINK_INIT(elt, link); + } + + elt->key = key; + elt->type = type; + elt->value = value; + + /* + * We prepend so that the most recent definition will be found. + */ + ISC_LIST_PREPEND(symtab->table[bucket], elt, link); + + return (ISC_R_SUCCESS); +} + +isc_result_t +isccc_symtab_undefine(isccc_symtab_t *symtab, const char *key, + unsigned int type) { + unsigned int bucket; + elt_t *elt; + + REQUIRE(VALID_SYMTAB(symtab)); + REQUIRE(key != NULL); + + FIND(symtab, key, type, bucket, elt); + + if (elt == NULL) { + return (ISC_R_NOTFOUND); + } + + free_elt(symtab, bucket, elt); + + return (ISC_R_SUCCESS); +} + +void +isccc_symtab_foreach(isccc_symtab_t *symtab, isccc_symtabforeachaction_t action, + void *arg) { + unsigned int i; + elt_t *elt, *nelt; + + REQUIRE(VALID_SYMTAB(symtab)); + REQUIRE(action != NULL); + + for (i = 0; i < symtab->size; i++) { + for (elt = ISC_LIST_HEAD(symtab->table[i]); elt != NULL; + elt = nelt) + { + nelt = ISC_LIST_NEXT(elt, link); + if ((action)(elt->key, elt->type, elt->value, arg)) { + free_elt(symtab, i, elt); + } + } + } +} |