diff options
Diffstat (limited to 'lib/ipc')
| -rw-r--r-- | lib/ipc/Makefile.am | 67 | ||||
| -rw-r--r-- | lib/ipc/Makefile.in | 1073 | ||||
| -rw-r--r-- | lib/ipc/client.c | 574 | ||||
| -rw-r--r-- | lib/ipc/common.c | 204 | ||||
| -rw-r--r-- | lib/ipc/heim-ipc.h | 130 | ||||
| -rw-r--r-- | lib/ipc/heim_ipc.defs | 66 | ||||
| -rw-r--r-- | lib/ipc/heim_ipc_async.defs | 56 | ||||
| -rw-r--r-- | lib/ipc/heim_ipc_reply.defs | 51 | ||||
| -rw-r--r-- | lib/ipc/heim_ipc_types.h | 44 | ||||
| -rw-r--r-- | lib/ipc/hi_locl.h | 83 | ||||
| -rw-r--r-- | lib/ipc/server.c | 1187 | ||||
| -rw-r--r-- | lib/ipc/tc.c | 127 | ||||
| -rw-r--r-- | lib/ipc/ts-http.c | 136 | ||||
| -rw-r--r-- | lib/ipc/ts.c | 105 | 
14 files changed, 3903 insertions, 0 deletions
| diff --git a/lib/ipc/Makefile.am b/lib/ipc/Makefile.am new file mode 100644 index 000000000000..fc3ba469d481 --- /dev/null +++ b/lib/ipc/Makefile.am @@ -0,0 +1,67 @@ +include $(top_srcdir)/Makefile.am.common + +noinst_LTLIBRARIES = libheim-ipcc.la libheim-ipcs.la + +dist_libheim_ipcc_la_SOURCES = hi_locl.h heim_ipc_types.h client.c common.c +dist_libheim_ipcs_la_SOURCES = hi_locl.h heim_ipc_types.h server.c common.c + +include_HEADERS = heim-ipc.h + +## +## Enable when this is not a noinst_ library +## +#libheim_ipcc_la_LDFLAGS = -version-info 0:0:0 +#libheim_ipcs_la_LDFLAGS = -version-info 0:0:0 +# +#if versionscript +#libheim_ipcc_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scriptc.map +#libheim_ipcs_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scripts.map +#endif + +libheim_ipcc_la_LIBADD = \ +	$(LIB_heimbase) \ +	$(LIB_roken) \ +	$(PTHREAD_LIBADD) + +libheim_ipcs_la_LIBADD = $(libheim_ipcc_la_LIBADD) + +TESTS =	$(check_PROGRAMS) + +noinst_PROGRAMS = tc ts ts-http + +ts_LDADD = libheim-ipcs.la $(LIB_roken) +ts_http_LDADD = $(ts_LDADD) +tc_LDADD = libheim-ipcc.la $(LIB_roken) + +if have_gcd + +EXTRA_DIST = heim_ipc.defs heim_ipc_async.defs heim_ipc_reply.defs + +heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs +	mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs + +heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs +	mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs + +heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs +	mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs + +built_ipcc = heim_ipc.h heim_ipcUser.c +built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h + +nodist_libheim_ipcc_la_SOURCES = $(built_ipcc) + +built_ipcs = heim_ipcServer.c heim_ipcServer.h +built_ipcs += heim_ipc_asyncUser.c heim_ipc_async.h +built_ipcs += heim_ipc_reply.h heim_ipc_replyUser.c + +nodist_libheim_ipcs_la_SOURCES = $(built_ipcs) + +libheim_ipcs_la_LIBADD += -lbsm + +CLEANFILES = $(built_ipcc) $(built_ipcs) + +$(srcdir)/client.c: $(built_ipcc) +$(srcdir)/server.c: $(built_ipcs) + +endif
\ No newline at end of file diff --git a/lib/ipc/Makefile.in b/lib/ipc/Makefile.in new file mode 100644 index 000000000000..1fd0c227bd6e --- /dev/null +++ b/lib/ipc/Makefile.in @@ -0,0 +1,1073 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009  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@ + +# $Id$ + +# $Id$ + + + +VPATH = @srcdir@ +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@ +DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ +	$(srcdir)/Makefile.in $(top_srcdir)/Makefile.am.common \ +	$(top_srcdir)/cf/Makefile.am.common +TESTS = +noinst_PROGRAMS = tc$(EXEEXT) ts$(EXEEXT) ts-http$(EXEEXT) +@have_gcd_TRUE@am__append_1 = -lbsm +subdir = lib/ipc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ +	$(top_srcdir)/cf/auth-modules.m4 \ +	$(top_srcdir)/cf/broken-getaddrinfo.m4 \ +	$(top_srcdir)/cf/broken-glob.m4 \ +	$(top_srcdir)/cf/broken-realloc.m4 \ +	$(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \ +	$(top_srcdir)/cf/broken2.m4 $(top_srcdir)/cf/c-attribute.m4 \ +	$(top_srcdir)/cf/capabilities.m4 \ +	$(top_srcdir)/cf/check-compile-et.m4 \ +	$(top_srcdir)/cf/check-getpwnam_r-posix.m4 \ +	$(top_srcdir)/cf/check-man.m4 \ +	$(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \ +	$(top_srcdir)/cf/check-type-extra.m4 \ +	$(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \ +	$(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \ +	$(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \ +	$(top_srcdir)/cf/dispatch.m4 $(top_srcdir)/cf/dlopen.m4 \ +	$(top_srcdir)/cf/find-func-no-libs.m4 \ +	$(top_srcdir)/cf/find-func-no-libs2.m4 \ +	$(top_srcdir)/cf/find-func.m4 \ +	$(top_srcdir)/cf/find-if-not-broken.m4 \ +	$(top_srcdir)/cf/framework-security.m4 \ +	$(top_srcdir)/cf/have-struct-field.m4 \ +	$(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \ +	$(top_srcdir)/cf/krb-bigendian.m4 \ +	$(top_srcdir)/cf/krb-func-getlogin.m4 \ +	$(top_srcdir)/cf/krb-ipv6.m4 $(top_srcdir)/cf/krb-prog-ln-s.m4 \ +	$(top_srcdir)/cf/krb-readline.m4 \ +	$(top_srcdir)/cf/krb-struct-spwd.m4 \ +	$(top_srcdir)/cf/krb-struct-winsize.m4 \ +	$(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/libtool.m4 \ +	$(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \ +	$(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.m4 \ +	$(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \ +	$(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \ +	$(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/pkg.m4 \ +	$(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \ +	$(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \ +	$(top_srcdir)/cf/roken-frag.m4 \ +	$(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \ +	$(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \ +	$(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \ +	$(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \ +	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +	$(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libheim_ipcc_la_DEPENDENCIES = $(LIB_heimbase) $(am__DEPENDENCIES_1) \ +	$(am__DEPENDENCIES_1) +dist_libheim_ipcc_la_OBJECTS = client.lo common.lo +@have_gcd_TRUE@am__objects_1 = heim_ipcUser.lo heim_ipc_asyncServer.lo +@have_gcd_TRUE@nodist_libheim_ipcc_la_OBJECTS = $(am__objects_1) +libheim_ipcc_la_OBJECTS = $(dist_libheim_ipcc_la_OBJECTS) \ +	$(nodist_libheim_ipcc_la_OBJECTS) +am__DEPENDENCIES_2 = $(LIB_heimbase) $(am__DEPENDENCIES_1) \ +	$(am__DEPENDENCIES_1) +libheim_ipcs_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ +	$(am__DEPENDENCIES_1) +dist_libheim_ipcs_la_OBJECTS = server.lo common.lo +@have_gcd_TRUE@am__objects_2 = heim_ipcServer.lo heim_ipc_asyncUser.lo \ +@have_gcd_TRUE@	heim_ipc_replyUser.lo +@have_gcd_TRUE@nodist_libheim_ipcs_la_OBJECTS = $(am__objects_2) +libheim_ipcs_la_OBJECTS = $(dist_libheim_ipcs_la_OBJECTS) \ +	$(nodist_libheim_ipcs_la_OBJECTS) +PROGRAMS = $(noinst_PROGRAMS) +tc_SOURCES = tc.c +tc_OBJECTS = tc.$(OBJEXT) +tc_DEPENDENCIES = libheim-ipcc.la $(am__DEPENDENCIES_1) +ts_SOURCES = ts.c +ts_OBJECTS = ts.$(OBJEXT) +ts_DEPENDENCIES = libheim-ipcs.la $(am__DEPENDENCIES_1) +ts_http_SOURCES = ts-http.c +ts_http_OBJECTS = ts-http.$(OBJEXT) +am__DEPENDENCIES_3 = libheim-ipcs.la $(am__DEPENDENCIES_1) +ts_http_DEPENDENCIES = $(am__DEPENDENCIES_3) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ +	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ +	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ +	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ +	$(LDFLAGS) -o $@ +SOURCES = $(dist_libheim_ipcc_la_SOURCES) \ +	$(nodist_libheim_ipcc_la_SOURCES) \ +	$(dist_libheim_ipcs_la_SOURCES) \ +	$(nodist_libheim_ipcs_la_SOURCES) tc.c ts.c ts-http.c +DIST_SOURCES = $(dist_libheim_ipcc_la_SOURCES) \ +	$(dist_libheim_ipcs_la_SOURCES) tc.c ts.c ts-http.c +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__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ +AMTAR = @AMTAR@ +AR = @AR@ +ASN1_COMPILE = @ASN1_COMPILE@ +ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CANONICAL_HOST = @CANONICAL_HOST@ +CAPNG_CFLAGS = @CAPNG_CFLAGS@ +CAPNG_LIBS = @CAPNG_LIBS@ +CATMAN = @CATMAN@ +CATMANEXT = @CATMANEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILE_ET = @COMPILE_ET@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBHEADER = @DBHEADER@ +DBLIB = @DBLIB@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DIR_com_err = @DIR_com_err@ +DIR_hcrypto = @DIR_hcrypto@ +DIR_hdbdir = @DIR_hdbdir@ +DIR_roken = @DIR_roken@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GROFF = @GROFF@ +INCLUDES_roken = @INCLUDES_roken@ +INCLUDE_hcrypto = @INCLUDE_hcrypto@ +INCLUDE_hesiod = @INCLUDE_hesiod@ +INCLUDE_krb4 = @INCLUDE_krb4@ +INCLUDE_libedit = @INCLUDE_libedit@ +INCLUDE_libintl = @INCLUDE_libintl@ +INCLUDE_openldap = @INCLUDE_openldap@ +INCLUDE_readline = @INCLUDE_readline@ +INCLUDE_sqlite3 = @INCLUDE_sqlite3@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_roken = @LIBADD_roken@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@ +LIB_NDBM = @LIB_NDBM@ +LIB_XauFileName = @LIB_XauFileName@ +LIB_XauReadAuth = @LIB_XauReadAuth@ +LIB_XauWriteAuth = @LIB_XauWriteAuth@ +LIB_bswap16 = @LIB_bswap16@ +LIB_bswap32 = @LIB_bswap32@ +LIB_com_err = @LIB_com_err@ +LIB_com_err_a = @LIB_com_err_a@ +LIB_com_err_so = @LIB_com_err_so@ +LIB_crypt = @LIB_crypt@ +LIB_db_create = @LIB_db_create@ +LIB_dbm_firstkey = @LIB_dbm_firstkey@ +LIB_dbopen = @LIB_dbopen@ +LIB_dispatch_async_f = @LIB_dispatch_async_f@ +LIB_dlopen = @LIB_dlopen@ +LIB_dn_expand = @LIB_dn_expand@ +LIB_dns_search = @LIB_dns_search@ +LIB_door_create = @LIB_door_create@ +LIB_freeaddrinfo = @LIB_freeaddrinfo@ +LIB_gai_strerror = @LIB_gai_strerror@ +LIB_getaddrinfo = @LIB_getaddrinfo@ +LIB_gethostbyname = @LIB_gethostbyname@ +LIB_gethostbyname2 = @LIB_gethostbyname2@ +LIB_getnameinfo = @LIB_getnameinfo@ +LIB_getpwnam_r = @LIB_getpwnam_r@ +LIB_getsockopt = @LIB_getsockopt@ +LIB_hcrypto = @LIB_hcrypto@ +LIB_hcrypto_a = @LIB_hcrypto_a@ +LIB_hcrypto_appl = @LIB_hcrypto_appl@ +LIB_hcrypto_so = @LIB_hcrypto_so@ +LIB_hesiod = @LIB_hesiod@ +LIB_hstrerror = @LIB_hstrerror@ +LIB_kdb = @LIB_kdb@ +LIB_krb4 = @LIB_krb4@ +LIB_libedit = @LIB_libedit@ +LIB_libintl = @LIB_libintl@ +LIB_loadquery = @LIB_loadquery@ +LIB_logout = @LIB_logout@ +LIB_logwtmp = @LIB_logwtmp@ +LIB_openldap = @LIB_openldap@ +LIB_openpty = @LIB_openpty@ +LIB_otp = @LIB_otp@ +LIB_pidfile = @LIB_pidfile@ +LIB_readline = @LIB_readline@ +LIB_res_ndestroy = @LIB_res_ndestroy@ +LIB_res_nsearch = @LIB_res_nsearch@ +LIB_res_search = @LIB_res_search@ +LIB_roken = @LIB_roken@ +LIB_security = @LIB_security@ +LIB_setsockopt = @LIB_setsockopt@ +LIB_socket = @LIB_socket@ +LIB_sqlite3 = @LIB_sqlite3@ +LIB_syslog = @LIB_syslog@ +LIB_tgetent = @LIB_tgetent@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NO_AFS = @NO_AFS@ +NROFF = @NROFF@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +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@ +PKG_CONFIG = @PKG_CONFIG@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LDADD = @PTHREAD_LDADD@ +PTHREAD_LIBADD = @PTHREAD_LIBADD@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SLC = @SLC@ +SLC_DEP = @SLC_DEP@ +STRIP = @STRIP@ +VERSION = @VERSION@ +VERSIONING = @VERSIONING@ +WFLAGS = @WFLAGS@ +WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ +WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +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_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@ +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@ +dpagaix_cflags = @dpagaix_cflags@ +dpagaix_ldadd = @dpagaix_ldadd@ +dpagaix_ldflags = @dpagaix_ldflags@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUFFIXES = .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include +AM_CPPFLAGS = $(INCLUDES_roken) +@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME +AM_CFLAGS = $(WFLAGS) +CP = cp +buildinclude = $(top_builddir)/include +LIB_el_init = @LIB_el_init@ +LIB_getattr = @LIB_getattr@ +LIB_getpwent_r = @LIB_getpwent_r@ +LIB_odm_initialize = @LIB_odm_initialize@ +LIB_setpcred = @LIB_setpcred@ +HESIODLIB = @HESIODLIB@ +HESIODINCLUDE = @HESIODINCLUDE@ +libexec_heimdaldir = $(libexecdir)/heimdal +NROFF_MAN = groff -mandoc -Tascii +LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) +@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \ +@KRB5_TRUE@	$(top_builddir)/lib/asn1/libasn1.la + +@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la +LIB_heimbase = $(top_builddir)/base/libheimbase.la +@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la +noinst_LTLIBRARIES = libheim-ipcc.la libheim-ipcs.la +dist_libheim_ipcc_la_SOURCES = hi_locl.h heim_ipc_types.h client.c common.c +dist_libheim_ipcs_la_SOURCES = hi_locl.h heim_ipc_types.h server.c common.c +include_HEADERS = heim-ipc.h + +#libheim_ipcc_la_LDFLAGS = -version-info 0:0:0 +#libheim_ipcs_la_LDFLAGS = -version-info 0:0:0 +# +#if versionscript +#libheim_ipcc_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scriptc.map +#libheim_ipcs_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scripts.map +#endif +libheim_ipcc_la_LIBADD = \ +	$(LIB_heimbase) \ +	$(LIB_roken) \ +	$(PTHREAD_LIBADD) + +libheim_ipcs_la_LIBADD = $(libheim_ipcc_la_LIBADD) $(am__append_1) +ts_LDADD = libheim-ipcs.la $(LIB_roken) +ts_http_LDADD = $(ts_LDADD) +tc_LDADD = libheim-ipcc.la $(LIB_roken) +@have_gcd_TRUE@EXTRA_DIST = heim_ipc.defs heim_ipc_async.defs heim_ipc_reply.defs +@have_gcd_TRUE@built_ipcc = heim_ipc.h heim_ipcUser.c \ +@have_gcd_TRUE@	heim_ipc_asyncServer.c heim_ipc_asyncServer.h +@have_gcd_TRUE@nodist_libheim_ipcc_la_SOURCES = $(built_ipcc) +@have_gcd_TRUE@built_ipcs = heim_ipcServer.c heim_ipcServer.h \ +@have_gcd_TRUE@	heim_ipc_asyncUser.c heim_ipc_async.h \ +@have_gcd_TRUE@	heim_ipc_reply.h heim_ipc_replyUser.c +@have_gcd_TRUE@nodist_libheim_ipcs_la_SOURCES = $(built_ipcs) +@have_gcd_TRUE@CLEANFILES = $(built_ipcc) $(built_ipcs) +all: all-am + +.SUFFIXES: +.SUFFIXES: .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(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/ipc/Makefile'; \ +	$(am__cd) $(top_srcdir) && \ +	  $(AUTOMAKE) --foreign lib/ipc/Makefile +.PRECIOUS: 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__depfiles_maybe)'; \ +	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ +	esac; + +$(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): + +clean-noinstLTLIBRARIES: +	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) +	@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ +	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ +	  test "$$dir" != "$$p" || dir=.; \ +	  echo "rm -f \"$${dir}/so_locations\""; \ +	  rm -f "$${dir}/so_locations"; \ +	done +libheim-ipcc.la: $(libheim_ipcc_la_OBJECTS) $(libheim_ipcc_la_DEPENDENCIES)  +	$(LINK)  $(libheim_ipcc_la_OBJECTS) $(libheim_ipcc_la_LIBADD) $(LIBS) +libheim-ipcs.la: $(libheim_ipcs_la_OBJECTS) $(libheim_ipcs_la_DEPENDENCIES)  +	$(LINK)  $(libheim_ipcs_la_OBJECTS) $(libheim_ipcs_la_LIBADD) $(LIBS) + +clean-noinstPROGRAMS: +	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ +	echo " rm -f" $$list; \ +	rm -f $$list || exit $$?; \ +	test -n "$(EXEEXT)" || exit 0; \ +	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ +	echo " rm -f" $$list; \ +	rm -f $$list +tc$(EXEEXT): $(tc_OBJECTS) $(tc_DEPENDENCIES)  +	@rm -f tc$(EXEEXT) +	$(LINK) $(tc_OBJECTS) $(tc_LDADD) $(LIBS) +ts$(EXEEXT): $(ts_OBJECTS) $(ts_DEPENDENCIES)  +	@rm -f ts$(EXEEXT) +	$(LINK) $(ts_OBJECTS) $(ts_LDADD) $(LIBS) +ts-http$(EXEEXT): $(ts_http_OBJECTS) $(ts_http_DEPENDENCIES)  +	@rm -f ts-http$(EXEEXT) +	$(LINK) $(ts_http_OBJECTS) $(ts_http_LDADD) $(LIBS) + +mostlyclean-compile: +	-rm -f *.$(OBJEXT) + +distclean-compile: +	-rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heim_ipcServer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heim_ipcUser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heim_ipc_asyncServer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heim_ipc_asyncUser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heim_ipc_replyUser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts-http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: +	-rm -f *.lo + +clean-libtool: +	-rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) +	@$(NORMAL_INSTALL) +	test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" +	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ +	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)$(includedir)'"; \ +	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ +	done + +uninstall-includeHEADERS: +	@$(NORMAL_UNINSTALL) +	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ +	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ +	test -n "$$files" || exit 0; \ +	echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ +	cd "$(DESTDIR)$(includedir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) +	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	mkid -fID $$unique +tags: TAGS + +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ +		$(TAGS_FILES) $(LISP) +	set x; \ +	here=`pwd`; \ +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	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 +CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ +		$(TAGS_FILES) $(LISP) +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \ +	unique=`for i in $$list; do \ +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +	  done | \ +	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ +	      END { if (nonempty) { for (i in files) print i; }; }'`; \ +	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" + +distclean-tags: +	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) +	@failed=0; all=0; xfail=0; xpass=0; skip=0; \ +	srcdir=$(srcdir); export srcdir; \ +	list=' $(TESTS) '; \ +	$(am__tty_colors); \ +	if test -n "$$list"; then \ +	  for tst in $$list; do \ +	    if test -f ./$$tst; then dir=./; \ +	    elif test -f $$tst; then dir=; \ +	    else dir="$(srcdir)/"; fi; \ +	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ +	      all=`expr $$all + 1`; \ +	      case " $(XFAIL_TESTS) " in \ +	      *[\ \	]$$tst[\ \	]*) \ +		xpass=`expr $$xpass + 1`; \ +		failed=`expr $$failed + 1`; \ +		col=$$red; res=XPASS; \ +	      ;; \ +	      *) \ +		col=$$grn; res=PASS; \ +	      ;; \ +	      esac; \ +	    elif test $$? -ne 77; then \ +	      all=`expr $$all + 1`; \ +	      case " $(XFAIL_TESTS) " in \ +	      *[\ \	]$$tst[\ \	]*) \ +		xfail=`expr $$xfail + 1`; \ +		col=$$lgn; res=XFAIL; \ +	      ;; \ +	      *) \ +		failed=`expr $$failed + 1`; \ +		col=$$red; res=FAIL; \ +	      ;; \ +	      esac; \ +	    else \ +	      skip=`expr $$skip + 1`; \ +	      col=$$blu; res=SKIP; \ +	    fi; \ +	    echo "$${col}$$res$${std}: $$tst"; \ +	  done; \ +	  if test "$$all" -eq 1; then \ +	    tests="test"; \ +	    All=""; \ +	  else \ +	    tests="tests"; \ +	    All="All "; \ +	  fi; \ +	  if test "$$failed" -eq 0; then \ +	    if test "$$xfail" -eq 0; then \ +	      banner="$$All$$all $$tests passed"; \ +	    else \ +	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ +	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ +	    fi; \ +	  else \ +	    if test "$$xpass" -eq 0; then \ +	      banner="$$failed of $$all $$tests failed"; \ +	    else \ +	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ +	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ +	    fi; \ +	  fi; \ +	  dashes="$$banner"; \ +	  skipped=""; \ +	  if test "$$skip" -ne 0; then \ +	    if test "$$skip" -eq 1; then \ +	      skipped="($$skip test was not run)"; \ +	    else \ +	      skipped="($$skip tests were not run)"; \ +	    fi; \ +	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ +	      dashes="$$skipped"; \ +	  fi; \ +	  report=""; \ +	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ +	    report="Please report to $(PACKAGE_BUGREPORT)"; \ +	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ +	      dashes="$$report"; \ +	  fi; \ +	  dashes=`echo "$$dashes" | sed s/./=/g`; \ +	  if test "$$failed" -eq 0; then \ +	    echo "$$grn$$dashes"; \ +	  else \ +	    echo "$$red$$dashes"; \ +	  fi; \ +	  echo "$$banner"; \ +	  test -z "$$skipped" || echo "$$skipped"; \ +	  test -z "$$report" || echo "$$report"; \ +	  echo "$$dashes$$std"; \ +	  test "$$failed" -eq 0; \ +	else :; fi + +distdir: $(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 +	$(MAKE) $(AM_MAKEFLAGS) \ +	  top_distdir="$(top_distdir)" distdir="$(distdir)" \ +	  dist-hook +check-am: all-am +	$(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local +installdirs: +	for dir in "$(DESTDIR)$(includedir)"; 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: +	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +	  `test -z '$(STRIP)' || \ +	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: +	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libtool clean-noinstLTLIBRARIES \ +	clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am +	-rm -rf ./$(DEPDIR) +	-rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ +	distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS +	@$(NORMAL_INSTALL) +	$(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: +	@$(NORMAL_INSTALL) +	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook +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 -rf ./$(DEPDIR) +	-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: + +uninstall-am: uninstall-includeHEADERS +	@$(NORMAL_INSTALL) +	$(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: check-am install-am install-data-am install-exec-am \ +	install-strip uninstall-am + +.PHONY: CTAGS GTAGS all all-am all-local check check-TESTS check-am \ +	check-local clean clean-generic clean-libtool \ +	clean-noinstLTLIBRARIES clean-noinstPROGRAMS ctags dist-hook \ +	distclean distclean-compile distclean-generic \ +	distclean-libtool distclean-tags distdir dvi dvi-am html \ +	html-am info info-am install install-am install-data \ +	install-data-am install-data-hook install-dvi install-dvi-am \ +	install-exec install-exec-am install-exec-hook install-html \ +	install-html-am install-includeHEADERS install-info \ +	install-info-am 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 uninstall uninstall-am uninstall-hook \ +	uninstall-includeHEADERS + + +install-suid-programs: +	@foo='$(bin_SUIDS)'; \ +	for file in $$foo; do \ +	x=$(DESTDIR)$(bindir)/$$file; \ +	if chown 0:0 $$x && chmod u+s $$x; then :; else \ +	echo "*"; \ +	echo "* Failed to install $$x setuid root"; \ +	echo "*"; \ +	fi; done + +install-exec-hook: install-suid-programs + +install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS) +	@foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \ +	for f in $$foo; do \ +		f=`basename $$f`; \ +		if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ +		else file="$$f"; fi; \ +		if cmp -s  $$file $(buildinclude)/$$f 2> /dev/null ; then \ +		: ; else \ +			echo " $(CP) $$file $(buildinclude)/$$f"; \ +			$(CP) $$file $(buildinclude)/$$f; \ +		fi ; \ +	done ; \ +	foo='$(nobase_include_HEADERS)'; \ +	for f in $$foo; do \ +		if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ +		else file="$$f"; fi; \ +		$(mkdir_p) $(buildinclude)/`dirname $$f` ; \ +		if cmp -s  $$file $(buildinclude)/$$f 2> /dev/null ; then \ +		: ; else \ +			echo " $(CP) $$file $(buildinclude)/$$f"; \ +			$(CP) $$file $(buildinclude)/$$f; \ +		fi ; \ +	done + +all-local: install-build-headers + +check-local:: +	@if test '$(CHECK_LOCAL)' = "no-check-local"; then \ +	  foo=''; elif test '$(CHECK_LOCAL)'; then \ +	  foo='$(CHECK_LOCAL)'; else \ +	  foo='$(PROGRAMS)'; fi; \ +	  if test "$$foo"; then \ +	  failed=0; all=0; \ +	  for i in $$foo; do \ +	    all=`expr $$all + 1`; \ +	    if (./$$i --version && ./$$i --help) > /dev/null 2>&1; then \ +	      echo "PASS: $$i"; \ +	    else \ +	      echo "FAIL: $$i"; \ +	      failed=`expr $$failed + 1`; \ +	    fi; \ +	  done; \ +	  if test "$$failed" -eq 0; then \ +	    banner="All $$all tests passed"; \ +	  else \ +	    banner="$$failed of $$all tests failed"; \ +	  fi; \ +	  dashes=`echo "$$banner" | sed s/./=/g`; \ +	  echo "$$dashes"; \ +	  echo "$$banner"; \ +	  echo "$$dashes"; \ +	  test "$$failed" -eq 0 || exit 1; \ +	fi + +.x.c: +	@cmp -s $< $@ 2> /dev/null || cp $< $@ + +.hx.h: +	@cmp -s $< $@ 2> /dev/null || cp $< $@ +#NROFF_MAN = nroff -man +.1.cat1: +	$(NROFF_MAN) $< > $@ +.3.cat3: +	$(NROFF_MAN) $< > $@ +.5.cat5: +	$(NROFF_MAN) $< > $@ +.8.cat8: +	$(NROFF_MAN) $< > $@ + +dist-cat1-mans: +	@foo='$(man1_MANS)'; \ +	bar='$(man_MANS)'; \ +	for i in $$bar; do \ +	case $$i in \ +	*.1) foo="$$foo $$i";; \ +	esac; done ;\ +	for i in $$foo; do \ +		x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \ +		echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \ +		$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \ +	done + +dist-cat3-mans: +	@foo='$(man3_MANS)'; \ +	bar='$(man_MANS)'; \ +	for i in $$bar; do \ +	case $$i in \ +	*.3) foo="$$foo $$i";; \ +	esac; done ;\ +	for i in $$foo; do \ +		x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \ +		echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \ +		$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \ +	done + +dist-cat5-mans: +	@foo='$(man5_MANS)'; \ +	bar='$(man_MANS)'; \ +	for i in $$bar; do \ +	case $$i in \ +	*.5) foo="$$foo $$i";; \ +	esac; done ;\ +	for i in $$foo; do \ +		x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \ +		echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \ +		$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \ +	done + +dist-cat8-mans: +	@foo='$(man8_MANS)'; \ +	bar='$(man_MANS)'; \ +	for i in $$bar; do \ +	case $$i in \ +	*.8) foo="$$foo $$i";; \ +	esac; done ;\ +	for i in $$foo; do \ +		x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \ +		echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \ +		$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \ +	done + +dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans + +install-cat-mans: +	$(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +uninstall-cat-mans: +	$(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +install-data-hook: install-cat-mans +uninstall-hook: uninstall-cat-mans + +.et.h: +	$(COMPILE_ET) $< +.et.c: +	$(COMPILE_ET) $< + +# +# Useful target for debugging +# + +check-valgrind: +	tobjdir=`cd $(top_builddir) && pwd` ; \ +	tsrcdir=`cd $(top_srcdir) && pwd` ; \ +	env TESTS_ENVIRONMENT="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" make check + +# +# Target to please samba build farm, builds distfiles in-tree. +# Will break when automake changes... +# + +distdir-in-tree: $(DISTFILES) $(INFO_DEPS) +	list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ +	  if test "$$subdir" != .; then \ +	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \ +	  fi ; \ +	done + +@have_gcd_TRUE@heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs +@have_gcd_TRUE@	mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs + +@have_gcd_TRUE@heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs +@have_gcd_TRUE@	mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs + +@have_gcd_TRUE@heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs +@have_gcd_TRUE@	mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs + +@have_gcd_TRUE@$(srcdir)/client.c: $(built_ipcc) +@have_gcd_TRUE@$(srcdir)/server.c: $(built_ipcs) + +# 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/ipc/client.c b/lib/ipc/client.c new file mode 100644 index 000000000000..bb7d9750bffa --- /dev/null +++ b/lib/ipc/client.c @@ -0,0 +1,574 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hi_locl.h" + +#if defined(__APPLE__) && defined(HAVE_GCD) + +#include "heim_ipc.h" +#include "heim_ipc_asyncServer.h" + +#include <dispatch/dispatch.h> +#include <mach/mach.h> + +static dispatch_once_t jobqinited = 0; +static dispatch_queue_t jobq = NULL; +static dispatch_queue_t syncq; + +struct mach_ctx { +    mach_port_t server; +    char *name; +}; + +static int +mach_release(void *ctx); + +static int +mach_init(const char *service, void **ctx) +{ +    struct mach_ctx *ipc; +    mach_port_t sport; +    int ret; + +    dispatch_once(&jobqinited, ^{ +	    jobq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); +	    syncq = dispatch_queue_create("heim-ipc-syncq", NULL); +	}); + +    ret = bootstrap_look_up(bootstrap_port, service, &sport); +    if (ret) +	return ret; + +    ipc = malloc(sizeof(*ipc)); +    if (ipc == NULL) { +	mach_port_destroy(mach_task_self(), sport); +	return ENOMEM; +    } + +    ipc->server = sport; +    ipc->name = strdup(service); +    if (ipc->name == NULL) { +	mach_release(ipc); +	return ENOMEM; +    } + +    *ctx = ipc; + +    return 0; +} + +static int +mach_ipc(void *ctx, +	 const heim_idata *request, heim_idata *response, +	 heim_icred *cred) +{ +    struct mach_ctx *ipc = ctx; +    heim_ipc_message_inband_t requestin; +    mach_msg_type_number_t requestin_length = 0; +    heim_ipc_message_outband_t requestout = NULL; +    mach_msg_type_number_t requestout_length = 0; +    heim_ipc_message_inband_t replyin; +    mach_msg_type_number_t replyin_length; +    heim_ipc_message_outband_t replyout; +    mach_msg_type_number_t replyout_length; +    int ret, errorcode, retries = 0; + +    memcpy(requestin, request->data, request->length); +    requestin_length = request->length; + +    while (retries < 2) { +	__block mach_port_t sport; + +	dispatch_sync(syncq, ^{ sport = ipc->server; }); + +	ret = mheim_ipc_call(sport, +			     requestin, requestin_length, +			     requestout, requestout_length, +			     &errorcode, +			     replyin, &replyin_length, +			     &replyout, &replyout_length); +	if (ret == MACH_SEND_INVALID_DEST) { +	    mach_port_t nport; +	    /* race other threads to get a new port */ +	    ret = bootstrap_look_up(bootstrap_port, ipc->name, &nport); +	    if (ret) +		return ret; +	    dispatch_sync(syncq, ^{ +		    /* check if we lost the race to lookup the port */ +		    if (sport != ipc->server) { +			mach_port_deallocate(mach_task_self(), nport); +		    } else { +			mach_port_deallocate(mach_task_self(), ipc->server); +			ipc->server = nport; +		    } +		}); +	    retries++; +	} else if (ret) { +	    return ret; +	} else +	    break; +    } +    if (retries >= 2) +	return EINVAL; + +    if (errorcode) { +	if (replyout_length) +	    vm_deallocate (mach_task_self (), (vm_address_t) replyout, +			   replyout_length); +	return errorcode; +    } + +    if (replyout_length) { +	response->data = malloc(replyout_length); +	if (response->data == NULL) { +	    vm_deallocate (mach_task_self (), (vm_address_t) replyout, +			   replyout_length); +	    return ENOMEM; +	} +	memcpy(response->data, replyout, replyout_length); +	response->length = replyout_length; +	vm_deallocate (mach_task_self (), (vm_address_t) replyout, +		       replyout_length); +    } else { +	response->data = malloc(replyin_length); +	if (response->data == NULL) +	    return ENOMEM; +	memcpy(response->data, replyin, replyin_length); +	response->length = replyin_length; +    } + +    return 0; +} + +struct async_client { +    mach_port_t mp; +    dispatch_source_t source; +    dispatch_queue_t queue; +    void (*func)(void *, int, heim_idata *, heim_icred); +    void *userctx; +}; + +kern_return_t +mheim_ado_acall_reply(mach_port_t server_port, +		      audit_token_t client_creds, +		      int returnvalue, +		      heim_ipc_message_inband_t replyin, +		      mach_msg_type_number_t replyinCnt, +		      heim_ipc_message_outband_t replyout, +		      mach_msg_type_number_t replyoutCnt) +{ +    struct async_client *c = dispatch_get_context(dispatch_get_current_queue()); +    heim_idata response; + +    if (returnvalue) { +	response.data = NULL; +	response.length = 0; +    } else if (replyoutCnt) { +	response.data = replyout; +	response.length = replyoutCnt; +    } else { +	response.data = replyin; +	response.length = replyinCnt; +    } + +    (*c->func)(c->userctx, returnvalue, &response, NULL); + +    if (replyoutCnt) +	vm_deallocate (mach_task_self (), (vm_address_t) replyout, replyoutCnt); + +    dispatch_source_cancel(c->source); + +    return 0; + + +} + + +static int +mach_async(void *ctx, const heim_idata *request, void *userctx, +	   void (*func)(void *, int, heim_idata *, heim_icred)) +{ +    struct mach_ctx *ipc = ctx; +    heim_ipc_message_inband_t requestin; +    mach_msg_type_number_t requestin_length = 0; +    heim_ipc_message_outband_t requestout = NULL; +    mach_msg_type_number_t requestout_length = 0; +    int ret, retries = 0; +    kern_return_t kr; +    struct async_client *c; + +    /* first create the service that will catch the reply from the server */ +    /* XXX these object should be cached and reused */ + +    c = malloc(sizeof(*c)); +    if (c == NULL) +	return ENOMEM; + +    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &c->mp); +    if (kr != KERN_SUCCESS) +	return EINVAL; + +    c->queue = dispatch_queue_create("heim-ipc-async-client", NULL); +    c->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, c->mp, 0, c->queue); +    dispatch_set_context(c->queue, c); + +    dispatch_source_set_event_handler(c->source, ^{ +	    dispatch_mig_server(c->source, +				sizeof(union __RequestUnion__mheim_ado_mheim_aipc_subsystem), +				mheim_aipc_server); +	}); + +    dispatch_source_set_cancel_handler(c->source, ^{ +	    mach_port_mod_refs(mach_task_self(), c->mp, +			       MACH_PORT_RIGHT_RECEIVE, -1); +	    dispatch_release(c->queue); +	    dispatch_release(c->source); +	    free(c); +	}); + +    c->func = func; +    c->userctx = userctx; + +    dispatch_resume(c->source); + +    /* ok, send the message */ + +    memcpy(requestin, request->data, request->length); +    requestin_length = request->length; + +    while (retries < 2) { +	__block mach_port_t sport; + +	dispatch_sync(syncq, ^{ sport = ipc->server; }); + +	ret = mheim_ipc_call_request(sport, c->mp, +				     requestin, requestin_length, +				     requestout, requestout_length); +	if (ret == MACH_SEND_INVALID_DEST) { +	    ret = bootstrap_look_up(bootstrap_port, ipc->name, &sport); +	    if (ret) { +		dispatch_source_cancel(c->source); +		return ret; +	    } +	    mach_port_deallocate(mach_task_self(), ipc->server); +	    ipc->server = sport; +	    retries++; +	} else if (ret) { +	    dispatch_source_cancel(c->source); +	    return ret; +	} else +	    break; +    } +    if (retries >= 2) { +	dispatch_source_cancel(c->source); +	return EINVAL; +    } + +    return 0; +} + +static int +mach_release(void *ctx) +{ +    struct mach_ctx *ipc = ctx; +    if (ipc->server != MACH_PORT_NULL) +	mach_port_deallocate(mach_task_self(), ipc->server); +    free(ipc->name); +    free(ipc); +    return 0; +} + +#endif + +struct path_ctx { +    char *path; +    int fd; +}; + +static int common_release(void *); + +static int +connect_unix(struct path_ctx *s) +{ +    struct sockaddr_un addr; + +    addr.sun_family = AF_UNIX; +    strlcpy(addr.sun_path, s->path, sizeof(addr.sun_path)); + +    s->fd = socket(AF_UNIX, SOCK_STREAM, 0); +    if (s->fd < 0) +	return errno; +    rk_cloexec(s->fd); + +    if (connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { +	close(s->fd); +	return errno; +    } + +    return 0; +} + +static int +common_path_init(const char *service, +		 const char *file, +		 void **ctx) +{ +    struct path_ctx *s; + +    s = malloc(sizeof(*s)); +    if (s == NULL) +	return ENOMEM; +    s->fd = -1; + +    asprintf(&s->path, "/var/run/.heim_%s-%s", service, file); + +    *ctx = s; + +    return 0; +} + +static int +unix_socket_init(const char *service, +		 void **ctx) +{ +    int ret; + +    ret = common_path_init(service, "socket", ctx); +    if (ret) +	return ret; +    ret = connect_unix(*ctx); +    if (ret) +	common_release(*ctx); + +    return ret; +} + +static int +unix_socket_ipc(void *ctx, +		const heim_idata *req, heim_idata *rep, +		heim_icred *cred) +{ +    struct path_ctx *s = ctx; +    uint32_t len = htonl(req->length); +    uint32_t rv; +    int retval; + +    if (cred) +	*cred = NULL; + +    rep->data = NULL; +    rep->length = 0; + +    if (net_write(s->fd, &len, sizeof(len)) != sizeof(len)) +	return -1; +    if (net_write(s->fd, req->data, req->length) != (ssize_t)req->length) +	return -1; + +    if (net_read(s->fd, &len, sizeof(len)) != sizeof(len)) +	return -1; +    if (net_read(s->fd, &rv, sizeof(rv)) != sizeof(rv)) +	return -1; +    retval = ntohl(rv); + +    rep->length = ntohl(len); +    if (rep->length > 0) { +	rep->data = malloc(rep->length); +	if (rep->data == NULL) +	    return -1; +	if (net_read(s->fd, rep->data, rep->length) != (ssize_t)rep->length) +	    return -1; +    } else +	rep->data = NULL; + +    return retval; +} + +int +common_release(void *ctx) +{ +    struct path_ctx *s = ctx; +    if (s->fd >= 0) +	close(s->fd); +    free(s->path); +    free(s); +    return 0; +} + +#ifdef HAVE_DOOR + +static int +door_init(const char *service, +	  void **ctx) +{ +    ret = common_path_init(context, service, "door", ctx); +    if (ret) +	return ret; +    ret = connect_door(*ctx); +    if (ret) +	common_release(*ctx); +    return ret; +} + +static int +door_ipc(void *ctx, +	 const heim_idata *request, heim_idata *response, +	 heim_icred *cred) +{ +    door_arg_t arg; +    int ret; + +    arg.data_ptr = request->data; +    arg.data_size = request->length; +    arg.desc_ptr = NULL; +    arg.desc_num = 0; +    arg.rbuf = NULL; +    arg.rsize = 0; + +    ret = door_call(fd, &arg); +    close(fd); +    if (ret != 0) +	return errno; + +    response->data = malloc(arg.rsize); +    if (response->data == NULL) { +	munmap(arg.rbuf, arg.rsize); +	return ENOMEM; +    } +    memcpy(response->data, arg.rbuf, arg.rsize); +    response->length = arg.rsize; +    munmap(arg.rbuf, arg.rsize); + +    return ret; +} + +#endif + +struct hipc_ops { +    const char *prefix; +    int (*init)(const char *, void **); +    int (*release)(void *); +    int (*ipc)(void *,const heim_idata *, heim_idata *, heim_icred *); +    int (*async)(void *, const heim_idata *, void *, +		 void (*)(void *, int, heim_idata *, heim_icred)); +}; + +struct hipc_ops ipcs[] = { +#if defined(__APPLE__) && defined(HAVE_GCD) +    { "MACH", mach_init, mach_release, mach_ipc, mach_async }, +#endif +#ifdef HAVE_DOOR +    { "DOOR", door_init, common_release, door_ipc, NULL } +#endif +    { "UNIX", unix_socket_init, common_release, unix_socket_ipc, NULL } +}; + +struct heim_ipc { +    struct hipc_ops *ops; +    void *ctx; +}; + + +int +heim_ipc_init_context(const char *name, heim_ipc *ctx) +{ +    unsigned int i; +    int ret, any = 0; + +    for(i = 0; i < sizeof(ipcs)/sizeof(ipcs[0]); i++) { +	size_t prefix_len = strlen(ipcs[i].prefix); +	heim_ipc c; +	if(strncmp(ipcs[i].prefix, name, prefix_len) == 0 +	   && name[prefix_len] == ':')  { +	} else if (strncmp("ANY:", name, 4) == 0) { +	    prefix_len = 3; +	    any = 1; +	} else +	    continue; + +	c = calloc(1, sizeof(*c)); +	if (c == NULL) +	    return ENOMEM; + +	c->ops = &ipcs[i]; + +	ret = (c->ops->init)(name + prefix_len + 1, &c->ctx); +	if (ret) { +	    free(c); +	    if (any) +		continue; +	    return ret; +	} + +	*ctx = c; +	return 0; +    } + +    return ENOENT; +} + +void +heim_ipc_free_context(heim_ipc ctx) +{ +    (ctx->ops->release)(ctx->ctx); +    free(ctx); +} + +int +heim_ipc_call(heim_ipc ctx, const heim_idata *snd, heim_idata *rcv, +	      heim_icred *cred) +{ +    if (cred) +	*cred = NULL; +    return (ctx->ops->ipc)(ctx->ctx, snd, rcv, cred); +} + +int +heim_ipc_async(heim_ipc ctx, const heim_idata *snd, void *userctx, +	       void (*func)(void *, int, heim_idata *, heim_icred)) +{ +    if (ctx->ops->async == NULL) { +	heim_idata rcv; +	heim_icred cred = NULL; +	int ret; + +	ret = (ctx->ops->ipc)(ctx->ctx, snd, &rcv, &cred); +	(*func)(userctx, ret, &rcv, cred); +	heim_ipc_free_cred(cred); +	free(rcv.data); +	return ret; +    } else { +	return (ctx->ops->async)(ctx->ctx, snd, userctx, func); +    } +} diff --git a/lib/ipc/common.c b/lib/ipc/common.c new file mode 100644 index 000000000000..0e8f36dd2090 --- /dev/null +++ b/lib/ipc/common.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hi_locl.h" +#ifdef HAVE_GCD +#include <dispatch/dispatch.h> +#else +#include "heim_threads.h" +#endif + +struct heim_icred { +    uid_t uid; +    gid_t gid; +    pid_t pid; +    pid_t session; +}; + +void +heim_ipc_free_cred(heim_icred cred) +{ +    free(cred); +} + +uid_t +heim_ipc_cred_get_uid(heim_icred cred) +{ +    return cred->uid; +} + +gid_t +heim_ipc_cred_get_gid(heim_icred cred) +{ +    return cred->gid; +} + +pid_t +heim_ipc_cred_get_pid(heim_icred cred) +{ +    return cred->pid; +} + +pid_t +heim_ipc_cred_get_session(heim_icred cred) +{ +    return cred->session; +} + + +int +_heim_ipc_create_cred(uid_t uid, gid_t gid, pid_t pid, pid_t session, heim_icred *cred) +{ +    *cred = calloc(1, sizeof(**cred)); +    if (*cred == NULL) +	return ENOMEM; +    (*cred)->uid = uid; +    (*cred)->gid = gid; +    (*cred)->pid = pid; +    (*cred)->session = session; +    return 0; +} + +#ifndef HAVE_GCD +struct heim_isemaphore { +    HEIMDAL_MUTEX mutex; +    pthread_cond_t cond; +    long counter; +}; +#endif + +heim_isemaphore +heim_ipc_semaphore_create(long value) +{ +#ifdef HAVE_GCD +    return (heim_isemaphore)dispatch_semaphore_create(value); +#elif !defined(ENABLE_PTHREAD_SUPPORT) +    heim_assert(0, "no semaphore support w/o pthreads"); +    return NULL; +#else +    heim_isemaphore s = malloc(sizeof(*s)); +    if (s == NULL) +	return NULL; +    HEIMDAL_MUTEX_init(&s->mutex); +    pthread_cond_init(&s->cond, NULL); +    s->counter = value; +    return s; +#endif +} + +long +heim_ipc_semaphore_wait(heim_isemaphore s, time_t t) +{ +#ifdef HAVE_GCD +    uint64_t timeout; +    if (t == HEIM_IPC_WAIT_FOREVER) +	timeout = DISPATCH_TIME_FOREVER; +    else +	timeout = (uint64_t)t * NSEC_PER_SEC; + +    return dispatch_semaphore_wait((dispatch_semaphore_t)s, timeout); +#elif !defined(ENABLE_PTHREAD_SUPPORT) +    heim_assert(0, "no semaphore support w/o pthreads"); +    return 0; +#else +    HEIMDAL_MUTEX_lock(&s->mutex); +    /* if counter hits below zero, we get to wait */ +    if (--s->counter < 0) { +	int ret; + +	if (t == HEIM_IPC_WAIT_FOREVER) +	    ret = pthread_cond_wait(&s->cond, &s->mutex); +	else { +	    struct timespec ts; +	    ts.tv_sec = t; +	    ts.tv_nsec = 0; +	    ret = pthread_cond_timedwait(&s->cond, &s->mutex, &ts); +	} +	if (ret) { +	    HEIMDAL_MUTEX_unlock(&s->mutex); +	    return errno; +	} +    } +    HEIMDAL_MUTEX_unlock(&s->mutex); + +    return 0; +#endif +} + +long +heim_ipc_semaphore_signal(heim_isemaphore s) +{ +#ifdef HAVE_GCD +    return dispatch_semaphore_signal((dispatch_semaphore_t)s); +#elif !defined(ENABLE_PTHREAD_SUPPORT) +    heim_assert(0, "no semaphore support w/o pthreads"); +    return EINVAL; +#else +    int wakeup; +    HEIMDAL_MUTEX_lock(&s->mutex); +    wakeup = (++s->counter == 0) ; +    HEIMDAL_MUTEX_unlock(&s->mutex); +    if (wakeup) +	pthread_cond_signal(&s->cond); +    return 0; +#endif +} + +void +heim_ipc_semaphore_release(heim_isemaphore s) +{ +#ifdef HAVE_GCD +    dispatch_release((dispatch_semaphore_t)s); +#elif !defined(ENABLE_PTHREAD_SUPPORT) +    heim_assert(0, "no semaphore support w/o pthreads"); +#else +    HEIMDAL_MUTEX_lock(&s->mutex); +    if (s->counter != 0) +	abort(); +    HEIMDAL_MUTEX_unlock(&s->mutex); +    HEIMDAL_MUTEX_destroy(&s->mutex); +    pthread_cond_destroy(&s->cond); +    free(s); +#endif +} + +void +heim_ipc_free_data(heim_idata *data) +{ +    if (data->data) +	free(data->data); +    data->data = NULL; +    data->length = 0; +} diff --git a/lib/ipc/heim-ipc.h b/lib/ipc/heim-ipc.h new file mode 100644 index 000000000000..6fbf309f7cd4 --- /dev/null +++ b/lib/ipc/heim-ipc.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <asn1-common.h> + +typedef struct heim_ipc *heim_ipc; +typedef struct heim_sipc *heim_sipc; +typedef struct heim_icred *heim_icred; +typedef struct heim_isemaphore *heim_isemaphore; +typedef struct heim_octet_string heim_idata; +typedef struct heim_sipc_call *heim_sipc_call; + +/* common */ + +void +heim_ipc_free_cred(heim_icred); + +uid_t +heim_ipc_cred_get_uid(heim_icred); + +gid_t +heim_ipc_cred_get_gid(heim_icred); + +pid_t +heim_ipc_cred_get_pid(heim_icred); + +pid_t +heim_ipc_cred_get_session(heim_icred); + +void +heim_ipc_main(void); + +heim_isemaphore +heim_ipc_semaphore_create(long); + +long +heim_ipc_semaphore_wait(heim_isemaphore, time_t); + +long +heim_ipc_semaphore_signal(heim_isemaphore); + +void +heim_ipc_semaphore_release(heim_isemaphore); + +#define HEIM_IPC_WAIT_FOREVER ((time_t)-1) + +void +heim_ipc_free_data(heim_idata *); + +/* client */ + +int +heim_ipc_init_context(const char *, heim_ipc *); + +void +heim_ipc_free_context(heim_ipc); + +int +heim_ipc_call(heim_ipc, const heim_idata *, heim_idata *, heim_icred *); + +int +heim_ipc_async(heim_ipc, const heim_idata *, void *, void (*func)(void *, int, heim_idata *, heim_icred)); + +/* server */ + +#define HEIM_SIPC_TYPE_IPC		1 +#define HEIM_SIPC_TYPE_UINT32		2 +#define HEIM_SIPC_TYPE_HTTP		4 + +typedef void +(*heim_ipc_complete)(heim_sipc_call, int, heim_idata *); + +typedef void +(*heim_ipc_callback)(void *, const heim_idata *, +		     const heim_icred, heim_ipc_complete, heim_sipc_call); + + +int +heim_sipc_launchd_mach_init(const char *, heim_ipc_callback, +			    void *, heim_sipc *); + +int +heim_sipc_stream_listener(int, int, heim_ipc_callback, +			  void *, heim_sipc *); + +int +heim_sipc_service_unix(const char *, heim_ipc_callback, +		       void *, heim_sipc *); + + +void +heim_sipc_timeout(time_t); + +void +heim_sipc_set_timeout_handler(void (*)(void)); + +void +heim_sipc_free_context(heim_sipc); diff --git a/lib/ipc/heim_ipc.defs b/lib/ipc/heim_ipc.defs new file mode 100644 index 000000000000..ae84791375d3 --- /dev/null +++ b/lib/ipc/heim_ipc.defs @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +type heim_ipc_message_inband_t = array [ * : 2048 ] of char; +type heim_ipc_message_outband_t = array [] of char; + +import "heim_ipc_types.h"; + +subsystem mheim_ipc 1; +userprefix mheim_ipc_; +serverprefix mheim_do_; + +routine call( +				server_port	: mach_port_t; +		ServerAuditToken client_creds	: audit_token_t; +		sreplyport	reply_port	: mach_port_make_send_once_t; +		in		requestin	: heim_ipc_message_inband_t; +		in		requestout	: heim_ipc_message_outband_t; +		out		returnvalue	: int; +		out		replyin		: heim_ipc_message_inband_t; +		out		replyout	: heim_ipc_message_outband_t, dealloc); + +simpleroutine call_request( +				server_port	: mach_port_t; +		ServerAuditToken client_creds	: audit_token_t; +		in		reply_to	: mach_port_make_send_once_t; +		in		requestin	: heim_ipc_message_inband_t; +		in		requestout	: heim_ipc_message_outband_t); + + + diff --git a/lib/ipc/heim_ipc_async.defs b/lib/ipc/heim_ipc_async.defs new file mode 100644 index 000000000000..73157c0d1ae5 --- /dev/null +++ b/lib/ipc/heim_ipc_async.defs @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +type heim_ipc_message_inband_t = array [ * : 2048 ] of char; +type heim_ipc_message_outband_t = array [] of char; + +import "heim_ipc_types.h"; + +subsystem mheim_aipc 201; +userprefix mheim_aipc_; +serverprefix mheim_ado_; + +simpleroutine acall_reply( +				server_port	: mach_port_move_send_once_t; +		ServerAuditToken client_creds	: audit_token_t; +		in		returnvalue	: int; +		in		requestin	: heim_ipc_message_inband_t; +		in		requestout	: heim_ipc_message_outband_t); + + + diff --git a/lib/ipc/heim_ipc_reply.defs b/lib/ipc/heim_ipc_reply.defs new file mode 100644 index 000000000000..8209485562f0 --- /dev/null +++ b/lib/ipc/heim_ipc_reply.defs @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +type heim_ipc_message_inband_t = array [ * : 2048 ] of char; +type heim_ipc_message_outband_t = array [] of char; + +import "heim_ipc_types.h"; + +subsystem heim_ipc 101; +userprefix mheim_ripc_; + +simpleroutine call_reply( +				reply_port	: mach_port_move_send_once_t; +				returnvalue	: int; +				replyin		: heim_ipc_message_inband_t; +				replyout	: heim_ipc_message_outband_t, dealloc); diff --git a/lib/ipc/heim_ipc_types.h b/lib/ipc/heim_ipc_types.h new file mode 100644 index 000000000000..c853610f1a49 --- /dev/null +++ b/lib/ipc/heim_ipc_types.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _HEIM_IPC_TYPES_H_ +#define _HEIM_IPC_TYPES_H_ + +#define HEIM_KCM_BOOTSTRAP_NAME "org.h5l.Kerberos.kcm" + +typedef char  heim_ipc_message_inband_t[2048]; +typedef char *heim_ipc_message_outband_t; + +#endif diff --git a/lib/ipc/hi_locl.h b/lib/ipc/hi_locl.h new file mode 100644 index 000000000000..7efe6ca841ee --- /dev/null +++ b/lib/ipc/hi_locl.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include <sys/types.h> +#include <sys/socket.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif + +#include <sys/poll.h> + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifdef HAVE_GETPEERUCRED +#include <ucred.h> +#endif + +#include <krb5-types.h> +#include <asn1-common.h> + +#include <heimbase.h> +#include <base64.h> + +#include <heim-ipc.h> + +#if defined(__APPLE__) && defined(HAVE_GCD) +#include <mach/mach.h> +#include <servers/bootstrap.h> +#include <dispatch/dispatch.h> +#include <bsm/libbsm.h> + +#ifndef __APPLE_PRIVATE__ /* awe, using private interface */ +typedef boolean_t (*dispatch_mig_callback_t)(mach_msg_header_t *message, mach_msg_header_t *reply); + +mach_msg_return_t +dispatch_mig_server(dispatch_source_t ds, size_t maxmsgsz, dispatch_mig_callback_t callback); +#endif + +#endif + + +#include <roken.h> + +int +_heim_ipc_create_cred(uid_t, gid_t, pid_t, pid_t, heim_icred *); diff --git a/lib/ipc/server.c b/lib/ipc/server.c new file mode 100644 index 000000000000..245f2e3c5d82 --- /dev/null +++ b/lib/ipc/server.c @@ -0,0 +1,1187 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hi_locl.h" +#include <assert.h> + +#define MAX_PACKET_SIZE (128 * 1024) + +struct heim_sipc { +    int (*release)(heim_sipc ctx); +    heim_ipc_callback callback; +    void *userctx; +    void *mech; +}; + +#if defined(__APPLE__) && defined(HAVE_GCD) + +#include "heim_ipcServer.h" +#include "heim_ipc_reply.h" +#include "heim_ipc_async.h" + +static dispatch_source_t timer; +static dispatch_queue_t timerq; +static uint64_t timeoutvalue; + +static dispatch_queue_t eventq; + +static dispatch_queue_t workq; + +static void +default_timer_ev(void) +{ +    exit(0); +} + +static void (*timer_ev)(void) = default_timer_ev; + +static void +set_timer(void) +{ +    dispatch_source_set_timer(timer, +			      dispatch_time(DISPATCH_TIME_NOW, +					    timeoutvalue * NSEC_PER_SEC), +			      timeoutvalue * NSEC_PER_SEC, 1000000); +} + +static void +init_globals(void) +{ +    static dispatch_once_t once; +    dispatch_once(&once, ^{ +	timerq = dispatch_queue_create("hiem-sipc-timer-q", NULL); +        timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, timerq); +	dispatch_source_set_event_handler(timer, ^{ timer_ev(); } ); + +	workq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); +	eventq = dispatch_queue_create("heim-ipc.event-queue", NULL); +    }); +} + +static void +suspend_timer(void) +{ +    dispatch_suspend(timer); +} + +static void +restart_timer(void) +{ +    dispatch_sync(timerq, ^{ set_timer(); }); +    dispatch_resume(timer); +} + +struct mach_service { +    mach_port_t sport; +    dispatch_source_t source; +    dispatch_queue_t queue; +}; + +struct mach_call_ctx { +    mach_port_t reply_port; +    heim_icred cred; +    heim_idata req; +}; + + +static void +mach_complete_sync(heim_sipc_call ctx, int returnvalue, heim_idata *reply) +{ +    struct mach_call_ctx *s = (struct mach_call_ctx *)ctx; +    heim_ipc_message_inband_t replyin; +    mach_msg_type_number_t replyinCnt; +    heim_ipc_message_outband_t replyout; +    mach_msg_type_number_t replyoutCnt; +    kern_return_t kr; + +    if (returnvalue) { +	/* on error, no reply */ +	replyinCnt = 0; +	replyout = 0; replyoutCnt = 0; +	kr = KERN_SUCCESS; +    } else if (reply->length < 2048) { +	replyinCnt = reply->length; +	memcpy(replyin, reply->data, replyinCnt); +	replyout = 0; replyoutCnt = 0; +	kr = KERN_SUCCESS; +    } else { +	replyinCnt = 0; +	kr = vm_read(mach_task_self(), +		     (vm_address_t)reply->data, reply->length, +		     (vm_address_t *)&replyout, &replyoutCnt); +    } + +    mheim_ripc_call_reply(s->reply_port, returnvalue, +			  replyin, replyinCnt, +			  replyout, replyoutCnt); + +    heim_ipc_free_cred(s->cred); +    free(s->req.data); +    free(s); +    restart_timer(); +} + +static void +mach_complete_async(heim_sipc_call ctx, int returnvalue, heim_idata *reply) +{ +    struct mach_call_ctx *s = (struct mach_call_ctx *)ctx; +    heim_ipc_message_inband_t replyin; +    mach_msg_type_number_t replyinCnt; +    heim_ipc_message_outband_t replyout; +    mach_msg_type_number_t replyoutCnt; +    kern_return_t kr; + +    if (returnvalue) { +	/* on error, no reply */ +	replyinCnt = 0; +	replyout = 0; replyoutCnt = 0; +	kr = KERN_SUCCESS; +    } else if (reply->length < 2048) { +	replyinCnt = reply->length; +	memcpy(replyin, reply->data, replyinCnt); +	replyout = 0; replyoutCnt = 0; +	kr = KERN_SUCCESS; +    } else { +	replyinCnt = 0; +	kr = vm_read(mach_task_self(), +		     (vm_address_t)reply->data, reply->length, +		     (vm_address_t *)&replyout, &replyoutCnt); +    } + +    kr = mheim_aipc_acall_reply(s->reply_port, returnvalue, +				replyin, replyinCnt, +				replyout, replyoutCnt); +    heim_ipc_free_cred(s->cred); +    free(s->req.data); +    free(s); +    restart_timer(); +} + + +kern_return_t +mheim_do_call(mach_port_t server_port, +	      audit_token_t client_creds, +	      mach_port_t reply_port, +	      heim_ipc_message_inband_t requestin, +	      mach_msg_type_number_t requestinCnt, +	      heim_ipc_message_outband_t requestout, +	      mach_msg_type_number_t requestoutCnt, +	      int *returnvalue, +	      heim_ipc_message_inband_t replyin, +	      mach_msg_type_number_t *replyinCnt, +	      heim_ipc_message_outband_t *replyout, +	      mach_msg_type_number_t *replyoutCnt) +{ +    heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); +    struct mach_call_ctx *s; +    kern_return_t kr; +    uid_t uid; +    gid_t gid; +    pid_t pid; +    au_asid_t session; + +    *replyout = NULL; +    *replyoutCnt = 0; +    *replyinCnt = 0; + +    s = malloc(sizeof(*s)); +    if (s == NULL) +	return KERN_MEMORY_FAILURE; /* XXX */ + +    s->reply_port = reply_port; + +    audit_token_to_au32(client_creds, NULL, &uid, &gid, NULL, NULL, &pid, &session, NULL); + +    kr = _heim_ipc_create_cred(uid, gid, pid, session, &s->cred); +    if (kr) { +	free(s); +	return kr; +    } + +    suspend_timer(); + +    if (requestinCnt) { +	s->req.data = malloc(requestinCnt); +	memcpy(s->req.data, requestin, requestinCnt); +	s->req.length = requestinCnt; +    } else { +	s->req.data = malloc(requestoutCnt); +	memcpy(s->req.data, requestout, requestoutCnt); +	s->req.length = requestoutCnt; +    } + +    dispatch_async(workq, ^{ +	(ctx->callback)(ctx->userctx, &s->req, s->cred, +			mach_complete_sync, (heim_sipc_call)s); +    }); + +    return MIG_NO_REPLY; +} + +kern_return_t +mheim_do_call_request(mach_port_t server_port, +		      audit_token_t client_creds, +		      mach_port_t reply_port, +		      heim_ipc_message_inband_t requestin, +		      mach_msg_type_number_t requestinCnt, +		      heim_ipc_message_outband_t requestout, +		      mach_msg_type_number_t requestoutCnt) +{ +    heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); +    struct mach_call_ctx *s; +    kern_return_t kr; +    uid_t uid; +    gid_t gid; +    pid_t pid; +    au_asid_t session; + +    s = malloc(sizeof(*s)); +    if (s == NULL) +	return KERN_MEMORY_FAILURE; /* XXX */ + +    s->reply_port = reply_port; + +    audit_token_to_au32(client_creds, NULL, &uid, &gid, NULL, NULL, &pid, &session, NULL); + +    kr = _heim_ipc_create_cred(uid, gid, pid, session, &s->cred); +    if (kr) { +	free(s); +	return kr; +    } + +    suspend_timer(); + +    if (requestinCnt) { +	s->req.data = malloc(requestinCnt); +	memcpy(s->req.data, requestin, requestinCnt); +	s->req.length = requestinCnt; +    } else { +	s->req.data = malloc(requestoutCnt); +	memcpy(s->req.data, requestout, requestoutCnt); +	s->req.length = requestoutCnt; +    } + +    dispatch_async(workq, ^{ +	(ctx->callback)(ctx->userctx, &s->req, s->cred, +			mach_complete_async, (heim_sipc_call)s); +    }); + +    return KERN_SUCCESS; +} + +static int +mach_init(const char *service, mach_port_t sport, heim_sipc ctx) +{ +    struct mach_service *s; +    char *name; + +    init_globals(); + +    s = calloc(1, sizeof(*s)); +    if (s == NULL) +	return ENOMEM; + +    asprintf(&name, "heim-ipc-mach-%s", service); + +    s->queue = dispatch_queue_create(name, NULL); +    free(name); +    s->sport = sport; + +    s->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, +				       s->sport, 0, s->queue); +    if (s->source == NULL) { +	dispatch_release(s->queue); +	free(s); +	return ENOMEM; +    } +    ctx->mech = s; + +    dispatch_set_context(s->queue, ctx); +    dispatch_set_context(s->source, s); + +    dispatch_source_set_event_handler(s->source, ^{ +	    dispatch_mig_server(s->source, sizeof(union __RequestUnion__mheim_do_mheim_ipc_subsystem), mheim_ipc_server); +	}); + +    dispatch_source_set_cancel_handler(s->source, ^{ +	    heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); +	    struct mach_service *st = ctx->mech; +	    mach_port_mod_refs(mach_task_self(), st->sport, +			       MACH_PORT_RIGHT_RECEIVE, -1); +	    dispatch_release(st->queue); +	    dispatch_release(st->source); +	    free(st); +	    free(ctx); +	}); + +    dispatch_resume(s->source); + +    return 0; +} + +static int +mach_release(heim_sipc ctx) +{ +    struct mach_service *s = ctx->mech; +    dispatch_source_cancel(s->source); +    dispatch_release(s->source); +    return 0; +} + +static mach_port_t +mach_checkin_or_register(const char *service) +{ +    mach_port_t mp; +    kern_return_t kr; + +    kr = bootstrap_check_in(bootstrap_port, service, &mp); +    if (kr == KERN_SUCCESS) +	return mp; + +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 +    /* Pre SnowLeopard version */ +    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); +    if (kr != KERN_SUCCESS) +	return MACH_PORT_NULL; + +    kr = mach_port_insert_right(mach_task_self(), mp, mp, +				MACH_MSG_TYPE_MAKE_SEND); +    if (kr != KERN_SUCCESS) { +	mach_port_destroy(mach_task_self(), mp); +	return MACH_PORT_NULL; +    } + +    kr = bootstrap_register(bootstrap_port, rk_UNCONST(service), mp); +    if (kr != KERN_SUCCESS) { +	mach_port_destroy(mach_task_self(), mp); +	return MACH_PORT_NULL; +    } + +    return mp; +#else +    return MACH_PORT_NULL; +#endif +} + + +#endif /* __APPLE__ && HAVE_GCD */ + + +int +heim_sipc_launchd_mach_init(const char *service, +			    heim_ipc_callback callback, +			    void *user, heim_sipc *ctx) +{ +#if defined(__APPLE__) && defined(HAVE_GCD) +    mach_port_t sport = MACH_PORT_NULL; +    heim_sipc c = NULL; +    int ret; + +    *ctx = NULL; + +    sport = mach_checkin_or_register(service); +    if (sport == MACH_PORT_NULL) { +	ret = ENOENT; +	goto error; +    } + +    c = calloc(1, sizeof(*c)); +    if (c == NULL) { +	ret = ENOMEM; +	goto error; +    } +    c->release = mach_release; +    c->userctx = user; +    c->callback = callback; + +    ret = mach_init(service, sport, c); +    if (ret) +	goto error; + +    *ctx = c; +    return 0; + error: +    if (c) +	free(c); +    if (sport != MACH_PORT_NULL) +	mach_port_mod_refs(mach_task_self(), sport, +			   MACH_PORT_RIGHT_RECEIVE, -1); +    return ret; +#else /* !(__APPLE__ && HAVE_GCD) */ +    *ctx = NULL; +    return EINVAL; +#endif /* __APPLE__ && HAVE_GCD */ +} + +struct client { +    int fd; +    heim_ipc_callback callback; +    void *userctx; +    int flags; +#define LISTEN_SOCKET	1 +#define WAITING_READ	2 +#define WAITING_WRITE	4 +#define WAITING_CLOSE	8 + +#define HTTP_REPLY	16 + +#define INHERIT_MASK	0xffff0000 +#define INCLUDE_ERROR_CODE (1 << 16) +#define ALLOW_HTTP	(1<<17) +#define UNIX_SOCKET	(1<<18) +    unsigned calls; +    size_t ptr, len; +    uint8_t *inmsg; +    size_t olen; +    uint8_t *outmsg; +#ifdef HAVE_GCD +    dispatch_source_t in; +    dispatch_source_t out; +#endif +    struct { +	uid_t uid; +	gid_t gid; +	pid_t pid; +    } unixrights; +}; + +#ifndef HAVE_GCD +static unsigned num_clients = 0; +static struct client **clients = NULL; +#endif + +static void handle_read(struct client *); +static void handle_write(struct client *); +static int maybe_close(struct client *); + +/* + * Update peer credentials from socket. + * + * SCM_CREDS can only be updated the first time there is read data to + * read from the filedescriptor, so if we read do it before this + * point, the cred data might not be is not there yet. + */ + +static int +update_client_creds(struct client *c) +{ +#ifdef HAVE_GETPEERUCRED +    /* Solaris 10 */ +    { +	ucred_t *peercred; + +	if (getpeerucred(c->fd, &peercred) != 0) { +	    c->unixrights.uid = ucred_geteuid(peercred); +	    c->unixrights.gid = ucred_getegid(peercred); +	    c->unixrights.pid = 0; +	    ucred_free(peercred); +	    return 1; +	} +    } +#endif +#ifdef HAVE_GETPEEREID +    /* FreeBSD, OpenBSD */ +    { +	uid_t uid; +	gid_t gid; + +	if (getpeereid(c->fd, &uid, &gid) == 0) { +	    c->unixrights.uid = uid; +	    c->unixrights.gid = gid; +	    c->unixrights.pid = 0; +	    return 1; +	} +    } +#endif +#ifdef SO_PEERCRED +    /* Linux */ +    { +	struct ucred pc; +	socklen_t pclen = sizeof(pc); + +	if (getsockopt(c->fd, SOL_SOCKET, SO_PEERCRED, (void *)&pc, &pclen) == 0) { +	    c->unixrights.uid = pc.uid; +	    c->unixrights.gid = pc.gid; +	    c->unixrights.pid = pc.pid; +	    return 1; +	} +    } +#endif +#if defined(LOCAL_PEERCRED) && defined(XUCRED_VERSION) +    { +	struct xucred peercred; +	socklen_t peercredlen = sizeof(peercred); + +	if (getsockopt(c->fd, LOCAL_PEERCRED, 1, +		       (void *)&peercred, &peercredlen) == 0 +	    && peercred.cr_version == XUCRED_VERSION) +	{ +	    c->unixrights.uid = peercred.cr_uid; +	    c->unixrights.gid = peercred.cr_gid; +	    c->unixrights.pid = 0; +	    return 1; +	} +    } +#endif +#if defined(SOCKCREDSIZE) && defined(SCM_CREDS) +    /* NetBSD */ +    if (c->unixrights.uid == (uid_t)-1) { +	struct msghdr msg; +	socklen_t crmsgsize; +	void *crmsg; +	struct cmsghdr *cmp; +	struct sockcred *sc; + +	memset(&msg, 0, sizeof(msg)); +	crmsgsize = CMSG_SPACE(SOCKCREDSIZE(NGROUPS)); +	if (crmsgsize == 0) +	    return 1 ; + +	crmsg = malloc(crmsgsize); +	if (crmsg == NULL) +	    goto failed_scm_creds; + +	memset(crmsg, 0, crmsgsize); + +	msg.msg_control = crmsg; +	msg.msg_controllen = crmsgsize; + +	if (recvmsg(c->fd, &msg, 0) < 0) { +	    free(crmsg); +	    goto failed_scm_creds; +	} + +	if (msg.msg_controllen == 0 || (msg.msg_flags & MSG_CTRUNC) != 0) { +	    free(crmsg); +	    goto failed_scm_creds; +	} + +	cmp = CMSG_FIRSTHDR(&msg); +	if (cmp->cmsg_level != SOL_SOCKET || cmp->cmsg_type != SCM_CREDS) { +	    free(crmsg); +	    goto failed_scm_creds; +	} + +	sc = (struct sockcred *)(void *)CMSG_DATA(cmp); + +	c->unixrights.uid = sc->sc_euid; +	c->unixrights.gid = sc->sc_egid; +	c->unixrights.pid = 0; + +	free(crmsg); +	return 1; +    } else { +	/* we already got the cred, just return it */ +	return 1; +    } + failed_scm_creds: +#endif +    return 0; +} + + +static struct client * +add_new_socket(int fd, +	       int flags, +	       heim_ipc_callback callback, +	       void *userctx) +{ +    struct client *c; +    int fileflags; + +    c = calloc(1, sizeof(*c)); +    if (c == NULL) +	return NULL; + +    if (flags & LISTEN_SOCKET) { +	c->fd = fd; +    } else { +	c->fd = accept(fd, NULL, NULL); +	if(c->fd < 0) { +	    free(c); +	    return NULL; +	} +    } + +    c->flags = flags; +    c->callback = callback; +    c->userctx = userctx; + +    fileflags = fcntl(c->fd, F_GETFL, 0); +    fcntl(c->fd, F_SETFL, fileflags | O_NONBLOCK); + +#ifdef HAVE_GCD +    init_globals(); + +    c->in = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, +				   c->fd, 0, eventq); +    c->out = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, +				    c->fd, 0, eventq); + +    dispatch_source_set_event_handler(c->in, ^{ +	    int rw = (c->flags & WAITING_WRITE); +	    handle_read(c); +	    if (rw == 0 && (c->flags & WAITING_WRITE)) +		dispatch_resume(c->out); +	    if ((c->flags & WAITING_READ) == 0) +		dispatch_suspend(c->in); +	    maybe_close(c); +	}); +    dispatch_source_set_event_handler(c->out, ^{ +	    handle_write(c); +	    if ((c->flags & WAITING_WRITE) == 0) { +		dispatch_suspend(c->out); +	    } +	    maybe_close(c); +	}); + +    dispatch_resume(c->in); +#else +    clients = erealloc(clients, sizeof(clients[0]) * (num_clients + 1)); +    clients[num_clients] = c; +    num_clients++; +#endif + +    return c; +} + +static int +maybe_close(struct client *c) +{ +    if (c->calls != 0) +	return 0; +    if (c->flags & (WAITING_READ|WAITING_WRITE)) +	return 0; + +#ifdef HAVE_GCD +    dispatch_source_cancel(c->in); +    if ((c->flags & WAITING_READ) == 0) +	dispatch_resume(c->in); +    dispatch_release(c->in); + +    dispatch_source_cancel(c->out); +    if ((c->flags & WAITING_WRITE) == 0) +	dispatch_resume(c->out); +    dispatch_release(c->out); +#endif +    close(c->fd); /* ref count fd close */ +    free(c); +    return 1; +} + + +struct socket_call { +    heim_idata in; +    struct client *c; +    heim_icred cred; +}; + +static void +output_data(struct client *c, const void *data, size_t len) +{ +    if (c->olen + len < c->olen) +	abort(); +    c->outmsg = erealloc(c->outmsg, c->olen + len); +    memcpy(&c->outmsg[c->olen], data, len); +    c->olen += len; +    c->flags |= WAITING_WRITE; +} + +static void +socket_complete(heim_sipc_call ctx, int returnvalue, heim_idata *reply) +{ +    struct socket_call *sc = (struct socket_call *)ctx; +    struct client *c = sc->c; + +    /* double complete ? */ +    if (c == NULL) +	abort(); + +    if ((c->flags & WAITING_CLOSE) == 0) { +	uint32_t u32; + +	/* length */ +	u32 = htonl(reply->length); +	output_data(c, &u32, sizeof(u32)); + +	/* return value */ +	if (c->flags & INCLUDE_ERROR_CODE) { +	    u32 = htonl(returnvalue); +	    output_data(c, &u32, sizeof(u32)); +	} + +	/* data */ +	output_data(c, reply->data, reply->length); + +	/* if HTTP, close connection */ +	if (c->flags & HTTP_REPLY) { +	    c->flags |= WAITING_CLOSE; +	    c->flags &= ~WAITING_READ; +	} +    } + +    c->calls--; +    if (sc->cred) +	heim_ipc_free_cred(sc->cred); +    free(sc->in.data); +    sc->c = NULL; /* so we can catch double complete */ +    free(sc); + +    maybe_close(c); +} + +/* remove HTTP %-quoting from buf */ +static int +de_http(char *buf) +{ +    unsigned char *p, *q; +    for(p = q = (unsigned char *)buf; *p; p++, q++) { +	if(*p == '%' && isxdigit(p[1]) && isxdigit(p[2])) { +	    unsigned int x; +	    if(sscanf((char *)p + 1, "%2x", &x) != 1) +		return -1; +	    *q = x; +	    p += 2; +	} else +	    *q = *p; +    } +    *q = '\0'; +    return 0; +} + +static struct socket_call * +handle_http_tcp(struct client *c) +{ +    struct socket_call *cs; +    char *s, *p, *t; +    void *data; +    char *proto; +    int len; + +    s = (char *)c->inmsg; + +    p = strstr(s, "\r\n"); +    if (p == NULL) +	return NULL; + +    *p = 0; + +    p = NULL; +    t = strtok_r(s, " \t", &p); +    if (t == NULL) +	return NULL; + +    t = strtok_r(NULL, " \t", &p); +    if (t == NULL) +	return NULL; + +    data = malloc(strlen(t)); +    if (data == NULL) +	return NULL; + +    if(*t == '/') +	t++; +    if(de_http(t) != 0) { +	free(data); +	return NULL; +    } +    proto = strtok_r(NULL, " \t", &p); +    if (proto == NULL) { +	free(data); +	return NULL; +    } +    len = base64_decode(t, data); +    if(len <= 0){ +	const char *msg = +	    " 404 Not found\r\n" +	    "Server: Heimdal/" VERSION "\r\n" +	    "Cache-Control: no-cache\r\n" +	    "Pragma: no-cache\r\n" +	    "Content-type: text/html\r\n" +	    "Content-transfer-encoding: 8bit\r\n\r\n" +	    "<TITLE>404 Not found</TITLE>\r\n" +	    "<H1>404 Not found</H1>\r\n" +	    "That page doesn't exist, maybe you are looking for " +	    "<A HREF=\"http://www.h5l.org/\">Heimdal</A>?\r\n"; +	free(data); +	output_data(c, proto, strlen(proto)); +	output_data(c, msg, strlen(msg)); +	return NULL; +    } + +    cs = emalloc(sizeof(*cs)); +    cs->c = c; +    cs->in.data = data; +    cs->in.length = len; +    c->ptr = 0; + +    { +	const char *msg = +	    " 200 OK\r\n" +	    "Server: Heimdal/" VERSION "\r\n" +	    "Cache-Control: no-cache\r\n" +	    "Pragma: no-cache\r\n" +	    "Content-type: application/octet-stream\r\n" +	    "Content-transfer-encoding: binary\r\n\r\n"; +	output_data(c, proto, strlen(proto)); +	output_data(c, msg, strlen(msg)); +    } + +    return cs; +} + + +static void +handle_read(struct client *c) +{ +    ssize_t len; +    uint32_t dlen; + +    if (c->flags & LISTEN_SOCKET) { +	add_new_socket(c->fd, +		       WAITING_READ | (c->flags & INHERIT_MASK), +		       c->callback, +		       c->userctx); +	return; +    } + +    if (c->ptr - c->len < 1024) { +	c->inmsg = erealloc(c->inmsg, +			    c->len + 1024); +	c->len += 1024; +    } + +    len = read(c->fd, c->inmsg + c->ptr, c->len - c->ptr); +    if (len <= 0) { +	c->flags |= WAITING_CLOSE; +	c->flags &= ~WAITING_READ; +	return; +    } +    c->ptr += len; +    if (c->ptr > c->len) +	abort(); + +    while (c->ptr >= sizeof(dlen)) { +	struct socket_call *cs; + +	if((c->flags & ALLOW_HTTP) && c->ptr >= 4 && +	   strncmp((char *)c->inmsg, "GET ", 4) == 0 && +	   strncmp((char *)c->inmsg + c->ptr - 4, "\r\n\r\n", 4) == 0) { + +	    /* remove the trailing \r\n\r\n so the string is NUL terminated */ +	    c->inmsg[c->ptr - 4] = '\0'; + +	    c->flags |= HTTP_REPLY; + +	    cs = handle_http_tcp(c); +	    if (cs == NULL) { +		c->flags |= WAITING_CLOSE; +		c->flags &= ~WAITING_READ; +		break; +	    } +	} else { +	    memcpy(&dlen, c->inmsg, sizeof(dlen)); +	    dlen = ntohl(dlen); + +	    if (dlen > MAX_PACKET_SIZE) { +		c->flags |= WAITING_CLOSE; +		c->flags &= ~WAITING_READ; +		return; +	    } +	    if (dlen > c->ptr - sizeof(dlen)) { +		break; +	    } + +	    cs = emalloc(sizeof(*cs)); +	    cs->c = c; +	    cs->in.data = emalloc(dlen); +	    memcpy(cs->in.data, c->inmsg + sizeof(dlen), dlen); +	    cs->in.length = dlen; + +	    c->ptr -= sizeof(dlen) + dlen; +	    memmove(c->inmsg, +		    c->inmsg + sizeof(dlen) + dlen, +		    c->ptr); +	} + +	c->calls++; + +	if ((c->flags & UNIX_SOCKET) != 0) { +	    if (update_client_creds(c)) +		_heim_ipc_create_cred(c->unixrights.uid, c->unixrights.gid, +				      c->unixrights.pid, -1, &cs->cred); +	} + +	c->callback(c->userctx, &cs->in, +		    cs->cred, socket_complete, +		    (heim_sipc_call)cs); +    } +} + +static void +handle_write(struct client *c) +{ +    ssize_t len; + +    len = write(c->fd, c->outmsg, c->olen); +    if (len <= 0) { +	c->flags |= WAITING_CLOSE; +	c->flags &= ~(WAITING_WRITE); +    } else if (c->olen != (size_t)len) { +	memmove(&c->outmsg[0], &c->outmsg[len], c->olen - len); +	c->olen -= len; +    } else { +	c->olen = 0; +	free(c->outmsg); +	c->outmsg = NULL; +	c->flags &= ~(WAITING_WRITE); +    } +} + + +#ifndef HAVE_GCD + +static void +process_loop(void) +{ +    struct pollfd *fds; +    unsigned n; +    unsigned num_fds; + +    while(num_clients > 0) { + +	fds = malloc(num_clients * sizeof(fds[0])); +	if(fds == NULL) +	    abort(); + +	num_fds = num_clients; + +	for (n = 0 ; n < num_fds; n++) { +	    fds[n].fd = clients[n]->fd; +	    fds[n].events = 0; +	    if (clients[n]->flags & WAITING_READ) +		fds[n].events |= POLLIN; +	    if (clients[n]->flags & WAITING_WRITE) +		fds[n].events |= POLLOUT; + +	    fds[n].revents = 0; +	} + +	poll(fds, num_fds, -1); + +	for (n = 0 ; n < num_fds; n++) { +	    if (clients[n] == NULL) +		continue; +	    if (fds[n].revents & POLLERR) { +		clients[n]->flags |= WAITING_CLOSE; +		continue; +	    } + +	    if (fds[n].revents & POLLIN) +		handle_read(clients[n]); +	    if (fds[n].revents & POLLOUT) +		handle_write(clients[n]); +	} + +	n = 0; +	while (n < num_clients) { +	    struct client *c = clients[n]; +	    if (maybe_close(c)) { +		if (n < num_clients - 1) +		    clients[n] = clients[num_clients - 1]; +		num_clients--; +	    } else +		n++; +	} + +	free(fds); +    } +} + +#endif + +static int +socket_release(heim_sipc ctx) +{ +    struct client *c = ctx->mech; +    c->flags |= WAITING_CLOSE; +    return 0; +} + +int +heim_sipc_stream_listener(int fd, int type, +			  heim_ipc_callback callback, +			  void *user, heim_sipc *ctx) +{ +    heim_sipc ct = calloc(1, sizeof(*ct)); +    struct client *c; + +    if ((type & HEIM_SIPC_TYPE_IPC) && (type & (HEIM_SIPC_TYPE_UINT32|HEIM_SIPC_TYPE_HTTP))) +	return EINVAL; + +    switch (type) { +    case HEIM_SIPC_TYPE_IPC: +	c = add_new_socket(fd, LISTEN_SOCKET|WAITING_READ|INCLUDE_ERROR_CODE, callback, user); +	break; +    case HEIM_SIPC_TYPE_UINT32: +	c = add_new_socket(fd, LISTEN_SOCKET|WAITING_READ, callback, user); +	break; +    case HEIM_SIPC_TYPE_HTTP: +    case HEIM_SIPC_TYPE_UINT32|HEIM_SIPC_TYPE_HTTP: +	c = add_new_socket(fd, LISTEN_SOCKET|WAITING_READ|ALLOW_HTTP, callback, user); +	break; +    default: +	free(ct); +	return EINVAL; +    } + +    ct->mech = c; +    ct->release = socket_release; + +    c->unixrights.uid = (uid_t) -1; +    c->unixrights.gid = (gid_t) -1; +    c->unixrights.pid = (pid_t) 0; + +    *ctx = ct; +    return 0; +} + +int +heim_sipc_service_unix(const char *service, +		       heim_ipc_callback callback, +		       void *user, heim_sipc *ctx) +{ +    struct sockaddr_un un; +    int fd, ret; + +    un.sun_family = AF_UNIX; + +    snprintf(un.sun_path, sizeof(un.sun_path), +	     "/var/run/.heim_%s-socket", service); +    fd = socket(AF_UNIX, SOCK_STREAM, 0); +    if (fd < 0) +	return errno; + +    socket_set_reuseaddr(fd, 1); +#ifdef LOCAL_CREDS +    { +	int one = 1; +	setsockopt(fd, 0, LOCAL_CREDS, (void *)&one, sizeof(one)); +    } +#endif + +    unlink(un.sun_path); + +    if (bind(fd, (struct sockaddr *)&un, sizeof(un)) < 0) { +	close(fd); +	return errno; +    } + +    if (listen(fd, SOMAXCONN) < 0) { +	close(fd); +	return errno; +    } + +    chmod(un.sun_path, 0666); + +    ret = heim_sipc_stream_listener(fd, HEIM_SIPC_TYPE_IPC, +				    callback, user, ctx); +    if (ret == 0) { +	struct client *c = (*ctx)->mech; +	c->flags |= UNIX_SOCKET; +    } + +    return ret; +} + +/** + * Set the idle timeout value + + * The timeout event handler is triggered recurrently every idle + * period `t'. The default action is rather draconian and just calls + * exit(0), so you might want to change this to something more + * graceful using heim_sipc_set_timeout_handler(). + */ + +void +heim_sipc_timeout(time_t t) +{ +#ifdef HAVE_GCD +    static dispatch_once_t timeoutonce; +    init_globals(); +    dispatch_sync(timerq, ^{ +	    timeoutvalue = t; +	    set_timer(); +	}); +    dispatch_once(&timeoutonce, ^{  dispatch_resume(timer); }); +#else +    abort(); +#endif +} + +/** + * Set the timeout event handler + * + * Replaces the default idle timeout action. + */ + +void +heim_sipc_set_timeout_handler(void (*func)(void)) +{ +#ifdef HAVE_GCD +    init_globals(); +    dispatch_sync(timerq, ^{ timer_ev = func; }); +#else +    abort(); +#endif +} + + +void +heim_sipc_free_context(heim_sipc ctx) +{ +    (ctx->release)(ctx); +} + +void +heim_ipc_main(void) +{ +#ifdef HAVE_GCD +    dispatch_main(); +#else +    process_loop(); +#endif +} + diff --git a/lib/ipc/tc.c b/lib/ipc/tc.c new file mode 100644 index 000000000000..8b56d21aa472 --- /dev/null +++ b/lib/ipc/tc.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <krb5-types.h> +#include <asn1-common.h> +#include <heim-ipc.h> +#include <getarg.h> +#include <err.h> +#include <roken.h> + +static int help_flag; +static int version_flag; + +static struct getargs args[] = { +    {	"help",		'h',	arg_flag,   &help_flag }, +    {	"version",	'v',	arg_flag,   &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +static void +usage(int ret) +{ +    arg_printusage (args, num_args, NULL, ""); +    exit (ret); +} + +static void +reply(void *ctx, int errorcode, heim_idata *reply, heim_icred cred) +{ +    printf("got reply\n"); +    heim_ipc_semaphore_signal((heim_isemaphore)ctx); /* tell caller we are done */ +} + +static void +test_ipc(const char *service) +{ +    heim_isemaphore s; +    heim_idata req, rep; +    heim_ipc ipc; +    int ret; + +    ret = heim_ipc_init_context(service, &ipc); +    if (ret) +	errx(1, "heim_ipc_init_context: %d", ret); + +    req.length = 0; +    req.data = NULL; + +    ret = heim_ipc_call(ipc, &req, &rep, NULL); +    if (ret) +	errx(1, "heim_ipc_call: %d", ret); + +    s = heim_ipc_semaphore_create(0); +    if (s == NULL) +	errx(1, "heim_ipc_semaphore_create"); + +    ret = heim_ipc_async(ipc, &req, s, reply); +    if (ret) +	errx(1, "heim_ipc_async: %d", ret); + +    heim_ipc_semaphore_wait(s, HEIM_IPC_WAIT_FOREVER); /* wait for reply to complete the work */ + +    heim_ipc_free_context(ipc); +} + + +int +main(int argc, char **argv) +{ +    int optidx = 0; + +    setprogname(argv[0]); + +    if (getarg(args, num_args, argc, argv, &optidx)) +	usage(1); + +    if (help_flag) +	usage(0); + +    if (version_flag) { +	print_version(NULL); +	exit(0); +    } + +#ifdef __APPLE__ +    test_ipc("MACH:org.h5l.test-ipc"); +#endif +    test_ipc("ANY:org.h5l.test-ipc"); +    test_ipc("UNIX:org.h5l.test-ipc"); + +    return 0; +} diff --git a/lib/ipc/ts-http.c b/lib/ipc/ts-http.c new file mode 100644 index 000000000000..b493079d94a3 --- /dev/null +++ b/lib/ipc/ts-http.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <krb5-types.h> +#include <heim-ipc.h> +#include <getarg.h> +#include <roken.h> + +static int help_flag; +static int version_flag; + +static struct getargs args[] = { +    {	"help",		'h',	arg_flag,   &help_flag }, +    {	"version",	'v',	arg_flag,   &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +static void +usage(int ret) +{ +    arg_printusage (args, num_args, NULL, ""); +    exit (ret); +} + +static void +test_service(void *ctx, const heim_idata *req, +	     const heim_icred cred, +	     heim_ipc_complete complete, +	     heim_sipc_call cctx) +{ +    heim_idata rep; +    printf("got request\n"); +    rep.length = 3; +    rep.data = strdup("hej"); +    (*complete)(cctx, 0, &rep); +} + + +static void +setup_sockets(void) +{ +    struct addrinfo hints, *res, *res0; +    int ret, s; +    heim_sipc u; + +    memset(&hints, 0, sizeof(hints)); +    hints.ai_family = PF_UNSPEC; +    hints.ai_socktype = SOCK_STREAM; +    hints.ai_flags = AI_PASSIVE; +    ret = getaddrinfo(NULL, "8080", &hints, &res0); +    if (ret) +	errx(1, "%s", gai_strerror(ret)); + +    for (res = res0; res ; res = res->ai_next) { +	s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); +	if (s < 0) { +	    warn("socket"); +	    continue; +	} +	socket_set_reuseaddr(s, 1); +	socket_set_ipv6only(s, 1); + +	if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { +	    warn("bind"); +	    close(s); +	    continue; +	} +	listen(s, 5); +	ret = heim_sipc_stream_listener(s, HEIM_SIPC_TYPE_HTTP, +					test_service, NULL, &u); +	if (ret) +	    errx(1, "heim_sipc_stream_listener: %d", ret); +    } +    freeaddrinfo(res0); +} + + +int +main(int argc, char **argv) +{ +    int optidx = 0; + +    setprogname(argv[0]); + +    if (getarg(args, num_args, argc, argv, &optidx)) +	usage(1); + +    if (help_flag) +	usage(0); + +    if (version_flag) { +	print_version(NULL); +	exit(0); +    } + +    setup_sockets(); + +    heim_ipc_main(); + +    return 0; +} diff --git a/lib/ipc/ts.c b/lib/ipc/ts.c new file mode 100644 index 000000000000..680d77bc913e --- /dev/null +++ b/lib/ipc/ts.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <krb5-types.h> +#include <heim-ipc.h> +#include <getarg.h> +#include <roken.h> + +static int help_flag; +static int version_flag; + +static struct getargs args[] = { +    {	"help",		'h',	arg_flag,   &help_flag }, +    {	"version",	'v',	arg_flag,   &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +static void +usage(int ret) +{ +    arg_printusage (args, num_args, NULL, ""); +    exit (ret); +} + +static void +test_service(void *ctx, const heim_idata *req, +	     const heim_icred cred, +	     heim_ipc_complete complete, +	     heim_sipc_call cctx) +{ +    heim_idata rep; +    printf("got request\n"); +    rep.length = 0; +    rep.data = NULL; +    (*complete)(cctx, 0, &rep); +} + + +int +main(int argc, char **argv) +{ +    heim_sipc u; +    int optidx = 0; + +    setprogname(argv[0]); + +    if (getarg(args, num_args, argc, argv, &optidx)) +	usage(1); + +    if (help_flag) +	usage(0); + +    if (version_flag) { +	print_version(NULL); +	exit(0); +    } + +#if __APPLE__ +    { +	heim_sipc mach; +	heim_sipc_launchd_mach_init("org.h5l.test-ipc", +				    test_service, NULL, &mach); +    } +#endif +    heim_sipc_service_unix("org.h5l.test-ipc", +			   test_service, NULL, &u); +    heim_ipc_main(); + +    return 0; +} | 
