This commit was manufactured by cvs2svn to create branch 'branch_2_1'.
authorcvs2svn <admin@example.com>
Fri, 18 Feb 2011 11:52:01 +0000 (11:52 +0000)
committercvs2svn <admin@example.com>
Fri, 18 Feb 2011 11:52:01 +0000 (11:52 +0000)
Cherrypick from master 2011-01-21 16:14:33 UTC Zdeněk Šustr <sustr4@cesnet.cz> 'The most recent version copied. Do not modify this instance (RW in ./org.glite.lb).':
    org.glite.lbjp-common.gsoap-plugin/Makefile
    org.glite.lbjp-common.gsoap-plugin/configure
    org.glite.lbjp-common.gsoap-plugin/project/ChangeLog
    org.glite.lbjp-common.gsoap-plugin/project/version.properties
    org.glite.lbjp-common.gss/Makefile
    org.glite.lbjp-common.gss/configure
    org.glite.lbjp-common.gss/interface/glite_gss.h
    org.glite.lbjp-common.gss/project/ChangeLog
    org.glite.lbjp-common.gss/project/version.properties
Cherrypick from master 2011-02-18 11:52:00 UTC Daniel Kouřil <kouril@ics.muni.cz> 'make sure credentials are loaded':
    org.glite.lbjp-common.gss/src/glite_gss.c

org.glite.lbjp-common.gsoap-plugin/Makefile [new file with mode: 0644]
org.glite.lbjp-common.gsoap-plugin/configure [new file with mode: 0755]
org.glite.lbjp-common.gsoap-plugin/project/ChangeLog [new file with mode: 0644]
org.glite.lbjp-common.gsoap-plugin/project/version.properties [new file with mode: 0644]
org.glite.lbjp-common.gss/Makefile [new file with mode: 0644]
org.glite.lbjp-common.gss/configure [new file with mode: 0755]
org.glite.lbjp-common.gss/interface/glite_gss.h [new file with mode: 0644]
org.glite.lbjp-common.gss/project/ChangeLog [new file with mode: 0644]
org.glite.lbjp-common.gss/project/version.properties [new file with mode: 0644]
org.glite.lbjp-common.gss/src/glite_gss.c [new file with mode: 0644]

diff --git a/org.glite.lbjp-common.gsoap-plugin/Makefile b/org.glite.lbjp-common.gsoap-plugin/Makefile
new file mode 100644 (file)
index 0000000..49dd394
--- /dev/null
@@ -0,0 +1,338 @@
+# defaults
+top_srcdir=..
+builddir=build
+top_builddir=${top_srcdir}/${builddir}
+stagedir=.
+globalprefix=glite
+package=gsoap-plugin
+version=1.0.0
+PREFIX=/opt/glite
+
+glite_location=/opt/glite
+gsoap_prefix=/opt/gsoap
+
+CC=gcc
+
+gsoap_versions_noflavours?=2.6.2 2.7.0f 2.7.6b 2.7.6d 2.7.9d 2.7.9b
+gsoap_versions_flavours?=2.7.10
+
+-include Makefile.inc
+-include ../Makefile.inc
+-include ../project/version.properties
+-include ../../project/version.properties
+
+version=${module.version}
+gsoap_versions_flavours:=${shell if ! echo ${gsoap_versions_flavours} | grep '\<${gsoap_default_version}\>' >/dev/null; then echo "${gsoap_default_version} "; else echo ''; fi} ${gsoap_versions_flavours}
+
+GSPLUGIN_DEBUG?=no
+GSPLUGIN_VERSION_CHECKING?=yes
+CC=gcc
+
+# In order to use libtool versioning correcty, we must have:
+#
+# current = major + minor + offset
+# revision = patch
+# age = minor
+#
+# where offset is a sum of maximal released minor's of all previous major's
+# 
+
+# counted minors: 1.5
+# TODO: bump offset to 5 on next major change
+offset=-1
+version_info:=-version-info ${shell \
+       perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' }
+
+ext_repository:=${shell if [ -d "${repository}/externals" ]; then \
+       echo "${repository}/externals"; \
+       else echo "${repository}"; \
+       fi}
+
+gsoap_version=${gsoap_default_version}
+gsoap_prefix?=${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}
+ifdef lang
+langflavour:=_${lang}
+langsuffix:=.${lang}
+endif
+
+VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/examples
+
+default: all
+
+DEBUG:=-g -O0 -W -Wall -Wno-unused-parameter
+# not for globus and gsoap: -Werror
+ifeq ($(GSPLUGIN_DEBUG),yes)
+       DEBUG:=${DEBUG} -DGSPLUGIN_DEBUG=1
+endif
+# gsoap logs: -DDEBUG
+ifeq ($(GSOAP_DEBUG),yes)
+       DEBUG:=${DEBUG} -DDEBUG=1
+endif
+
+#ifeq ($(GSPLUGIN_VERSION_CHECKING),yes)
+#      DEBUG:=${DEBUG} -DCHECK_GSOAP_VERSION
+#endif
+
+CFLAGS:= ${CFLAGS} ${DEBUG} \
+       -DVERSION=\"${version}\" \
+       -DWITH_NONAMESPACES \
+       -I. -I${top_srcdir}/interface \
+       -I${stagedir}/include \
+       ${COVERAGE_FLAGS} -D_GNU_SOURCE -DDATAGRID_EXTENSION -DWITH_IPV6
+
+LDFLAGS:=${LDFLAGS} ${COVERAGE_FLAGS}
+
+COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
+COMPILEXX:=libtool --mode=compile ${CXX} ${CFLAGS}
+LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/${libdir} ${LDFLAGS}
+LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}/${libdir} ${LDFLAGS}
+INSTALL:=libtool --mode=install install
+LINK_lang:=PATH=${top_srcdir}/project/libtoolhack:${PATH} libtool --mode=link ${CXX} -rpath ${stagedir}/${libdir} ${LDFLAGS}
+ifeq (${lang},c)
+LINK_lang:=${LINK}
+endif
+ifeq (${lang},cxx)
+LINK_lang:=${LINKXX}
+endif
+
+gsoaplibdir=$(shell if test -d "${gsoap_prefix}/${libdir}"; then echo "${gsoap_prefix}/${libdir}"; else echo "${gsoap_prefix}/lib"; fi)
+GSOAP_LIBS?=-L${gsoaplibdir} -lgsoap
+
+EX_NOTHRLIBS:=-L${stagedir}/${libdir} -lglite_security_gss_${nothrflavour}
+EX_THRLIBS:=-L${stagedir}/${libdir} -lglite_security_gss_${thrflavour}
+EX_LIBS:=-L${stagedir}/${libdir} -lglite_security_gss
+HDRS:=glite_gsplugin.h glite_gscompat.h glite_gsplugin-int.h
+EXAMPLES:=wscalc_clt_ex wscalc_srv_ex wscalc_srv_ex2
+TESTS:=test_cxx
+
+NOTHRSTATICLIB:=libglite_security_gsoap_plugin_${nothrflavour}${langflavour}.a
+THRSTATICLIB:=libglite_security_gsoap_plugin_${thrflavour}${langflavour}.a
+STATICLIB:=libglite_security_gsoap_plugin${langflavour}.a
+NOTHRLTLIB:=libglite_security_gsoap_plugin_${nothrflavour}${langflavour}.la
+THRLTLIB:=libglite_security_gsoap_plugin_${thrflavour}${langflavour}.la
+LTLIB:=libglite_security_gsoap_plugin${langflavour}.la
+
+OBJS:=${GSS_OBJS} glite_gsplugin${langsuffix}.o
+LOBJS:=${OBJS:.o=.lo}
+THROBJS:=${OBJS:.o=.thr.o}
+THRLOBJS:=${OBJS:.o=.thr.lo}
+
+dotless_ver:=${shell echo ${gsoap_version} | tr -d '.'}
+NOTHRSTATICLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}_${nothrflavour}${langflavour}.a
+THRSTATICLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}_${thrflavour}${langflavour}.a
+STATICLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}${langflavour}.a
+NOTHRLTLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}_${nothrflavour}${langflavour}.la
+THRLTLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}_${thrflavour}${langflavour}.la
+LTLIB_S:=libglite_security_gsoap_plugin_${dotless_ver}${langflavour}.la
+
+ifeq (${thrflavour},)
+lib_LTLIBRARIES:=${STATICLIB} ${LTLIB}
+lib_LTLIBRARIES_S:=${LTLIB_S}
+LTLIB_TEST_S:=libglite_security_gsoap_plugin_${dotless_ver}_cxx.la
+default_ltlib_s:=${LTLIB_S}
+else
+lib_LTLIBRARIES:=${NOTHRSTATICLIB} ${NOTHRLTLIB} ${THRSTATICLIB} ${THRLTLIB}
+lib_LTLIBRARIES_S:=${NOTHRLTLIB_S} ${THRLTLIB_S}
+LTLIB_TEST_S:=libglite_security_gsoap_plugin_${dotless_ver}_${nothrflavour}_cxx.la
+default_ltlib_s:=${NOTHRLTLIB_S}
+endif
+
+ifeq (${gsoap_version},${gsoap_default_version})
+OBJS_S:=glite_gsplugin${langsuffix}.o
+GSOAP_DEFAULT_LIBS:=${GSOAP_LIBS}
+else
+OBJS_S:=glite_gsplugin${langsuffix}.o stdsoap2${langsuffix}.o
+GSOAP_DEFAULT_LIBS:=
+endif
+LOBJS_S:=${OBJS_S:.o=.lo}
+THROBJS_S:=${OBJS_S:.o=.thr.o}
+THRLOBJS_S:=${OBJS_S:.o=.thr.lo}
+
+ifeq (${thrflavour},)
+${STATICLIB}: ${OBJS}
+       ar crv $@ ${OBJS}
+       ranlib $@
+
+${LTLIB}: ${OBJS}
+       ${LINK_lang} ${version_info} -o $@ ${LOBJS} ${EX_LIBS}
+
+${STATICLIB_S}: ${OBJS_S}
+       ar crv $@ ${OBJS_S}
+       ranlib $@
+
+${LTLIB_S}: ${OBJS_S}
+       ${LINK_lang} ${version_info} -o $@ ${LOBJS_S} ${EX_LIBS} ${GSOAP_DEFAULT_LIBS}
+else
+${NOTHRSTATICLIB}: ${OBJS}
+       ar crv $@ ${OBJS}
+       ranlib $@
+
+${THRSTATICLIB}: ${THROBJS}
+       ar crv $@ ${THROBJS}
+       ranlib $@
+
+${NOTHRLTLIB}: ${OBJS} 
+       ${LINK_lang} ${version_info} -o $@ ${LOBJS} ${EX_NOTHRLIBS}
+
+${THRLTLIB}: ${THROBJS}
+       ${LINK_lang} ${version_info} -o $@ ${THRLOBJS} ${EX_THRLIBS}
+
+${NOTHRSTATICLIB_S}: ${OBJS_S}
+       ar crv $@ ${OBJS_S}
+       ranlib $@
+
+${THRSTATICLIB_S}: ${THROBJS_S}
+       ar crv $@ ${THROBJS_S}
+       ranlib $@
+
+${NOTHRLTLIB_S}: ${OBJS_S} 
+       ${LINK_lang} ${version_info} -o $@ ${LOBJS_S} ${EX_NOTHRLIBS} ${GSOAP_DEFAULT_LIBS}
+
+${THRLTLIB_S}: ${THROBJS_S}
+       ${LINK_lang} ${version_info} -o $@ ${THRLOBJS_S} ${EX_THRLIBS}
+endif
+
+all compile: \
+       ${lib_LTLIBRARIES} \
+       all-libs-with-soap examples
+
+check: check.cxx
+
+# C/C++ compatibility test
+# (C flavour, gsoap 2.7.10 ==> C++ test fails)
+check.cxx:
+       ${MAKE} lang=cxx -f ${top_srcdir}/Makefile ${LTLIB_TEST_S} test_cxx
+       LD_LIBRARY_PATH=${cares_prefix}/${libdir}:${LD_LIBRARY_PATH} ./test_cxx
+
+examples: ${EXAMPLES}
+
+all-libs-with-soap:
+       for v in ${gsoap_versions_noflavours}; do       \
+               dir=`echo $$v | tr -d .`; \
+               mkdir $$dir; \
+               ${MAKE} -C $$dir -f ../Makefile gsoap_version=$$v top_srcdir=../.. lang= libs-with-soap || exit $?; \
+       done
+       for v in ${gsoap_versions_flavours}; do \
+               dir=`echo $$v | tr -d .`; \
+               mkdir $$dir; \
+               ${MAKE} -C $$dir -f ../Makefile gsoap_version=$$v top_srcdir=../.. lang=c libs-with-soap || exit $?; \
+               ${MAKE} -C $$dir -f ../Makefile gsoap_version=$$v top_srcdir=../.. lang=cxx libs-with-soap || exit $?; \
+       done
+
+libs-with-soap: ${lib_LTLIBRARIES_S}
+
+gsoap_srcname=gsoap-`echo ${gsoap_version} | cut -d. -f1,2`
+
+link-gsoap:
+       if [ ${gsoap_version} = ${gsoap_default_version} ]; then \
+               ln -sf ${gsoap_prefix}/include/stdsoap2.h stdsoap2.h; \
+       elif [ -f ${top_srcdir}/src/stdsoap2_${gsoap_version}.c ]; then \
+               ln -sf ${top_srcdir}/src/stdsoap2_${gsoap_version}.c stdsoap2.c; \
+               ln -sf ${top_srcdir}/src/stdsoap2_${gsoap_version}.h stdsoap2.h; \
+       elif [ -f ${ext_repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.c ]; then \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.[ch] .; \
+       elif [ -f ${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/stdsoap2.c ]; then \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/stdsoap2.[ch] .; \
+       elif [ -f ${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/src/stdsoap2.c ]; then \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/src/stdsoap2.c .; \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/include/stdsoap2.h .; \
+       elif [ -f ${ext_repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.c ]; then \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.[ch] .; \
+       elif [ -f ${ext_repository}/${gsoap_name}/${gsoap_version}/src/${gsoap_srcname}/soapcpp2/stdsoap2.c ]; then \
+               ln -sf ${ext_repository}/${gsoap_name}/${gsoap_version}/src/${gsoap_srcname}/soapcpp2/stdsoap2.[ch] .; \
+       else false ; \
+       fi
+
+stdsoap2.c stdsoap2.h: link-gsoap
+
+GSOAP_FPREFIX:= GSOAP_
+
+WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o
+WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o
+WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o
+
+wscalc_clt_ex.o wscalc_srv_ex.o wscalc_srv_ex2.o: ${GSOAP_FPREFIX}H.h
+
+wscalc_clt_ex: ${WSCALC_CLT_OBJS} ${default_ltlib_s}
+       ${LINK_lang} -o $@ ${WSCALC_CLT_OBJS} ${default_ltlib_s} ${GSOAP_DEFAULT_LIBS}
+
+wscalc_srv_ex: ${WSCALC_SRV_OBJS} ${default_ltlib_s}
+       ${LINK_lang} -o $@ ${WSCALC_SRV_OBJS} ${default_ltlib_s} ${GSOAP_DEFAULT_LIBS}
+
+wscalc_srv_ex2: ${WSCALC_SRV2_OBJS} ${default_ltlib_s}
+       ${LINK_lang} -o $@ ${WSCALC_SRV2_OBJS} ${default_ltlib_s} ${GSOAP_DEFAULT_LIBS}
+
+test_cxx: test_gsplugin_cxx.o ${GSOAP_FPREFIX}C.cxx.o
+       ${LINKXX} -o $@ $+ ${LTLIB_TEST_S}
+
+soapcpp:=${shell if [ -x ${gsoap_prefix}/bin/soapcpp2 ]; then \
+       echo ${gsoap_prefix}/bin/soapcpp2; \
+       else echo ${gsoap_prefix}/soapcpp2; \
+       fi}
+
+${GSOAP_FPREFIX}H.h ${GSOAP_FPREFIX}C.c ${GSOAP_FPREFIX}Server.c ${GSOAP_FPREFIX}Client.c ${GSOAP_FPREFIX}ServerLib.c ${GSOAP_FPREFIX}ClientLib.c: calc.h.S
+       ${soapcpp} -c -p ${GSOAP_FPREFIX} ${top_srcdir}/examples/calc.h.S
+
+wscalc_clt_ex.o: wscalc_clt_ex.c
+       ${CC} -c ${CFLAGS} -o $@ $<
+
+doc:
+
+stage:
+       $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes
+
+install:
+       -mkdir -p ${PREFIX}/${libdir}
+       -mkdir -p ${PREFIX}/include/glite/security
+       -mkdir -p ${PREFIX}/share/doc/${package}-${version}
+       -mkdir -p ${PREFIX}/include/glite/security/
+       ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
+       cd ${top_srcdir}/interface && ${INSTALL} -m 644 ${HDRS} ${PREFIX}/include/glite/security/
+       for v in ${gsoap_versions_noflavours}; do \
+               ${MAKE} -C `echo $$v | tr -d .` -f ../Makefile install-soaplib gsoap_version=$$v lang= PREFIX=${PREFIX} top_srcdir=${top_srcdir}/.. || exit $?; \
+       done
+       for v in ${gsoap_versions_flavours}; do \
+               ${MAKE} -C `echo $$v | tr -d .` -f ../Makefile install-soaplib gsoap_version=$$v lang=c PREFIX=${PREFIX} top_srcdir=${top_srcdir}/.. || exit $?; \
+               ${MAKE} -C `echo $$v | tr -d .` -f ../Makefile install-soaplib gsoap_version=$$v lang=cxx PREFIX=${PREFIX} top_srcdir=${top_srcdir}/.. || exit $?; \
+       done
+
+install-soaplib:
+       ${INSTALL} -m 755 ${lib_LTLIBRARIES_S} ${PREFIX}/${libdir}
+
+clean:
+       rm -rvf ${lib_LTLIBRARIES}
+       rm -rvf ${lib_LTLIBRARIES_S}
+       rm -rvf ${LTLIB_TEST_S}
+       rm -rvf *.c *.h *.xml *.nsmap *.o *.lo .libs ${EXAMPLES} ${TESTS}
+       rm -rvf CalcService.wsdl wscalc.xsd
+       rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ debian/
+       for v in ${gsoap_versions_noflavours} ${gsoap_versions_flavours}; do \
+               rm -rvf `echo $$v | tr -d .`; \
+       done
+
+%.c.o: %.c
+       ${COMPILE} -o $@ -c $<
+
+%.cxx.o: %.c
+       ${COMPILEXX} -o $@ -c $<
+
+%.o: %.c
+       ${COMPILE} -o $@ -c $<
+
+%.c.thr.o: %.c
+       ${COMPILE} -o $@ -c $<
+
+%.cxx.thr.o: %.c
+       ${COMPILEXX} -o $@ -c $<
+
+%.thr.o: %.c
+       ${COMPILE} -o $@ -c $<
+
+test_gsplugin_cxx.o: %.o: %.cpp stdsoap2.h
+       ${COMPILEXX} -c ${GLOBUS_INC} $<
+
+glite_gsplugin${langsuffix}.o glite_gsplugin${langsuffix}.thr.o: soap_version.h
+
+soap_version.h: stdsoap2.h
+       head stdsoap2.h | \
+       perl -ne '/^\s*stdsoap2.h\s+([0-9])\.([0-9])\.(\S+)\s.*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_MIN_VERSION \"$$3\"\n#ident \"soap_version.h $$1.$$2.$$3\"\n",$$1,$$2,$$3' >$@
diff --git a/org.glite.lbjp-common.gsoap-plugin/configure b/org.glite.lbjp-common.gsoap-plugin/configure
new file mode 100755 (executable)
index 0000000..598d569
--- /dev/null
@@ -0,0 +1,1069 @@
+#!/usr/bin/perl
+
+# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
+#
+# For the purpose of standalone builds of lb/jobid/lbjp-common components
+# it is copied on tagging 
+
+# $Header$
+#
+# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
+# See http://www.eu-egee.org/partners/ for details on the copyright holders.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+use Getopt::Long;
+
+my $pwd = `pwd`; chomp $pwd;
+my $prefix = $pwd.'/stage';
+my $stagedir;
+my $staged;
+my $module;
+my $thrflavour = 'gcc64dbgpthr';
+my $nothrflavour = 'gcc64dbg';
+my $mode = 'build';
+my $help = 0;
+my $listmodules;
+my $version;
+my $branch;
+my $output;
+my $lb_tag = '';
+my $lbjp_tag = '';
+my $jp_tag = '';
+my $sec_tag = '';
+my $jobid_tag = '';
+my $libdir = getlibdir();
+
+my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient harvester/;
+my %enable_nodes;
+my %disable_nodes;
+
+my %externs = (
+       cares => {
+               prefix => '/opt/c-ares',
+               pkg => 'libcares'
+       },
+       classads => {
+               prefix=> '/opt/classads',
+               pkg => 'classads'
+       },
+       cppunit => {
+               prefix=> '/usr',
+               pkg => 'cppunit'
+       },
+       expat => {
+               prefix=> '/usr',
+               pkg => 'expat'
+       },
+       globus => {
+               prefix=> '/opt/globus',
+               pkg => 'globus-gssapi-gsi'
+       },
+       myproxy => {
+               prefix=> '/opt/myproxy',
+               pkg => 'myproxy'
+       },
+       gsoap => {
+               prefix=> '/usr',
+               pkg => 'gsoap'
+       },
+       mysql => {
+               prefix=> '/usr'
+       },
+       'mysql-devel' => {
+               prefix=> ''
+       },
+       'mysql-server' => {
+               prefix => ''
+       },
+       voms => {
+               prefix => '/opt/glite',
+               pkg => 'voms-1.0'
+       },
+       gridsite => {
+               prefix => '/opt/glite'
+       },
+       lcas => {
+               prefix => '/opt/glite'
+       },
+       trustmanager => {
+               prefix => '/opt/glite'
+       },
+       utiljava => {
+               prefix=> '/opt/glite'
+       },
+       ant => {
+               prefix=> '/usr'
+       },
+       jdk => {
+               prefix=> '/usr'
+       },
+       libtar => {
+               prefix=> '/usr'
+       },
+       axis => {
+               prefix=> '/usr'
+       },
+       log4c => {
+               prefix=> '/usr'
+       },
+       postgresql => {
+               prefix=> '/usr'
+       }
+);
+
+my %jar = (
+       'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
+       'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
+);
+
+
+my %glite_prefix;
+my %need_externs;
+my %need_externs_type;
+my %need_jars;
+my %extrafull;
+my %extranodmod;
+my %deps;
+my %deps_type;
+my %buildroot;
+
+my %lbmodules = (
+       'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim glite-LB/], 
+       'security' => [qw/gss gsoap-plugin/],
+       'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin/],
+       'jobid' => [qw/api-c api-cpp api-java/],
+       'jp' => [ qw/client doc index primary server-common ws-interface/ ],
+       'gridsite' => [ qw/apache shared commands core/ ],
+       'px' => [ qw/proxyrenewal glite-PX myproxy-yaim myproxy-config/ ],
+       );
+
+
+my @opts = (
+       'prefix=s' => \$prefix,
+       'staged=s' => \$staged,
+       'module=s' => \$module,
+       'thrflavour:s' => \$thrflavour,
+       'nothrflavour:s' => \$nothrflavour,
+       'mode=s' => \$mode,
+       'listmodules=s' => \$listmodules,
+       'version=s' => \$version,
+       'branch=s' => \$branch,
+       'output=s' => \$output,
+       'stage=s' => \$stagedir,
+       'lb-tag=s' => \$lb_tag,
+       'lbjp-common-tag=s' => \$lbjp_tag,
+       'jp-tag=s' => \$jp_tag,
+       'security-tag=s' => \$sec_tag,
+       'jobid-tag=s' => \$jobid_tag,
+       'help' => \$help,
+       'libdir=s' => \$libdir,
+       'emi' => \$emi,
+);
+
+for (@nodes) {
+       $enable_nodes{$_} = 0;
+       $disable_nodes{$_} = 0;
+       
+       push @opts,"disable-$_",\$disable_nodes{$_};
+       push @opts,"enable-$_",\$enable_nodes{$_};
+}
+
+push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
+push @opts,"with-$_=s",\$jar{$_} for keys %jar;
+
+my @keeparg = @ARGV;
+
+GetOptions @opts or die "Errors parsing command line\n";
+
+$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
+$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
+
+if ($help) { usage(); exit 0; }
+
+if ($listmodules) {
+       my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}};
+       print "@m\n";
+       exit 0;
+}
+
+warn "$0: --version, --branch and --output make sense only in --mode=etics\n"
+       if ($version || $output || $branch) && $mode ne 'etics';
+
+my $en;
+for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
+
+my $dis;
+for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
+
+die "--enable-* and --disable-* are mutually exclusive\n"
+       if $en && $dis;
+
+die "--module cannot be used with --enable-* or --disable-*\n"
+       if $module && ($en || $dis);
+
+die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}};
+
+if ($mode eq 'build') { for my $ext (keys %externs) {
+       if (defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
+       elsif (defined $externs{$ext}{pkg}) {
+               my ($prefix, $flag);
+               my $pkg = $externs{$ext}{pkg};
+               my $flagname = uc $externs{$ext}{pkg};
+               $flagname =~ s/-[0-9\.]*$//;
+               $flagname =~ s/-/_/g;
+
+               print "Checking $pkg ... ";
+               `pkg-config "$pkg" --exists >/dev/null`;
+               if ($? == 0) {
+                       $externs{$ext}{prefix}=`pkg-config $pkg --variable=prefix`;
+                       chomp $externs{$ext}{prefix};
+                       print "$externs{$ext}{prefix}\n";
+
+                       $flag=`pkg-config $pkg --cflags`;
+                       $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
+                       $flag=`pkg-config $pkg --libs`;
+                       $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
+               } else {
+                       print "(using default)\n";
+               }
+       }
+} }
+
+if ($dis) {
+       for (@nodes) {
+               $enable_nodes{$_} = 1 unless $disable_nodes{$_};
+       }
+}
+
+if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ;
+
+for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
+
+$stagedir = $prefix unless $stagedir;
+
+if ($mode eq 'build') {
+       print "Writing config.status\n";
+       open CONF,">config.status" or die "config.status: $!\n";
+       print CONF "PKG_CONFIG_PATH=$ENV{PKG_CONFIG_PATH} $0 @keeparg\n";
+       close CONF;
+}
+
+
+my @modules;
+my %aux;
+
+if ($module) {
+#      push @modules,split(/[,.]+/,$module);
+       push @modules,$module;
+}
+else {
+       @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
+       
+       my $n;
+
+       do {
+               local $"="\n";
+               $n = $#modules;
+               push @modules,(map @{$deps{$_}},@modules);
+
+               undef %aux; @aux{@modules} = (1) x ($#modules+1);
+               @modules = keys %aux;
+       } while ($#modules > $n);
+}
+
+@aux{@modules} = (1) x ($#modules+1);
+delete $aux{$_} for (split /,/,$staged);
+@modules = keys %aux;
+
+mode_build() if $mode eq 'build';
+mode_checkout() if $mode eq 'checkout';
+mode_etics($module) if $mode eq 'etics';
+
+sub mode_build {
+       print "\nBuilding modules: @modules\n";
+       
+       my @ext = map @{$need_externs{$_}},@modules;
+       my @myjars = map @{$need_jars{$_}},@modules;
+       undef %aux; @aux{@ext} = 1;
+       @ext = keys %aux;
+       undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
+       @myjars = keys %aux;
+       
+       print "\nRequired externals:\n";
+       print "\t$_: $externs{$_}{prefix}\n" for @ext;
+       print "\t$_: $jar{$_}\n" for @myjars;
+       for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
+       print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
+       
+       mkinc($_) for @modules;
+       
+       print "Creating Makefile\n";
+       
+       open MAK,">Makefile" or die "Makefile: $!\n";
+       
+       print MAK "all: @modules\n\nclean:\n";
+       
+       for (@modules) {
+               my $full = full($_);
+               print MAK "\tcd $full/$buildroot{$_} && \${MAKE} clean\n"
+       }
+       
+       print MAK "\ndistclean:\n";
+       
+       for (@modules) {
+               my $full = full($_);
+               print MAK $buildroot{$_} eq '' ?
+                       "\tcd $full && \${MAKE} distclean\n" :
+                       "\trm -rf $full/$buildroot{$_}\n"
+       }
+       
+       print MAK "\n";
+       
+       for (@modules) {
+               my %ldeps; undef %ldeps;  
+               @ldeps{@{$deps{$_}}} = 1;
+               for my $x (split /,/,$staged) { delete $ldeps{$x}; }
+               my @dnames = $module ? () : keys %ldeps;
+       
+               my $full = full($_);
+               my $build = $buildroot{$_};
+       
+               print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
+       }
+       
+       close MAK;
+}
+       
+sub mode_checkout() {
+       for (@modules) {
+               my $module = $_;
+               my $tag = "";
+               if ($lb_tag){
+                       for (@{$lbmodules{lb}}){
+                               if ("lb.".$_ eq $module){
+                                       $tag = '-r '.$lb_tag;
+                               }
+                       }       
+               }
+               if ($lbjp_tag){
+                       for (@{$lbmodules{'lbjp-common'}}){
+                               if ("lbjp-common.".$_ eq $module){
+                                        $tag = '-r '.$lbjp_tag;
+                                }
+                       }
+               }
+               if ($jp_tag){
+                       for (@{$lbmodules{'jp'}}){
+                               if ("jp.".$_ eq $module){
+                                        $tag = '-r '.$jp_tag;
+                               }
+                        }
+               }
+               if ($sec_tag){
+                       for (@{$lbmodules{security}}){
+                               if ("security.".$_ eq $module){
+                                        $tag = '-r '.$sec_tag;
+                                }
+                       }
+               }
+               if ($jobid_tag){
+                       for (@{$lbmodules{jobid}}){
+                               if ("jobid.".$_ eq $module){
+                                        $tag = '-r '.$jobid_tag;
+                                }
+                       }
+               }
+               #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
+               #       print "found";
+               #}
+               $_ = full($_);
+               print "\n*** Checking out $_\n";
+               system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
+       }
+}
+
+BEGIN{
+%need_externs_aux = (
+       'lb.client' => [ qw/cppunit:B classads/ ],
+       'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava/ ],
+       'lb.common' => [ qw/expat cares:B cppunit:B classads/ ],
+       'lb.doc' => [],
+       'lb.logger' => [ qw/cppunit:B/ ],
+       'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql:R mysql-server:R mysql-devel:B cppunit:B gsoap:B classads voms lcas gridsite/ ],
+       'lb.state-machine' => [ qw/classads/ ],
+       'lb.utils' => [ qw/cppunit:B/ ],
+       'lb.ws-interface' => [],
+       'lb.ws-test' => [ qw/gsoap:B/ ],
+       'lb.types' => [ qw// ],
+       'lb.harvester' => [ qw// ],
+       'lb.yaim' => [ qw/yaim_core:R/ ],
+       'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
+       'lbjp-common.db' => [ qw/mysql:B mysql-devel:B postgresql:B cppunit:B log4c:B/ ],
+       'lbjp-common.log' => [ qw/log4c/ ],
+       'lbjp-common.maildir' => [ qw// ],
+       'lbjp-common.server-bones' => [ qw// ],
+       'lbjp-common.trio' => [ qw/cppunit:B/ ],
+       'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B/ ],
+       'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B/ ],
+       'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap:B/ ],
+       'security.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B/ ],
+       'security.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap:B/ ],
+       'jobid.api-c' =>  [ qw/cppunit:B/ ],
+       'jobid.api-cpp' =>  [ qw/cppunit:B/ ],
+       'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
+       'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
+        'jp.doc' => [],
+        'jp.index' => [ qw/gsoap globus_essentials:R globus:B/ ],
+        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B/ ],
+        'jp.server-common' => [],
+        'jp.ws-interface' => [],
+       'gridsite.core' => [qw/httpd-devel:B gsoap:B globus:B/ ],
+       'px.proxyrenewal' => [ qw/globus:B myproxy voms/ ],
+       'px.glite-PX' => [qw/myproxy:R fetchcrl:R gip_service:R bdii:R glite_version:R/],
+       'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
+       'px.myproxy-config' => [],
+);
+
+for my $ext (keys %need_externs_aux) {
+       for (@{$need_externs_aux{$ext}}) {
+               /([^:]*)(?::(.*))?/;
+               push @{$need_externs{$ext}},$1;
+               my $type = $2 ? $2 : 'BR';
+               $need_externs_type{$ext}->{$1} = $type;
+       }
+}
+
+%need_jars = (
+       'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
+       'lb.client-java' => [ qw/jakarta-commons-lang/ ],
+);
+
+for my $jar (keys %need_jars) {
+       for (@{$need_jars{$jar}}) {
+               $need_externs_type{$jar}->{$_} = 'BR';  # XXX
+       }
+}
+
+%deps_aux = (
+       'lb.client' => [ qw/
+               lb.types:B lb.common
+               lbjp-common.trio
+               jobid.api-cpp:B jobid.api-c
+               lbjp-common.gss
+       / ],
+       'lb.client-java' => [ qw/
+               lb.types:B
+               lb.ws-interface:B
+               jobid.api-java
+       / ],
+       'lb.common' => [ qw/
+               jobid.api-cpp:B jobid.api-c
+               lb.types:B lbjp-common.trio lbjp-common.gss
+       / ],
+       'lb.doc' => [ qw/lb.types:B/ ],
+       'lb.logger' => [ qw/
+               lbjp-common.trio
+               lbjp-common.log
+               jobid.api-c
+               lb.common
+               lbjp-common.gss
+       / ],
+       'lb.server' => [ qw/
+               lb.ws-interface lb.types:B lb.common lb.state-machine
+               lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
+               jobid.api-c
+               lbjp-common.gsoap-plugin lbjp-common.gss
+       / ],
+       'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
+       'lb.utils' => [ qw/
+               lbjp-common.jp-interface
+               jobid.api-c
+               lbjp-common.trio lbjp-common.maildir
+               lb.client lb.state-machine
+       / ],
+       'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
+       'lb.ws-interface' => [ qw/lb.types:B/ ],
+       'lb.types' => [ qw// ],
+       'lb.harvester' => [ qw/
+               jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
+               lbjp-common.gss lbjp-common.log
+       / ],
+       'lb.yaim' => [ qw// ],
+       'lb.glite-LB' => [ qw/
+               lb.logger:R lb.server:R lb.utils:R lb.doc:R
+               lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
+       / ],
+       'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
+       'lbjp-common.maildir' => [ qw// ],
+       'lbjp-common.log' => [ qw// ],
+       'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
+       'lbjp-common.trio' => [ qw// ],
+       'lbjp-common.gss' =>  [ qw// ],
+       'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
+       'security.gss' =>  [ qw// ],
+       'security.gsoap-plugin' =>  [ qw/security.gss/ ],
+       'jobid.api-c' =>  [ qw// ],
+       'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
+       'jobid.api-java' =>  [ qw// ],
+
+       'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ],
+
+       'jp.client' => [ qw/
+                jp.ws-interface
+                lbjp-common.jp-interface lbjp-common.maildir
+                jobid.api-c
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.doc' => [ qw// ],
+       'jp.index' => [ qw/
+                jp.server-common jp.ws-interface
+                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.primary' => [ qw/
+                jobid.api-c
+                jp.server-common jp.ws-interface
+                lb.state-machine
+                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.server-common' => [ qw/ 
+                lbjp-common.jp-interface lbjp-common.db
+        / ],
+       'jp.ws-interface' => [ qw// ],
+
+       'gridsite.core' => [ qw/build.common-cpp:B/ ],
+
+       'px.proxyrenewal' => [ qw// ],
+       'px.glite-PX' => [qw/px.myproxy-yaim:R/],
+       'px.myproxy-yaim' => [],
+       'px.myproxy-config' => [],
+);
+
+for my $ext (keys %deps_aux) {
+       for (@{$deps_aux{$ext}}) {
+               /([^:]*)(?::(.*))?/;
+               push @{$deps{$ext}},$1;
+               my $type = $2 ? $2 : 'BR';
+               $deps_type{$ext}->{$1} = $type;
+       }
+}
+
+
+%extrafull = ( gridsite=>'org.gridsite.core');
+
+#( java => 'client-java' );
+%extranodmod = (
+       db => 'lbjp-common.db',
+       jpprimary => 'jp.primary',
+       jpindex => 'jp.index',
+       jpclient => 'jp.client',
+);
+
+%obsoletes = (
+       'lb.yaim' => [ qq/glite-yaim-lb/ ],
+       'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
+       'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
+       'px.myproxy-config' => [ qq/myproxy-config/ ],
+       'lbjp-common.gss' => [ qq/glite-security-gss/ ],
+       'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
+);
+
+%cvs_prefix = (
+       'lb' => 'org.glite',
+       'jp' => 'org.glite',
+       'jobid' => 'org.glite',
+       'lbjp-common' => 'org.glite',
+       'gridsite' => 'org',
+       'security' => 'org.glite',
+       'px' => 'org.glite',
+);
+
+%conf_prefix = (
+       'lb' => 'glite-',
+       'jp' => 'glite-',
+       'jobid' => 'glite-',
+       'lbjp-common' => 'glite-',
+       'gridsite' => '',
+       'security' => 'glite-',
+       'px' => 'glite-',
+);
+
+%emi_conf_prefix = (
+       'lb' => 'emi-',
+       'jp' => 'emi-',
+       'jobid' => 'emi-',
+       'lbjp-common' => 'emi-',
+       'gridsite' => '',
+       'security' => 'emi-',
+       'px' => 'emi-',
+);
+
+my @k = keys %deps_aux;
+@buildroot{@k} = ('build') x ($#k+1);
+
+my @t = qw/lb.client-java jobid.api-java lb.types/;
+@buildroot{@t} = ('') x ($#t+1);
+
+$buildroot{'gridsite.core'} = 'src';
+}
+
+sub full
+{
+       my $short = shift;
+       return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short;
+}
+
+sub mkinc
+{
+       my %aux;
+       undef %aux;
+       my @m=qw/
+lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB
+security.gss security.gsoap-plugin
+jobid.api-c jobid.api-cpp jobid.api-java
+lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
+jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
+px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config
+/;
+       @aux{@m} = (1) x ($#m+1);
+
+       my $short = shift;
+       my $full = full $short;
+
+       unless ($aux{$short}) {
+               print "Makefile.inc not needed in $full\n";
+               return;
+       }
+
+       my $build = '';
+       
+       unless ($buildroot{$_} eq '') {
+               $build = "/$buildroot{$_}";
+               unless (-d "$full/$buildroot{$_}") {
+                       mkdir "$full/$buildroot{$_}" or die "mkdir $full/$buildroot{$_}: $!\n";
+               }
+               unlink "$full/$buildroot{$_}/Makefile";
+               symlink "../Makefile","$full/$buildroot{$_}/Makefile" or die "symlink ../Makefile $full/$buildroot{$_}/Makefile: $!\n";
+       }
+
+       open MKINC,">$full/$buildroot{$_}/Makefile.inc"
+               or die "$full/$buildroot{$_}/Makefile.inc: $!\n";
+
+       print "Creating $full/$buildroot{$_}/Makefile.inc\n";
+
+       print MKINC qq{
+PREFIX = $prefix
+stagedir = $stagedir
+thrflavour = $thrflavour
+nothrflavour = $nothrflavour
+libdir = $libdir
+};
+
+       for (@{$need_externs{$short}}) {
+               print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
+               print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
+       }
+
+       for (@{$need_jars{$short}}) {
+               print MKINC "${_}_jar = $jar{$_}\n"
+       }
+
+       my $need_gsoap = 0;
+       for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
+
+       print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
+
+       close MKINC;
+}
+
+my %etics_externs;
+my %etics_projects;
+BEGIN{
+       %etics_externs = (
+               globus_essentials=>'vdt_globus_essentials',
+               globus=>'globus',
+               myproxy=>'myproxy',
+               cares=>'c-ares',
+               voms=>'org.glite.security.voms-api-cpp',
+               gridsite=>'org.gridsite.shared',
+               lcas=>'org.glite.security.lcas',
+               trustmanager=>'org.glite.security.trustmanager',
+               utiljava=>'org.glite.security.util-java',
+               gpt=>'gpt',
+               fetchcrl=>'fetch-crl',
+               gip_release=>'glite-info-provider-release',
+               gip_service=>'glite-info-provider-service',
+               bdii=>'bdii',
+               glite_version=>'glite-version',
+               glite_info_templates=>'glite-info-templates',
+               glue_schema=>'glue-schema',
+               yaim_core=>'org.glite.yaim.core',
+       );
+       %etics_projects = (
+               vdt=>[qw/globus globus_essentials myproxy/],
+               'org.glite'=>[qw/voms gridsite lcas gpt gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
+       );
+
+       %platform_properties = (
+               'gridsite.core' => {
+                       sl5_x86_64_gcc412 => { aprSuffix => '1' },
+                       sl5_ia32_gcc412 => { aprSuffix => '1' },
+                       deb5_x86_64_gcc432 => { aprSuffix => '1.0' },
+                       deb5_ia32_gcc432 => { aprSuffix => '1.0' },
+                       slc4_x86_64_gcc346 => { aprSuffix => '0' },
+                       slc4_ia32_gcc346 => { aprSuffix => '0' },
+                       default => { 
+                       }
+               },
+       );
+};
+
+sub mode_etics {
+       $fmod = shift;
+
+       die "$0: --module required with --etics\n" unless $fmod;
+       
+       my ($subsys,$module) = split /\./,$fmod;
+
+       my ($major,$minor,$rev,$age);
+
+       if ($version) {
+               $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
+               ($major,$minor,$rev,$age) = ($1,$2,$3,$4);
+       }
+       else { 
+               open V,"$cvs_prefix{$subsys}.$subsys.$module/project/version.properties"
+                       or die "$cvs_prefix{$subsys}.$subsys.$module/project/version.properties: $!\n";
+       
+               while ($_ = <V>) {
+                       chomp;
+                       ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
+                       $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
+               }
+               close V;
+       }
+
+       my @copts = ();
+       my %ge;
+       @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1);
+
+       for (@{$need_externs{"$subsys.$module"}}) {
+           if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+               if ($emi) {
+                       if ($ge{$_} and not defined $externs{$_}{pkg}) {
+                               push @copts, "--with-$_=\${stageDir}";
+                       }
+               } else {
+                       push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
+               }
+           }
+       }
+
+       for (@{$need_jars{"$subsys.$module"}}) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+
+               push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (not $emi);
+       }
+
+       my $conf;
+       my $conftag;
+       my $confprefix;
+
+       $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
+
+       if ($emi) { $confprefix = $emi_conf_prefix{$subsys} }
+       else { $confprefix = $conf_prefix{$subsys} }
+
+       if ($branch) {
+               $conf = "$confprefix${subsys}-${module}_$branch"; 
+               $conftag = $branch;
+               # forced low age number
+               $age = $branch eq 'HEAD' ? '0head' : '0dev'; }
+       else {
+               $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; 
+
+# XXX: gridsite hack
+               $conftag = $subsys eq 'gridsite' ? "$conf_prefix{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
+                       "$conf_prefix{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; }
+       if ($emi) {
+               $age = "${age}emi";
+       } 
+
+       my $file = $output ? $output : "$conf.ini";
+       open C,">$file" or die "$file: $!\n";
+
+       my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
+
+       my $confdir = $buildroot{"$subsys.$module"} eq '' ? '..' : '../..';
+
+       my $package_description = "";
+       my $package_summary = "";
+
+       if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.description") {
+               open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.description";
+               $package_description = join ("", <V>);
+               close V;
+               chomp $package_description;
+               $package_description =~ s/\n/\\n/g; 
+               $package_description = "package.description = $package_description\n";
+       } 
+       else { 
+               print STDERR "package.description not found for $subsys.$module!\n"; }
+
+       if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary") {
+               open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary";
+               $package_summary = join ("", <V>);
+               close V;
+               chomp $package_summary;
+               $package_summary =~ s/\n/\\n/g; 
+               $package_summary = "package.summary = $package_summary\n";
+       } 
+       else { 
+               print STDERR "package.summary not found for $subsys.$module!\n"; }
+
+       my %cmd;
+       @cmd{qw/configure compile test install packaging clean/} = ('None') x 6;
+       $cmd{clean} = 'make clean';
+
+       if ($subsys eq 'gridsite') {
+               if ($module eq 'core') {
+                       my $flags = 'RELEASE_VERSION=${age}.${platformFamily} prefix=${prefix} libdir=${libdir} GSOAPDIR=${gsoap.location} OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}/ FLAVOR_GLOBUS_EXT=_${globus.dbg.nothr.flavor} HTTPD_FLAGS="-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-${aprSuffix} -I${httpd-devel.location}/include/pcre"';
+
+                       $cmd{compile} = "make $flags build";
+                       $cmd{install} = "make $flags install";
+                       $cmd{packaging} = "make $flags rpm";
+               }
+               else {
+                       $cmd{packaging} = "echo building nothing, org.gridsite.core make rpm step will create this";
+               }
+       }
+       else {
+               my $flavours = $emi ? "--thrflavour= --nothrflavour=" : "--thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor}";
+               $cmd{configure} = "cd $confdir && /usr/bin/perl \${moduleName}/configure $flavours --prefix=\${prefix} --stage=\${stageDir} --libdir=\${libdir} --module $subsys.$module @copts";
+               $cmd{compile} = 'make';
+               $cmd{test} = 'make check';
+               $cmd{install} = 'make install';
+       }
+
+       my $defprops = '';
+
+       for my $p (keys %{$platform_properties{"$subsys.$module"}->{default}}) {
+               $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
+       }
+
+       my $checkoutcmd;
+       if ($conftag eq 'HEAD') {
+               $checkoutcmd = "cvs -d \${vcsroot} co -A \${moduleName}";
+       } else {
+               $checkoutcmd = "cvs -d \${vcsroot} co -r \${tag} \${moduleName}";
+       }
+
+       print STDERR "Writing $file\n";
+       print C qq{
+[Configuration-$conf]
+profile = None
+moduleName = $cvs_prefix{$subsys}.$subsys.$module
+displayName = $conf
+description = $cvs_prefix{$subsys}.$subsys.$module
+projectName = org.glite
+age = $age
+deploymentType = None
+tag = $conftag
+version = $major.$minor.$rev
+$dwpath
+[Platform-default:VcsCommand]
+displayName = None
+description = None
+tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName}
+branch = None
+commit = None
+checkout = $checkoutcmd
+
+[Platform-default:BuildCommand]
+postpublish = None
+packaging = $cmd{packaging}
+displayName = None
+description = None
+doc = None
+prepublish = None
+publish = None
+compile = $cmd{compile}
+init = None
+install = $cmd{install}
+clean = $cmd{clean}
+test = $cmd{test}
+configure = $cmd{configure}
+checkstyle = None
+
+[Platform-default:Property]
+$buildroot
+aprSuffix = 0
+package.RPMSLocation = \${moduleDir}/RPMTMP/RPMS
+package.SRPMSLocation = \${moduleDir}/RPMTMP/SRPMS
+package.preserve.libtool = false
+$package_description$package_summary$defprops};
+
+       for (@{$obsoletes{"$subsys.$module"}}) {
+               print C "package.obsoletes = $_\n";
+               print C "package.replaces = $_\n";
+       }
+
+       for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
+               next if $pp eq 'default';
+               print C "[Platform-$pp:Property]\n$buildroot\n";
+
+               for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
+                       print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
+               }
+               print C q{package.RPMSLocation = ${moduleDir}/RPMTMP/RPMS
+package.SRPMSLocation = ${moduleDir}/RPMTMP/SRPMS
+};
+               print C "$package_description$package_summary\n";
+       }
+
+       print C qq{
+[Platform-default:DynamicDependency]
+};
+       for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+
+               my $proj = 'externals';
+               for my $p (keys %etics_projects) {
+                       for $m (@{$etics_projects{$p}}) {
+                               $proj = $p if $m eq $_;
+                       }
+               }
+
+               my $type = $need_externs_type{"$subsys.$module"}->{$_};
+               print C "$proj|$eext = $type\n";
+       }
+
+       for (@{$deps{"$subsys.$module"}}) {
+               my $type = $deps_type{"$subsys.$module"}->{$_};
+               print C "org.glite|org.glite.$_ = $type\n";
+       }
+
+       close C;
+}
+
+sub gsoap_version {
+       local $_;
+       my $gsoap_version;
+       open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
+
+       while ($_ = <S>) {
+               chomp;
+
+               $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
+       }
+       close S;
+       return $gsoap_version;
+}
+
+sub getlibdir {
+       if ( -e "/etc/debian_version") { # We are on Debian
+               $lib64="lib";
+               $lib32="lib32"; }
+       else { # Another distribution
+               $lib64="lib64";
+               $lib32="lib";   }
+        $libdir=$lib32;
+
+        open INP, "uname -s | "; # Check kernel name
+        $kname= <INP>;
+        chomp($kname);
+        close INP;
+
+        if ( $kname == "Linux") {
+                $arch = ("x86_64\npowerpc\nppc64\n");
+
+                open INP, "uname -p | "; # Check processor type
+                $procname= <INP>;
+                chomp($procname);
+                close INP;
+
+                if ($arch =~/^$procname\n/) {
+                        return ($lib64); }
+
+                open INP, "uname -m | "; # Check machine hardware
+                $machname= <INP>;
+                chomp($machname);
+                close INP;
+
+                if ($arch =~/^$machname\n/) {
+                        return ($lib64); }
+
+                # special cases (hyperlink lib64, Debian)
+                if (-l "/usr/lib64") {
+                        $libdir=$lib32; }
+
+                # if /usr/lib64 doesn't exist at all (AIX)
+                unless ( -e "/usr/lib64" ) {
+                        $libdir=$lib32; }
+        }
+
+        if ( $kname == "SunOS") {
+                if (-e "/usr/lib/64") {
+                $libdir="lib/64"; }
+        }
+
+        return $libdir;
+}
+
+sub usage {
+       my @ext = keys %externs;
+       my @myjars, keys %jar;
+
+       print STDERR qq{
+usage: $0 options
+
+General options (defaults in []):
+  --prefix=PREFIX              destination directory [./stage]
+  --staged=module,module,...   what is already in PREFIX (specify without org.glite.)
+  --thrflavour=flavour
+  --nothrflavour=flavour       threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
+  --listmodules=subsys          list modules of a subsystem
+  --version=maj.min.rev-age    specify version here instead of reading version.properties
+  --branch=branch              CVS branch/etics name suffix (HEAD, branch_2_1, ...)
+  --libdir=libdir              typically [lib,lib64] postfix
+  --emi                                generate configurations with emi flavor in mode 'etics'
+  
+Mode of operation:
+  --mode={checkout|build|etics}        what to do [build]
+  
+What to build:
+  --module=module              build this module only (mostly in-Etics operation)
+  --enable-NODE                        build this "node" (set of modules) only. Available nodes are
+                                       @{$lbmodules{lb}},@{$lbmodules{security}}
+  --disable-NODE               don't build this node
+  --lb-tag=tag                 checkout LB modules with specific tag
+  --jp-tag=tag                 checkout JP modules with specific tag
+  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
+  --security-tag=tag           checkout security modules with specific tag
+  --jobid-tag=tag              checkout jobid modules with specific tag
+
+Dependencies:
+  --with-EXTERNAL=PATH         where to look for an external. Required externals
+                               (not all for all modules) are:
+                                       @ext
+  --with-JAR=JAR               where to look for jars. Required jars are:
+                                       @myjars
+                               Summary of what will be used is always printed
+
+};
+
+}
diff --git a/org.glite.lbjp-common.gsoap-plugin/project/ChangeLog b/org.glite.lbjp-common.gsoap-plugin/project/ChangeLog
new file mode 100644 (file)
index 0000000..9d39895
--- /dev/null
@@ -0,0 +1,52 @@
+1.5.3-1
+- avoid memleak in gsoap
+- fix #32059
+- support gsoap 2.7.10
+
+1.5.4-1
+- handle client connection errors in gsoap (generate faults)
+- don't define gsoap.platformName in configuration confusingly
+
+1.5.4-2
+- disctinct c and c++ builds (concerns gsoap 2.7.10 only)
+
+2.0.0-1
+- LB 2.0 release
+
+2.0.0-2
+- configure script update (globus flavors added to configure call)
+
+2.0.1-1
+- API reverted towards backward compatibility
+
+2.0.1-2
+- Module repacked
+
+2.0.1-3
+- install libraries into $libdir
+
+2.0.2-1
+- Updated Makefile & Configure script
+
+2.1.0-1
+- IPv6 fixes
+- Fixed error reporting
+- Attempt to fix compatibility with gsoap 2.7.10
+- Improved portability
+
+2.1.1-1
+- libtool version numbering reintroduced
+
+2.1.2-1
+- Fixed target 'clean' in the Makefile to handle debian builds
+
+2.1.2-2
+- Module rebuilt
+
+2.1.3-1
+- Module renamed
+- Makefile a configuration updated to work across org.glite & EMI
+
+2.1.3-2
+- Module rebuilt
+
diff --git a/org.glite.lbjp-common.gsoap-plugin/project/version.properties b/org.glite.lbjp-common.gsoap-plugin/project/version.properties
new file mode 100644 (file)
index 0000000..1cb0126
--- /dev/null
@@ -0,0 +1,3 @@
+# $Header$
+module.version=2.1.3
+module.age=2
diff --git a/org.glite.lbjp-common.gss/Makefile b/org.glite.lbjp-common.gss/Makefile
new file mode 100644 (file)
index 0000000..612b573
--- /dev/null
@@ -0,0 +1,170 @@
+# defaults
+top_srcdir=..
+builddir=build
+top_builddir=${top_srcdir}/${builddir}
+stagedir=.
+globalprefix=glite
+package=gss
+version=1.0.0
+PREFIX=/opt/glite
+
+glite_location=/opt/glite
+globus_prefix=/opt/globus
+cppunit_prefix=/opt/cppunit
+
+CC=gcc
+
+-include Makefile.inc
+-include ../project/version.properties
+
+version=${module.version}
+
+# In order to use libtool versioning correcty, we must have:
+#
+# current = major + minor + offset
+# revision = patch
+# age = minor
+#
+# where offset is a sum of maximal released minor's of all previous major's
+#
+
+# counted minors: gsoap-plugin 1.5
+# TODO: bump offset to 5 on next major change
+offset=-1
+version_info:=-version-info ${shell \
+       perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' }
+
+VPATH=${top_srcdir}/src:${top_srcdir}/test
+
+default: all
+
+DEBUG:=-g -O0 -W -Wall -Wno-unused-parameter
+# not for globus, gsoap: -Werror
+
+CFLAGS:= ${CFLAGS} ${DEBUG} \
+       -DVERSION=\"${version}\" \
+       -I. -I${top_srcdir}/interface \
+       -I${stagedir}/include \
+       ${COVERAGE_FLAGS} -D_GNU_SOURCE -DDATAGRID_EXTENSION
+
+LDFLAGS:=${LDFLAGS} ${COVERAGE_FLAGS}
+
+COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
+LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/${libdir} ${LDFLAGS} 
+LINKXX:=libtool --mode=link  ${CXX} -rpath ${stagedir}/${libdir} ${LDFLAGS}
+INSTALL:=libtool --mode=install install
+
+CPPUNIT_LIBS?=-L${cppunit_prefix}/${libdir} -lcppunit
+CPPUNIT_CFLAGS?=-I${cppunit_prefix}/include
+
+GLOBUS_NOTHR_INC:= -I${globus_prefix}/include/${nothrflavour}
+GLOBUS_THR_INC:= -I${globus_prefix}/include/${thrflavour}
+
+GLOBUS_NOTHR_LIBS:= -L${globus_prefix}/lib \
+       -lglobus_common_${nothrflavour} \
+       -lglobus_gssapi_gsi_${nothrflavour}
+GLOBUS_THR_LIBS:= -L${globus_prefix}/lib \
+       -lglobus_common_${thrflavour} \
+       -lglobus_gssapi_gsi_${thrflavour}
+
+GLOBUS_GSSAPI_GSI_LIBS?=${GLOBUS_NOTHR_LIBS}
+GLOBUS_GSSAPI_GSI_CFLAGS?=${GLOBUS_NOTHR_INC}
+
+LIBCARES_CFLAGS?=-I${cares_prefix}/include
+LIBCARES_LIBS?=-L${cares_prefix}/${libdir} -L${cares_prefix}/lib -lcares
+
+HDRS:=glite_gss.h
+
+GSS_OBJS:=glite_gss.o
+GSS_LOBJS:=${GSS_OBJS:.o=.lo}
+GSS_THROBJS:=${GSS_OBJS:.o=.thr.o}
+GSS_THRLOBJS:=${GSS_OBJS:.o=.thr.lo}
+
+GSS_NOTHRSTATICLIB:=libglite_security_gss_${nothrflavour}.a
+GSS_THRSTATICLIB:=libglite_security_gss_${thrflavour}.a
+GSS_STATICLIB:=libglite_security_gss.a
+GSS_NOTHRLTLIB:=libglite_security_gss_${nothrflavour}.la
+GSS_THRLTLIB:=libglite_security_gss_${thrflavour}.la
+GSS_LTLIB:=libglite_security_gss.la
+
+ifeq ($(thrflavour),)
+lib_LTLIBRARIES=${GSS_LTLIB}
+lib_LIBRARIES=${GSS_STATICLIB}
+default_gss=${GSS_LTLIB}
+else
+lib_LTLIBRARIES=${GSS_NOTHRLTLIB} ${GSS_THRLTLIB}
+lib_LIBRARIES=${GSS_NOTHRSTATICLIB} ${GSS_THRSTATICLIB}
+default_gss=${GSS_NOTHRLTLIB}
+endif
+
+
+ifeq ($(thrflavour),)
+${GSS_STATICLIB}: ${GSS_OBJS}
+       ar crv $@ ${GSS_OBJS}
+       ranlib $@
+
+${GSS_LTLIB}: ${GSS_OBJS}
+       ${LINK} ${version_info} -o $@ ${GSS_LOBJS} ${GLOBUS_GSSAPI_GSI_LIBS} ${LIBCARES_LIBS}
+else
+${GSS_NOTHRSTATICLIB}: ${GSS_OBJS}
+       ar crv $@ ${GSS_OBJS}
+       ranlib $@
+
+${GSS_THRSTATICLIB}: ${GSS_THROBJS}
+       ar crv $@ ${GSS_THROBJS}
+       ranlib $@
+
+${GSS_NOTHRLTLIB}: ${GSS_OBJS}
+       ${LINK} ${version_info} -o $@ ${GSS_LOBJS} ${GLOBUS_NOTHR_LIBS} ${LIBCARES_LIBS}
+
+${GSS_THRLTLIB}: ${GSS_THROBJS}
+       ${LINK} ${version_info} -o $@ ${GSS_THRLOBJS} ${GLOBUS_THR_LIBS} ${LIBCARES_LIBS}
+endif
+
+
+all compile: $(lib_LTLIBRARIES) ${lib_LIBRARIES} examples
+
+check: compile check.gss
+
+check.gss: test_gss
+       # ./test_gss out.xml
+       echo test_gss not run automatically util we have got some credentials in X509_USER_PROXY
+
+test_gss: test_gss.o
+       ${LINKXX} -o $@ test_gss.o ${default_gss} ${CPPUNIT_LIBS} ${GLOBUS_GSSAPI_GSI_LIBS} ${LIBCARES_LIBS}
+
+test_coverage:
+       -mkdir coverage
+       cd coverage && $(MAKE) -f ../Makefile top_srcdir=../../ COVERAGE_FLAGS="-fprofile-arcs -ftest-coverage" check
+       cd coverage && for i in ${OBJS}; do gcov -o .libs/ $$i ; done
+
+examples:
+
+doc:
+
+stage:
+       $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes
+
+install:
+       -mkdir -p ${PREFIX}/${libdir}
+       -mkdir -p ${PREFIX}/share/doc/${package}-${version}
+       -mkdir -p ${PREFIX}/include/glite/security
+       ${INSTALL} -m 755 ${lib_LTLIBRARIES} ${PREFIX}/${libdir}
+       ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
+       cd ${top_srcdir}/interface && ${INSTALL} -m 644 ${HDRS} ${PREFIX}/include/glite/security/
+       if [ x${DOSTAGE} = xyes ]; then \
+               install -m 644 ${lib_LIBRARIES} ${PREFIX}/${libdir}; \
+       fi
+
+clean:
+       rm -rf *.o *.lo *.a *.la .libs test_gss
+       rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ debian/
+
+%.o: %.c
+       ${COMPILE} ${GLOBUS_GSSAPI_GSI_CFLAGS} ${LIBCARES_CFLAGS} -o $@ -c $<
+
+%.thr.o: %.c
+       ${COMPILE} ${GLOBUS_THR_INC} ${LIBCARES_CFLAGS} -o $@ -c $<
+
+test_gss.o: %.o: %.cpp
+       ${CXX} -c ${CFLAGS} ${GLOBUS_GSSAPI_GSI_CFLAGS} ${CPPUNIT_CFLAGS} -Wno-error $<
diff --git a/org.glite.lbjp-common.gss/configure b/org.glite.lbjp-common.gss/configure
new file mode 100755 (executable)
index 0000000..598d569
--- /dev/null
@@ -0,0 +1,1069 @@
+#!/usr/bin/perl
+
+# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
+#
+# For the purpose of standalone builds of lb/jobid/lbjp-common components
+# it is copied on tagging 
+
+# $Header$
+#
+# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
+# See http://www.eu-egee.org/partners/ for details on the copyright holders.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+use Getopt::Long;
+
+my $pwd = `pwd`; chomp $pwd;
+my $prefix = $pwd.'/stage';
+my $stagedir;
+my $staged;
+my $module;
+my $thrflavour = 'gcc64dbgpthr';
+my $nothrflavour = 'gcc64dbg';
+my $mode = 'build';
+my $help = 0;
+my $listmodules;
+my $version;
+my $branch;
+my $output;
+my $lb_tag = '';
+my $lbjp_tag = '';
+my $jp_tag = '';
+my $sec_tag = '';
+my $jobid_tag = '';
+my $libdir = getlibdir();
+
+my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient harvester/;
+my %enable_nodes;
+my %disable_nodes;
+
+my %externs = (
+       cares => {
+               prefix => '/opt/c-ares',
+               pkg => 'libcares'
+       },
+       classads => {
+               prefix=> '/opt/classads',
+               pkg => 'classads'
+       },
+       cppunit => {
+               prefix=> '/usr',
+               pkg => 'cppunit'
+       },
+       expat => {
+               prefix=> '/usr',
+               pkg => 'expat'
+       },
+       globus => {
+               prefix=> '/opt/globus',
+               pkg => 'globus-gssapi-gsi'
+       },
+       myproxy => {
+               prefix=> '/opt/myproxy',
+               pkg => 'myproxy'
+       },
+       gsoap => {
+               prefix=> '/usr',
+               pkg => 'gsoap'
+       },
+       mysql => {
+               prefix=> '/usr'
+       },
+       'mysql-devel' => {
+               prefix=> ''
+       },
+       'mysql-server' => {
+               prefix => ''
+       },
+       voms => {
+               prefix => '/opt/glite',
+               pkg => 'voms-1.0'
+       },
+       gridsite => {
+               prefix => '/opt/glite'
+       },
+       lcas => {
+               prefix => '/opt/glite'
+       },
+       trustmanager => {
+               prefix => '/opt/glite'
+       },
+       utiljava => {
+               prefix=> '/opt/glite'
+       },
+       ant => {
+               prefix=> '/usr'
+       },
+       jdk => {
+               prefix=> '/usr'
+       },
+       libtar => {
+               prefix=> '/usr'
+       },
+       axis => {
+               prefix=> '/usr'
+       },
+       log4c => {
+               prefix=> '/usr'
+       },
+       postgresql => {
+               prefix=> '/usr'
+       }
+);
+
+my %jar = (
+       'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
+       'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
+);
+
+
+my %glite_prefix;
+my %need_externs;
+my %need_externs_type;
+my %need_jars;
+my %extrafull;
+my %extranodmod;
+my %deps;
+my %deps_type;
+my %buildroot;
+
+my %lbmodules = (
+       'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim glite-LB/], 
+       'security' => [qw/gss gsoap-plugin/],
+       'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin/],
+       'jobid' => [qw/api-c api-cpp api-java/],
+       'jp' => [ qw/client doc index primary server-common ws-interface/ ],
+       'gridsite' => [ qw/apache shared commands core/ ],
+       'px' => [ qw/proxyrenewal glite-PX myproxy-yaim myproxy-config/ ],
+       );
+
+
+my @opts = (
+       'prefix=s' => \$prefix,
+       'staged=s' => \$staged,
+       'module=s' => \$module,
+       'thrflavour:s' => \$thrflavour,
+       'nothrflavour:s' => \$nothrflavour,
+       'mode=s' => \$mode,
+       'listmodules=s' => \$listmodules,
+       'version=s' => \$version,
+       'branch=s' => \$branch,
+       'output=s' => \$output,
+       'stage=s' => \$stagedir,
+       'lb-tag=s' => \$lb_tag,
+       'lbjp-common-tag=s' => \$lbjp_tag,
+       'jp-tag=s' => \$jp_tag,
+       'security-tag=s' => \$sec_tag,
+       'jobid-tag=s' => \$jobid_tag,
+       'help' => \$help,
+       'libdir=s' => \$libdir,
+       'emi' => \$emi,
+);
+
+for (@nodes) {
+       $enable_nodes{$_} = 0;
+       $disable_nodes{$_} = 0;
+       
+       push @opts,"disable-$_",\$disable_nodes{$_};
+       push @opts,"enable-$_",\$enable_nodes{$_};
+}
+
+push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
+push @opts,"with-$_=s",\$jar{$_} for keys %jar;
+
+my @keeparg = @ARGV;
+
+GetOptions @opts or die "Errors parsing command line\n";
+
+$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
+$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
+
+if ($help) { usage(); exit 0; }
+
+if ($listmodules) {
+       my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}};
+       print "@m\n";
+       exit 0;
+}
+
+warn "$0: --version, --branch and --output make sense only in --mode=etics\n"
+       if ($version || $output || $branch) && $mode ne 'etics';
+
+my $en;
+for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
+
+my $dis;
+for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
+
+die "--enable-* and --disable-* are mutually exclusive\n"
+       if $en && $dis;
+
+die "--module cannot be used with --enable-* or --disable-*\n"
+       if $module && ($en || $dis);
+
+die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}};
+
+if ($mode eq 'build') { for my $ext (keys %externs) {
+       if (defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
+       elsif (defined $externs{$ext}{pkg}) {
+               my ($prefix, $flag);
+               my $pkg = $externs{$ext}{pkg};
+               my $flagname = uc $externs{$ext}{pkg};
+               $flagname =~ s/-[0-9\.]*$//;
+               $flagname =~ s/-/_/g;
+
+               print "Checking $pkg ... ";
+               `pkg-config "$pkg" --exists >/dev/null`;
+               if ($? == 0) {
+                       $externs{$ext}{prefix}=`pkg-config $pkg --variable=prefix`;
+                       chomp $externs{$ext}{prefix};
+                       print "$externs{$ext}{prefix}\n";
+
+                       $flag=`pkg-config $pkg --cflags`;
+                       $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
+                       $flag=`pkg-config $pkg --libs`;
+                       $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
+               } else {
+                       print "(using default)\n";
+               }
+       }
+} }
+
+if ($dis) {
+       for (@nodes) {
+               $enable_nodes{$_} = 1 unless $disable_nodes{$_};
+       }
+}
+
+if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ;
+
+for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
+
+$stagedir = $prefix unless $stagedir;
+
+if ($mode eq 'build') {
+       print "Writing config.status\n";
+       open CONF,">config.status" or die "config.status: $!\n";
+       print CONF "PKG_CONFIG_PATH=$ENV{PKG_CONFIG_PATH} $0 @keeparg\n";
+       close CONF;
+}
+
+
+my @modules;
+my %aux;
+
+if ($module) {
+#      push @modules,split(/[,.]+/,$module);
+       push @modules,$module;
+}
+else {
+       @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
+       
+       my $n;
+
+       do {
+               local $"="\n";
+               $n = $#modules;
+               push @modules,(map @{$deps{$_}},@modules);
+
+               undef %aux; @aux{@modules} = (1) x ($#modules+1);
+               @modules = keys %aux;
+       } while ($#modules > $n);
+}
+
+@aux{@modules} = (1) x ($#modules+1);
+delete $aux{$_} for (split /,/,$staged);
+@modules = keys %aux;
+
+mode_build() if $mode eq 'build';
+mode_checkout() if $mode eq 'checkout';
+mode_etics($module) if $mode eq 'etics';
+
+sub mode_build {
+       print "\nBuilding modules: @modules\n";
+       
+       my @ext = map @{$need_externs{$_}},@modules;
+       my @myjars = map @{$need_jars{$_}},@modules;
+       undef %aux; @aux{@ext} = 1;
+       @ext = keys %aux;
+       undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
+       @myjars = keys %aux;
+       
+       print "\nRequired externals:\n";
+       print "\t$_: $externs{$_}{prefix}\n" for @ext;
+       print "\t$_: $jar{$_}\n" for @myjars;
+       for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
+       print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
+       
+       mkinc($_) for @modules;
+       
+       print "Creating Makefile\n";
+       
+       open MAK,">Makefile" or die "Makefile: $!\n";
+       
+       print MAK "all: @modules\n\nclean:\n";
+       
+       for (@modules) {
+               my $full = full($_);
+               print MAK "\tcd $full/$buildroot{$_} && \${MAKE} clean\n"
+       }
+       
+       print MAK "\ndistclean:\n";
+       
+       for (@modules) {
+               my $full = full($_);
+               print MAK $buildroot{$_} eq '' ?
+                       "\tcd $full && \${MAKE} distclean\n" :
+                       "\trm -rf $full/$buildroot{$_}\n"
+       }
+       
+       print MAK "\n";
+       
+       for (@modules) {
+               my %ldeps; undef %ldeps;  
+               @ldeps{@{$deps{$_}}} = 1;
+               for my $x (split /,/,$staged) { delete $ldeps{$x}; }
+               my @dnames = $module ? () : keys %ldeps;
+       
+               my $full = full($_);
+               my $build = $buildroot{$_};
+       
+               print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
+       }
+       
+       close MAK;
+}
+       
+sub mode_checkout() {
+       for (@modules) {
+               my $module = $_;
+               my $tag = "";
+               if ($lb_tag){
+                       for (@{$lbmodules{lb}}){
+                               if ("lb.".$_ eq $module){
+                                       $tag = '-r '.$lb_tag;
+                               }
+                       }       
+               }
+               if ($lbjp_tag){
+                       for (@{$lbmodules{'lbjp-common'}}){
+                               if ("lbjp-common.".$_ eq $module){
+                                        $tag = '-r '.$lbjp_tag;
+                                }
+                       }
+               }
+               if ($jp_tag){
+                       for (@{$lbmodules{'jp'}}){
+                               if ("jp.".$_ eq $module){
+                                        $tag = '-r '.$jp_tag;
+                               }
+                        }
+               }
+               if ($sec_tag){
+                       for (@{$lbmodules{security}}){
+                               if ("security.".$_ eq $module){
+                                        $tag = '-r '.$sec_tag;
+                                }
+                       }
+               }
+               if ($jobid_tag){
+                       for (@{$lbmodules{jobid}}){
+                               if ("jobid.".$_ eq $module){
+                                        $tag = '-r '.$jobid_tag;
+                                }
+                       }
+               }
+               #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
+               #       print "found";
+               #}
+               $_ = full($_);
+               print "\n*** Checking out $_\n";
+               system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
+       }
+}
+
+BEGIN{
+%need_externs_aux = (
+       'lb.client' => [ qw/cppunit:B classads/ ],
+       'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava/ ],
+       'lb.common' => [ qw/expat cares:B cppunit:B classads/ ],
+       'lb.doc' => [],
+       'lb.logger' => [ qw/cppunit:B/ ],
+       'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql:R mysql-server:R mysql-devel:B cppunit:B gsoap:B classads voms lcas gridsite/ ],
+       'lb.state-machine' => [ qw/classads/ ],
+       'lb.utils' => [ qw/cppunit:B/ ],
+       'lb.ws-interface' => [],
+       'lb.ws-test' => [ qw/gsoap:B/ ],
+       'lb.types' => [ qw// ],
+       'lb.harvester' => [ qw// ],
+       'lb.yaim' => [ qw/yaim_core:R/ ],
+       'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
+       'lbjp-common.db' => [ qw/mysql:B mysql-devel:B postgresql:B cppunit:B log4c:B/ ],
+       'lbjp-common.log' => [ qw/log4c/ ],
+       'lbjp-common.maildir' => [ qw// ],
+       'lbjp-common.server-bones' => [ qw// ],
+       'lbjp-common.trio' => [ qw/cppunit:B/ ],
+       'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B/ ],
+       'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B/ ],
+       'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap:B/ ],
+       'security.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B/ ],
+       'security.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap:B/ ],
+       'jobid.api-c' =>  [ qw/cppunit:B/ ],
+       'jobid.api-cpp' =>  [ qw/cppunit:B/ ],
+       'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
+       'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
+        'jp.doc' => [],
+        'jp.index' => [ qw/gsoap globus_essentials:R globus:B/ ],
+        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B/ ],
+        'jp.server-common' => [],
+        'jp.ws-interface' => [],
+       'gridsite.core' => [qw/httpd-devel:B gsoap:B globus:B/ ],
+       'px.proxyrenewal' => [ qw/globus:B myproxy voms/ ],
+       'px.glite-PX' => [qw/myproxy:R fetchcrl:R gip_service:R bdii:R glite_version:R/],
+       'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
+       'px.myproxy-config' => [],
+);
+
+for my $ext (keys %need_externs_aux) {
+       for (@{$need_externs_aux{$ext}}) {
+               /([^:]*)(?::(.*))?/;
+               push @{$need_externs{$ext}},$1;
+               my $type = $2 ? $2 : 'BR';
+               $need_externs_type{$ext}->{$1} = $type;
+       }
+}
+
+%need_jars = (
+       'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
+       'lb.client-java' => [ qw/jakarta-commons-lang/ ],
+);
+
+for my $jar (keys %need_jars) {
+       for (@{$need_jars{$jar}}) {
+               $need_externs_type{$jar}->{$_} = 'BR';  # XXX
+       }
+}
+
+%deps_aux = (
+       'lb.client' => [ qw/
+               lb.types:B lb.common
+               lbjp-common.trio
+               jobid.api-cpp:B jobid.api-c
+               lbjp-common.gss
+       / ],
+       'lb.client-java' => [ qw/
+               lb.types:B
+               lb.ws-interface:B
+               jobid.api-java
+       / ],
+       'lb.common' => [ qw/
+               jobid.api-cpp:B jobid.api-c
+               lb.types:B lbjp-common.trio lbjp-common.gss
+       / ],
+       'lb.doc' => [ qw/lb.types:B/ ],
+       'lb.logger' => [ qw/
+               lbjp-common.trio
+               lbjp-common.log
+               jobid.api-c
+               lb.common
+               lbjp-common.gss
+       / ],
+       'lb.server' => [ qw/
+               lb.ws-interface lb.types:B lb.common lb.state-machine
+               lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
+               jobid.api-c
+               lbjp-common.gsoap-plugin lbjp-common.gss
+       / ],
+       'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
+       'lb.utils' => [ qw/
+               lbjp-common.jp-interface
+               jobid.api-c
+               lbjp-common.trio lbjp-common.maildir
+               lb.client lb.state-machine
+       / ],
+       'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
+       'lb.ws-interface' => [ qw/lb.types:B/ ],
+       'lb.types' => [ qw// ],
+       'lb.harvester' => [ qw/
+               jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
+               lbjp-common.gss lbjp-common.log
+       / ],
+       'lb.yaim' => [ qw// ],
+       'lb.glite-LB' => [ qw/
+               lb.logger:R lb.server:R lb.utils:R lb.doc:R
+               lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
+       / ],
+       'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
+       'lbjp-common.maildir' => [ qw// ],
+       'lbjp-common.log' => [ qw// ],
+       'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
+       'lbjp-common.trio' => [ qw// ],
+       'lbjp-common.gss' =>  [ qw// ],
+       'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
+       'security.gss' =>  [ qw// ],
+       'security.gsoap-plugin' =>  [ qw/security.gss/ ],
+       'jobid.api-c' =>  [ qw// ],
+       'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
+       'jobid.api-java' =>  [ qw// ],
+
+       'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ],
+
+       'jp.client' => [ qw/
+                jp.ws-interface
+                lbjp-common.jp-interface lbjp-common.maildir
+                jobid.api-c
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.doc' => [ qw// ],
+       'jp.index' => [ qw/
+                jp.server-common jp.ws-interface
+                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.primary' => [ qw/
+                jobid.api-c
+                jp.server-common jp.ws-interface
+                lb.state-machine
+                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
+                lbjp-common.gsoap-plugin
+        / ],
+       'jp.server-common' => [ qw/ 
+                lbjp-common.jp-interface lbjp-common.db
+        / ],
+       'jp.ws-interface' => [ qw// ],
+
+       'gridsite.core' => [ qw/build.common-cpp:B/ ],
+
+       'px.proxyrenewal' => [ qw// ],
+       'px.glite-PX' => [qw/px.myproxy-yaim:R/],
+       'px.myproxy-yaim' => [],
+       'px.myproxy-config' => [],
+);
+
+for my $ext (keys %deps_aux) {
+       for (@{$deps_aux{$ext}}) {
+               /([^:]*)(?::(.*))?/;
+               push @{$deps{$ext}},$1;
+               my $type = $2 ? $2 : 'BR';
+               $deps_type{$ext}->{$1} = $type;
+       }
+}
+
+
+%extrafull = ( gridsite=>'org.gridsite.core');
+
+#( java => 'client-java' );
+%extranodmod = (
+       db => 'lbjp-common.db',
+       jpprimary => 'jp.primary',
+       jpindex => 'jp.index',
+       jpclient => 'jp.client',
+);
+
+%obsoletes = (
+       'lb.yaim' => [ qq/glite-yaim-lb/ ],
+       'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
+       'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
+       'px.myproxy-config' => [ qq/myproxy-config/ ],
+       'lbjp-common.gss' => [ qq/glite-security-gss/ ],
+       'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
+);
+
+%cvs_prefix = (
+       'lb' => 'org.glite',
+       'jp' => 'org.glite',
+       'jobid' => 'org.glite',
+       'lbjp-common' => 'org.glite',
+       'gridsite' => 'org',
+       'security' => 'org.glite',
+       'px' => 'org.glite',
+);
+
+%conf_prefix = (
+       'lb' => 'glite-',
+       'jp' => 'glite-',
+       'jobid' => 'glite-',
+       'lbjp-common' => 'glite-',
+       'gridsite' => '',
+       'security' => 'glite-',
+       'px' => 'glite-',
+);
+
+%emi_conf_prefix = (
+       'lb' => 'emi-',
+       'jp' => 'emi-',
+       'jobid' => 'emi-',
+       'lbjp-common' => 'emi-',
+       'gridsite' => '',
+       'security' => 'emi-',
+       'px' => 'emi-',
+);
+
+my @k = keys %deps_aux;
+@buildroot{@k} = ('build') x ($#k+1);
+
+my @t = qw/lb.client-java jobid.api-java lb.types/;
+@buildroot{@t} = ('') x ($#t+1);
+
+$buildroot{'gridsite.core'} = 'src';
+}
+
+sub full
+{
+       my $short = shift;
+       return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short;
+}
+
+sub mkinc
+{
+       my %aux;
+       undef %aux;
+       my @m=qw/
+lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB
+security.gss security.gsoap-plugin
+jobid.api-c jobid.api-cpp jobid.api-java
+lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
+jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
+px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config
+/;
+       @aux{@m} = (1) x ($#m+1);
+
+       my $short = shift;
+       my $full = full $short;
+
+       unless ($aux{$short}) {
+               print "Makefile.inc not needed in $full\n";
+               return;
+       }
+
+       my $build = '';
+       
+       unless ($buildroot{$_} eq '') {
+               $build = "/$buildroot{$_}";
+               unless (-d "$full/$buildroot{$_}") {
+                       mkdir "$full/$buildroot{$_}" or die "mkdir $full/$buildroot{$_}: $!\n";
+               }
+               unlink "$full/$buildroot{$_}/Makefile";
+               symlink "../Makefile","$full/$buildroot{$_}/Makefile" or die "symlink ../Makefile $full/$buildroot{$_}/Makefile: $!\n";
+       }
+
+       open MKINC,">$full/$buildroot{$_}/Makefile.inc"
+               or die "$full/$buildroot{$_}/Makefile.inc: $!\n";
+
+       print "Creating $full/$buildroot{$_}/Makefile.inc\n";
+
+       print MKINC qq{
+PREFIX = $prefix
+stagedir = $stagedir
+thrflavour = $thrflavour
+nothrflavour = $nothrflavour
+libdir = $libdir
+};
+
+       for (@{$need_externs{$short}}) {
+               print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
+               print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
+       }
+
+       for (@{$need_jars{$short}}) {
+               print MKINC "${_}_jar = $jar{$_}\n"
+       }
+
+       my $need_gsoap = 0;
+       for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
+
+       print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
+
+       close MKINC;
+}
+
+my %etics_externs;
+my %etics_projects;
+BEGIN{
+       %etics_externs = (
+               globus_essentials=>'vdt_globus_essentials',
+               globus=>'globus',
+               myproxy=>'myproxy',
+               cares=>'c-ares',
+               voms=>'org.glite.security.voms-api-cpp',
+               gridsite=>'org.gridsite.shared',
+               lcas=>'org.glite.security.lcas',
+               trustmanager=>'org.glite.security.trustmanager',
+               utiljava=>'org.glite.security.util-java',
+               gpt=>'gpt',
+               fetchcrl=>'fetch-crl',
+               gip_release=>'glite-info-provider-release',
+               gip_service=>'glite-info-provider-service',
+               bdii=>'bdii',
+               glite_version=>'glite-version',
+               glite_info_templates=>'glite-info-templates',
+               glue_schema=>'glue-schema',
+               yaim_core=>'org.glite.yaim.core',
+       );
+       %etics_projects = (
+               vdt=>[qw/globus globus_essentials myproxy/],
+               'org.glite'=>[qw/voms gridsite lcas gpt gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
+       );
+
+       %platform_properties = (
+               'gridsite.core' => {
+                       sl5_x86_64_gcc412 => { aprSuffix => '1' },
+                       sl5_ia32_gcc412 => { aprSuffix => '1' },
+                       deb5_x86_64_gcc432 => { aprSuffix => '1.0' },
+                       deb5_ia32_gcc432 => { aprSuffix => '1.0' },
+                       slc4_x86_64_gcc346 => { aprSuffix => '0' },
+                       slc4_ia32_gcc346 => { aprSuffix => '0' },
+                       default => { 
+                       }
+               },
+       );
+};
+
+sub mode_etics {
+       $fmod = shift;
+
+       die "$0: --module required with --etics\n" unless $fmod;
+       
+       my ($subsys,$module) = split /\./,$fmod;
+
+       my ($major,$minor,$rev,$age);
+
+       if ($version) {
+               $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
+               ($major,$minor,$rev,$age) = ($1,$2,$3,$4);
+       }
+       else { 
+               open V,"$cvs_prefix{$subsys}.$subsys.$module/project/version.properties"
+                       or die "$cvs_prefix{$subsys}.$subsys.$module/project/version.properties: $!\n";
+       
+               while ($_ = <V>) {
+                       chomp;
+                       ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
+                       $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
+               }
+               close V;
+       }
+
+       my @copts = ();
+       my %ge;
+       @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1);
+
+       for (@{$need_externs{"$subsys.$module"}}) {
+           if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+               if ($emi) {
+                       if ($ge{$_} and not defined $externs{$_}{pkg}) {
+                               push @copts, "--with-$_=\${stageDir}";
+                       }
+               } else {
+                       push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
+               }
+           }
+       }
+
+       for (@{$need_jars{"$subsys.$module"}}) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+
+               push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (not $emi);
+       }
+
+       my $conf;
+       my $conftag;
+       my $confprefix;
+
+       $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
+
+       if ($emi) { $confprefix = $emi_conf_prefix{$subsys} }
+       else { $confprefix = $conf_prefix{$subsys} }
+
+       if ($branch) {
+               $conf = "$confprefix${subsys}-${module}_$branch"; 
+               $conftag = $branch;
+               # forced low age number
+               $age = $branch eq 'HEAD' ? '0head' : '0dev'; }
+       else {
+               $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; 
+
+# XXX: gridsite hack
+               $conftag = $subsys eq 'gridsite' ? "$conf_prefix{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
+                       "$conf_prefix{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; }
+       if ($emi) {
+               $age = "${age}emi";
+       } 
+
+       my $file = $output ? $output : "$conf.ini";
+       open C,">$file" or die "$file: $!\n";
+
+       my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
+
+       my $confdir = $buildroot{"$subsys.$module"} eq '' ? '..' : '../..';
+
+       my $package_description = "";
+       my $package_summary = "";
+
+       if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.description") {
+               open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.description";
+               $package_description = join ("", <V>);
+               close V;
+               chomp $package_description;
+               $package_description =~ s/\n/\\n/g; 
+               $package_description = "package.description = $package_description\n";
+       } 
+       else { 
+               print STDERR "package.description not found for $subsys.$module!\n"; }
+
+       if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary") {
+               open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary";
+               $package_summary = join ("", <V>);
+               close V;
+               chomp $package_summary;
+               $package_summary =~ s/\n/\\n/g; 
+               $package_summary = "package.summary = $package_summary\n";
+       } 
+       else { 
+               print STDERR "package.summary not found for $subsys.$module!\n"; }
+
+       my %cmd;
+       @cmd{qw/configure compile test install packaging clean/} = ('None') x 6;
+       $cmd{clean} = 'make clean';
+
+       if ($subsys eq 'gridsite') {
+               if ($module eq 'core') {
+                       my $flags = 'RELEASE_VERSION=${age}.${platformFamily} prefix=${prefix} libdir=${libdir} GSOAPDIR=${gsoap.location} OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}/ FLAVOR_GLOBUS_EXT=_${globus.dbg.nothr.flavor} HTTPD_FLAGS="-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-${aprSuffix} -I${httpd-devel.location}/include/pcre"';
+
+                       $cmd{compile} = "make $flags build";
+                       $cmd{install} = "make $flags install";
+                       $cmd{packaging} = "make $flags rpm";
+               }
+               else {
+                       $cmd{packaging} = "echo building nothing, org.gridsite.core make rpm step will create this";
+               }
+       }
+       else {
+               my $flavours = $emi ? "--thrflavour= --nothrflavour=" : "--thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor}";
+               $cmd{configure} = "cd $confdir && /usr/bin/perl \${moduleName}/configure $flavours --prefix=\${prefix} --stage=\${stageDir} --libdir=\${libdir} --module $subsys.$module @copts";
+               $cmd{compile} = 'make';
+               $cmd{test} = 'make check';
+               $cmd{install} = 'make install';
+       }
+
+       my $defprops = '';
+
+       for my $p (keys %{$platform_properties{"$subsys.$module"}->{default}}) {
+               $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
+       }
+
+       my $checkoutcmd;
+       if ($conftag eq 'HEAD') {
+               $checkoutcmd = "cvs -d \${vcsroot} co -A \${moduleName}";
+       } else {
+               $checkoutcmd = "cvs -d \${vcsroot} co -r \${tag} \${moduleName}";
+       }
+
+       print STDERR "Writing $file\n";
+       print C qq{
+[Configuration-$conf]
+profile = None
+moduleName = $cvs_prefix{$subsys}.$subsys.$module
+displayName = $conf
+description = $cvs_prefix{$subsys}.$subsys.$module
+projectName = org.glite
+age = $age
+deploymentType = None
+tag = $conftag
+version = $major.$minor.$rev
+$dwpath
+[Platform-default:VcsCommand]
+displayName = None
+description = None
+tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName}
+branch = None
+commit = None
+checkout = $checkoutcmd
+
+[Platform-default:BuildCommand]
+postpublish = None
+packaging = $cmd{packaging}
+displayName = None
+description = None
+doc = None
+prepublish = None
+publish = None
+compile = $cmd{compile}
+init = None
+install = $cmd{install}
+clean = $cmd{clean}
+test = $cmd{test}
+configure = $cmd{configure}
+checkstyle = None
+
+[Platform-default:Property]
+$buildroot
+aprSuffix = 0
+package.RPMSLocation = \${moduleDir}/RPMTMP/RPMS
+package.SRPMSLocation = \${moduleDir}/RPMTMP/SRPMS
+package.preserve.libtool = false
+$package_description$package_summary$defprops};
+
+       for (@{$obsoletes{"$subsys.$module"}}) {
+               print C "package.obsoletes = $_\n";
+               print C "package.replaces = $_\n";
+       }
+
+       for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
+               next if $pp eq 'default';
+               print C "[Platform-$pp:Property]\n$buildroot\n";
+
+               for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
+                       print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
+               }
+               print C q{package.RPMSLocation = ${moduleDir}/RPMTMP/RPMS
+package.SRPMSLocation = ${moduleDir}/RPMTMP/SRPMS
+};
+               print C "$package_description$package_summary\n";
+       }
+
+       print C qq{
+[Platform-default:DynamicDependency]
+};
+       for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
+               my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
+
+               my $proj = 'externals';
+               for my $p (keys %etics_projects) {
+                       for $m (@{$etics_projects{$p}}) {
+                               $proj = $p if $m eq $_;
+                       }
+               }
+
+               my $type = $need_externs_type{"$subsys.$module"}->{$_};
+               print C "$proj|$eext = $type\n";
+       }
+
+       for (@{$deps{"$subsys.$module"}}) {
+               my $type = $deps_type{"$subsys.$module"}->{$_};
+               print C "org.glite|org.glite.$_ = $type\n";
+       }
+
+       close C;
+}
+
+sub gsoap_version {
+       local $_;
+       my $gsoap_version;
+       open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
+
+       while ($_ = <S>) {
+               chomp;
+
+               $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
+       }
+       close S;
+       return $gsoap_version;
+}
+
+sub getlibdir {
+       if ( -e "/etc/debian_version") { # We are on Debian
+               $lib64="lib";
+               $lib32="lib32"; }
+       else { # Another distribution
+               $lib64="lib64";
+               $lib32="lib";   }
+        $libdir=$lib32;
+
+        open INP, "uname -s | "; # Check kernel name
+        $kname= <INP>;
+        chomp($kname);
+        close INP;
+
+        if ( $kname == "Linux") {
+                $arch = ("x86_64\npowerpc\nppc64\n");
+
+                open INP, "uname -p | "; # Check processor type
+                $procname= <INP>;
+                chomp($procname);
+                close INP;
+
+                if ($arch =~/^$procname\n/) {
+                        return ($lib64); }
+
+                open INP, "uname -m | "; # Check machine hardware
+                $machname= <INP>;
+                chomp($machname);
+                close INP;
+
+                if ($arch =~/^$machname\n/) {
+                        return ($lib64); }
+
+                # special cases (hyperlink lib64, Debian)
+                if (-l "/usr/lib64") {
+                        $libdir=$lib32; }
+
+                # if /usr/lib64 doesn't exist at all (AIX)
+                unless ( -e "/usr/lib64" ) {
+                        $libdir=$lib32; }
+        }
+
+        if ( $kname == "SunOS") {
+                if (-e "/usr/lib/64") {
+                $libdir="lib/64"; }
+        }
+
+        return $libdir;
+}
+
+sub usage {
+       my @ext = keys %externs;
+       my @myjars, keys %jar;
+
+       print STDERR qq{
+usage: $0 options
+
+General options (defaults in []):
+  --prefix=PREFIX              destination directory [./stage]
+  --staged=module,module,...   what is already in PREFIX (specify without org.glite.)
+  --thrflavour=flavour
+  --nothrflavour=flavour       threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
+  --listmodules=subsys          list modules of a subsystem
+  --version=maj.min.rev-age    specify version here instead of reading version.properties
+  --branch=branch              CVS branch/etics name suffix (HEAD, branch_2_1, ...)
+  --libdir=libdir              typically [lib,lib64] postfix
+  --emi                                generate configurations with emi flavor in mode 'etics'
+  
+Mode of operation:
+  --mode={checkout|build|etics}        what to do [build]
+  
+What to build:
+  --module=module              build this module only (mostly in-Etics operation)
+  --enable-NODE                        build this "node" (set of modules) only. Available nodes are
+                                       @{$lbmodules{lb}},@{$lbmodules{security}}
+  --disable-NODE               don't build this node
+  --lb-tag=tag                 checkout LB modules with specific tag
+  --jp-tag=tag                 checkout JP modules with specific tag
+  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
+  --security-tag=tag           checkout security modules with specific tag
+  --jobid-tag=tag              checkout jobid modules with specific tag
+
+Dependencies:
+  --with-EXTERNAL=PATH         where to look for an external. Required externals
+                               (not all for all modules) are:
+                                       @ext
+  --with-JAR=JAR               where to look for jars. Required jars are:
+                                       @myjars
+                               Summary of what will be used is always printed
+
+};
+
+}
diff --git a/org.glite.lbjp-common.gss/interface/glite_gss.h b/org.glite.lbjp-common.gss/interface/glite_gss.h
new file mode 100644 (file)
index 0000000..37f719f
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__
+#define __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__
+
+#ident "$Header$"
+/*
+Copyright (c) Members of the EGEE Collaboration. 2004-2010.
+See http://www.eu-egee.org/partners for details on the copyright holders.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/time.h>
+#include <stdlib.h>
+
+enum {
+  EDG_WLL_GSS_OK               =  0,  /* no GSS errors */
+  EDG_WLL_GSS_ERROR_GSS                = -1,  /* GSS specific error, call edg_wll_get_gss_error() for details */
+  EDG_WLL_GSS_ERROR_TIMEOUT    = -2,  /* Timeout */
+  EDG_WLL_GSS_ERROR_EOF                = -3,  /* EOF occured */
+  EDG_WLL_GSS_ERROR_ERRNO      = -4,  /* System error. See errno */
+  EDG_WLL_GSS_ERROR_HERRNO     = -5   /* Resolver error. See h_errno */
+};
+
+enum {
+  EDG_WLL_GSS_FLAG_DELEG = 1,
+  EDG_WLL_GSS_FLAG_CONF = 16,
+  EDG_WLL_GSS_FLAG_INTEG = 32,
+  EDG_WLL_GSS_FLAG_ANON = 64,
+};
+
+typedef void * edg_wll_GssCtx;
+
+typedef struct _edg_wll_GssConnection {
+  edg_wll_GssCtx context;
+  int sock;
+  char *buffer;
+  size_t bufsize;
+} edg_wll_GssConnection;
+
+typedef struct _edg_wll_GssStatus {
+  unsigned int major_status;
+  unsigned int minor_status;
+} edg_wll_GssStatus;
+
+typedef struct _edg_wll_GssPrincipal_data {
+   char *name;
+   unsigned int flags;
+   char **fqans;
+#if 0
+   char **voms_groups; /* needed for legacy LB server authZ mechanism */
+   edg_wll_GssOid authn_mech;
+#endif
+} edg_wll_GssPrincipal_data;
+typedef struct _edg_wll_GssPrincipal_data *edg_wll_GssPrincipal;
+
+typedef struct _edg_wll_GssCred_data {
+   void *gss_cred;
+   time_t lifetime;
+   char *name;
+} _edg_wll_GssCred_data;
+typedef struct _edg_wll_GssCred_data *edg_wll_GssCred;
+
+int
+edg_wll_gss_initialize(void);
+
+void
+edg_wll_gss_finalize(void);
+
+int
+edg_wll_gss_acquire_cred_gsi(const char *cert_file,
+                            const char *key_file,
+                            edg_wll_GssCred *cred,
+                            edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_release_cred(edg_wll_GssCred *cred,
+                        edg_wll_GssStatus* gss_code);
+
+int 
+edg_wll_gss_connect(edg_wll_GssCred cred,
+                   char const *hostname,
+                   int port,
+                   struct timeval *timeout,
+                   edg_wll_GssConnection *connection,
+                   edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_accept(edg_wll_GssCred cred,
+                  int sock,
+                  struct timeval *timeout,
+                  edg_wll_GssConnection *connection,
+                  edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_read(edg_wll_GssConnection *connection,
+                void *buf,
+                size_t bufsize,
+                struct timeval *timeout,
+                edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_write(edg_wll_GssConnection *connection,
+                 const void *buf,
+                 size_t bufsize,
+                 struct timeval *timeout,
+                 edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_read_full(edg_wll_GssConnection *connection,
+                     void *buf,
+                     size_t bufsize,
+                     struct timeval *timeout,
+                     size_t *total,
+                     edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_write_full(edg_wll_GssConnection *connection,
+                      const void *buf,
+                      size_t bufsize,
+                      struct timeval *timeout,
+                      size_t *total,
+                      edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_watch_creds(const char * proxy_file,
+                       time_t * proxy_mtime);
+
+int
+edg_wll_gss_get_error(edg_wll_GssStatus* gss_code,
+                     const char *prefix,
+                     char **errmsg);
+
+int
+edg_wll_gss_close(edg_wll_GssConnection *connection,
+                 struct timeval *timeout);
+
+int 
+edg_wll_gss_reject(int sock);
+
+int
+edg_wll_gss_get_client_conn(edg_wll_GssConnection *connection,
+                           edg_wll_GssPrincipal *principal,
+                           edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_get_client_pem(edg_wll_GssConnection *connection,
+                          const char *my_cert_file, const char *my_key_file,
+                           char **pem_string);
+
+void
+edg_wll_gss_free_princ(edg_wll_GssPrincipal principal);
+
+int
+edg_wll_gss_gethostname(char *name, int len);
+
+char *
+edg_wll_gss_normalize_subj(char *in, 
+                          int replace_in);
+
+int
+edg_wll_gss_equal_subj(const char *a,
+                      const char *b);
+
+int
+edg_wll_gss_unread(edg_wll_GssConnection *connection,
+                   void *data,
+                   size_t len);
+
+#ifdef __cplusplus
+} 
+#endif
+       
+#endif /* __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ */
diff --git a/org.glite.lbjp-common.gss/project/ChangeLog b/org.glite.lbjp-common.gss/project/ChangeLog
new file mode 100644 (file)
index 0000000..3a73c6b
--- /dev/null
@@ -0,0 +1,47 @@
+2.0.0-1
+- LB 2.0 release 
+
+2.0.0-2
+- proper reference to cppunit
+
+2.0.0-3
+- globus flavors added to configure
+
+2.0.0-4
+- Module repacked.
+
+2.0.0-5
+- New age to fix an erroneous lock
+
+2.0.0-6
+- install libraries into $libdir
+
+2.0.1-1
+- Memleak fixes
+- Working with c-ares >= 1.5.0
+- Added edg_wll_gss_unread()
+- Consider arch libdir when linking c-ares
+
+2.1.0-1
+- IPv6 fixes
+
+2.1.1-1
+- Fixed making target 'check'
+
+2.1.2-1
+- Fixed target 'clean' in the Makefile to handle debian builds
+
+2.1.3-1
+- c-ares function call adjusted to new/old c-ares version
+
+2.1.4-1
+- Support IPv6 literal adresses.
+
+2.1.5-1
+- EMI build (flavor-less globus, pkg-config, ...)
+- fix using globus in thread environment
+- new finalize function
+
+2.1.5-2
+- Module rebuilt
+
diff --git a/org.glite.lbjp-common.gss/project/version.properties b/org.glite.lbjp-common.gss/project/version.properties
new file mode 100644 (file)
index 0000000..2cf185d
--- /dev/null
@@ -0,0 +1,3 @@
+# $Header$
+module.version=2.1.5
+module.age=2
diff --git a/org.glite.lbjp-common.gss/src/glite_gss.c b/org.glite.lbjp-common.gss/src/glite_gss.c
new file mode 100644 (file)
index 0000000..f77c3c3
--- /dev/null
@@ -0,0 +1,1553 @@
+#ident "$Header$"
+/*
+Copyright (c) Members of the EGEE Collaboration. 2004-2010.
+See http://www.eu-egee.org/partners for details on the copyright holders.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <ares.h>
+#include <ares_version.h>
+#include <errno.h>
+
+#include <globus_common.h>
+#include <gssapi.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/stack.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+
+#include "glite_gss.h"
+
+#define tv_sub(a,b) {\
+       (a).tv_usec -= (b).tv_usec;\
+       (a).tv_sec -= (b).tv_sec;\
+       if ((a).tv_usec < 0) {\
+               (a).tv_sec--;\
+               (a).tv_usec += 1000000;\
+       }\
+}
+
+struct asyn_result {
+       struct hostent *ent;
+       int             err;
+};
+
+static int globus_common_activated = 0;
+
+static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after)
+{
+        (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec);
+        (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec);
+        while ( (*timeout).tv_usec < 0) {
+                (*timeout).tv_sec--;
+                (*timeout).tv_usec += 1000000;
+        }
+        if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1);
+        else return(0);
+}
+
+/* ares callback handler for ares_gethostbyname()       */
+#if ARES_VERSION >= 0x010500
+static void callback_ares_gethostbyname(void *arg, int status, int timeouts, struct hostent *h)
+#else
+static void callback_ares_gethostbyname(void *arg, int status, struct hostent *h)
+#endif
+{
+       struct asyn_result *arp = (struct asyn_result *) arg;
+
+       switch (status) {
+          case ARES_SUCCESS:
+               if (h && h->h_addr_list[0]) {
+                       arp->ent->h_addr_list =
+                               (char **) malloc(2 * sizeof(char *));
+                       if (arp->ent->h_addr_list == NULL) {
+                               arp->err = NETDB_INTERNAL;
+                               break;
+                       }
+                       arp->ent->h_addr_list[0] =
+                               malloc(h->h_length);
+                       if (arp->ent->h_addr_list[0] == NULL) {
+                               free(arp->ent->h_addr_list);
+                               arp->err = NETDB_INTERNAL;
+                               break;
+                       }
+                       memcpy(arp->ent->h_addr_list[0], h->h_addr_list[0],
+                               h->h_length);
+                       arp->ent->h_addr_list[1] = NULL;
+                       arp->ent->h_addrtype = h->h_addrtype;
+                       arp->err = NETDB_SUCCESS;
+               } else {
+                       arp->err = NO_DATA;
+               }
+               break;
+           case ARES_EBADNAME:
+           case ARES_ENOTFOUND:
+               arp->err = HOST_NOT_FOUND;
+               break;
+           case ARES_ENOTIMP:
+               arp->err = NO_RECOVERY;
+               break;
+           case ARES_ENOMEM:
+           case ARES_EDESTRUCTION:
+           default:
+               arp->err = NETDB_INTERNAL;
+               break;
+       }
+}
+
+static void free_hostent(struct hostent *h){
+        int i;
+
+        if (h) {
+                if (h->h_name) free(h->h_name);
+               if (h->h_aliases) {
+                       for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]);
+                       free(h->h_aliases);
+               }
+                if (h->h_addr_list) {
+                        for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]);
+                        free(h->h_addr_list);
+                }
+                free(h);
+        }
+}
+
+static int asyn_getservbyname2(int af, struct sockaddr_storage *addrOut, socklen_t *a_len,char const *name, int port, struct timeval *timeout) {
+       struct asyn_result ar;
+       ares_channel channel;
+       int nfds;
+       fd_set readers, writers;
+       struct timeval tv, *tvp;
+       struct timeval start_time,check_time;
+       int     err = NETDB_INTERNAL;
+       char    *name2, *p;
+       size_t  namelen;
+
+       name2 = name;
+       namelen = strlen(name);
+       if (name[0]=='[' && name[namelen-1]==']') {
+               /* IPv6 literal, strip brackets */
+               name2 = strdup(name);
+               if (!name2) return NETDB_INTERNAL;
+               name2[namelen-1] = '\0';
+               name2++;
+               /* Ignore scope identifier, not supported by c-ares */
+               p = strchr(name2, '%'); 
+               if (p) *p = '\0';
+       }       
+
+/* start timer */
+       gettimeofday(&start_time,0);
+
+/* ares init */
+       if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL);
+       ar.ent = (struct hostent *) calloc (sizeof(*ar.ent),1);
+
+/* query DNS server asynchronously */
+       ares_gethostbyname(channel, name2, af, callback_ares_gethostbyname,
+                          (void *) &ar);
+
+/* wait for result */
+       while (1) {
+               FD_ZERO(&readers);
+               FD_ZERO(&writers);
+               nfds = ares_fds(channel, &readers, &writers);
+               if (nfds == 0)
+                       break;
+
+               gettimeofday(&check_time,0);
+               if (timeout && decrement_timeout(timeout, start_time, check_time)) {
+                       ares_destroy(channel);
+                       free_hostent(ar.ent);
+                       return(TRY_AGAIN);
+               }
+               start_time = check_time;
+
+               tvp = ares_timeout(channel, timeout, &tv);
+
+               switch ( select(nfds, &readers, &writers, NULL, tvp) ) {
+                       case -1: if (errno != EINTR) {
+                                       ares_destroy(channel);
+                                       free_hostent(ar.ent);
+                                       return NETDB_INTERNAL;
+                                } else
+                                       continue;
+                       case 0: 
+                               FD_ZERO(&readers);
+                               FD_ZERO(&writers);
+                               /* fallthrough */
+                       default: ares_process(channel, &readers, &writers);
+               }
+       }
+
+       if (ar.err == NETDB_SUCCESS) {
+               struct sockaddr_in *p4 = (struct sockaddr_in *)addrOut;
+               struct sockaddr_in6 *p6 = (struct sockaddr_in6 *)addrOut;
+
+               memset(addrOut, 0, sizeof *addrOut);
+               addrOut->ss_family = ar.ent->h_addrtype;
+               switch (ar.ent->h_addrtype) {
+                       case AF_INET:
+                               memcpy(&p4->sin_addr,ar.ent->h_addr_list[0], sizeof(struct in_addr));
+                               p4->sin_port = htons(port);
+                               *a_len = sizeof (struct sockaddr_in);
+                               break;
+                       case AF_INET6:
+                               memcpy(&p6->sin6_addr,ar.ent->h_addr_list[0], sizeof(struct in6_addr));
+                               p6->sin6_port = htons(port);
+                               *a_len = sizeof (struct sockaddr_in6);
+                               break;
+                       default:
+                               return NETDB_INTERNAL;
+                               break;
+               }
+       }
+       free_hostent(ar.ent); ar.ent = NULL;
+       err = ar.err;
+
+       /* literal conversion should always succeed */
+       if (name2 != name) free(name2-1); 
+
+       ares_destroy(channel);
+
+       return err;
+}
+
+static int asyn_getservbyname(struct sockaddr_storage *addrOut, socklen_t *a_len,char const *name, int port, struct timeval *timeout) {
+       int res;
+
+       res = asyn_getservbyname2(AF_INET6, addrOut, a_len, name, port, timeout);
+       if (res != HOST_NOT_FOUND) return res;
+       res = asyn_getservbyname2(AF_INET, addrOut, a_len, name, port, timeout);
+       return res;
+}
+
+static int
+do_connect(int *s, char const *hostname, int port, struct timeval *timeout)
+{
+   int sock;
+   struct timeval before,after,to;
+   struct sockaddr_storage a;
+   socklen_t a_len;
+   int sock_err;
+   socklen_t err_len;
+   int h_errno;
+   int opt;
+
+   /* XXX todo: try multiple addresses */
+      switch (h_errno = asyn_getservbyname(&a, &a_len, hostname, port, timeout)) {
+               case NETDB_SUCCESS:
+                       break;
+               case TRY_AGAIN:
+                       close(sock);
+                       return EDG_WLL_GSS_ERROR_TIMEOUT;
+               case NETDB_INTERNAL: 
+                       /* fall through */
+               default:
+                       close(sock);
+                       /* h_errno may be thread safe with Linux pthread libs,
+                        * but such an assumption is not portable
+                        */
+                       errno = h_errno;
+                       return EDG_WLL_GSS_ERROR_HERRNO;
+      }
+
+   sock = socket(a.ss_family, SOCK_STREAM, 0);
+   if (sock < 0) return EDG_WLL_GSS_ERROR_ERRNO;
+
+   opt = 1;
+   setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,&opt,sizeof opt);
+
+   if (timeout) {
+            int        flags = fcntl(sock, F_GETFL, 0);
+            if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0)
+                    return EDG_WLL_GSS_ERROR_ERRNO;
+            gettimeofday(&before,NULL);
+   }
+   
+   if (connect(sock,(struct sockaddr *) &a, a_len) < 0) {
+            if (timeout && errno == EINPROGRESS) {
+                    fd_set     fds;
+                    FD_ZERO(&fds);
+                    FD_SET(sock,&fds);
+                    memcpy(&to,timeout,sizeof to);
+                    gettimeofday(&before,NULL);
+                    switch (select(sock+1,NULL,&fds,NULL,&to)) {
+                            case -1: close(sock);
+                                     return EDG_WLL_GSS_ERROR_ERRNO;
+                            case 0: close(sock);
+                                    return EDG_WLL_GSS_ERROR_TIMEOUT;
+                    }
+                    gettimeofday(&after,NULL);
+                    tv_sub(after,before);
+                    tv_sub(*timeout,after);
+
+                    err_len = sizeof sock_err;
+                    if (getsockopt(sock,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) {
+                            close(sock);
+                            return EDG_WLL_GSS_ERROR_ERRNO;
+                    }
+                    if (sock_err) {
+                            close(sock);
+                            errno = sock_err;
+                            return EDG_WLL_GSS_ERROR_ERRNO;
+                    }
+            }
+            else {
+                    close(sock);
+                    return EDG_WLL_GSS_ERROR_ERRNO;
+            }
+   }
+
+   *s = sock;
+   return 0;
+}
+
+static int
+send_token(int sock, void *token, size_t token_length, struct timeval *to)
+{
+   size_t num_written = 0;
+   ssize_t count;
+   fd_set fds;
+   struct timeval timeout,before,after;
+   int ret;
+
+   if (to) {
+       memcpy(&timeout,to,sizeof(timeout));
+       gettimeofday(&before,NULL);
+   }
+
+
+   ret = 0;
+   while(num_written < token_length) {
+      FD_ZERO(&fds);
+      FD_SET(sock,&fds);
+      switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) {
+        case 0: ret = EDG_WLL_GSS_ERROR_TIMEOUT;
+                goto end;
+                break;
+        case -1: ret = EDG_WLL_GSS_ERROR_ERRNO;
+                 goto end;
+                 break;
+      }
+
+      count = write(sock, ((char *)token) + num_written,
+                   token_length - num_written);
+      if(count < 0) {
+        if(errno == EINTR)
+           continue;
+        else {
+           ret = EDG_WLL_GSS_ERROR_ERRNO;
+           goto end;
+        }
+      }
+      num_written += count;
+   }
+
+end:
+   if (to) {
+      gettimeofday(&after,NULL);
+      tv_sub(after,before);
+      tv_sub(*to,after);
+      if (to->tv_sec < 0) {
+        to->tv_sec = 0;
+        to->tv_usec = 0;
+      }
+   }
+
+   return ret;
+}
+
+static int
+recv_token(int sock, void **token, size_t *token_length, struct timeval *to)
+{
+   ssize_t count;
+   char buf[4098];
+   char *t = NULL;
+   char *tmp;
+   size_t tl = 0;
+   fd_set fds;
+   struct timeval timeout,before,after;
+   int ret;
+
+   if (to) {
+      memcpy(&timeout,to,sizeof(timeout));
+      gettimeofday(&before,NULL);
+   }
+
+   ret = 0;
+   do {
+      FD_ZERO(&fds);
+      FD_SET(sock,&fds);
+      switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) {
+        case 0: 
+           ret = EDG_WLL_GSS_ERROR_TIMEOUT;
+           goto end;
+           break;
+        case -1:
+           ret = EDG_WLL_GSS_ERROR_ERRNO;
+           goto end;
+           break;
+      }
+      
+      count = read(sock, buf, sizeof(buf));
+      if (count < 0) {
+        if (errno == EINTR)
+           continue;
+        else {
+           ret = EDG_WLL_GSS_ERROR_ERRNO;
+           goto end;
+        }
+      }
+
+      if (count==0) {
+         if (tl==0) {
+            free(t);
+            return EDG_WLL_GSS_ERROR_EOF;
+         } else goto end;
+      }
+      tmp=realloc(t, tl + count);
+      if (tmp == NULL) {
+       errno = ENOMEM;
+       free(t);
+       return EDG_WLL_GSS_ERROR_ERRNO;
+      }
+      t = tmp;
+      memcpy(t + tl, buf, count);
+      tl += count;
+
+   } while (count < 0); /* restart on EINTR */
+
+end:
+   if (to) {
+      gettimeofday(&after,NULL);
+      tv_sub(after,before);
+      tv_sub(*to,after);
+      if (to->tv_sec < 0) {
+        to->tv_sec = 0;
+        to->tv_usec = 0;
+      }
+   }
+
+   if (ret == 0) {
+      *token = t;
+      *token_length = tl;
+   } else
+      free(t);
+
+   return ret;
+}
+
+static int
+create_proxy(const char *cert_file, const char *key_file, char **proxy_file)
+{
+   char buf[4096];
+   int in, out;
+   char *name = NULL;
+   int ret, len;
+
+   *proxy_file = NULL;
+
+   asprintf(&name, "%s/%d.lb.XXXXXX", P_tmpdir, getpid());
+
+   out = mkstemp(name);
+   if (out < 0)
+      return EDG_WLL_GSS_ERROR_ERRNO;
+
+   in = open(cert_file, O_RDONLY);
+   if (in < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+   while ((ret = read(in, buf, sizeof(buf))) > 0) {
+      len = write(out, buf, ret);
+      if (len != ret) {
+        ret = -1;
+        break;
+      }
+   }
+   close(in);
+   if (ret < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   len = write(out, "\n", 1);
+   if (len != 1) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   in = open(key_file, O_RDONLY);
+   if (in < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+   while ((ret = read(in, buf, sizeof(buf))) > 0) {
+      len = write(out, buf, ret);
+      if (len != ret) {
+        ret = -1;
+        break;
+      }
+   }
+   close(in);
+   if (ret < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   ret = 0;
+   *proxy_file = name;
+
+end:
+   close(out);
+   if (ret) {
+      unlink(name);
+      free(name);
+   }
+
+   return ret;
+}
+
+static int
+destroy_proxy(char *proxy_file)
+{
+   /* XXX we should erase the contents safely (i.e. overwrite with 0's) */
+   unlink(proxy_file);
+   return 0;
+}
+
+int
+edg_wll_gss_acquire_cred_gsi(const char *cert_file, const char *key_file, edg_wll_GssCred *cred,
+                            edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 major_status = 0, minor_status, minor_status2;
+   gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
+   gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+   gss_name_t gss_name = GSS_C_NO_NAME;
+   OM_uint32 lifetime;
+   char *proxy_file = NULL;
+   char *name = NULL;
+   int ret;
+
+   if ((cert_file == NULL && key_file != NULL) ||
+       (cert_file != NULL && key_file == NULL))
+      return EINVAL;
+
+   if (cert_file == NULL) {
+      major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0,
+                                     GSS_C_NO_OID_SET, GSS_C_BOTH,
+                                     &gss_cred, NULL, NULL);
+      if (GSS_ERROR(major_status)) {
+        ret = EDG_WLL_GSS_ERROR_GSS;
+        goto end;
+      }
+   } else {
+      proxy_file = (char *)cert_file;
+      if (strcmp(cert_file, key_file) != 0 &&
+         (ret = create_proxy(cert_file, key_file, &proxy_file))) {
+        proxy_file = NULL;
+        goto end;
+      }
+      
+      asprintf((char**)&buffer.value, "X509_USER_PROXY=%s", proxy_file);
+      if (buffer.value == NULL) {
+        errno = ENOMEM;
+        ret = EDG_WLL_GSS_ERROR_ERRNO;
+        goto end;
+      }
+      buffer.length = strlen(proxy_file);
+
+      major_status = gss_import_cred(&minor_status, &gss_cred, GSS_C_NO_OID, 1,
+                                    &buffer, 0, NULL);
+      free(buffer.value);
+      if (GSS_ERROR(major_status)) {
+        ret = EDG_WLL_GSS_ERROR_GSS;
+        goto end;
+      }
+   }
+
+  /* gss_import_cred() doesn't check validity of credential loaded, so let's
+    * verify it now */
+    major_status = gss_inquire_cred(&minor_status, gss_cred, &gss_name,
+                                   &lifetime, NULL, NULL);
+    if (GSS_ERROR(major_status)) {
+       ret = EDG_WLL_GSS_ERROR_GSS;
+       goto end;
+    }
+
+    /* Must cast to time_t since OM_uint32 is unsinged and hence we couldn't
+     * detect negative values. */
+    if ((time_t) lifetime <= 0) {
+       major_status = GSS_S_CREDENTIALS_EXPIRED;
+       minor_status = 0; /* XXX */
+       ret = EDG_WLL_GSS_ERROR_GSS;
+       goto end;
+    }
+
+   major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL);
+   if (GSS_ERROR(major_status)) {
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+   name = buffer.value;
+   memset(&buffer, 0, sizeof(buffer));
+    
+   *cred = calloc(1, sizeof(**cred));
+   if (*cred == NULL) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      free(name);
+      goto end;
+   }
+
+   (*cred)->gss_cred = gss_cred;
+   gss_cred = GSS_C_NO_CREDENTIAL;
+   (*cred)->lifetime = lifetime;
+   (*cred)->name = name;
+
+   ret = 0;
+
+end:
+   if (cert_file && key_file && proxy_file && strcmp(cert_file, key_file) != 0) {
+      destroy_proxy(proxy_file);
+      free(proxy_file);
+   }
+
+   if (gss_name != GSS_C_NO_NAME)
+      gss_release_name(&minor_status2, &gss_name);
+
+   if (gss_cred != GSS_C_NO_CREDENTIAL)
+      gss_release_cred(&minor_status2, &gss_cred);
+
+   if (GSS_ERROR(major_status)) {
+      if (gss_code) {
+        gss_code->major_status = major_status;
+        gss_code->minor_status = minor_status;
+      }
+      ret = EDG_WLL_GSS_ERROR_GSS;
+   }
+
+   return ret;
+}
+
+/* XXX XXX This is black magic. "Sometimes" server refuses the client with SSL
+ *  * alert "certificate expired" even if it is not true. In this case the server
+ *   * slave terminates (which helps, usually), and we can reconnect transparently.
+ *    */
+
+/* This string appears in the error message in this case */
+#define _EXPIRED_ALERT_MESSAGE "function SSL3_READ_BYTES: sslv3 alert certificate expired"
+#define _EXPIRED_ALERT_RETRY_COUNT 10   /* default number of slaves, hope that not all
+                                                                                     are in the bad state */
+#define _EXPIRED_ALERT_RETRY_DELAY 10   /* ms */
+
+/* XXX XXX This is black magic. "Sometimes" server refuses the client with SSL
+ *  * alert "certificate expired" even if it is not true. In this case the server
+ *   * slave terminates (which helps, usually), and we can reconnect transparently.
+ *    */
+
+/* This string appears in the error message in this case */
+#define _EXPIRED_ALERT_MESSAGE "function SSL3_READ_BYTES: sslv3 alert certificate expired"
+#define _EXPIRED_ALERT_RETRY_COUNT 10   /* default number of slaves, hope that not all
+                                                                                     are in the bad state */
+#define _EXPIRED_ALERT_RETRY_DELAY 10   /* ms */
+
+int 
+edg_wll_gss_connect(edg_wll_GssCred cred, char const *hostname, int port,
+                   struct timeval *timeout, edg_wll_GssConnection *connection,
+                   edg_wll_GssStatus* gss_code)
+{
+   int sock, ret;
+   OM_uint32 maj_stat, min_stat, min_stat2, req_flags;
+   int context_established = 0;
+   gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+   gss_name_t server = GSS_C_NO_NAME;
+   gss_ctx_id_t context = GSS_C_NO_CONTEXT;
+   char *servername = NULL;
+   int retry = _EXPIRED_ALERT_RETRY_COUNT;
+
+   maj_stat = min_stat = min_stat2 = req_flags = 0;
+   memset(connection, 0, sizeof(*connection));
+
+   /* GSI specific */
+   req_flags = GSS_C_GLOBUS_SSL_COMPATIBLE;
+
+   ret = do_connect(&sock, hostname, port, timeout);
+   if (ret)
+      return ret;
+
+   /* XXX find appropriate fqdn */
+   asprintf (&servername, "host@%s", hostname);
+   if (servername == NULL) {
+      errno = ENOMEM;
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+   input_token.value = servername;
+   input_token.length = strlen(servername) + 1;
+
+   maj_stat = gss_import_name(&min_stat, &input_token,
+                             GSS_C_NT_HOSTBASED_SERVICE, &server);
+   if (GSS_ERROR(maj_stat)) {
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+
+   free(servername);
+   memset(&input_token, 0, sizeof(input_token));
+
+   /* XXX if cred == GSS_C_NO_CREDENTIAL set the ANONYMOUS flag */
+
+   do { /* XXX: the black magic above */
+
+   /* XXX prepsat na do {} while (maj_stat == CONT) a osetrit chyby*/
+   while (!context_established) {
+      /* XXX verify ret_flags match what was requested */
+      maj_stat = gss_init_sec_context(&min_stat, cred->gss_cred, &context,
+                                     GSS_C_NO_NAME, GSS_C_NO_OID,
+                                     req_flags | GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG,
+                                     0, GSS_C_NO_CHANNEL_BINDINGS,
+                                     &input_token, NULL, &output_token,
+                                     NULL, NULL);
+      if (input_token.length > 0) {
+        free(input_token.value);
+        input_token.length = 0;
+      }
+
+      if (output_token.length != 0) {
+        ret = send_token(sock, output_token.value, output_token.length, timeout);
+        gss_release_buffer(&min_stat2, &output_token);
+        if (ret)
+           goto end;
+      }
+
+      if (GSS_ERROR(maj_stat)) {
+        if (context != GSS_C_NO_CONTEXT) {
+           gss_delete_sec_context(&min_stat2, &context, &output_token);
+           context = GSS_C_NO_CONTEXT;
+           if (output_token.length) {
+               send_token(sock, output_token.value, output_token.length, timeout);
+               gss_release_buffer(&min_stat2, &output_token);
+           }
+        }
+        ret = EDG_WLL_GSS_ERROR_GSS;
+        goto end;
+      }
+
+      if(maj_stat & GSS_S_CONTINUE_NEEDED) {
+        ret = recv_token(sock, &input_token.value, &input_token.length, timeout);
+        if (ret)
+           goto end;
+      } else
+        context_established = 1;
+   }
+
+   /* XXX check ret_flags matches to what was requested */
+
+   /* retry on false "certificate expired" */
+   if (ret == EDG_WLL_GSS_ERROR_GSS) {
+          edg_wll_GssStatus    gss_stat;
+          char *msg = NULL;
+
+          gss_stat.major_status = maj_stat;
+          gss_stat.minor_status = min_stat;
+          edg_wll_gss_get_error(&gss_stat,"",&msg);
+
+          if (strstr(msg,_EXPIRED_ALERT_MESSAGE)) {
+                  usleep(_EXPIRED_ALERT_RETRY_DELAY);
+                  retry--;
+          }
+          else retry = 0;
+
+          free(msg);
+   }
+   else retry = 0;
+
+   } while (retry);
+
+   connection->sock = sock;
+   connection->context = context;
+   servername = NULL;
+   ret = 0;
+
+end:
+   if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) {
+      gss_code->major_status = maj_stat;
+      gss_code->minor_status = min_stat;
+   }
+   if (server != GSS_C_NO_NAME)
+      gss_release_name(&min_stat2, &server);
+   if (servername == NULL)
+      free(servername);
+   if (ret)
+      close(sock);
+
+   return ret;
+}
+
+int
+edg_wll_gss_accept(edg_wll_GssCred cred, int sock, struct timeval *timeout,
+                  edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 maj_stat, min_stat, min_stat2;
+   OM_uint32 ret_flags = 0;
+   gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+   gss_name_t client_name = GSS_C_NO_NAME;
+   gss_ctx_id_t context = GSS_C_NO_CONTEXT;
+   int ret;
+
+   maj_stat = min_stat = min_stat2 = 0;
+   memset(connection, 0, sizeof(*connection));
+
+   if (cred == NULL)
+       return EINVAL;
+
+   /* GSI specific */
+   ret_flags = GSS_C_GLOBUS_SSL_COMPATIBLE;
+
+   do {
+      ret = recv_token(sock, &input_token.value, &input_token.length, timeout);
+      if (ret)
+        goto end;
+
+      if (client_name != GSS_C_NO_NAME)
+        gss_release_name(&min_stat2, &client_name);
+
+      maj_stat = gss_accept_sec_context(&min_stat, &context,
+                                       cred->gss_cred, &input_token,
+                                       GSS_C_NO_CHANNEL_BINDINGS,
+                                       &client_name, NULL, &output_token,
+                                       &ret_flags, NULL, NULL);
+      if (input_token.length > 0) {
+        free(input_token.value);
+        input_token.length = 0;
+      }
+
+      if (output_token.length) {
+        ret = send_token(sock, output_token.value, output_token.length, timeout);
+        gss_release_buffer(&min_stat2, &output_token);
+        if (ret)
+           goto end;
+      }
+   } while(maj_stat & GSS_S_CONTINUE_NEEDED);
+
+   if (GSS_ERROR(maj_stat)) {
+      if (context != GSS_C_NO_CONTEXT) {
+        gss_delete_sec_context(&min_stat2, &context, &output_token);
+        context = GSS_C_NO_CONTEXT;
+        if (output_token.length) {
+               send_token(sock, output_token.value, output_token.length, timeout);
+               gss_release_buffer(&min_stat2, &output_token);
+        }
+      }
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+
+#if 0
+   maj_stat = gss_display_name(&min_stat, client_name, &output_token, NULL);
+   gss_release_buffer(&min_stat2, &output_token);
+   if (GSS_ERROR(maj_stat)) {
+      /* XXX close context ??? */
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+#endif
+
+   connection->sock = sock;
+   connection->context = context;
+   ret = 0;
+
+end:
+   if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) {
+      gss_code->major_status = maj_stat;
+      gss_code->minor_status = min_stat;
+   }
+   if (client_name != GSS_C_NO_NAME)
+      gss_release_name(&min_stat2, &client_name);
+
+   return ret;
+}
+
+int
+edg_wll_gss_write(edg_wll_GssConnection *connection, const void *buf, size_t bufsize,
+                 struct timeval *timeout, edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 maj_stat, min_stat;
+   gss_buffer_desc  input_token;
+   gss_buffer_desc  output_token;
+   int  ret;
+
+   input_token.value = (void*)buf;
+   input_token.length = bufsize;
+
+   maj_stat = gss_wrap (&min_stat, connection->context, 1, GSS_C_QOP_DEFAULT,
+                       &input_token, NULL, &output_token);
+   if (GSS_ERROR(maj_stat)) {
+      if (gss_code) {
+        gss_code->minor_status = min_stat;
+        gss_code->major_status = maj_stat;
+      }
+
+      return EDG_WLL_GSS_ERROR_GSS;
+   }
+
+   ret = send_token(connection->sock, output_token.value, output_token.length,
+                   timeout);
+   gss_release_buffer(&min_stat, &output_token);
+
+   return ret;
+}
+
+
+int
+edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize,
+                struct timeval *timeout, edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 maj_stat, min_stat, min_stat2;
+   gss_buffer_desc input_token;
+   gss_buffer_desc output_token;
+   size_t i, len;
+   int ret;
+
+   if (connection->bufsize > 0) {
+      len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
+      memcpy(buf, connection->buffer, len);
+      if (connection->bufsize - len == 0) {
+        free(connection->buffer);
+        connection->buffer = NULL;
+      } else {
+        for (i = 0; i < connection->bufsize - len; i++)
+           connection->buffer[i] = connection->buffer[i+len];
+      }
+      connection->bufsize -= len;
+
+      return len;
+   }
+
+   do {
+      ret = recv_token(connection->sock, &input_token.value, &input_token.length,
+                      timeout);
+      if (ret)
+        return ret;
+
+      ERR_clear_error();
+      maj_stat = gss_unwrap(&min_stat, connection->context, &input_token,
+                           &output_token, NULL, NULL);
+      gss_release_buffer(&min_stat2, &input_token);
+      if (GSS_ERROR(maj_stat)) {
+        if (gss_code) {
+           gss_code->minor_status = min_stat;
+           gss_code->major_status = maj_stat;
+         }
+        return EDG_WLL_GSS_ERROR_GSS;
+      }
+   } while (maj_stat == 0 && output_token.length == 0 && output_token.value == NULL);
+
+   if (output_token.length > bufsize) {
+      connection->bufsize = output_token.length - bufsize;
+      connection->buffer = malloc(connection->bufsize);
+      if (connection->buffer == NULL) {
+        connection->bufsize = 0;
+        ret = EDG_WLL_GSS_ERROR_ERRNO;
+        goto end;
+      }
+      memcpy(connection->buffer, output_token.value + bufsize, connection->bufsize);
+      output_token.length = bufsize;
+   }
+
+   memcpy(buf, output_token.value, output_token.length);
+   ret = output_token.length;
+
+end:
+   gss_release_buffer(&min_stat, &output_token);
+
+   return ret;
+}
+
+int
+edg_wll_gss_read_full(edg_wll_GssConnection *connection, void *buf, 
+                             size_t bufsize, struct timeval *timeout, size_t *total,
+                     edg_wll_GssStatus* gss_code)
+{
+   size_t      len, i;
+   *total = 0;
+
+   if (connection->bufsize > 0) {
+      len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
+      memcpy(buf, connection->buffer, len);
+      if (connection->bufsize - len == 0) {
+        free(connection->buffer);
+        connection->buffer = NULL;
+      } else {
+         for (i = 0; i < connection->bufsize - len; i++)
+            connection->buffer[i] = connection->buffer[i+len];
+      }
+      connection->bufsize -= len;
+      *total = len;
+   }
+
+   while (*total < bufsize) {
+      int len;
+
+      len = edg_wll_gss_read(connection, buf+*total, bufsize-*total,
+                            timeout, gss_code);
+      if (len < 0) return len;
+      *total += len;
+   }
+
+   return 0;
+}
+
+int
+edg_wll_gss_write_full(edg_wll_GssConnection *connection, const void *buf,
+                       size_t bufsize, struct timeval *timeout, size_t *total,
+                      edg_wll_GssStatus* gss_code)
+{
+   return edg_wll_gss_write(connection, buf, bufsize, timeout, gss_code);
+}
+
+/* Request credential reload each 60 seconds in order to work around
+ * Globus bug (not reloading expired CRLs)
+ */
+#define GSS_CRED_WATCH_LIMIT  60
+int
+edg_wll_gss_watch_creds(const char *proxy_file, time_t *last_time)
+{
+      struct stat     pstat;
+      time_t  now;
+
+      now = time(NULL);
+
+      if ( now >= (*last_time+GSS_CRED_WATCH_LIMIT) ) {
+              *last_time = now;
+              return 1;
+      }
+
+      if (!proxy_file) return 0;
+      if (stat(proxy_file,&pstat)) return -1;
+
+      if ( pstat.st_mtime >= *last_time ) {
+              *last_time = now + 1;
+              return 1;
+      }
+
+      return 0;
+}
+
+int
+edg_wll_gss_close(edg_wll_GssConnection *con, struct timeval *timeout)
+{
+   OM_uint32 min_stat;
+   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+   struct timeval def_timeout = { 0, 100000};
+
+   if (con->context != GSS_C_NO_CONTEXT) {
+      gss_delete_sec_context(&min_stat, (gss_ctx_id_t *)&con->context, &output_token);
+
+#if 0
+      /* XXX: commented out till timeout handling in caller is fixed */
+
+      /* send the buffer (if any) to the peer. GSSAPI specs doesn't
+       * recommend sending it, but we want SSL compatibility */
+      if (output_token.length && con->sock>=0) {
+              send_token(con->sock, output_token.value, output_token.length,
+                              timeout ? timeout : &def_timeout);
+      }
+#endif
+      gss_release_buffer(&min_stat, &output_token);
+
+      /* XXX can socket be open even if context == GSS_C_NO_CONTEXT) ? */
+      /* XXX ensure that edg_wll_GssConnection is created with sock set to -1 */
+      if (con->sock >= 0)
+        close(con->sock);
+   }
+   if (con->buffer)
+      free(con->buffer);
+   memset(con, 0, sizeof(*con));
+   con->context = GSS_C_NO_CONTEXT;
+   con->sock = -1;
+   return 0;
+}
+
+int
+edg_wll_gss_get_error(edg_wll_GssStatus *gss_err, const char *prefix, char **msg)
+{
+   OM_uint32 maj_stat, min_stat;
+   OM_uint32 msg_ctx = 0;
+   gss_buffer_desc maj_status_string = GSS_C_EMPTY_BUFFER;
+   gss_buffer_desc min_status_string = GSS_C_EMPTY_BUFFER;
+   char *str = NULL;
+   char *line, *tmp;
+
+   str = strdup(prefix);
+   do {
+      maj_stat = gss_display_status(&min_stat, gss_err->major_status,
+                                   GSS_C_GSS_CODE, GSS_C_NO_OID,
+                                   &msg_ctx, &maj_status_string);
+      if (GSS_ERROR(maj_stat))
+        break;
+      maj_stat = gss_display_status(&min_stat, gss_err->minor_status,
+                                   GSS_C_MECH_CODE, GSS_C_NULL_OID,
+                                   &msg_ctx, &min_status_string);
+      if (GSS_ERROR(maj_stat)) {
+        gss_release_buffer(&min_stat, &maj_status_string);
+        break;
+      }
+
+      asprintf(&line, ": %s (%s)", (char *)maj_status_string.value,
+              (char *)min_status_string.value);
+      gss_release_buffer(&min_stat, &maj_status_string);
+      gss_release_buffer(&min_stat, &min_status_string);
+
+      tmp = realloc(str, strlen(str) + strlen(line) + 1);
+      if (tmp == NULL) {
+         /* abort() ? */
+        free(line);
+        free(str);
+        str = "WARNING: Not enough memory to produce error message";
+        break;
+      }
+      str = tmp;
+      strcat(str, line);
+      free(line);
+   } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+   *msg = str;
+   return 0;
+}
+
+int
+edg_wll_gss_oid_equal(const gss_OID a, const gss_OID b)
+{
+   if (a == b)
+      return 1;
+   else {
+      if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
+        return 0;
+      else
+        return (memcmp(a->elements, b->elements, a->length) == 0);
+   }
+}
+
+int 
+edg_wll_gss_reject(int sock)
+{
+   /* XXX is it possible to cut & paste edg_wll_ssl_reject() ? */
+   return 0;
+}
+
+
+int
+edg_wll_gss_initialize(void)
+{
+   int ret = 0;
+
+   if (globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE) != GLOBUS_SUCCESS) {
+      errno = EINVAL;
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+   }
+
+   if (globus_module_activate(GLOBUS_COMMON_MODULE) == GLOBUS_SUCCESS)
+       globus_common_activated = 1;
+
+   return ret;
+}
+
+
+void
+edg_wll_gss_finalize(void)
+{
+   globus_module_deactivate(GLOBUS_GSI_GSSAPI_MODULE);
+   if (globus_common_activated) {
+      globus_module_deactivate(GLOBUS_COMMON_MODULE);
+      globus_common_activated = 0;
+   }
+}
+
+
+int
+edg_wll_gss_release_cred(edg_wll_GssCred *cred, edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 maj_stat, min_stat;
+   int ret = 0;
+
+   if (gss_code)
+      gss_code->major_status = gss_code->minor_status = 0;
+
+   if (cred == NULL || *cred == NULL)
+      return ret;
+
+   if ((*cred)->gss_cred) {
+      maj_stat = gss_release_cred(&min_stat, (gss_cred_id_t*)&(*cred)->gss_cred); 
+      if (GSS_ERROR(maj_stat)) {
+         ret = EDG_WLL_GSS_ERROR_GSS;
+         if (gss_code) {
+            gss_code->major_status = maj_stat;
+            gss_code->minor_status = min_stat;
+         }
+      }
+   }
+
+   if ((*cred)->name)
+      free((*cred)->name);
+
+   free(*cred);
+   *cred = NULL;
+
+   return ret;
+}
+
+int
+edg_wll_gss_get_client_conn(edg_wll_GssConnection *connection,
+                            edg_wll_GssPrincipal *principal,
+                           edg_wll_GssStatus* gss_code)
+{
+   gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
+   OM_uint32 maj_stat, min_stat, ctx_flags;
+   gss_name_t client_name = GSS_C_NO_NAME;
+   edg_wll_GssPrincipal p;
+   int ret;
+
+   maj_stat = gss_inquire_context(&min_stat, connection->context, &client_name,
+                                  NULL, NULL, NULL, &ctx_flags, NULL, NULL);
+   if (GSS_ERROR(maj_stat))
+      goto end;
+
+   maj_stat = gss_display_name(&min_stat, client_name, &token, NULL);
+   if (GSS_ERROR(maj_stat))
+      goto end;
+
+   p = calloc(1, sizeof(*p));
+   if (p == NULL) {
+      errno = ENOMEM;
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   p->name = strdup(token.value);
+   p->flags = ctx_flags;
+
+   *principal = p;
+   ret = 0;
+
+end:
+   if (GSS_ERROR(maj_stat)) {
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      if (gss_code) {
+         gss_code->major_status = maj_stat;
+         gss_code->minor_status = min_stat;
+      }
+   }
+       
+   if (token.length)
+      gss_release_buffer(&min_stat, &token);
+   if (client_name != GSS_C_NO_NAME)
+      gss_release_name(&min_stat, &client_name);
+
+   return ret;
+}
+
+/* Beware, this call manipulates with environment variables and is not
+   thread-safe */
+static int
+get_peer_cred(edg_wll_GssConnection *gss, const char *my_cert_file,
+              const char *my_key_file, STACK_OF(X509) **chain,
+              edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 maj_stat, min_stat;
+   gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+   BIO *bio = NULL;
+   SSL_SESSION *session = NULL;
+   unsigned char int_buffer[4];
+   long length;
+   int ret, index;
+   STACK_OF(X509) *cert_chain = NULL;
+   X509 *p_cert;
+   char *orig_cert = NULL, *orig_key = NULL;
+
+   maj_stat = gss_export_sec_context(&min_stat, (gss_ctx_id_t *) &gss->context,
+                                    &buffer);
+   if (GSS_ERROR(maj_stat)) {
+      if (gss_code) {
+         gss_code->major_status = maj_stat;
+         gss_code->minor_status = min_stat;
+      }
+      return EDG_WLL_GSS_ERROR_GSS;
+   }
+
+   /* The GSSAPI specs requires gss_export_sec_context() to destroy the
+    * context after exporting. So we have to resurrect the context here by
+    * importing from just generated buffer. gss_import_sec_context() must be
+    * able to read valid credential before it loads the exported context
+    * so we set the environment temporarily to point to the ones used by
+    * the server.
+    * */
+
+   orig_cert = getenv("X509_USER_CERT");
+   orig_key = getenv("X509_USER_KEY");
+
+   if (my_cert_file)
+      setenv("X509_USER_CERT", my_cert_file, 1);
+   if (my_key_file)
+      setenv("X509_USER_KEY", my_key_file, 1);
+   
+   maj_stat = gss_import_sec_context(&min_stat, &buffer,
+                                    (gss_ctx_id_t *)&gss->context);
+
+   if (orig_cert)
+       setenv("X509_USER_CERT", orig_cert, 1);
+   else
+       unsetenv("X509_USER_CERT");
+
+   if (orig_key) 
+       setenv("X509_USER_KEY", orig_key, 1);
+   else 
+       unsetenv("X509_USER_KEY");
+
+   if (GSS_ERROR(maj_stat)) {
+      if (gss_code) {
+         gss_code->major_status = maj_stat;
+         gss_code->minor_status = min_stat;
+      }
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+
+   bio = BIO_new(BIO_s_mem());
+   if (bio == NULL) {
+      ret = ENOMEM;
+      goto end;
+   }
+   
+   /* Store exported context to memory, skipping the version number and and cred_usage fields */
+   BIO_write(bio, buffer.value + 8 , buffer.length - 8);
+
+   /* decode the session data in order to skip at the start of the cert chain */
+   session = d2i_SSL_SESSION_bio(bio, NULL);
+   if (session == NULL) {
+      ret = EINVAL;
+      goto end;
+   }
+   SSL_SESSION_free(session);
+
+   cert_chain = sk_X509_new_null();
+
+   BIO_read(bio, (char *) int_buffer, 4);
+   length  = (((size_t) int_buffer[0]) << 24) & 0xffff;
+   length |= (((size_t) int_buffer[1]) << 16) & 0xffff;
+   length |= (((size_t) int_buffer[2]) <<  8) & 0xffff;
+   length |= (((size_t) int_buffer[3])      ) & 0xffff;
+
+   if (length == 0) {
+      ret = EINVAL;
+      goto end;
+   }
+
+   for(index = 0; index < length; index++) {
+      p_cert = d2i_X509_bio(bio, NULL);
+      if (p_cert == NULL) {
+        ret = EINVAL;
+        sk_X509_pop_free(cert_chain, X509_free);
+        goto end;
+      }
+
+      sk_X509_push(cert_chain, p_cert);
+   }
+
+   *chain = cert_chain;
+   ret = 0;
+
+end:
+   gss_release_buffer(&min_stat, &buffer);
+
+   return ret;
+}
+
+int
+edg_wll_gss_get_client_pem(edg_wll_GssConnection *connection,
+                           const char *my_cert_file, const char *my_key_file,
+                           char **pem_string)
+{
+   char *tmp = NULL;
+   STACK_OF(X509) *chain = NULL;
+   BIO *bio = NULL;
+   int ret, i;
+   size_t total_len, l;
+
+   ret = get_peer_cred(connection, my_cert_file, my_key_file, &chain, NULL);
+   if (ret)
+      return ret;
+
+   bio = BIO_new(BIO_s_mem());
+   if (bio == NULL) {
+      ret = ENOMEM;
+      goto end;
+   }
+
+   for (i = 0; i < sk_X509_num(chain); i++) {
+      ret = PEM_write_bio_X509(bio, sk_X509_value(chain, i));
+      if (ret <= 0) {
+        ret = EINVAL;
+        goto end;
+      }
+   }
+
+   total_len = BIO_pending(bio);
+   if (total_len <= 0) {
+      ret = EINVAL;
+      goto end;
+   }
+
+   tmp = malloc(total_len + 1);
+   if (tmp == NULL) {
+      ret = ENOMEM;
+      goto end;
+   }
+
+   l = 0;
+   while (l < total_len) {
+      ret = BIO_read(bio, tmp+l, total_len-l);
+      if (ret <= 0) {
+        ret = EINVAL;
+        goto end;
+      }
+      l += ret;
+   }
+
+   tmp[total_len] = '\0';
+   *pem_string = tmp;
+   tmp = NULL;
+
+   ret = 0;
+
+end:
+   sk_X509_pop_free(chain, X509_free);
+   if (bio)
+      BIO_free(bio);
+   if (tmp)
+      free(tmp);
+
+   return ret;
+}
+
+void
+edg_wll_gss_free_princ(edg_wll_GssPrincipal principal)
+{
+   if (principal == NULL)
+      return;
+
+   if (principal->name)
+      free(principal->name);
+
+   free(principal);
+}
+
+int
+edg_wll_gss_gethostname(char *name, int len)
+{
+   int ret;
+
+   if (globus_common_activated)
+      ret = globus_libc_gethostname(name, len);
+   else
+      ret = gethostname(name, len);
+
+   return ret;
+}
+
+char *
+edg_wll_gss_normalize_subj(char *in, int replace_in)
+{
+       char *new, *ptr;
+       size_t len;
+
+       if (in == NULL) return NULL;
+       if (replace_in) 
+               new = in;
+       else
+               new = strdup(in);
+       
+       while ((ptr = strstr(new, "/emailAddress="))) {
+               memcpy(ptr, "/Email=",7);
+               memmove(ptr+7, ptr+14, strlen(ptr+14)+1);
+       }
+       
+       len = strlen(new);
+       while (len > 9 && !strcmp(new+len-9, "/CN=proxy")) {
+               *(new+len-9) = '\0';
+               len -= 9;
+       }
+
+       return new;
+}
+
+int
+edg_wll_gss_equal_subj(const char *a, const char *b)
+{
+       char *an,*bn;
+       int res;
+
+       an = edg_wll_gss_normalize_subj((char*)a, 0);
+       bn = edg_wll_gss_normalize_subj((char*)b, 0);
+
+       if (!an || !bn)
+               res = 0;
+       else 
+               res = !strcmp(an,bn);
+       
+       free(an); free(bn);
+       return res;
+}
+
+int
+edg_wll_gss_unread(edg_wll_GssConnection *con, void *data, size_t len)
+{
+   char *tmp;
+
+   if (len == 0)
+       return 0;
+
+   tmp = malloc(len + con->bufsize);
+   if (tmp == NULL)
+       return ENOMEM;
+
+   memcpy(tmp, data, len);
+   if (con->bufsize > 0)
+       memcpy(tmp + len, con->buffer, con->bufsize);
+
+   free(con->buffer);
+   con->buffer = tmp;
+   con->bufsize += len;
+
+   return 0;
+}