From f2a6c2f47d71e9b72365be3638392190836c0eeb Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Tue, 27 Mar 2007 14:33:59 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'merge_31_head_after'. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Sprout from master 2007-03-23 14:08:55 UTC Aleš Křenek 'merge' Cherrypick from master 2006-10-10 18:57:39 UTC Aleš Křenek 'builds after merge': org.glite.jp.client/src/jpimporter.c org.glite.jp.common/Makefile org.glite.jp.common/interface/attr.h org.glite.jp.common/interface/context.h org.glite.jp.common/interface/known_attr.h org.glite.jp.common/interface/strmd5.h org.glite.jp.common/src/attr.c org.glite.jp.common/src/stdtypes.c org.glite.jp.common/src/strmd5.c org.glite.jp.index/Makefile org.glite.jp.index/config/glite-jpis-config.xml org.glite.jp.index/config/startup org.glite.jp.index/doc/README org.glite.jp.index/doc/glite-jp-indexd.sgml org.glite.jp.index/examples/jpis-client.c org.glite.jp.index/examples/jpis-test.c org.glite.jp.index/examples/query-tests/authz.out org.glite.jp.index/examples/query-tests/complex_query.out org.glite.jp.index/examples/query-tests/dump1.sql org.glite.jp.index/examples/query-tests/run-test.sh org.glite.jp.index/examples/query-tests/simple_query.out org.glite.jp.index/src/conf.c org.glite.jp.index/src/context.c org.glite.jp.index/src/context.h org.glite.jp.index/src/db_ops.c org.glite.jp.index/src/soap_ops.c org.glite.jp.primary/Makefile org.glite.jp.primary/config/startup org.glite.jp.primary/examples/jpps-test.c org.glite.jp.primary/interface/file_plugin.h org.glite.jp.primary/project/configure.properties.xml org.glite.jp.primary/src/attrs.c org.glite.jp.primary/src/attrs.h org.glite.jp.primary/src/backend.h org.glite.jp.primary/src/builtin_plugins.h org.glite.jp.primary/src/feed.c org.glite.jp.primary/src/new_ftp_backend.c org.glite.jp.primary/src/soap_ops.c org.glite.jp.primary/src/tags.c org.glite.jp.primary/src/tags.h org.glite.jp.primary/src/tags_plugin.c org.glite.jp.server-common/Makefile Cherrypick from master 2007-03-27 14:33:58 UTC František Dvořák 'merge': org.glite.security.gsoap-plugin/Makefile org.glite.security.gsoap-plugin/build.xml org.glite.security.gsoap-plugin/interface/glite_gscompat.h org.glite.security.gsoap-plugin/project/version.properties org.glite.security.gsoap-plugin/src/glite_gsplugin.c org.glite.security.gsoap-plugin/src/glite_gss.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h Delete: org.glite.deployment.jpis/build.xml org.glite.deployment.jpis/config/scripts/glite-jpis-config.py org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml org.glite.deployment.jpis/project/build.number org.glite.deployment.jpis/project/build.properties org.glite.deployment.jpis/project/glite-jp.sdf.xml.template org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template org.glite.deployment.jpis/project/lxscript-rpm.xsl org.glite.deployment.jpis/project/lxscript-tgz.xsl org.glite.deployment.jpis/project/properties.xml org.glite.deployment.jpis/project/quattor-template.xsl org.glite.deployment.jpis/project/version.properties org.glite.deployment.jpps/build.xml org.glite.deployment.jpps/config/scripts/glite-jpps-config.py org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml org.glite.deployment.jpps/project/build.number org.glite.deployment.jpps/project/build.properties org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template org.glite.deployment.jpps/project/lxscript-rpm.xsl org.glite.deployment.jpps/project/lxscript-tgz.xsl org.glite.deployment.jpps/project/properties.xml org.glite.deployment.jpps/project/quattor-template.xsl org.glite.deployment.jpps/project/version.properties org.glite.deployment.lb/.cvsignore org.glite.deployment.lb/CHANGELOG org.glite.deployment.lb/LICENSE org.glite.deployment.lb/build.xml org.glite.deployment.lb/config/scripts/glite-lb-config.py org.glite.deployment.lb/config/templates/glite-lb.cfg.xml org.glite.deployment.lb/doc/release_notes/release_notes.doc org.glite.deployment.lb/doc/release_notes/release_notes.html org.glite.deployment.lb/doc/release_notes/release_notes.pdf org.glite.deployment.lb/project/.cvsignore org.glite.deployment.lb/project/build.number org.glite.deployment.lb/project/build.properties org.glite.deployment.lb/project/glite-lb.sdf.xml.template org.glite.deployment.lb/project/lxscript-rpm.xsl org.glite.deployment.lb/project/lxscript-tgz.xsl org.glite.deployment.lb/project/properties.xml org.glite.deployment.lb/project/quattor-template.xsl org.glite.deployment.lb/project/version.properties org.glite.jp.common/test/base64_test.cpp org.glite.jp.common/test/type_test.cpp org.glite.jp.index/examples/query-tests/jobid_query.in org.glite.jp.index/examples/query-tests/jobid_query.out org.glite.jp.index/examples/query-tests/origin_query.in org.glite.jp.index/examples/query-tests/origin_query.out org.glite.jp.primary/src/classad_plugin.c org.glite.jp.primary/src/sandbox_plugin.c org.glite.jp.primary/src/utils.c org.glite.jp.primary/src/utils.h org.glite.lb-utils.context/.cvsignore org.glite.lb-utils.context/LICENSE org.glite.lb-utils.context/build.xml org.glite.lb-utils.context/project/build.number org.glite.lb-utils.context/project/build.properties org.glite.lb-utils.context/project/configure.properties.xml org.glite.lb-utils.context/project/properties.xml org.glite.lb-utils.context/project/version.properties org.glite.lb-utils.db/.cvsignore org.glite.lb-utils.db/LICENSE org.glite.lb-utils.db/Makefile org.glite.lb-utils.db/build.xml org.glite.lb-utils.db/examples/db_test.c org.glite.lb-utils.db/interface/db.h org.glite.lb-utils.db/project/build.number org.glite.lb-utils.db/project/build.properties org.glite.lb-utils.db/project/configure.properties.xml org.glite.lb-utils.db/project/properties.xml org.glite.lb-utils.db/project/tar_exclude org.glite.lb-utils.db/project/version.properties org.glite.lb-utils.db/src/db.c org.glite.lb-utils.jobid/.cvsignore org.glite.lb-utils.jobid/LICENSE org.glite.lb-utils.jobid/Makefile org.glite.lb-utils.jobid/build.xml org.glite.lb-utils.jobid/interface/Exception.h org.glite.lb-utils.jobid/interface/JobId.h org.glite.lb-utils.jobid/interface/JobIdExceptions.h org.glite.lb-utils.jobid/interface/cjobid.h org.glite.lb-utils.jobid/interface/strmd5.h org.glite.lb-utils.jobid/project/build.number org.glite.lb-utils.jobid/project/build.properties org.glite.lb-utils.jobid/project/configure.properties.xml org.glite.lb-utils.jobid/project/properties.xml org.glite.lb-utils.jobid/project/tar_exclude org.glite.lb-utils.jobid/project/version.properties org.glite.lb-utils.jobid/src/cjobid.c org.glite.lb-utils.jobid/src/strmd5.c org.glite.lb-utils.server-bones/.cvsignore org.glite.lb-utils.server-bones/LICENSE org.glite.lb-utils.server-bones/build.xml org.glite.lb-utils.server-bones/project/build.number org.glite.lb-utils.server-bones/project/build.properties org.glite.lb-utils.server-bones/project/configure.properties.xml org.glite.lb-utils.server-bones/project/properties.xml org.glite.lb-utils.server-bones/project/version.properties org.glite.lb-utils.trio/.cvsignore org.glite.lb-utils.trio/LICENSE org.glite.lb-utils.trio/Makefile org.glite.lb-utils.trio/build.xml org.glite.lb-utils.trio/interface/escape.h org.glite.lb-utils.trio/interface/trio.h org.glite.lb-utils.trio/project/build.number org.glite.lb-utils.trio/project/build.properties org.glite.lb-utils.trio/project/configure.properties.xml org.glite.lb-utils.trio/project/properties.xml org.glite.lb-utils.trio/project/version.properties org.glite.lb-utils.trio/src/escape.c org.glite.lb-utils.trio/src/strio.c org.glite.lb-utils.trio/src/strio.h org.glite.lb-utils.trio/src/trio.c org.glite.lb-utils.trio/src/triop.h org.glite.lb-utils.trio/test/trio_test.cpp org.glite.lb-utils/.cvsignore org.glite.lb-utils/LICENSE org.glite.lb-utils/build.xml org.glite.lb-utils/project/build.number org.glite.lb-utils/project/build.properties org.glite.lb-utils/project/dependencies.properties org.glite.lb-utils/project/glite.lb-utils.csf.xml org.glite.lb-utils/project/properties.xml org.glite.lb-utils/project/taskdefs.xml org.glite.lb-utils/project/version.properties org.glite.lb.common/doc/events.tex.T org.glite.lb.common/doc/status.tex.T org.glite.lb/.cvsignore org.glite.lb/LICENSE org.glite.lb/build.xml org.glite.lb/deployment/README org.glite.lb/deployment/deploy_all.diff org.glite.lb/deployment/deploy_jp.diff org.glite.lb/deployment/deploy_lb.diff org.glite.lb/doc/README.lb4vdt org.glite.lb/doc/copyright.tex org.glite.lb/doc/frontmatter.tex org.glite.lb/doc/perf_clear_proxy org.glite.lb/doc/perf_purge org.glite.lb/doc/perf_reg_jobs org.glite.lb/doc/perf_results/il_sci_09062006.txt org.glite.lb/doc/perf_results/il_sci_09062006_01.txt org.glite.lb/doc/perf_results/il_sci_12062006.txt org.glite.lb/doc/perf_results/ll_michal_21062006.txt org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt org.glite.lb/doc/perf_results/proxy_sci_09062006.txt org.glite.lb/doc/perf_run_interlogd org.glite.lb/doc/perf_run_proxy org.glite.lb/doc/perf_run_server org.glite.lb/doc/perf_run_test org.glite.lb/doc/perftest.tex org.glite.lb/doc/testplan.tex org.glite.lb/lb4vdt/LB_install.sh org.glite.lb/lb4vdt/Makefile.inc org.glite.lb/lb4vdt/scripts/org.gridsite.core.build org.glite.lb/project/MultiStruct.pm org.glite.lb/project/StructField.pm org.glite.lb/project/at3 org.glite.lb/project/build.number org.glite.lb/project/build.properties org.glite.lb/project/check_version.pl org.glite.lb/project/dependencies.properties org.glite.lb/project/events.T org.glite.lb/project/glite.lb.csf.xml org.glite.lb/project/properties.xml org.glite.lb/project/run-workspace org.glite.lb/project/status.T org.glite.lb/project/taskdefs.xml org.glite.lb/project/types.T org.glite.lb/project/version.properties org.glite.security.proxyrenewal/.cvsignore org.glite.security.proxyrenewal/LICENSE org.glite.security.proxyrenewal/Makefile org.glite.security.proxyrenewal/build.xml org.glite.security.proxyrenewal/config/startup org.glite.security.proxyrenewal/examples/renew_core.c org.glite.security.proxyrenewal/interface/renewal.h org.glite.security.proxyrenewal/interface/renewal_core.h org.glite.security.proxyrenewal/project/build.number org.glite.security.proxyrenewal/project/build.properties org.glite.security.proxyrenewal/project/configure.properties.xml org.glite.security.proxyrenewal/project/properties.xml org.glite.security.proxyrenewal/project/tar_exclude org.glite.security.proxyrenewal/project/taskdefs.xml org.glite.security.proxyrenewal/project/version.properties org.glite.security.proxyrenewal/src/api.c org.glite.security.proxyrenewal/src/client.c org.glite.security.proxyrenewal/src/commands.c org.glite.security.proxyrenewal/src/common.c org.glite.security.proxyrenewal/src/renew.c org.glite.security.proxyrenewal/src/renewal_core.c org.glite.security.proxyrenewal/src/renewal_locl.h org.glite.security.proxyrenewal/src/renewd.c org.glite.security.proxyrenewal/src/renewd_locl.h org.glite.security.proxyrenewal/src/voms.c org.glite.testsuites.ctb/LB/Makefile org.glite.testsuites.ctb/LB/lb-l1.sh org.glite.testsuites.ctb/LB/lb-l2.sh org.glite.testsuites.ctb/LB/lb-l2Stat.sh org.glite.testsuites.ctb/LB/testSocket.c org.glite.wms-utils.exception/.cvsignore org.glite.wms-utils.exception/LICENSE org.glite.wms-utils.exception/Makefile.am org.glite.wms-utils.exception/bootstrap org.glite.wms-utils.exception/build.xml org.glite.wms-utils.exception/configure.ac org.glite.wms-utils.exception/interface/Makefile.am org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h org.glite.wms-utils.exception/project/build.number org.glite.wms-utils.exception/project/build.properties org.glite.wms-utils.exception/project/configure.properties.xml org.glite.wms-utils.exception/project/properties.xml org.glite.wms-utils.exception/project/version.properties org.glite.wms-utils.exception/src/Exception.cpp org.glite.wms-utils.exception/src/Makefile.am org.glite.wms-utils.exception/test/Makefile.am org.glite.wms-utils.exception/test/exception_cu_main.cpp org.glite.wms-utils.exception/test/exception_cu_suite.cpp org.glite.wms-utils.exception/test/exception_cu_suite.h org.glite.wms-utils.jobid/.cvsignore org.glite.wms-utils.jobid/LICENSE org.glite.wms-utils.jobid/Makefile.am org.glite.wms-utils.jobid/bootstrap org.glite.wms-utils.jobid/build.xml org.glite.wms-utils.jobid/configure.ac org.glite.wms-utils.jobid/examples/Makefile.am org.glite.wms-utils.jobid/examples/testjobid.c org.glite.wms-utils.jobid/interface/Makefile.am org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h org.glite.wms-utils.jobid/project/build.number org.glite.wms-utils.jobid/project/build.properties org.glite.wms-utils.jobid/project/configure.properties.xml org.glite.wms-utils.jobid/project/properties.xml org.glite.wms-utils.jobid/project/version.properties org.glite.wms-utils.jobid/src/Makefile.am org.glite.wms-utils.jobid/src/jobid/JobId.cpp org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp org.glite.wms-utils.jobid/src/jobid/Makefile.am org.glite.wms-utils.jobid/src/jobid/cjobid.c org.glite.wms-utils.jobid/src/jobid/manipulation.cpp org.glite.wms-utils.jobid/src/jobid/strmd5.c org.glite.wms-utils.jobid/src/jobid/strmd5.h org.glite.wms-utils.jobid/test/Makefile.am org.glite.wms-utils.jobid/test/jobid_cu_main.cpp org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp org.glite.wms-utils.jobid/test/jobid_cu_suite.h org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp org.glite.wms-utils.jobid/test/manipulation_cu_suite.h org.gridsite.core/.cvsignore org.gridsite.core/CHANGES org.gridsite.core/INSTALL org.gridsite.core/LICENSE org.gridsite.core/README org.gridsite.core/VERSION org.gridsite.core/build.xml org.gridsite.core/doc/README.htcp-bin org.gridsite.core/doc/build-apache2.sh org.gridsite.core/doc/delegation-1.1.0.wsdl org.gridsite.core/doc/findproxyfile.1 org.gridsite.core/doc/fuse.spec org.gridsite.core/doc/gridsite-delegation.8 org.gridsite.core/doc/gsexec.8 org.gridsite.core/doc/gsoap-devel.spec org.gridsite.core/doc/htcp.1 org.gridsite.core/doc/htfind.1 org.gridsite.core/doc/htll.1 org.gridsite.core/doc/htls.1 org.gridsite.core/doc/htmkdir.1 org.gridsite.core/doc/htmv.1 org.gridsite.core/doc/htping.1 org.gridsite.core/doc/htproxydestroy.1 org.gridsite.core/doc/htproxyinfo.1 org.gridsite.core/doc/htproxyput.1 org.gridsite.core/doc/htproxyrenew.1 org.gridsite.core/doc/htproxytime.1 org.gridsite.core/doc/htproxyunixtime.1 org.gridsite.core/doc/htrm.1 org.gridsite.core/doc/httpd-fileserver.conf org.gridsite.core/doc/httpd-webserver.conf org.gridsite.core/doc/index.html org.gridsite.core/doc/mod_gridsite.8 org.gridsite.core/doc/slashgrid.8 org.gridsite.core/doc/urlencode.1 org.gridsite.core/interface/gridsite-gacl.h org.gridsite.core/interface/gridsite.h org.gridsite.core/project/build.number org.gridsite.core/project/build.properties org.gridsite.core/project/configure.properties.xml org.gridsite.core/project/dependencies.properties org.gridsite.core/project/gridsite.core.csf.xml org.gridsite.core/project/properties.xml org.gridsite.core/project/taskdefs.xml org.gridsite.core/project/version.properties org.gridsite.core/src/Doxyfile org.gridsite.core/src/Makefile org.gridsite.core/src/delegation.h org.gridsite.core/src/doxygen.css org.gridsite.core/src/doxyheader.html org.gridsite.core/src/findproxyfile.c org.gridsite.core/src/gaclexample.c org.gridsite.core/src/gridsite-copy.c org.gridsite.core/src/grst-delegation.c org.gridsite.core/src/grst_admin.h org.gridsite.core/src/grst_admin_file.c org.gridsite.core/src/grst_admin_gacl.c org.gridsite.core/src/grst_admin_main.c org.gridsite.core/src/grst_asn1.c org.gridsite.core/src/grst_err.c org.gridsite.core/src/grst_gacl.c org.gridsite.core/src/grst_htcp.c org.gridsite.core/src/grst_http.c org.gridsite.core/src/grst_x509.c org.gridsite.core/src/grst_xacml.c org.gridsite.core/src/gsexec.c org.gridsite.core/src/gsexec.h org.gridsite.core/src/htcp.c org.gridsite.core/src/htproxyput.c org.gridsite.core/src/make-gridsite-spec org.gridsite.core/src/mod_gridsite.c org.gridsite.core/src/mod_ssl-private.h org.gridsite.core/src/roffit org.gridsite.core/src/showx509exts.c org.gridsite.core/src/slashgrid.c org.gridsite.core/src/slashgrid.init org.gridsite.core/src/urlencode.c org.gridsite.core/src/xacmlexample.c --- org.glite.deployment.jpis/build.xml | 94 - .../config/scripts/glite-jpis-config.py | 492 - .../config/templates/glite-jpis.cfg.xml | 92 - org.glite.deployment.jpis/project/build.number | 2 - org.glite.deployment.jpis/project/build.properties | 0 .../project/glite-jp.sdf.xml.template | 117 - .../project/glite-jpis.sdf.xml.template | 117 - org.glite.deployment.jpis/project/lxscript-rpm.xsl | 336 - org.glite.deployment.jpis/project/lxscript-tgz.xsl | 62 - org.glite.deployment.jpis/project/properties.xml | 63 - .../project/quattor-template.xsl | 64 - .../project/version.properties | 4 - org.glite.deployment.jpps/build.xml | 94 - .../config/scripts/glite-jpps-config.py | 500 - .../config/templates/glite-jpps.cfg.xml | 93 - org.glite.deployment.jpps/project/build.number | 2 - org.glite.deployment.jpps/project/build.properties | 0 .../project/glite-jpps.sdf.xml.template | 127 - org.glite.deployment.jpps/project/lxscript-rpm.xsl | 336 - org.glite.deployment.jpps/project/lxscript-tgz.xsl | 62 - org.glite.deployment.jpps/project/properties.xml | 63 - .../project/quattor-template.xsl | 64 - .../project/version.properties | 4 - org.glite.deployment.lb/.cvsignore | 1 - org.glite.deployment.lb/CHANGELOG | 40 - org.glite.deployment.lb/LICENSE | 69 - org.glite.deployment.lb/build.xml | 110 - .../config/scripts/glite-lb-config.py | 574 - .../config/templates/glite-lb.cfg.xml | 73 - .../doc/release_notes/release_notes.doc | Bin 192512 -> 0 bytes .../doc/release_notes/release_notes.html | 2712 ---- .../doc/release_notes/release_notes.pdf | Bin 157326 -> 0 bytes org.glite.deployment.lb/project/.cvsignore | 1 - org.glite.deployment.lb/project/build.number | 2 - org.glite.deployment.lb/project/build.properties | 0 .../project/glite-lb.sdf.xml.template | 157 - org.glite.deployment.lb/project/lxscript-rpm.xsl | 336 - org.glite.deployment.lb/project/lxscript-tgz.xsl | 62 - org.glite.deployment.lb/project/properties.xml | 73 - .../project/quattor-template.xsl | 64 - org.glite.deployment.lb/project/version.properties | 4 - org.glite.jp.client/src/jpimporter.c | 6 +- org.glite.jp.common/Makefile | 29 +- org.glite.jp.common/interface/attr.h | 8 - org.glite.jp.common/interface/context.h | 8 - org.glite.jp.common/interface/known_attr.h | 13 - org.glite.jp.common/interface/strmd5.h | 8 - org.glite.jp.common/src/attr.c | 131 +- org.glite.jp.common/src/stdtypes.c | 127 + org.glite.jp.common/src/strmd5.c | 10 +- org.glite.jp.common/test/base64_test.cpp | 75 - org.glite.jp.common/test/type_test.cpp | 184 - org.glite.jp.index/Makefile | 19 +- org.glite.jp.index/config/glite-jpis-config.xml | 1 - org.glite.jp.index/config/startup | 9 +- org.glite.jp.index/doc/README | 10 +- org.glite.jp.index/doc/glite-jp-indexd.sgml | 29 +- org.glite.jp.index/examples/jpis-client.c | 17 +- org.glite.jp.index/examples/jpis-test.c | 6 +- org.glite.jp.index/examples/query-tests/authz.out | 5 +- .../examples/query-tests/complex_query.out | 10 +- org.glite.jp.index/examples/query-tests/dump1.sql | 4 +- .../examples/query-tests/jobid_query.in | 19 - .../examples/query-tests/jobid_query.out | 14 - .../examples/query-tests/origin_query.in | 20 - .../examples/query-tests/origin_query.out | 14 - .../examples/query-tests/run-test.sh | 23 +- .../examples/query-tests/simple_query.out | 5 +- org.glite.jp.index/src/conf.c | 93 +- org.glite.jp.index/src/context.c | 10 - org.glite.jp.index/src/context.h | 2 - org.glite.jp.index/src/db_ops.c | 41 +- org.glite.jp.index/src/soap_ops.c | 103 +- org.glite.jp.primary/Makefile | 36 +- org.glite.jp.primary/config/startup | 2 +- org.glite.jp.primary/examples/jpps-test.c | 14 +- org.glite.jp.primary/interface/file_plugin.h | 15 +- .../project/configure.properties.xml | 4 - org.glite.jp.primary/src/attrs.c | 210 +- org.glite.jp.primary/src/attrs.h | 1 - org.glite.jp.primary/src/backend.h | 7 - org.glite.jp.primary/src/builtin_plugins.h | 9 +- org.glite.jp.primary/src/classad_plugin.c | 208 - org.glite.jp.primary/src/new_ftp_backend.c | 98 - org.glite.jp.primary/src/sandbox_plugin.c | 261 - org.glite.jp.primary/src/soap_ops.c | 62 +- org.glite.jp.primary/src/tags.c | 231 +- org.glite.jp.primary/src/tags.h | 11 +- org.glite.jp.primary/src/tags_plugin.c | 298 + org.glite.jp.primary/src/utils.c | 129 - org.glite.jp.primary/src/utils.h | 28 - org.glite.jp.server-common/Makefile | 2 +- org.glite.lb-utils.context/.cvsignore | 2 - org.glite.lb-utils.context/LICENSE | 69 - org.glite.lb-utils.context/build.xml | 122 - org.glite.lb-utils.context/project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 37 - org.glite.lb-utils.context/project/properties.xml | 73 - .../project/version.properties | 2 - org.glite.lb-utils.db/.cvsignore | 5 - org.glite.lb-utils.db/LICENSE | 69 - org.glite.lb-utils.db/Makefile | 128 - org.glite.lb-utils.db/build.xml | 126 - org.glite.lb-utils.db/examples/db_test.c | 196 - org.glite.lb-utils.db/interface/db.h | 336 - org.glite.lb-utils.db/project/build.number | 1 - org.glite.lb-utils.db/project/build.properties | 3 - .../project/configure.properties.xml | 81 - org.glite.lb-utils.db/project/properties.xml | 73 - org.glite.lb-utils.db/project/tar_exclude | 10 - org.glite.lb-utils.db/project/version.properties | 2 - org.glite.lb-utils.db/src/db.c | 1037 -- org.glite.lb-utils.jobid/.cvsignore | 2 - org.glite.lb-utils.jobid/LICENSE | 69 - org.glite.lb-utils.jobid/Makefile | 98 - org.glite.lb-utils.jobid/build.xml | 129 - org.glite.lb-utils.jobid/interface/Exception.h | 138 - org.glite.lb-utils.jobid/interface/JobId.h | 126 - .../interface/JobIdExceptions.h | 80 - org.glite.lb-utils.jobid/interface/cjobid.h | 109 - org.glite.lb-utils.jobid/interface/strmd5.h | 30 - org.glite.lb-utils.jobid/project/build.number | 1 - org.glite.lb-utils.jobid/project/build.properties | 4 - .../project/configure.properties.xml | 63 - org.glite.lb-utils.jobid/project/properties.xml | 73 - org.glite.lb-utils.jobid/project/tar_exclude | 10 - .../project/version.properties | 2 - org.glite.lb-utils.jobid/src/cjobid.c | 260 - org.glite.lb-utils.jobid/src/strmd5.c | 122 - org.glite.lb-utils.server-bones/.cvsignore | 2 - org.glite.lb-utils.server-bones/LICENSE | 69 - org.glite.lb-utils.server-bones/build.xml | 122 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 37 - .../project/properties.xml | 73 - .../project/version.properties | 2 - org.glite.lb-utils.trio/.cvsignore | 2 - org.glite.lb-utils.trio/LICENSE | 69 - org.glite.lb-utils.trio/Makefile | 114 - org.glite.lb-utils.trio/build.xml | 126 - org.glite.lb-utils.trio/interface/escape.h | 59 - org.glite.lb-utils.trio/interface/trio.h | 187 - org.glite.lb-utils.trio/project/build.number | 1 - org.glite.lb-utils.trio/project/build.properties | 4 - .../project/configure.properties.xml | 59 - org.glite.lb-utils.trio/project/properties.xml | 73 - org.glite.lb-utils.trio/project/version.properties | 2 - org.glite.lb-utils.trio/src/escape.c | 224 - org.glite.lb-utils.trio/src/strio.c | 581 - org.glite.lb-utils.trio/src/strio.h | 227 - org.glite.lb-utils.trio/src/trio.c | 5706 -------- org.glite.lb-utils.trio/src/triop.h | 138 - org.glite.lb-utils.trio/test/trio_test.cpp | 85 - org.glite.lb-utils/.cvsignore | 1 - org.glite.lb-utils/LICENSE | 69 - org.glite.lb-utils/build.xml | 303 - org.glite.lb-utils/project/build.number | 1 - org.glite.lb-utils/project/build.properties | 0 org.glite.lb-utils/project/dependencies.properties | 13 - org.glite.lb-utils/project/glite.lb-utils.csf.xml | 218 - org.glite.lb-utils/project/properties.xml | 64 - org.glite.lb-utils/project/taskdefs.xml | 38 - org.glite.lb-utils/project/version.properties | 2 - org.glite.lb.common/doc/events.tex.T | 16 - org.glite.lb.common/doc/status.tex.T | 15 - org.glite.lb/.cvsignore | 2 - org.glite.lb/LICENSE | 69 - org.glite.lb/build.xml | 593 - org.glite.lb/deployment/README | 2 - org.glite.lb/deployment/deploy_all.diff | 454 - org.glite.lb/deployment/deploy_jp.diff | 222 - org.glite.lb/deployment/deploy_lb.diff | 281 - org.glite.lb/doc/README.lb4vdt | 16 - org.glite.lb/doc/copyright.tex | 24 - org.glite.lb/doc/frontmatter.tex | 41 - org.glite.lb/doc/perf_clear_proxy | 1 - org.glite.lb/doc/perf_purge | 1 - org.glite.lb/doc/perf_reg_jobs | 1 - org.glite.lb/doc/perf_results/il_sci_09062006.txt | 63 - .../doc/perf_results/il_sci_09062006_01.txt | 129 - org.glite.lb/doc/perf_results/il_sci_12062006.txt | 65 - .../doc/perf_results/ll_michal_21062006.txt | 20 - .../perf_results/proxy2serv_umbar2sci_22062006.txt | 20 - .../perf_results/proxy2serv_umbar2sci_23062006.txt | 25 - .../doc/perf_results/proxy_sci_09062006.txt | 21 - org.glite.lb/doc/perf_run_interlogd | 1 - org.glite.lb/doc/perf_run_proxy | 1 - org.glite.lb/doc/perf_run_server | 1 - org.glite.lb/doc/perf_run_test | 1 - org.glite.lb/doc/perftest.tex | 524 - org.glite.lb/doc/testplan.tex | 300 - org.glite.lb/lb4vdt/LB_install.sh | 113 - org.glite.lb/lb4vdt/Makefile.inc | 77 - .../lb4vdt/scripts/org.gridsite.core.build | 11 - org.glite.lb/project/MultiStruct.pm | 191 - org.glite.lb/project/StructField.pm | 116 - org.glite.lb/project/at3 | 93 - org.glite.lb/project/build.number | 2 - org.glite.lb/project/build.properties | 3 - org.glite.lb/project/check_version.pl | 36 - org.glite.lb/project/dependencies.properties | 20 - org.glite.lb/project/events.T | 327 - org.glite.lb/project/glite.lb.csf.xml | 398 - org.glite.lb/project/properties.xml | 55 - org.glite.lb/project/run-workspace | 10 - org.glite.lb/project/status.T | 111 - org.glite.lb/project/taskdefs.xml | 32 - org.glite.lb/project/types.T | 127 - org.glite.lb/project/version.properties | 3 - org.glite.security.gsoap-plugin/Makefile | 38 +- org.glite.security.gsoap-plugin/build.xml | 11 +- .../interface/glite_gscompat.h | 78 + .../project/version.properties | 4 +- .../src/glite_gsplugin.c | 16 +- org.glite.security.gsoap-plugin/src/glite_gss.c | 35 + .../src/stdsoap2_2.7.0f.c | 12026 ++++++++++++++++ .../src/stdsoap2_2.7.0f.h | 1885 +++ .../src/stdsoap2_2.7.6b.c | 13101 +++++++++++++++++ .../src/stdsoap2_2.7.6b.h | 2053 +++ .../src/stdsoap2_2.7.9b.c | 14172 +++++++++++++++++++ .../src/stdsoap2_2.7.9b.h | 2166 +++ org.glite.security.proxyrenewal/.cvsignore | 1 - org.glite.security.proxyrenewal/LICENSE | 69 - org.glite.security.proxyrenewal/Makefile | 167 - org.glite.security.proxyrenewal/build.xml | 128 - org.glite.security.proxyrenewal/config/startup | 80 - .../examples/renew_core.c | 63 - .../interface/renewal.h | 175 - .../interface/renewal_core.h | 62 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 60 - .../project/properties.xml | 62 - .../project/tar_exclude | 10 - .../project/taskdefs.xml | 4 - .../project/version.properties | 2 - org.glite.security.proxyrenewal/src/api.c | 550 - org.glite.security.proxyrenewal/src/client.c | 111 - org.glite.security.proxyrenewal/src/commands.c | 1256 -- org.glite.security.proxyrenewal/src/common.c | 322 - org.glite.security.proxyrenewal/src/renew.c | 256 - org.glite.security.proxyrenewal/src/renewal_core.c | 283 - org.glite.security.proxyrenewal/src/renewal_locl.h | 148 - org.glite.security.proxyrenewal/src/renewd.c | 609 - org.glite.security.proxyrenewal/src/renewd_locl.h | 82 - org.glite.security.proxyrenewal/src/voms.c | 356 - org.glite.testsuites.ctb/LB/Makefile | 14 - org.glite.testsuites.ctb/LB/lb-l1.sh | 145 - org.glite.testsuites.ctb/LB/lb-l2.sh | 253 - org.glite.testsuites.ctb/LB/lb-l2Stat.sh | 217 - org.glite.testsuites.ctb/LB/testSocket.c | 58 - org.glite.wms-utils.exception/.cvsignore | 1 - org.glite.wms-utils.exception/LICENSE | 69 - org.glite.wms-utils.exception/Makefile.am | 67 - org.glite.wms-utils.exception/bootstrap | 9 - org.glite.wms-utils.exception/build.xml | 104 - org.glite.wms-utils.exception/configure.ac | 127 - .../interface/Makefile.am | 14 - .../interface/glite/wmsutils/exception/Exception.h | 138 - .../glite/wmsutils/exception/exception_codes.h | 41 - org.glite.wms-utils.exception/project/build.number | 2 - .../project/build.properties | 2 - .../project/configure.properties.xml | 9 - .../project/properties.xml | 83 - .../project/version.properties | 2 - org.glite.wms-utils.exception/src/Exception.cpp | 124 - org.glite.wms-utils.exception/src/Makefile.am | 17 - org.glite.wms-utils.exception/test/Makefile.am | 33 - .../test/exception_cu_main.cpp | 33 - .../test/exception_cu_suite.cpp | 56 - .../test/exception_cu_suite.h | 29 - org.glite.wms-utils.jobid/.cvsignore | 2 - org.glite.wms-utils.jobid/LICENSE | 69 - org.glite.wms-utils.jobid/Makefile.am | 69 - org.glite.wms-utils.jobid/bootstrap | 9 - org.glite.wms-utils.jobid/build.xml | 104 - org.glite.wms-utils.jobid/configure.ac | 147 - org.glite.wms-utils.jobid/examples/Makefile.am | 28 - org.glite.wms-utils.jobid/examples/testjobid.c | 33 - org.glite.wms-utils.jobid/interface/Makefile.am | 16 - .../interface/glite/wmsutils/jobid/JobId.h | 126 - .../glite/wmsutils/jobid/JobIdExceptions.h | 80 - .../interface/glite/wmsutils/jobid/cjobid.h | 109 - .../interface/glite/wmsutils/jobid/manipulation.h | 24 - org.glite.wms-utils.jobid/project/build.number | 2 - org.glite.wms-utils.jobid/project/build.properties | 2 - .../project/configure.properties.xml | 9 - org.glite.wms-utils.jobid/project/properties.xml | 86 - .../project/version.properties | 2 - org.glite.wms-utils.jobid/src/Makefile.am | 12 - org.glite.wms-utils.jobid/src/jobid/JobId.cpp | 183 - .../src/jobid/JobIdExceptions.cpp | 58 - org.glite.wms-utils.jobid/src/jobid/Makefile.am | 30 - org.glite.wms-utils.jobid/src/jobid/cjobid.c | 258 - .../src/jobid/manipulation.cpp | 180 - org.glite.wms-utils.jobid/src/jobid/strmd5.c | 118 - org.glite.wms-utils.jobid/src/jobid/strmd5.h | 28 - org.glite.wms-utils.jobid/test/Makefile.am | 48 - org.glite.wms-utils.jobid/test/jobid_cu_main.cpp | 33 - org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp | 102 - org.glite.wms-utils.jobid/test/jobid_cu_suite.h | 34 - .../test/manipulation_cu_main.cpp | 33 - .../test/manipulation_cu_suite.cpp | 34 - .../test/manipulation_cu_suite.h | 29 - org.gridsite.core/.cvsignore | 1 - org.gridsite.core/CHANGES | 364 - org.gridsite.core/INSTALL | 37 - org.gridsite.core/LICENSE | 47 - org.gridsite.core/README | 6 - org.gridsite.core/VERSION | 4 - org.gridsite.core/build.xml | 294 - org.gridsite.core/doc/README.htcp-bin | 13 - org.gridsite.core/doc/build-apache2.sh | 79 - org.gridsite.core/doc/delegation-1.1.0.wsdl | 459 - org.gridsite.core/doc/findproxyfile.1 | 63 - org.gridsite.core/doc/fuse.spec | 139 - org.gridsite.core/doc/gridsite-delegation.8 | 19 - org.gridsite.core/doc/gsexec.8 | 134 - org.gridsite.core/doc/gsoap-devel.spec | 52 - org.gridsite.core/doc/htcp.1 | 200 - org.gridsite.core/doc/htfind.1 | 1 - org.gridsite.core/doc/htll.1 | 1 - org.gridsite.core/doc/htls.1 | 1 - org.gridsite.core/doc/htmkdir.1 | 1 - org.gridsite.core/doc/htmv.1 | 1 - org.gridsite.core/doc/htping.1 | 1 - org.gridsite.core/doc/htproxydestroy.1 | 1 - org.gridsite.core/doc/htproxyinfo.1 | 1 - org.gridsite.core/doc/htproxyput.1 | 121 - org.gridsite.core/doc/htproxyrenew.1 | 1 - org.gridsite.core/doc/htproxytime.1 | 1 - org.gridsite.core/doc/htproxyunixtime.1 | 1 - org.gridsite.core/doc/htrm.1 | 1 - org.gridsite.core/doc/httpd-fileserver.conf | 155 - org.gridsite.core/doc/httpd-webserver.conf | 226 - org.gridsite.core/doc/index.html | 82 - org.gridsite.core/doc/mod_gridsite.8 | 325 - org.gridsite.core/doc/slashgrid.8 | 67 - org.gridsite.core/doc/urlencode.1 | 43 - org.gridsite.core/interface/gridsite-gacl.h | 188 - org.gridsite.core/interface/gridsite.h | 379 - org.gridsite.core/project/build.number | 2 - org.gridsite.core/project/build.properties | 0 org.gridsite.core/project/configure.properties.xml | 9 - org.gridsite.core/project/dependencies.properties | 9 - org.gridsite.core/project/gridsite.core.csf.xml | 221 - org.gridsite.core/project/properties.xml | 53 - org.gridsite.core/project/taskdefs.xml | 31 - org.gridsite.core/project/version.properties | 2 - org.gridsite.core/src/Doxyfile | 993 -- org.gridsite.core/src/Makefile | 494 - org.gridsite.core/src/delegation.h | 86 - org.gridsite.core/src/doxygen.css | 49 - org.gridsite.core/src/doxyheader.html | 1 - org.gridsite.core/src/findproxyfile.c | 122 - org.gridsite.core/src/gaclexample.c | 147 - org.gridsite.core/src/gridsite-copy.c | 168 - org.gridsite.core/src/grst-delegation.c | 347 - org.gridsite.core/src/grst_admin.h | 57 - org.gridsite.core/src/grst_admin_file.c | 1573 -- org.gridsite.core/src/grst_admin_gacl.c | 981 -- org.gridsite.core/src/grst_admin_main.c | 378 - org.gridsite.core/src/grst_asn1.c | 506 - org.gridsite.core/src/grst_err.c | 41 - org.gridsite.core/src/grst_gacl.c | 1233 -- org.gridsite.core/src/grst_htcp.c | 311 - org.gridsite.core/src/grst_http.c | 443 - org.gridsite.core/src/grst_x509.c | 2160 --- org.gridsite.core/src/grst_xacml.c | 576 - org.gridsite.core/src/gsexec.c | 1104 -- org.gridsite.core/src/gsexec.h | 126 - org.gridsite.core/src/htcp.c | 2032 --- org.gridsite.core/src/htproxyput.c | 621 - org.gridsite.core/src/make-gridsite-spec | 301 - org.gridsite.core/src/mod_gridsite.c | 3572 ----- org.gridsite.core/src/mod_ssl-private.h | 106 - org.gridsite.core/src/roffit | 370 - org.gridsite.core/src/showx509exts.c | 133 - org.gridsite.core/src/slashgrid.c | 2492 ---- org.gridsite.core/src/slashgrid.init | 67 - org.gridsite.core/src/urlencode.c | 73 - org.gridsite.core/src/xacmlexample.c | 148 - 384 files changed, 46426 insertions(+), 60147 deletions(-) delete mode 100644 org.glite.deployment.jpis/build.xml delete mode 100755 org.glite.deployment.jpis/config/scripts/glite-jpis-config.py delete mode 100644 org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml delete mode 100644 org.glite.deployment.jpis/project/build.number delete mode 100644 org.glite.deployment.jpis/project/build.properties delete mode 100644 org.glite.deployment.jpis/project/glite-jp.sdf.xml.template delete mode 100644 org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template delete mode 100644 org.glite.deployment.jpis/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.jpis/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.jpis/project/properties.xml delete mode 100644 org.glite.deployment.jpis/project/quattor-template.xsl delete mode 100644 org.glite.deployment.jpis/project/version.properties delete mode 100644 org.glite.deployment.jpps/build.xml delete mode 100755 org.glite.deployment.jpps/config/scripts/glite-jpps-config.py delete mode 100644 org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml delete mode 100644 org.glite.deployment.jpps/project/build.number delete mode 100644 org.glite.deployment.jpps/project/build.properties delete mode 100644 org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template delete mode 100644 org.glite.deployment.jpps/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.jpps/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.jpps/project/properties.xml delete mode 100644 org.glite.deployment.jpps/project/quattor-template.xsl delete mode 100644 org.glite.deployment.jpps/project/version.properties delete mode 100644 org.glite.deployment.lb/.cvsignore delete mode 100644 org.glite.deployment.lb/CHANGELOG delete mode 100644 org.glite.deployment.lb/LICENSE delete mode 100644 org.glite.deployment.lb/build.xml delete mode 100644 org.glite.deployment.lb/config/scripts/glite-lb-config.py delete mode 100644 org.glite.deployment.lb/config/templates/glite-lb.cfg.xml delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.doc delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.html delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.pdf delete mode 100644 org.glite.deployment.lb/project/.cvsignore delete mode 100644 org.glite.deployment.lb/project/build.number delete mode 100644 org.glite.deployment.lb/project/build.properties delete mode 100644 org.glite.deployment.lb/project/glite-lb.sdf.xml.template delete mode 100644 org.glite.deployment.lb/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.lb/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.lb/project/properties.xml delete mode 100644 org.glite.deployment.lb/project/quattor-template.xsl delete mode 100644 org.glite.deployment.lb/project/version.properties create mode 100644 org.glite.jp.common/src/stdtypes.c delete mode 100644 org.glite.jp.common/test/base64_test.cpp delete mode 100644 org.glite.jp.common/test/type_test.cpp delete mode 100644 org.glite.jp.index/examples/query-tests/jobid_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/jobid_query.out delete mode 100644 org.glite.jp.index/examples/query-tests/origin_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/origin_query.out delete mode 100644 org.glite.jp.primary/src/classad_plugin.c delete mode 100644 org.glite.jp.primary/src/sandbox_plugin.c create mode 100644 org.glite.jp.primary/src/tags_plugin.c delete mode 100644 org.glite.jp.primary/src/utils.c delete mode 100644 org.glite.jp.primary/src/utils.h delete mode 100755 org.glite.lb-utils.context/.cvsignore delete mode 100755 org.glite.lb-utils.context/LICENSE delete mode 100644 org.glite.lb-utils.context/build.xml delete mode 100644 org.glite.lb-utils.context/project/build.number delete mode 100755 org.glite.lb-utils.context/project/build.properties delete mode 100644 org.glite.lb-utils.context/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.context/project/properties.xml delete mode 100755 org.glite.lb-utils.context/project/version.properties delete mode 100755 org.glite.lb-utils.db/.cvsignore delete mode 100755 org.glite.lb-utils.db/LICENSE delete mode 100644 org.glite.lb-utils.db/Makefile delete mode 100644 org.glite.lb-utils.db/build.xml delete mode 100644 org.glite.lb-utils.db/examples/db_test.c delete mode 100644 org.glite.lb-utils.db/interface/db.h delete mode 100644 org.glite.lb-utils.db/project/build.number delete mode 100755 org.glite.lb-utils.db/project/build.properties delete mode 100644 org.glite.lb-utils.db/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.db/project/properties.xml delete mode 100644 org.glite.lb-utils.db/project/tar_exclude delete mode 100755 org.glite.lb-utils.db/project/version.properties delete mode 100644 org.glite.lb-utils.db/src/db.c delete mode 100755 org.glite.lb-utils.jobid/.cvsignore delete mode 100755 org.glite.lb-utils.jobid/LICENSE delete mode 100644 org.glite.lb-utils.jobid/Makefile delete mode 100644 org.glite.lb-utils.jobid/build.xml delete mode 100644 org.glite.lb-utils.jobid/interface/Exception.h delete mode 100644 org.glite.lb-utils.jobid/interface/JobId.h delete mode 100644 org.glite.lb-utils.jobid/interface/JobIdExceptions.h delete mode 100755 org.glite.lb-utils.jobid/interface/cjobid.h delete mode 100755 org.glite.lb-utils.jobid/interface/strmd5.h delete mode 100644 org.glite.lb-utils.jobid/project/build.number delete mode 100755 org.glite.lb-utils.jobid/project/build.properties delete mode 100644 org.glite.lb-utils.jobid/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.jobid/project/properties.xml delete mode 100644 org.glite.lb-utils.jobid/project/tar_exclude delete mode 100755 org.glite.lb-utils.jobid/project/version.properties delete mode 100755 org.glite.lb-utils.jobid/src/cjobid.c delete mode 100755 org.glite.lb-utils.jobid/src/strmd5.c delete mode 100755 org.glite.lb-utils.server-bones/.cvsignore delete mode 100755 org.glite.lb-utils.server-bones/LICENSE delete mode 100644 org.glite.lb-utils.server-bones/build.xml delete mode 100644 org.glite.lb-utils.server-bones/project/build.number delete mode 100755 org.glite.lb-utils.server-bones/project/build.properties delete mode 100644 org.glite.lb-utils.server-bones/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.server-bones/project/properties.xml delete mode 100755 org.glite.lb-utils.server-bones/project/version.properties delete mode 100755 org.glite.lb-utils.trio/.cvsignore delete mode 100755 org.glite.lb-utils.trio/LICENSE delete mode 100644 org.glite.lb-utils.trio/Makefile delete mode 100644 org.glite.lb-utils.trio/build.xml delete mode 100644 org.glite.lb-utils.trio/interface/escape.h delete mode 100644 org.glite.lb-utils.trio/interface/trio.h delete mode 100644 org.glite.lb-utils.trio/project/build.number delete mode 100755 org.glite.lb-utils.trio/project/build.properties delete mode 100644 org.glite.lb-utils.trio/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.trio/project/properties.xml delete mode 100755 org.glite.lb-utils.trio/project/version.properties delete mode 100644 org.glite.lb-utils.trio/src/escape.c delete mode 100644 org.glite.lb-utils.trio/src/strio.c delete mode 100644 org.glite.lb-utils.trio/src/strio.h delete mode 100644 org.glite.lb-utils.trio/src/trio.c delete mode 100644 org.glite.lb-utils.trio/src/triop.h delete mode 100644 org.glite.lb-utils.trio/test/trio_test.cpp delete mode 100644 org.glite.lb-utils/.cvsignore delete mode 100755 org.glite.lb-utils/LICENSE delete mode 100644 org.glite.lb-utils/build.xml delete mode 100644 org.glite.lb-utils/project/build.number delete mode 100755 org.glite.lb-utils/project/build.properties delete mode 100644 org.glite.lb-utils/project/dependencies.properties delete mode 100644 org.glite.lb-utils/project/glite.lb-utils.csf.xml delete mode 100644 org.glite.lb-utils/project/properties.xml delete mode 100644 org.glite.lb-utils/project/taskdefs.xml delete mode 100755 org.glite.lb-utils/project/version.properties delete mode 100644 org.glite.lb.common/doc/events.tex.T delete mode 100644 org.glite.lb.common/doc/status.tex.T delete mode 100644 org.glite.lb/.cvsignore delete mode 100644 org.glite.lb/LICENSE delete mode 100755 org.glite.lb/build.xml delete mode 100644 org.glite.lb/deployment/README delete mode 100644 org.glite.lb/deployment/deploy_all.diff delete mode 100644 org.glite.lb/deployment/deploy_jp.diff delete mode 100644 org.glite.lb/deployment/deploy_lb.diff delete mode 100644 org.glite.lb/doc/README.lb4vdt delete mode 100644 org.glite.lb/doc/copyright.tex delete mode 100644 org.glite.lb/doc/frontmatter.tex delete mode 100644 org.glite.lb/doc/perf_clear_proxy delete mode 100644 org.glite.lb/doc/perf_purge delete mode 100644 org.glite.lb/doc/perf_reg_jobs delete mode 100644 org.glite.lb/doc/perf_results/il_sci_09062006.txt delete mode 100644 org.glite.lb/doc/perf_results/il_sci_09062006_01.txt delete mode 100644 org.glite.lb/doc/perf_results/il_sci_12062006.txt delete mode 100644 org.glite.lb/doc/perf_results/ll_michal_21062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy_sci_09062006.txt delete mode 100644 org.glite.lb/doc/perf_run_interlogd delete mode 100644 org.glite.lb/doc/perf_run_proxy delete mode 100644 org.glite.lb/doc/perf_run_server delete mode 100644 org.glite.lb/doc/perf_run_test delete mode 100644 org.glite.lb/doc/perftest.tex delete mode 100644 org.glite.lb/doc/testplan.tex delete mode 100755 org.glite.lb/lb4vdt/LB_install.sh delete mode 100644 org.glite.lb/lb4vdt/Makefile.inc delete mode 100644 org.glite.lb/lb4vdt/scripts/org.gridsite.core.build delete mode 100644 org.glite.lb/project/MultiStruct.pm delete mode 100644 org.glite.lb/project/StructField.pm delete mode 100755 org.glite.lb/project/at3 delete mode 100644 org.glite.lb/project/build.number delete mode 100644 org.glite.lb/project/build.properties delete mode 100644 org.glite.lb/project/check_version.pl delete mode 100644 org.glite.lb/project/dependencies.properties delete mode 100644 org.glite.lb/project/events.T delete mode 100644 org.glite.lb/project/glite.lb.csf.xml delete mode 100755 org.glite.lb/project/properties.xml delete mode 100644 org.glite.lb/project/run-workspace delete mode 100644 org.glite.lb/project/status.T delete mode 100755 org.glite.lb/project/taskdefs.xml delete mode 100644 org.glite.lb/project/types.T delete mode 100644 org.glite.lb/project/version.properties create mode 100644 org.glite.security.gsoap-plugin/interface/glite_gscompat.h create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h delete mode 100644 org.glite.security.proxyrenewal/.cvsignore delete mode 100644 org.glite.security.proxyrenewal/LICENSE delete mode 100644 org.glite.security.proxyrenewal/Makefile delete mode 100755 org.glite.security.proxyrenewal/build.xml delete mode 100755 org.glite.security.proxyrenewal/config/startup delete mode 100644 org.glite.security.proxyrenewal/examples/renew_core.c delete mode 100644 org.glite.security.proxyrenewal/interface/renewal.h delete mode 100644 org.glite.security.proxyrenewal/interface/renewal_core.h delete mode 100644 org.glite.security.proxyrenewal/project/build.number delete mode 100644 org.glite.security.proxyrenewal/project/build.properties delete mode 100644 org.glite.security.proxyrenewal/project/configure.properties.xml delete mode 100755 org.glite.security.proxyrenewal/project/properties.xml delete mode 100644 org.glite.security.proxyrenewal/project/tar_exclude delete mode 100755 org.glite.security.proxyrenewal/project/taskdefs.xml delete mode 100644 org.glite.security.proxyrenewal/project/version.properties delete mode 100644 org.glite.security.proxyrenewal/src/api.c delete mode 100644 org.glite.security.proxyrenewal/src/client.c delete mode 100644 org.glite.security.proxyrenewal/src/commands.c delete mode 100644 org.glite.security.proxyrenewal/src/common.c delete mode 100644 org.glite.security.proxyrenewal/src/renew.c delete mode 100644 org.glite.security.proxyrenewal/src/renewal_core.c delete mode 100644 org.glite.security.proxyrenewal/src/renewal_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/renewd.c delete mode 100644 org.glite.security.proxyrenewal/src/renewd_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/voms.c delete mode 100644 org.glite.testsuites.ctb/LB/Makefile delete mode 100755 org.glite.testsuites.ctb/LB/lb-l1.sh delete mode 100755 org.glite.testsuites.ctb/LB/lb-l2.sh delete mode 100755 org.glite.testsuites.ctb/LB/lb-l2Stat.sh delete mode 100755 org.glite.testsuites.ctb/LB/testSocket.c delete mode 100644 org.glite.wms-utils.exception/.cvsignore delete mode 100755 org.glite.wms-utils.exception/LICENSE delete mode 100755 org.glite.wms-utils.exception/Makefile.am delete mode 100755 org.glite.wms-utils.exception/bootstrap delete mode 100755 org.glite.wms-utils.exception/build.xml delete mode 100755 org.glite.wms-utils.exception/configure.ac delete mode 100755 org.glite.wms-utils.exception/interface/Makefile.am delete mode 100644 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h delete mode 100755 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h delete mode 100644 org.glite.wms-utils.exception/project/build.number delete mode 100755 org.glite.wms-utils.exception/project/build.properties delete mode 100644 org.glite.wms-utils.exception/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.exception/project/properties.xml delete mode 100755 org.glite.wms-utils.exception/project/version.properties delete mode 100644 org.glite.wms-utils.exception/src/Exception.cpp delete mode 100755 org.glite.wms-utils.exception/src/Makefile.am delete mode 100755 org.glite.wms-utils.exception/test/Makefile.am delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_main.cpp delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_suite.cpp delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_suite.h delete mode 100755 org.glite.wms-utils.jobid/.cvsignore delete mode 100755 org.glite.wms-utils.jobid/LICENSE delete mode 100755 org.glite.wms-utils.jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/bootstrap delete mode 100755 org.glite.wms-utils.jobid/build.xml delete mode 100755 org.glite.wms-utils.jobid/configure.ac delete mode 100755 org.glite.wms-utils.jobid/examples/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/examples/testjobid.c delete mode 100755 org.glite.wms-utils.jobid/interface/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h delete mode 100644 org.glite.wms-utils.jobid/project/build.number delete mode 100755 org.glite.wms-utils.jobid/project/build.properties delete mode 100644 org.glite.wms-utils.jobid/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/version.properties delete mode 100755 org.glite.wms-utils.jobid/src/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobId.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/cjobid.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/manipulation.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.h delete mode 100755 org.glite.wms-utils.jobid/test/Makefile.am delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_main.cpp delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_suite.h delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_suite.h delete mode 100644 org.gridsite.core/.cvsignore delete mode 100644 org.gridsite.core/CHANGES delete mode 100644 org.gridsite.core/INSTALL delete mode 100644 org.gridsite.core/LICENSE delete mode 100644 org.gridsite.core/README delete mode 100644 org.gridsite.core/VERSION delete mode 100644 org.gridsite.core/build.xml delete mode 100644 org.gridsite.core/doc/README.htcp-bin delete mode 100644 org.gridsite.core/doc/build-apache2.sh delete mode 100644 org.gridsite.core/doc/delegation-1.1.0.wsdl delete mode 100644 org.gridsite.core/doc/findproxyfile.1 delete mode 100644 org.gridsite.core/doc/fuse.spec delete mode 100644 org.gridsite.core/doc/gridsite-delegation.8 delete mode 100644 org.gridsite.core/doc/gsexec.8 delete mode 100644 org.gridsite.core/doc/gsoap-devel.spec delete mode 100644 org.gridsite.core/doc/htcp.1 delete mode 100644 org.gridsite.core/doc/htfind.1 delete mode 100644 org.gridsite.core/doc/htll.1 delete mode 100644 org.gridsite.core/doc/htls.1 delete mode 100644 org.gridsite.core/doc/htmkdir.1 delete mode 100644 org.gridsite.core/doc/htmv.1 delete mode 100644 org.gridsite.core/doc/htping.1 delete mode 100644 org.gridsite.core/doc/htproxydestroy.1 delete mode 100644 org.gridsite.core/doc/htproxyinfo.1 delete mode 100644 org.gridsite.core/doc/htproxyput.1 delete mode 100644 org.gridsite.core/doc/htproxyrenew.1 delete mode 100644 org.gridsite.core/doc/htproxytime.1 delete mode 100644 org.gridsite.core/doc/htproxyunixtime.1 delete mode 100644 org.gridsite.core/doc/htrm.1 delete mode 100644 org.gridsite.core/doc/httpd-fileserver.conf delete mode 100644 org.gridsite.core/doc/httpd-webserver.conf delete mode 100644 org.gridsite.core/doc/index.html delete mode 100644 org.gridsite.core/doc/mod_gridsite.8 delete mode 100644 org.gridsite.core/doc/slashgrid.8 delete mode 100644 org.gridsite.core/doc/urlencode.1 delete mode 100644 org.gridsite.core/interface/gridsite-gacl.h delete mode 100644 org.gridsite.core/interface/gridsite.h delete mode 100644 org.gridsite.core/project/build.number delete mode 100644 org.gridsite.core/project/build.properties delete mode 100644 org.gridsite.core/project/configure.properties.xml delete mode 100644 org.gridsite.core/project/dependencies.properties delete mode 100644 org.gridsite.core/project/gridsite.core.csf.xml delete mode 100644 org.gridsite.core/project/properties.xml delete mode 100644 org.gridsite.core/project/taskdefs.xml delete mode 100644 org.gridsite.core/project/version.properties delete mode 100644 org.gridsite.core/src/Doxyfile delete mode 100644 org.gridsite.core/src/Makefile delete mode 100644 org.gridsite.core/src/delegation.h delete mode 100644 org.gridsite.core/src/doxygen.css delete mode 100644 org.gridsite.core/src/doxyheader.html delete mode 100644 org.gridsite.core/src/findproxyfile.c delete mode 100644 org.gridsite.core/src/gaclexample.c delete mode 100644 org.gridsite.core/src/gridsite-copy.c delete mode 100644 org.gridsite.core/src/grst-delegation.c delete mode 100644 org.gridsite.core/src/grst_admin.h delete mode 100644 org.gridsite.core/src/grst_admin_file.c delete mode 100644 org.gridsite.core/src/grst_admin_gacl.c delete mode 100644 org.gridsite.core/src/grst_admin_main.c delete mode 100644 org.gridsite.core/src/grst_asn1.c delete mode 100644 org.gridsite.core/src/grst_err.c delete mode 100644 org.gridsite.core/src/grst_gacl.c delete mode 100644 org.gridsite.core/src/grst_htcp.c delete mode 100644 org.gridsite.core/src/grst_http.c delete mode 100644 org.gridsite.core/src/grst_x509.c delete mode 100644 org.gridsite.core/src/grst_xacml.c delete mode 100644 org.gridsite.core/src/gsexec.c delete mode 100644 org.gridsite.core/src/gsexec.h delete mode 100644 org.gridsite.core/src/htcp.c delete mode 100644 org.gridsite.core/src/htproxyput.c delete mode 100755 org.gridsite.core/src/make-gridsite-spec delete mode 100644 org.gridsite.core/src/mod_gridsite.c delete mode 100644 org.gridsite.core/src/mod_ssl-private.h delete mode 100755 org.gridsite.core/src/roffit delete mode 100644 org.gridsite.core/src/showx509exts.c delete mode 100644 org.gridsite.core/src/slashgrid.c delete mode 100755 org.gridsite.core/src/slashgrid.init delete mode 100644 org.gridsite.core/src/urlencode.c delete mode 100644 org.gridsite.core/src/xacmlexample.c diff --git a/org.glite.deployment.jpis/build.xml b/org.glite.deployment.jpis/build.xml deleted file mode 100644 index c2bf066..0000000 --- a/org.glite.deployment.jpis/build.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py b/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py deleted file mode 100755 index eb75155..0000000 --- a/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py +++ /dev/null @@ -1,492 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-jpis-config v. 1.0.0 -# -# Post-installation script for configuring the gLite Job Provenance Servers -# Robert Harakaly < mmulac@cern.ch > -# -# Version info: $Id$ -# -# Usage: python glite-jpis-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file - -class glite_jpis: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "1.0.0" - self.name = "glite-jpis" - self.friendly_name = "gLite Job Provenance Index Server" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - #------------------------------------------------------------------- - # Start Index Server - #------------------------------------------------------------------- - - pid = glib.getPID('indexd') - if pid != 0: - print 'The gLite JP Index Server service is already running. Restarting...' - os.system('%s/etc/init.d/glite-jp-indexd stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite JP Index Server service...' - - os.system('%s/etc/init.d/glite-jp-indexd start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('indexd') - - if (pid != 0): - print "The gLite JP Index Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite JP Index Server service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - #------------------------------------------------------------------- - # Stop Index Server - #------------------------------------------------------------------- - - pid = glib.getPID('indexd') - if (pid != 0): - os.system('%s/etc/init.d/glite-jp-indexd stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('indexd') - if (pid != 0): - print 'Could not stop the JP Index Server service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'JP Index Server service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-jp-indexd status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - jpis_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(jpis_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], jpis_cert_path)) - os.chown("%s/hostcert.pem" % jpis_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % jpis_cert_path, 0644) - os.chown("%s/hostkey.pem" % jpis_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % jpis_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('client','max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['jpis.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['jpis.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['jpis.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['jpis.database.name'],params['jpis.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['jpis.database.name'], - '\. %s/etc/glite-jp-index-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - else: - print "\n==> MySQL database %s already exist\n" % params['jpis.database.name'] - - self.mysql.stop() - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['mysql.max_allowed_packet'] = "17" - params['jpis.serviceName'] = 'JP IS Server service at %s' % glib.fq_hostname - params['jpis.serviceType'] = 'org.glite.jp.index' - params['jpis.statusScript'] = '%s/etc/init.d/glite-jp-indexd status' % params['GLITE_LOCATION'] - params['jpis.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - jpis_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % jpis_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % jpis_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # JP IS configuration - glib.export('GLITE_JPIS_PS',params['jpis.ps']) - glib.export('GLITE_JPIS_DEBUG',params['jpis.debug']) - glib.export('GLITE_JPIS_QT',params['jpis.qt']) - glib.export('GLITE_JPIS_AUTH',params['jpis.auth']) - glib.export('GLITE_JPIS_DB',"%s/@localhost:%s" % (params['jpis.database.username'], params['jpis.database.name']) ) - glib.export('GLITE_JPIS_PORT',params['jpis.port']) - glib.export('GLITE_JPIS_PIDFILE',params['jpis.pid.file']) - glib.export('GLITE_JPIS_LOGFILE',params['jpis.log.file']) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration("%s/../glite-jpis.cfg.xml" % glib.getScriptPath(),params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - - # Instantiate the service classes - service = glite_jpis() - service.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - sys.exit(0) - - if o == "--configure": - - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure JP IS manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml b/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml deleted file mode 100644 index cd56a80..0000000 --- a/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/build.number b/org.glite.deployment.jpis/project/build.number deleted file mode 100644 index 58569c4..0000000 --- a/org.glite.deployment.jpis/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Apr 13 09:36:57 CEST 2005 -module.build=232 diff --git a/org.glite.deployment.jpis/project/build.properties b/org.glite.deployment.jpis/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template b/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template deleted file mode 100644 index d27cdec..0000000 --- a/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template b/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template deleted file mode 100644 index d27cdec..0000000 --- a/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/lxscript-rpm.xsl b/org.glite.deployment.jpis/project/lxscript-rpm.xsl deleted file mode 100644 index 7b6c6e3..0000000 --- a/org.glite.deployment.jpis/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-jpis_installer v. -# -# The glite-jpis_installer installs the gLite Job Provenance Index Server -# -# Usage: glite-jpis_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-jpis - cd glite-jpis - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite JP, please create or update the configuration - echo files /opt/glite/etc/config/glite-jpis.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-jpis-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-jpis.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the JP RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the JP RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpis_installer v. - echo - echo The glite-jpis_installer installs the gLite Job Provenance Index Server - echo - echo Usage: glite-jpis_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpis_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.jpis/project/lxscript-tgz.xsl b/org.glite.deployment.jpis/project/lxscript-tgz.xsl deleted file mode 100644 index 8b1e0c0..0000000 --- a/org.glite.deployment.jpis/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-jpis_tgz_installer -# usage: glite-jpis_tgz_installer [-u] -# -u uninstall -# -# glite-jpis_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.jpis/project/properties.xml b/org.glite.deployment.jpis/project/properties.xml deleted file mode 100644 index 072dd67..0000000 --- a/org.glite.deployment.jpis/project/properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/quattor-template.xsl b/org.glite.deployment.jpis/project/quattor-template.xsl deleted file mode 100644 index d960582..0000000 --- a/org.glite.deployment.jpis/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_jpis; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-jpis Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.jpis/project/version.properties b/org.glite.deployment.jpis/project/version.properties deleted file mode 100644 index 809be8c..0000000 --- a/org.glite.deployment.jpis/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.2.0 -module.age = 2 - diff --git a/org.glite.deployment.jpps/build.xml b/org.glite.deployment.jpps/build.xml deleted file mode 100644 index c2bf066..0000000 --- a/org.glite.deployment.jpps/build.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py b/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py deleted file mode 100755 index 3612d6b..0000000 --- a/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py +++ /dev/null @@ -1,500 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-jpps-config v. 1.0.0 -# -# Post-installation script for configuring the gLite Job Provenance Servers -# Robert Harakaly < mmulac@cern.ch > -# -# Version info: $Id$ -# -# Usage: python glite-jpps-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file - -class glite_jpps: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "1.0.0" - self.name = "glite-jpps" - self.friendly_name = "gLite Job Provenance Primary Storage" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - #------------------------------------------------------------------- - # Start Primary Storage - #------------------------------------------------------------------- - - pid = glib.getPID('primarystoraged') - if pid != 0: - print 'The gLite JP Primary Storage service is already running. Restarting...' - os.system('%s/etc/init.d/glite-jp-primary stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite JP Primary Storage service...' - - os.system('%s/etc/init.d/glite-jp-primary start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('primarystoraged') - - if (pid != 0): - print "The gLite JP Primary Storage service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite JP Primary Storage service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - #------------------------------------------------------------------- - # Stop Primary Storage - #------------------------------------------------------------------- - - pid = glib.getPID('primarystoraged') - if (pid != 0): - os.system('%s/etc/init.d/glite-jp-primary stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('primarystoraged') - if (pid != 0): - print 'Could not stop the JP Primary Storage service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'JP Primary Storage service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-jp-primary status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - jpps_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(jpps_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], jpps_cert_path)) - os.chown("%s/hostcert.pem" % jpps_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % jpps_cert_path, 0644) - os.chown("%s/hostkey.pem" % jpps_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % jpps_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('client','max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['jpps.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['jpps.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['jpps.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['jpps.database.name'],params['jpps.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['jpps.database.name'], - '\. %s/etc/glite-jp-primary-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - else: - print "\n==> MySQL database %s already exist\n" % params['jpps.database.name'] - - self.mysql.stop() - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['mysql.max_allowed_packet'] = "17" - params['jpps.serviceName'] = 'JP PS Server service at %s' % glib.fq_hostname - params['jpps.serviceType'] = 'org.glite.jp.primary' - params['jpps.statusScript'] = '%s/etc/init.d/glite-jp-primary status' % params['GLITE_LOCATION'] - params['jpps.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - jpps_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % jpps_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % jpps_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # JP PS configuration - glib.export('GLITE_JP_PRIMARY_PEERS',params['jpps.peers']) - glib.export('GLITE_JP_PRIMARY_FTP_PORT',params['jpps.ftp.port']) - glib.export('GLITE_JP_PRIMARY_INTERNAL',params['jpps.internal']) - if not os.path.exists(os.environ['GLITE_JP_PRIMARY_INTERNAL']): - os.mkdir(os.environ['GLITE_JP_PRIMARY_INTERNAL'],0755) - import socket - glib.export('GLITE_JP_PRIMARY_EXTERNAL',"gsiftp://%s:%s%s" % (socket.getfqdn(socket.gethostname()), params['jpps.ftp.port'], params['jpps.internal']) ) - if not os.path.exists(params['jpps.internal']): - os.mkdir(params['jpps.internal'],0755) - #glite_setenv.sh does not like variables with spaces, - #and su don't like variables with " - #glib.export('GLITE_JP_DEBUG',params['jpps.debug']) - os.environ['GLITE_JP_DEBUG']='%s' % params['jpps.debug'] - glib.export('GLITE_JP_PRIMARY_PORT',params['jpps.port']) - glib.export('GLITE_JP_PRIMARY_DBCS',"%s/@localhost:%s" % (params['jpps.database.username'], params['jpps.database.name']) ) - glib.export('GLITE_JP_PRIMARY_PIDFILE',params['jpps.pid.file']) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration("%s/../glite-jpps.cfg.xml" % glib.getScriptPath(),params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - - # Instantiate the service classes - service = glite_jpps() - service.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - sys.exit(0) - - if o == "--configure": - - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure JP PS manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml b/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml deleted file mode 100644 index ef13a02..0000000 --- a/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/build.number b/org.glite.deployment.jpps/project/build.number deleted file mode 100644 index 58569c4..0000000 --- a/org.glite.deployment.jpps/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Apr 13 09:36:57 CEST 2005 -module.build=232 diff --git a/org.glite.deployment.jpps/project/build.properties b/org.glite.deployment.jpps/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template b/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template deleted file mode 100644 index ec2b692..0000000 --- a/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/lxscript-rpm.xsl b/org.glite.deployment.jpps/project/lxscript-rpm.xsl deleted file mode 100644 index c9bec9a..0000000 --- a/org.glite.deployment.jpps/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-jpps_installer v. -# -# The glite-jpps_installer installs the gLite Job Provenance Primary Storage -# -# Usage: glite-jpps_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-jpps - cd glite-jpps - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite JP PS, please create or update the configuration - echo files /opt/glite/etc/config/glite-jpps.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-jpps-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-jpps.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the JP PS RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the JP PS RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpps_installer v. - echo - echo The glite-jpps_installer installs the gLite Job Provenance Primary Storage - echo - echo Usage: glite-jpps_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpps_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.jpps/project/lxscript-tgz.xsl b/org.glite.deployment.jpps/project/lxscript-tgz.xsl deleted file mode 100644 index 4589cf6..0000000 --- a/org.glite.deployment.jpps/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-jpps_tgz_installer -# usage: glite-jpps_tgz_installer [-u] -# -u uninstall -# -# glite-jpps_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.jpps/project/properties.xml b/org.glite.deployment.jpps/project/properties.xml deleted file mode 100644 index 41d9f99..0000000 --- a/org.glite.deployment.jpps/project/properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/quattor-template.xsl b/org.glite.deployment.jpps/project/quattor-template.xsl deleted file mode 100644 index d4dc67b..0000000 --- a/org.glite.deployment.jpps/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_jpps; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-jpps Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.jpps/project/version.properties b/org.glite.deployment.jpps/project/version.properties deleted file mode 100644 index 809be8c..0000000 --- a/org.glite.deployment.jpps/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.2.0 -module.age = 2 - diff --git a/org.glite.deployment.lb/.cvsignore b/org.glite.deployment.lb/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.deployment.lb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.deployment.lb/CHANGELOG b/org.glite.deployment.lb/CHANGELOG deleted file mode 100644 index 882b0d8..0000000 --- a/org.glite.deployment.lb/CHANGELOG +++ /dev/null @@ -1,40 +0,0 @@ -DATE: 13-03-2006 16:20 -[flammer] Increased version to 2.3.0 after branching. - -DATE: 13-03-2006 16:15 -[flammer] Merge of HEAD with branch 2.1.0 -[flammer] Increased version to 2.2.0 - -DATE: 04-12-2005 21:15 -[dimeglio] Added configuration parameter for setting mysql max_allowed_packet - -DATE: 23-11-2005 23:50 -[dimeglio] Use ConfigParams class -[dimeglio] Removed servietool instabce config params, put instance creation in script - -DATE: 08-07-2005 15:20 -[dimeglio] Merged from branch 1.2.2 - -DATE: 25-05-2005 20:00 -[dimeglio] Merged from branch 1.2.2 - -DATE: 21-03-2005 17:21 -[dimeglio] Implemented status method - -DATE: 21-03-2005 00:32 -[dimeglio] Added PERL5LIB env var - -DATE: 17-03-2005 17:33 -[gdiez] Stopping and starting the database before the index creation (just after the database is created and the user granted) - -DATE: 09-03-2005 23:05 -[dimeglio] Moved creation of indices inside database creation (if database - exists indices are not recreated) - -DATE: 02-03-2005 11:05 -[dimeglio] Started CHANGELOG -[dimeglio] Fixed formatting, improved display of message using glib.printXxxMessage functions -[dimeglio] Fixed some problems when starting/stopping services -[dimeglio] GLITE_USER parameter not exposed anymore in config file, use same user parameters - as WMS to allow installation on same node -[dimeglio] Increased module version number to 1.2.0 \ No newline at end of file diff --git a/org.glite.deployment.lb/LICENSE b/org.glite.deployment.lb/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.deployment.lb/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.deployment.lb/build.xml b/org.glite.deployment.lb/build.xml deleted file mode 100644 index 874c661..0000000 --- a/org.glite.deployment.lb/build.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/config/scripts/glite-lb-config.py b/org.glite.deployment.lb/config/scripts/glite-lb-config.py deleted file mode 100644 index c0158ea..0000000 --- a/org.glite.deployment.lb/config/scripts/glite-lb-config.py +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-lb-config v. 2.3.0 -# -# Post-installation script for configuring the gLite Logging and Bookkeping Server -# Robert Harakaly < robert.harakaly@cern.ch > -# Diana Bosio -# Leanne Guy -# -# Version info: $Id$ -# -# Usage: python glite-lb-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -from gliteRgmaServicetool import gliteRgmaServicetoolInstance -from gliteRgmaServicetool import gliteRgmaServicetool -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file -global rgmaServicetool - -class glite_lb: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "2.3.0" - self.name = "glite-lb" - self.friendly_name = "gLite Logging and Bookkeeping" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - pid = glib.getPID('bkserverd') - if pid != 0: - print 'The gLite LB Server service is already running. Restarting...' - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite LB Server service...' - - os.system('%s/etc/init.d/glite-lb-bkserverd start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - - if (pid != 0): - print "The gLite LB Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite LB Server service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - #------------------------------------------------------------------- - # Start Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - errorcode = rgmaServicetool.start() - if (errorcode != 0): - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - pid = glib.getPID('bkserverd') - if (pid != 0): - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - if (pid != 0): - print 'Could not stop the LB Server service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'The LB Server service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - if rgmaServicetool.stop(): - error_level = 1 - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-lb-bkserverd status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - if rgmaServicetool.status() != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(lb_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], lb_cert_path)) - os.chown("%s/hostcert.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % lb_cert_path, 0644) - os.chown("%s/hostkey.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % lb_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('mysql','loose-max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['lb.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['lb.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['lb.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['lb.database.name'],params['lb.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['lb.database.name'], - '\. %s/etc/glite-lb-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - #Creating the indexes - print 'Creating the index configuration file %s/etc/glite-lb-index.conf ' % os.environ['GLITE_LOCATION'], - path = "%s/etc/glite-lb-index.conf" % os.environ['GLITE_LOCATION'] - pathBak = "%s/etc/glite-lb-index.conf.bak" % os.environ['GLITE_LOCATION'] - - if os.path.exists(pathBak): - os.remove(pathBak) - if os.path.exists(path): - os.rename(path,pathBak) - file = open(path, 'w') - file.write("[\n") - file.write(" JobIndices = {\n") - for index in params['lb.index.list']: - file.write(" [ type = \"system\"; name = \"%s\" ],\n" % index) - file.write(" }\n") - file.write("]\n") - file.close() - glib.printOkMessage() - - print "Running glite-lb-bkindex ", - if os.system('%s/bin/glite-lb-bkindex -r %s/etc/glite-lb-index.conf' % (os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])): - glib.printFailedMessage() - return 1 - else: - glib.printOkMessage() - - else: - print "\n==> MySQL database %s already exist\n" % params['lb.database.name'] - - self.mysql.stop() - - #------------------------------------------------------------------- - # RGMA servicetool: configure servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - # Instantiate the rgma-servicetool class - rgmaServicetool = gliteRgmaServicetool() - rgmaServicetool.verbose = self.verbose - - # Create Local Logger instance - serviceId = "%s_%s" % (glib.fq_hostname, params['lbserver.serviceType']) - servicetoolInstance = gliteRgmaServicetoolInstance(glib, serviceId) - - # set params - servicetoolInstance.setServiceName(params['lbserver.serviceName']) - servicetoolInstance.setServiceType(params['lbserver.serviceType']) - servicetoolInstance.setServiceVersion(self.version) - servicetoolInstance.setStatusScript(params['lbserver.statusScript']) - servicetoolInstance.setEndpoint(params['lbserver.endpoint']) - - # add instance to the gLite configuration - if servicetoolInstance.add() == 1: - return 1 - - # Configure servicetool - if rgmaServicetool.configure(glib): - # error in configuring servicetool - return 1 - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['lb.database.name'] = "lbserver20" - params['lb.database.username'] = "lbserver" - params['mysql.max_allowed_packet'] = "17" - - params['lbserver.serviceName'] = 'LB Server service at %s' % glib.fq_hostname - params['lbserver.serviceType'] = 'org.glite.lb.server' - params['lbserver.statusScript'] = '%s/etc/init.d/glite-lb-bkserverd status' % params['GLITE_LOCATION'] - params['lbserver.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % lb_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % lb_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration(["%s/../glite-lb.cfg.xml" % glib.getScriptPath(), \ - "%s/../glite-rgma-servicetool.cfg.xml" % glib.getScriptPath()],params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - # Instantiate the service classes - service = glite_lb() - service.verbose = verbose - # Instantiate the rgma servicetool class - rgmaServicetool = gliteRgmaServicetool() - rgmaServicetool.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - print - rgmaServicetool.showServices() - sys.exit(0) - - if o == "--configure": - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure LB manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml b/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml deleted file mode 100644 index 4e11e33..0000000 --- a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - owner - location - destination - - - - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.doc b/org.glite.deployment.lb/doc/release_notes/release_notes.doc deleted file mode 100644 index 2ad2d4d1bf359419707777ee266496f87aa65f73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192512 zcmeF42S8KT_s4HSAb=psaF0}R3$k3e5Cu_jfuk-kK!7OA1XQfMR;_hZ+uGI+t=c;3 zsC(2=M_v83?rrO;t1hh8E&RXdy}aZ-NDwLdSDWaEymjX}_uO;uyYFTHzLICZSzhiO z%k^o_Y*==V1G5tyx52hvW;jrSu?%d}Zgx&i4joOy&Oo38IAs021~qW~+pTP5KL-V4 z4_vqKqJ?Dff#7>~Vyrle=^xYo()df``IF+m4vJE&wyTVdy}>xjhw^8uky400uGl6$ z%E@st9<{VBTriK@*k6_3r*H8#9Sy3%pA&z(^M|;Fe;D7M_^t9zJ=?AZ;Ds^ z$z8ufd4+3ee>WsM7U4?aVAN{SXxA)bEK8JmqD!amiH_#?z4K30%z zp*)u2qj*oEK1ct-m=8?Yf@+Mdqllp&K?O;`!Zk-OFjfKQgz}7qzBpk&=niUw zwgEx!#{R(A+c>}c9Akl^IDfy!Sdt@SGf^KtI8ORUpKG}8FT~RI3BP|D;p0)Sw4aVc zw~>BPd?=ncL%ibn1pVrEg|P{!H=&+|Z$VzdzVI!M!`!yhe8z?%y>Z_&_AxFf2Ym_0 zx1f*0x4E$5W5JLs)&H|TLcVf;3-z4)c}o} zSEVOvRL_o3m7E%vk)%-#@>cnI`{JLfE5gO6CMBf~reyV+SV}{$O4Fqd(#C02>bN*9 z9Z@H#v?=kax@0x&snjv48R=Y_;*4lg((7^u4XMOw(ljY?nv__rM$exZkdiuB6_b&m zSE*CtR9d}0L&I;XRY_WXx+*oEKO38rs@KG+^xBkI4HsjYPBTcGnqe%sw<yo-q;OTMPSU1lLWUY0Di@@rs!XR;vF0Q47RS^oH6>n~kfGx;Lotcu zm!cW0N>l69$(nSHPOnN-57MY&G#UsjE)Ml6lnHszcqPSn$Hpgk4@pi^#cPu^fzHmI zg^;Qg#Gq`giC1SNrK<+1lQL+}sDetRE+JX%jVc(Vjn$;5rY3o-QMf_sbd54yhikiL z=u%XvDfLq09st8mIAg?j15jos2pUR8b&RUsdm}nQ7Ro5rY^t>XaIN zl}f!P-8(r`KQPH#mztXHou=072dC=dl=12$y++wKp096Xk)cvtWSq8a;4b@+lQs+yJgecR=>J)VXUpjqivPPAPyy;Yf)tO?!aMj$`AQyvJ zAQiqklGQ_^(biH2YvQ8Q)Ug9J=}O;*%3O88T>zn^@-<9#pC_28%D5IJ$VXZrQc_ht zO?qs-4=2%Rh^QV zoQfn2l_rgds*A58qeAKhjiSI715sM3s4gAZe@*E>+7ax&$m4vBy6Uns&%-Y>VyyE#b?EfPYz%F72dkE58JOgo39hu7Wh3Hd(F9E%2e9t4&2cMUs50Ye27fAJG)JXoxitA;t-b;(lLl>`(g%3z;*F8z^rY3pbxNF4as3l{E;r)-68C({m)2W}Q+;_oRlcbjD}^S`yr}*R6K95g z!q8{snN7eb-89LgtPjKR5(ZTk^614SkLLH{2U!Krfw5vSbIr{NcqQml)oEU7Ng0?` zS0+SuYS|g{y0pX1sU+xyo(^*c@H=0EVKs$9kRy~K(!pDHS)wdnrhb5D{QCY|XXjdZ?QeAlvIlcSiBGlI?ii^`#VKwEm^vhkhYIIVYldJt z1@~$7;u%wJs+7+U1ctcrSDzH?Unr$6TnePTY3aBvq*1lOEd^C)Zl0HJ%XY=|`~ciS ztJ$V=*ILT%t-Dg+;ipS%T+|hS^u0vU7gBXC7vFOHRCp9xkJ}?kDt#nv&}^4){UR@< zAsv*CqA&VFT8tls?C+=3DBGzAsa5SFLQuef!uqL}E18n;@{JCN_KWsujLDf;6fq=I*-EFunuc^O<_B~d++@+Fr(#}CxV24E_9hVr6t#d2>63f| zyh7T9gcNZjwj4hS-yt)yOSoZzlHXBzsakRKmC688xI&J0ElWe3q8Fb;A>Eb2reQ2L zKi=hw{X$D?7+Am1(ppLbrA0rKr3B3WtN5>^e7j?*=&n%?!aarIi(YuOF| zBU^=a>)NXpbl#`Pl|Y&!sJ@S{SK}hq`~1^DwG4_&k4{KRjmgkQYxH`)>Fbrr#`s+7W^qQX)^$Th%fpQ>BiLP0gT{d|c60 zX!HEiAo#SY89FS1iNz`pqK?5TF|1%pz!E3AzX56BhH8AO z%FB-$A68pJp?!UPd{h`#7FmgWeHu36rNeC%O__v9J7ArxU?$SF$r{WEC#UIYfnSZt z*hDmaEGDbL&2H9+;PtNtEQLBfqv(p~Ti?GvCox~zDx%^UB5ju%LpLImsg$tX@YZ0O zG_=GGOACui<$V1Ed>ip4psgY*fgw^DU1(i0H5^)3MK@Hjl$w)(swTt)%Sq)+C!2Sv zY44=v7Rc#UXfc{t_;s|nB1sD=p=G70jEhE#u$&DW8${KpVdEkzCl_fXE#Ref#VW&^ zQD|hEI)P-z_4i3JI4}guO|gp9&|7(Xdly~N8v6-F!&XrhjgOS(jre7UqOLX$YiRYV z!RWRURKfyavg?D?I#nE&kjB!Gya9BD!atst8NdNHBzr8x@%$L{unEC>$@?IH(z{ADm62;JD=!{Bi>- z5_eoh(?qDwqH&LW1N;Jbr-IumA|*6L3U3<@5xL>CqB|b$ahz&khDMi3h90JZbkA^s z9{#&No;v|kkNHko>}+tHxtqCoqNV7{?C)=AcmdcdsxtGD_TXBVv_I3R1}DO0=QS3K z(P_0d6^6WbJ*L2iK=|Cca=5~%lH3pN;31$GJT@deGJ&T#434DjJq zq@ll05&4}I6W@&a-bH0tzaN*1B~{TVX|yUHjl%TwMV^N~uol0l^Z}XSy)@b=8f`E{ ziD!j`$5y=YI127Fpu^#xE1*@JyyrtVgSq=4MOYpmuFFI&e2T0*6lF#liUaG)Kam3? zEM9xB!W;qJ5`sk*t}raaKuHbqEwUo|)c5C$h>apDA|EBplGNcLJ;Wnw;s>C3WgJXT z;?V;oMO7$tZhpo-#;@r57%tLOU4l3N3;~qVF!JVa*>R3rd`41|s(Ysnkx)v9DpKgf@z*L|l~AKm;4W4}j1vxOoQ}JCG;JxuE2IQ}2bM^477a zO4g`>Kd*DNQ8XnpL>bb$O>~d&=-M=X)6xVU_arq6U|5r0R3&KG*w^4sV54YCV2HAH z20fTbE`=I*gwrwl=B81(dzg6WGAXGjr{a7JKEH2$pQ7^lDJr-j#_<~OIe4dKa!-N| z#-o;yNm!@It{q!;2#Gdz!B`sPjpwlkB&Dk3_y>x0!eim4XDRt{dJlBTm{g`YzM_(+ zuTO(U4LI+K+bSA~3X$@%6CS(aohJ-k=@t`tzx0SD_v!^|cyVex5iA-BNnT%&q{eL! z!woR$-7p$3t)eM_ z5NQZEt0&Bbd2xEhm4tHdY~$>#a5nsPc6N4Cwe8p{yj$y#&TU(D?G_R8%!jG*=q)`; z&FO5k9uM++_fJcxqUuvy)gdIJO-N{`hz>2gw(S_wRpl=8P(~PDCex9gOINl|jrCTw z<(4?%^%uH8q#oKfJcKO2Dpw3DcY|G{nGU=OB`!6VvaiIN2)xI`&!?V`Z#_K7-2f$W zc5WNl)eAfRUiEz%HS+hTX}``b+n9;d-$PYT<)-S`tplBp%$q1~;ZlSaKhOUvp8uZ^ zc6c|RJ!4fsRnP!51U*1H7y(9s(O?XC7rY041Y5y5a1-1DcR)=C#sWYypa)aIhhQ4m z1NMS*;4!F;x1QAje_uXvVCUvFo0opK^t;VpZ~l4)*!=aBHRDE188jfacO>3ISSoQ| z89$aB=Ah66+CMjZtYn`*?}YPC3g+&Sc&qMKCWJB^MX0In16WF!gMB)nSb`(8(*2m9 zB>UC9R!a8$WZfkD*SepQ>{G79@qaLInPmU_8q)Lo8=f?sN3JQpQrzEUl!Ge^a!FSi z_se-CCdKzQToq_Px{3X0<2my{ALK0b&g?JVJo9qxs1CHS|kGQ2b{A&%6YDdfTyUIphema&o`3iJcQHMB))#S}7Z z)paO~tp>s|Cz5~pj(AHQ-t`#)-Ud(cdF|@Xn&IcH0fmCeWD2ssLR%k+?a_eR`;Xu- zI08<9lb}j5*b3kYT7qEkK9~sp1Q$VbyaKZY_!O)I>%j(a2pk0}XU5(FL%>il8+-%i zfOW-jJ-7regIdsdFHjHogU;Zeo0tB$ba2cytHdoo_`BheRJun8B@lM7?eWx zJzsl^^Er+!O!gQ1yXs7p>{Bx{+H)t5#N@KO4ZRAp<9ioM<#b{LQ(putPN7OAu2WVq z9mQ3WedASpzh&sxaFnjfb!};n#BaOX8Pcs!=AOSCahmT14Y47=d`{>u^@*lfgedBe zJttX{oJqzEG9(!rURufPRFqh?Bs=ZJXCyn~6VJabwS-hBMoS1=2tD9leJQ<4VlPEk zO=fIB9AyEvwX|Sf8i}`IMs~wV|UY5dH{QN zW888dbHuA!&&u46`rt$krBu*w_j|b5qk*jSJ-mCh4E-rb?T70Ms5{6hFWs#m-K{9y z4LEAYWVVQe+i*;* z$lrlv8xImdCG@N0b4>v6gU`S`uox@{_r>z~+v3g*@tG?YcMgir6mUlzbA>KtIwOvhA=aiDBShgOXW@~Pf#Sm&bB!>jqj_=y zpFj7UQ|>Vfg*L{9>vPXRiRYZk3v%58Ig)Hit_L8meqw2~E5wdC$n$QS(|4*zLEp&< zMn1`#o<+|6;pa8(eVF3o96#kq7q#2ds!UM|jV9Mek#6Rg2UIE7M{yNxO8WU1F28)H zo7mq+8BP8^ZI?fq=TL>bhbrbhWYPa8Ssw)F!398V_AuIMKXI8}b@@+*te&fLx5{4_ z|B+4BfOv2a90E7MP4EaLU_`40{lNfm9Gn0T!6RUYpSsBe?|@-oILHFGK?$_ulAt1( z3Z{YS;3HsL3SmJQXbZZ5U%;>6>WSSa)}L6ie#xi8#%N(+WK*@^v9+(SVZ z&;z^;(m@6o3f=+3zyxp?+ynQ)0}xjRekAx3d<7N)58P@l4a$JBfb;9%*5Th*)5c6o z`l|O=oSPSN0=*XF{gy9af1d5P7{~r8J#6zE`~L-RMl|-PtId!7=}f6a;k;y&4nNN9 zaibq5oXzD|{{Q-aB{5KZc0ICk)YiiQ$(rO$GLDDrUOD?uwQOnpPm@d5_Ft&>PqIz` zgTV|y?RPxd>MJMz{N{h$U^J}qFO>YrF24uHfo0$auo2WOhxK`&4yX%01D}K4U=KI~ zT9#+56=)4Yz;dtxoCD{y8{M;As`c61J^;rN{lrE zt-&^M>&*T$JNEBbdd9HvnXoZN*hn&L2))T*RY9yE-}5X*iqE!~{IyR}`hs2?ju!Ro zYYW#~82cca12@yNJ##jpHnsH$;4`ogkPgg5>0Yb$zXP3?wfz^W{gbS}0N;acfZF#; zYPU@EdDZ8CGmvSk{0k+2lJzRE7n}lQyN|;zzgF_E4%2Owf1%`0vOWQBfh<7%@(ony zYbF0%m96p@-6?#Y`CpRtP2dFo$`_E&6^iP7t>nM1idFuFlt1~^JHXFiCuj}Xhkyy- zeeelzRx#!RN`R8!eJ~N60;j2yzyYFhB=LaBU@G_!Oat~+aURqK zUZ62p29|@nfBd%Tx23<`U3&L3VPlN2ktA#|%OBoPFIKl8zBhkuxmpFkwsG}>T$}&u zk7xSk>{;GDpYI^lR-wli)u^qv0kL2VAh~}4dG-@m?W^wpEw5&6|AlP-BB@OuMOIQcAz`h4fcXx!2dvVbhRx&OVAO#4KlzGFciE4 zhJoQ=1egcD1>b?y;3selNY{9M^ufFD=m+Qryz@cqyWPXPqw8@k#jTvBIZfkQ)-oQ6 zacyDzESgn#8lcLROL5dR-6(yV^p7`zrxA7ruj2@^Nt?4vSQq}wpKg02)v7|4vyxvAQBU!&=oJA4N=31v? zoTU-YOG5KG_y9UC>P-dzBUenuzMIaQUAxW4=32iXvEh!ekd7or#_|YfbLGNV9^t$s zG&~(TE_goWN$yv`Rd53ohwMns7r|ArL?m+nk~0O|5l5E)HfPgqQ00Z`)2%K4IczMm zBRNx>y#*csYP);UPWy>PB$0gqcf{eJciUVEsC8Oe|CJ5{VbzsF`F~`ScY{6P7qA~3 z0mr}@a28w#b!#!^4e*>L3kMxQNAMxQa-8jJzWr>%u;gLAhP9sHpI6)kwTy{P3t|~P zJrXC>9%~o}3U-#>XhK$v-VesT-3xZmbQO&jC3di|))iyWv1R9)8-t>ZAN6$?oku5&ejoKax6xnN=t>(T1Kx8w z)T$u%fxkAQWkIerwh+=Sb1lS>^10>(iOrH#F}7k#C66u2<&&|3**9a`7vjv-_7MyJ zB%!!uxviv1koj83`V=79e-D}V6DxkZLhOixJn!~%w0+K3>FEYbO8yg;?cZ$o5b2J_62xmXLcZ&>Dn*Z^3uq3^)s}gI>6= z)CcqhQQ&{zSFjK42baKoU|SFO1VJVk3dVsIU=>&m)__|V4qw=OYssy{wDBozO#NW$ zyHhi?Q=_JK(vktH$i2a5N_)=t;@{2*FGm<0;r%&umoC>^J4*}i>Y;O@tIL&2+|w=# z-j|$pYG=c`03jlJhv)W4xoIEw`?%W-I4-#l$a|JY!V2OG7Syxs8d{Lp^7kMu`JK=5 z5m_Z_>kGhUa0rmBe}nv9EBoI809@0n7LQI*45bSYp#B z(6lMuD#qRN<6h=hhH)=5qag~z_#1ZuxqWJM4%}`-!x3t_;x|~+oj|&Z^Z)H&AguB) zjQs7$4xa}Xz@OkExCF#{@EE#K47b>wfHSBLYJfB_5DW%GKqeRpwu2qu61WVmg1^8u z5a5S*N`fY!DQE_ogYjSjSPoWzRbVw(19AYvtfC!If;;%VfIVB+FJHg#z``#k4mbTv zGi^>B&hKDmjg+fY;?R(du>I~P8;>(|%*>g$_#Pzpc~M_dUVIL3WEMw^KBI2mfu?kF zkM6PG)9ibaEpzezdJtfU@2t8k2YUhst$yktY8OX^K zR0AaIyW+-sy(n+P1VM zSSll@CEr-J#N7Me71W=S>>WS^hy?F~v4C`8JfJ&z2f-n55}X33!SA337UI}eSYF@^+<^xzH2|f78pMEa!FON*SO^w@yWk)2 z1Uv=VAP3wz&;2{Xe-(b`e})LC{gl9OP1t@f@=oX;p#@Lo+5U<}U#GJmW0GeaWJB_M zP1`?tbLQ?Oa_zrVM{6%(=Jy{ILVKmQSsiVO+Txoi{|~J4H*5a|+e>!#2_U=rCd!|6 zvbKM7?O*6esn6U3sE>RT<)2}dzuERL_(bIY%m?J}yovJv%PN1f@)!JD@@2;~g6|LB zMEOT|w%UJl_MgTtZ6Wh^U=$b)NC(D(_rN}|9~=Y6!3l5@cw*&WH4qK@ffx`A;=od{ z46Ffb!8))W*x-JE0(b#$-~)Vt9~cIPgR$T}Fb<3d2f#sKi`9L0z#cdNN6-~?1ARbW z5Cx*aLa+!t1dqTI@DyZ&Fsv|b3p#@?AOb{!ufW$}C)fq{fW3eXJ?P#bKcDF;%t?l2e{TJFTwb6QLXVfO&MESSv zVzvL~?7v`x$=)hqAIZMHiSplUmA~2cFZ8F>cRmKxSH6kz_m8l)e{=0$@Quh1+HLTA z-bDE?u*%FQb%RAz$o@d*GTNs2}zM@}4 ztk`ISY3?79l`y<9fLo+(Ihi#iMChHQ%<{wc@DkeYl##>JEk@(w9hwD{>rX}vHu47n_VUJX2@T# z$7Fjq1G2SmqWp(h8i0x513-9W`Iw@XW%@z0R9Gdz(3#~ zxDQ&kMtIN`v;*xyIG6!G1wVp~U^CbPegY17aK#an040Gda07inUoaU=0Uv^CU^+Mj zPJ{E{0?0aT{I}1vc{;1`JH|DCH0BULWWbE01Kz*4I3_WUKtxxVMj$LgkSWP;0AxY( zdK26KDQo*TYyXAzNo_HR+75UV<=?rx)&85a|AMV0yLuOp9eoq!|Fc#8X4}8eZ&Dw* z2~eN-Cdxmshqe8iYyW}|ME=fHK>p2}DF0?8n7Feg(L{AB%QG_jU$$Uc!yUm~mu9NAlcQG2YuTd)7F5xCNu^?yUFCi+9X<0w zXX%@J4_)muHP`j|cqOq<-6^nD$cev?G`9Pa@u$zAI<4~xJ6e!L9t3v1-b z!VGT>qe|n~|0N^K*8U&w-#Ti?WR5mTOnuJ=GO;5$7Y9OHrgnP}P&>UY7T*c+4o;dr zcyh?}vAkorMydn(-m^WQM`i_Cv(?$A8~6UFjZ{AA$IiC0^Z@qk#>;Xad&SpmNo&wj zE0SJC7RLB)43t+`A8RMrW3s(pfG>fh-A9RQ$MTN&s+YDcEn~jA)B{TwpTGSZbV+We zLMZ(6-%^`_6Kk251k)1gvA&rJ8qxs|jfsDozC{BI^Tp!fWhVCaht=YwlI zv}#uuZ(gi~4vPxtRO{+Qa$W zKE$&Hu{>%Ki~2HThtUiWu=9u zM&vUJ@|M6i-~Nkjaz)6VY_bZFO|A;aCRYb!lWPKrZfH%m6Qe!xPKe+_Z#{=dSq7W%15w@y;Rf z4hEQ}k0b)&@cZ=gSKH*=4Hj>A4UpL$EhAiJFGH^>`q&@E74SfmJIl?f+RttT#*xxb zKf6+H(j(ZjJ8hr)nA=ew9Lg~qHhhm_@C4|S>o~vfeh(*$_RX)3HlZ{~3&racWez3r zYHT^|m+;7&ycl=HZC+EdYR03^bX4XxZxx2ak~4e^GSRg%?k9Ea$%onwc7P+`C?MIB z+)sit;2OvQ^bRc*k6yg}%jUH| zES^7W@vIqu`#XK{l*Lo>_tH2aypTV+JuY}=oIw#hw34L~>37tU!x(f2AQVAsZ9`Sz(sE zSIkqH;xdLcBvet5Gs*ZmxB+g0TR@QcJ#lSc6YumB?^qrj!uFazScql%!0WK|ad0JF z7Hh1Xt4Z0J41+(kxev%z{Px_oLizD}nZ#bG%-9RnYilnA>oCMrVQNn~XGJ76%Iv94 zHwDc=b0Dvktw3uK0zyF>5C$YVks+3$Uc4i57ye&%_y>WZEu%?OzDUX2tDsBC z-IWMM;8bKoj=!>!Y8757o|&ghVRqMy{gDue+0Do^^~7~4`F9}*F6ml?E~VU2C&MW^ zol{=ATS2;8QMzlG?c+KUtka+tCFw<&Gs&_oXb0MZaL@sC1f4)l6B`EQ)l_c8^_9WZ$HdP1ND84L_Tf*|0ZYJ@{ODVYc3ux%lK) z?R{Z0TL0UowSUiFnGZMoR&vr9wurS~Sd8pYX^;vMSvvluu|QT2{}Nad(_&x4yxCy< zjlp*;zI7~x+e(yNQxD%bzhWy*~g&ZQz`Ji;e1FD{J+NXHNV_&sqP-iRxW!J%bm zbCvv$H@?KLisIIKk%~*AeH9c}3k7b(8dy}?{!l|+b(5ivq`JI^7Uz;&tKkGMQKA`q|&CpRzlQs zZpt9;uQ{9R^ISIf%73WruZl9ae38mbQ);h|MH&oW+Kcm*$rsnb?=JAP*=FpS{3#sPM--bfTgK3lL$?-5dNGuOqQ3Qkr3i|{bwNxS6ZvW zzH$nigbA|*ZeCeuP*UE?zL^U9yrs1&>?^0R(isTyY01j^zo8cPc}x4MD6Dms!RW(E zMHs`~prE^WUbw5q56TMe9=tBI47_{rZ%S@ek4{x>CmRTO#P zi<~YS`HD;yiPtAs8mQ^u?b2O0FW6w3^&Nz%Gn(~Hhh3)a$9d}LvaTi z6j^M)HEamyr>Ai?-L%Y;RJ!2Pf3M4J?V_uJS4FX{Q-T&0yFctUE!mI5d47$CX|O5u z0+wBp*JUQfoI*ce$zK&kE?7P~=JV7_$9$h!vFYz=dTPaHmf!fh>bj$OWW^{ob2o<_Qa}R_*vunjOpLkx_^0TG?iC(oo z?q*P*N?H}o0)QXz!DDu`@{*>3GtgJl+W7k1qj#3w&sU{aEqsZrM(!mVxn$gXpa;QH zpAufw_Bqj9lSL^QtJ^!x!nssb3Mtrvub15^w$vhl)ublL+8?R_a}8 z{Y}9pMz_5YrLrpEOSE`m1r!z>(6R$Bbi2axuh&}vpTAUA1$>DLmAxt=u0yZvC*ZZniz<*b&S49C|yBE(CW?(xA!@zV5FX%-xG}E1dA#OA` zp+}a3o>|lyrUU=&Y|D#y@yx4L;#Wm+YrRO{(M#lI=?(8p(nCcCffW2xV+t$Ty8ZwbP=hj5| zsU>Um=G9)SA~Bh@$ryjrKsLi_k)CDnU%w_JeIw^2L)W%l(zQ+Ey0+~F?b`B2l7BCg z_j>Bu%q3cY>NVxunke73S*w@2HmUYn6-m^!S({AmuFcwHtWD;uEbq&vjozT;CL`@n zHyZj=TSI?3UPfKpMy@}#<@(d{vS$tz^F|Vz>yEqBG0S_sr9>^7K^v6Rnuts;l~KOc zRSrLT*&4GI{73q$KW9svEiqq4v#|MpT$mz@-iNwE;h04+$ndjM%#q<U$ox=ifoYJgEE4-LHn;lv)t1gb^xiaT? z&RJHXU1-}-CX>rh52%TppIAwI)`#u3kyT;xk}{i;vYbmABl>R;%Hus!{2!w^T9& zQ`#wA?Co7t9s!7p?cBPkl~o41`;DIVjeXVN4rF=y$LPj5IF>41rfj)t)oawORXd=5 zgNBV72exV*651xLZM(>>-MaU9yJxT1I8A&)qPD+2J!8<|A(=zp9sAz6@e|&kIQ^rK zKbi6AXP?iUGk4y%-_2jJaM6mDt5&aByKeo4ZQFPJymQy?J$nxxI(+2lvEwIBo;!cx z&x@BXU%C3%?Z5Bb{pa5O2M-^~mW{p|DXXsXQ|IU@B}$h3#9ucCIbE zDAfbqs`!nzcMqQS&GM}dRsAEfJYsYQ97}lyoU3-5io}(uUR3|a8=k-M|w_XdRi^TmhFzvw@6&5Rl?>z99c{m+nb z+b&&cION`w)iG`VoDwiC`P)HNKk2*PBeKi7!?P2Q{_xrCwc2uWkJ^J&^-o;0fBePqsZSl{ZEuRFJKR$mr&V1kL(bdv-my|9$ zX=+rRz{lAwyU+UPV7;roTt_YnxU_Wfk3Y1#xvS!Z99HJ^gI?#4czrV_8B0`4!QLJ>Y%+1xu zetUCk=r60!FCBXP%VvR@!^<6rx})22Cg!4hm*~*UmLcw)WtIp#lm4_;VzZhyEqdp$ zsfk;zZ5;Wi#P`2E?f>=iVte9SYd3vz62Be}8my>cSS|+g;sucEI^rH|Nf|wxUW#RojJkFJ|rh zw7*N`rhP_KS>>6-x(>KFwb+Q`e^h&SNB5JJCpRtrOSK)}mm5B_an;Wq8YyFM?rU@< zWO%Fc<3}|wTdZc2o@t?(TkkLW`Rw=VUiUr-y{r9he7k{P-0#%n!LA%ud1mV4sZV|$ zT53$vOf#by8cM~kD`o=^N&AKe(@y5#;>b)$5%C-qrWA=Q!DEd4{- zfA`bxvIDM-v`fF?dZE>tvTi@-8Hlyzk_%rq7fD32FkMP%S@LD=vJKUychpM|%Vjau)Ehw{HzyH{` zW3~++;FDc(_P2|!Pg>Mz`iw`%AJ^L&xcE^HdoN&euZvw0Hm;bM=^=A0rb_YOH}vGP zS=o*w4sG^0w&h%ztop0RE!Z%6&BViD2bO)hzUt*KFV87=&!xE7yUUj}UKo7!D_f7heta?fz{Wd)kFE#Hr!K4?yS>Glqu+nm|Jrv?g0iNqh)6rsd-1f5RV!!C9eBs( zo26T>hbMR)&bTpr#QEkc!yhf3_`j?_HqC$VMY}ae(!XDK^ZL?Q7x(2~j;nm=YOjoo z0q3vZZ`kWS_by>_&gzrpuX&{=yV0e6h42yS!6QCjP(SnQVl{k+{~f$=XIfiUd3*h+ zilvU&`-N8fByI5eJ+X(UUHvtp?UL5}J{>t=$$-e)^LH#O{>1;#cYhz4)NyNQx62>i zh-i~Gd*p>9Hv+xZZa;J4!nS*XarcknH@>&1zE0heel~7pC0*u){S|tQ&pzDc_b1IB z+&MS3a+{R+Rhsv*w(Qv7pkj+#(^ubY?)@P1?7owAwr>b|dhzFjFFRiO`Q<1E@6C|LtcNDd^o z>!&_d^!R#MEX>cZ4WI7Hj@eXv`_qsuPxX}_*)RKbMGkvd=|Z!&a@f4NSAA#wUF)0d zS|hK9ta&{DYLvs{)Eu^_()jFc(?(u#iMj_hh7tBU(I_UAysj4!gg1 ziv{jZ0D7wOA=JILtDAjf3VE`>6)f)=WaP(`MSbKtq;^q zzck}~#InBC^)CFrdFq1x`rrHX-dcXs zyrVtJcbm~+-sLHeLz|CV-{a}~o69Cw4LrNg=4t(r4`yEarfHoKhe|fC{psMfPbz)e zw&T%>-5W(8AG~vI_YK)=&uVYBzPISRo5z&3rz}~~Vg7;5@HAxmhCbT6ar?Qc*RP$u z^IE&Ala6W`wdB-nLq<2d&&A(=b3 z3f)@R_BvBWI`#_v?T?x^W&0)f_pf^>?86z`+EiZt_(+3UO;#N`@vG|N9q!|Ab{pN| z;78YcG?;S!!1=_l)+#<-`A)aV&3~Oe?c$7s z{Tb^9hg4Ng>{>a%ulSVtSyxZT_4wcIVU7=OWDU(u++69J^T>YtzTDchcKJiY{JvWM zsK@by`R%@0s2Q=>{cPF&6-LxQ_U^7D+iTdL`1x-CD-%DS+brtxo`x-KvYS4M+Vo!2 z;ool>H><*^kDBiPp;N?%KW}Y5YIJn_Cw>nGd^48C(*YU{bL6v6x*lSCuf8`!-E*edldlOf<*IaPz@SQUg%h}Cc67}|;`Mt`& zTOp;)(nf#AtepGB`S7sio)NX@yvN!&{IqLJ{lC(C?21`8sQ&GUpF>xjtJUkt(o>#W zTAkW{X~o=@ozpLPuGz5Vugt--Zr9teXX+4j_L%isPJXm4TXlQZw)S+jCZTRDI1OHOXyIj0CaO#|uP4Aqw`(VM4 z!RM6Y12%O(_)e2w-ihyd<5J(Hi~CO4{iw&6*(d(6yIp!pdUWwt=YB19zw3;Xml8fn zzHquryQTg&qFWz``qMXJT%BvR2K@R?CH=gwns=%?^FfBT`K+@Y9FN|#8+YD0u*}8D z$D9_I81~)D&2@*>I?&u}NKA+FJtobqlR4vi(HG7A*cs`#5?)>4bM4 z4bVO8w!Y`>-=}V!deY_W-DL@9lRGR+zcg&>$_~YU+Z68q?z?xFY*7rW_jLA?_7{dX z+%cl=ZTFd-SA073;hkM7&7XdYySUC(P5UkI(&mM8Hq}a~KX22OkRMZjSvYa~&q*iT z+uR%zI`Fp^+gG;_@wl+0_^3G(YmMp>;?BfO-uBUz+Dk4j_|aE=dquaQYs1baHFo!^ z_|rG@EBsaZ$z?w{m%9h_@+epP`H3jr)b-fAQ zg=Z>8WB5V2=PAsJT!oQN++`Z7zOMikiKM?+A`+b zv}HVG-LTfc3#@^Tn6bQ_BWE2M{n{=6vBO>}mYLCO<&toSe!Shr)5dLHP5iuhO;+1e zruMYKlxM4UrC4;BOpzSsV6O-1VNQzfOcsQ>DLiNDj8JtQ%HppB3&SL<8WW%NC{_Zd zTYYiV9op|$ofQj}F}HbH+z+P*Rc9UyKb4K&@ov?w4C~ZR&boj^%=mU>axUJET)eG3 z-!mJp9~ZA2@yev}%8DD}72@p9Y()9A6rVrhD}f)kcdRbw{n!TvT`=GNA%8 z>{%33aPdZQ`9yGh@|HgUN8Qlw?L1|U)on~s+pvlhcLR&j<7Wb0UC)#l_M&uh~11?58#Aqvx(bkn2vMY+TD^qfDcFi}=hFqLV#Azpu z)6UIY)k3H2xmbDKLSTII)@>skb;s1dV|Ar8R%I#5sacshaPj6Zv&LM!4v5!Y8n3-c zX0B%Q-I}!w`a9Z7dyaqBB|uE$yVmp7h3}L>vo6JERrG z^y$vDL3eUi;@gRQ5booIXSvl_gPg?O#E`aH6_#2SW2Nc$VEO)1*l@H-Vrn`pXT=ap zO*SCtZq8PGLtzXbC1(NXwulxtOelT1!9Ikt?m=_dZRE^kFG_OxOybr<(+_~gp}o^{ zar{DkYV!jSgA;3BTNYf~DJ^jn8^wZHbv6gL+Ji)O;>yL7iuCC9W&Dkq2(FeWCR$rf zFSdj&VqvvqtR1TiskzG9iE?6Rv@{fg+E_`lT+Tb~nf#DzYE_w>ELYw(5WrN3tBNc@ z5*O7zpAU-58T~aE(YlgphzLi#SuNCsugqH%su(9n`e9QQ>M#Q~GzQxg9>3#`)-7Yf zGSr<>51h@Exhq1@t0hPv?#$PdK~AE^g}SSPc;xst#iL}cIIW@8=cF@qcgzEZbqEaW z5XM(?}5PqG^6n>pd$=eu&4@ABwe4yF%1Gw;I5&mPj zDg4KB1+1Pc!j#S@EZIy~Rt{m)(A5cfPqPuimdPh9Sw~k^9$~{3rm*3-qr|6MHlMI$ z1zlMMgso|73R}}w2wN_nuw?68p;azp6?Ueu3OgZe`Fz5XJ#%H15caGn>{&zDAQl`X zV}Dco#C80~fdxai;?TBL&=o;POR&nkchHpU!_mNOSReb*Sg4-e36hfc7sXH#FE^o< zL9IC*f7Q@dvVGLvP5wqj9N|0zIWp&HUvlgh+3xe2LXjNp`(c}Fzh$UJDByJ{(CH#9 zrR6HuiPCbzL*VAp>d!r~LG6To82BoRR)xJqC4kZ*EnSXl9KA4(Pw_NT)a9T|Mw?+w zvlo|U6?rdFnk6lyDJ`EfQsl}9Cko{Dmk{R%r$N|Y6ZrqA9l!!GFY|>h$%uIBZ|pc z;ybEXTgWyJ`R04EQmh(8xh$^t~p#r!?kq2;w5o z)QQ!|w+1_+)yUWwIecarF6TZ@u$=V1!em2P#kJ^!zLk^65J4g(B--16bwfWgP2NCM zkL1@_>_g>giC9B`-Z=`TnS;79wNa;B^Pq-e)%rDxi_so!(;Sy{q<@M=fAo`UtEfs3$AV7s$B(S-vQZoV5mbr?_z1mQNO_` zWobO-0}a7&zzo38yP?e>@3}^YjP>KnTg9fI zD2EPQn~jI;#r|9cSWU!W>nYWE;eOwMk=1f->f3BbFfiB`)^7 zRx+>MuYleN>AH-qAS*fc&ur3^C~Wt`w#ed}(wm6%O3H$5CW=Z_ob^JTry$Keut;hU zg1xTnFKm&o+5pc*Lkoqnd2nv1EnmJbOEh{5m&oMB$2NvpY|Q$CC;)xs#uVH*I1DPp zkAuZ_F`jin+mEn`7v-gxnf_UYGBVh!`i#$l+dMzCe?NG#;%cTkrdFIcohYu3V{D>C z>DU|ejBj@|_F$|mN{VuF4)QWtGdX+I}76SXsS&ir;&)$ zRUyu4LE(d(&&dC^XzTkhF>Pvx^Ocs_b z0{L(Z8rBA_I+K=wYGzdFK z0WZ;*kCLLWow?EqUKG_i$t#Y_OFLs;1W!?cycA<3XN>2K)=BD-Q(JOn?NM**&`o>h zMB%$1zG*JN=^0`9`GjzU{TO2o3i~m}8+=&jXN2YF5;`Dk8U{cVHqAx|Tl^Ve`MHFS z2pg{8!-gw_urALC%g-frLfD$NeAt?{Lf8_|2+PkUbVgW(9UoR}T0zAN%2(+PEJ=McAT^8$;O{L-F?2m32eN z{m>8!xgQ$BhxA9t7>gl!-Rh2zjUZzR*$6V`Lk1wE&SFSjvw9%pY)F_w&W42fko6IA zjKz?=UcHTw_NZqHX^(oQkb%qxA*b7l+jKEeIfG&QsJ|!cK(ppO`GHM&?4Sp1fUt9H zn~Unm*+N*p#vI`Fax)ke`0x!8enkPpQ@uH`-hB9qeE3EPzpa4bsrDS;O>pT~;=?ya z_=5!uPj%?P`tso`Q}|%k8sX2|23sgU^<(^dJ?KS()PEGmeIBXT5XwRj$KSS?+coN$ zi>MBB$HCWQalAQ%G>`W__QPuqWub^iZddSls6LBhv_*Qz$I}Qo2xV;$kLz>9L-kr5 zy(DQRAJ1&G*iaURc&a={JXF8M;c1hO^6}U!Nk4rNkDr|-{glp?JHSKWt{S4zA7KS8N%xd7@pV9 z1U|ecg&zTb=622)yAdKA>d4KT#G2@nbx?LRU^Ii?zu_9kbu;cvQ4*K;a-ZJif z%*~g`xcL$pH(w&-=1XLlFDYT1?O{0z))Dt$N(X^C3cnlt4UJtV?=HIBsFq$y-)b7|b%@(C%c8q*lDn}ypj-LnA za(X~MS}JmP8e<;vl}=-9Mt)XP%tlkJ@X(F1mM{}5jinM0Gw&;t7m$X!>CT#?jIK)D z^EB2C-KV1YKE8BrY#^0Rw1R+2i1`k>-=t#g!$`IHX$^xPp~m6PnA@XViN`B6-tUCc z<<$*411K>3W`?_8^e7tjIy7#gnFSgh(;Y>! zlr&dJs|*mAJ;loGsfHPKnD|R2W%d+1v!@zj_EaOx zp32JXsb-ixm5|v}iI_cS-tBqap#$dfP5MR0DNSklDKCWdD1TkdaaT|J&kBau?#(n<0jd7npuQ2T+ zNPSfQad@VC(UnsgG`mS<#bK11Qsd-?Z~jviUo`UCi&N*pV^9~>69PU2)4*)76l?%L zf+OH0ps1<>x}nw-1cT2}ko8~#I0TM@p-_)+z#K3atb?Mg2YbO~5P-~4zB__=kN_&7 zGHZbe;C=8Jm$fUDpz6z>SQ1TKRc;3U-W6!;t50S{># zN_hu3KrJ0X37~{>l7dzN!5|E@fvSc9daO1ByaVDP!~`%H%m814@i2xHz-M3~SO#Xg zGWG@d9&7`guc1ujASmw~JtZa1mSrx4;9C1NN#I`vvR=C%_r7^exmCSPM>p zv*7zGkU3Znc7uIjPF3g;_yMc|o4|*j&{Z%S>;s3v{A#ERuo)ZzXTWdOaUSdkm%!y3 z$TMhKld(tOF>tB{+YQP9Pf!h12btgsxC;IP&1yr2U=>&m?CUW09vBD4gVP|cE@K)H z4}JvIy%?(jYJ%b533v*!L8Lcy8vF#df>QNR2Cx7u1leGW4`c6wvET$y`{G_Uhz09F zJwL{LfG-#al>W#UZ~#%@F?a%=f`|arDcA$ZUi<>w;KI9u%AgLY3%tN6Pz=*MPQV%T z1E;`g@H_Bnhs4yuc`M3uJ-YAT$Vd0iJ-T zAfhGg2RH-{gCpQBxEIXWeIRcIeFiR|1c(I(!69%M)M$jME@TOKF)qz7y3HwHq10{|wZN zu|BxuXHWx)r&6g^QMdZ z7+&<4Wz&rEoz23L`?Ci{Z=ex60zPmGHop-`_Z4O~MInOOk z+O)HiHtnQMJ89ES+O!XzP5aQJjcE;SAP8-tJ#>Ih&>6ZwSMalc@8bNM;I)H)!tZ#t z@L^+(84d+70!G3p7!70KXc!CQU_4BKV_+gog2^xiroyo>4W`2kI1XmQERfCp8tRmR zyl=6#5dXy*;2_fkf`M2!IpHRMtY~R(A=ONg&Gtv7rY+>4W463NAedtL)0 zG(@{a=Ow3c?&iS)!U)T`f84J13)6j8{M?eVnA?(iAtSPdoIIG!FDBu0BwfXOZV!N4 zwPh(tAZIn*63SA|Fsu9gC1v6MYIC1krz}tE#a2sFFSKPUQNJhiOWn>dcDo$ItG1AX zj@hEyrutemvL$khZnw%`yu7r3+@kZK6QylBi6!%lTCM;S8}8&KB+Oo{sK$U6j}@FBmCXz5Y~p$j!B}c-<-r zli0)Mb>;m<*E#YRugBd@mC2q z-}G5oq%!rY@&bg4)r%XSD3QM^r_a5A1qf4(d+VD&6Fq-Q^FhCViJp~2_o3AI>a#>?NbE2E{Y&i6 zSD%XxTztOiOZ2=;6s5g@U2J}lQw4hQO&{Zl;`%F)TX6rz=cF%jy-BoD>60AV64#Bs z&!+o~$$M0ofk^*7fm@Z!NcX){flqv{n_qnHdnZ4C&U+`{`|gJ6=g)OZ#wQJseVqE% z)u+zI=7|EGB+qLX>!x!RxcTOn3ZLof$9K6zik0&K#^;;9%G9ZTa_U?K`t(g7-*?3= zv*c7kn2GMKZ+sQ%lQLP+#@+{=tDsE&pNy}<{IZ|*nJB(Wl##yo)-A7fi(~J5qVnZs zd5H78SHjKr`E%NQiRx6lf19Sr?Y?cuIkTR45uZqa&?TOdxIT6wqV z^f~@^NQhXSRX)r_awg-GZrMTyUZ08bQnZ`okx<%V+kDn3%jJLFP3^(P;b&8N@jQRk zax+$2KVF#8{RbyL_t~7EK$b*q3FJ%^-!=G)luI0kz}XV!r2^(ph|-zs%T9Z=TeLpo zx)DSiw?IW{i1rteC1DzLnQs~rJu9(gIbnnpkiEr^FX_);*R@G6b>+T?tjxB*#;9mc zrP%qD^p%x6cT#d*q=Ppvk~=5Tk6}Kf|FyZ04%R$K$vKcBb0BHFh&z769e?4Dx44c{ zvfOwJtK zJ(RKOS<|PLb8jV42o8nRnX&1+PRVw*pylr{$Dd+7$CD=%rt4;h8Oblvc~@aZ++t-p z)8kg&pDRnLB}>}`vbb(lmBs6?DzbD+AdBl(Raw0Lsv=AG1hTkpRh7l-uPUNCy>Q;tEwzse^rrXb^=*kx2nqG^;Z>HPD&t)>sD1+y#A^p%fbY*xNcRI z#p|ysvMfm;i|bZZS-k!#D~sJ8^!uJYw(aJv#}d2UUO@ZENuLRM+gYU<)pb){Ro@9y zdI@;iX9vP9C7g!qR;F6Bn}zF5tIg-8&rg>9?PidrCu#3Ux@RLs2c>-lKTObSPppWO zmrg}zu3JoA3Y2f75T>;S1F`-*dCA|O)1HXFw_}3d_O;$kxOy?6D7Qd$-J;WQ+u>Gx zp0v*I(xO%Z=`C-ZzlwxfWS)%PW(dDjP zURxO}#%>c^CT~5=4VisR|2@_%FX-MQ6N+`iw{!oZ-4ex@*e$x8P<(FL6I(x2-tF3g zSUCxEH0Mld+VxRxoC@IA%1r0<;x)90IZJHCYe^t|VJ(x(Y8T0);j2P8hLZp`$=$MZ;R+Da4Nci($dNqsi+ z#Fs%#&0$-^{hYpsm4@=q!zmS|&-Um4Jp929)A!y6EjR0VNcE(z0jHH`YVbTHdfu)0 zay{|Mkl7fvrzF;Ag8NrteA%A(vWSaW_RZ`A7+-Y$wAZUD*^`#=IjTwe{O(_B_w;JV zr)SzNchyGG=bd`WHnyyG8JQMcr+VwS#C267e+RoB^Xf(VNQ*q1QGJrCxcT09`?L>bb3oTSf7?c~@c9i%DN~+!DlRmF4cUsrbBgzxqJcaZ41R_x^eF^;Kon z&({@|t!^3=pIi2P@Y#Wj&#!Eq@%e#^&#!KL>Hx;)*VgF&#eqwoUt8)o2Qa?qwxU)# zXAPt;4_x~E+QOS_5TEb!7bForZ5!|NUfs67Z+xD%)M!uLKPOV2`L`7-(Uz(xzNMb{ zrtXLM;@5x1`S!qWt(g!i7WNj?-#mvEyuw>Tx9B=m{!}t+I(y zKjqSG(520h8JPtEzL9XI!V7USM3|}Uv7h;tpYtuZ3~wEv^0UJH;`sBuM~kd5{qMWu zPib)LIK`*Fp~~!%c;&U@FF||>)2H~{`d#r!CAyob)sHW5>P4o{puPmcraKpDqu6~5 z_x>rqh+CY#=zK1U*B5p48J$15JT&zbR$5as%C(84Psz0R-MQplHa9Qn*rfMi!C7q? zn@EG}rc{2}i@Zg zH!RGC6QK~6!y4cwnA0Hy=YeE>6j|HT!Fz;+-9#s7GKsqf*FL?r7ts2q zS3p`L^a3x!m>hdO)34YsB7bTf(>(I%d7$-6yEoxmZ_v7>qnnb4LF<(kl6PMRty8+O zIks-l`lL_8X!5hxCCw#IUj$l@bP0L;1JF98mqF&C+;g}Wx{}wm?&$L{tTp+h4e5nF zpmjvghrfZ=4?Q`EEbtCYYRej-p!Gs0w&R%wtrI%Dy)mVr^+9{`yj%)e7j!hw%q^hx zKu_vq%nNX8XV&n9_d#oYu7OiPYkocndq8V`_U}fX1Fije0o(&x`*Roo(8QQx)mM-tsz>kANm5V zA$mG&2CXIf3Z&(8?_dU;2wGG0Huwg#rs%l-l#!sdMSls;fYuK^1x-TQmxI<9eHT6gtus1cFzZu* z)){>h-UF>S+UrQ3Ptba!55qQi0vZk>zk${ry##&^T7UF?_#CwU=m^Te@t}1`uZG`) z)*;QJ@W} z=6T6&Skj)k-BasjaXh?Uz)DQxG9%mR*Fwp}`nrPolz zaerFAK_qH}pJIHRLKs0B#tZ3L6p_jjT8%-@ucE~n#9tAu#uAQ3qJxe6l55R;_p4Fd z`8D$0zec_X)X4Y18u>n=M!pBt$oF7#c#U#PpBnn_TSNc-YUn?|hW`84(EorM`X5+B z|1^c!Dzoy9R=Uv&H-4+zXoVZUl1?SCN_h%Az8X^LO-mQ*Lj$0SwchAb;8PQ*q_^KF zv)ivSol4Pr5&Rx@z#jMvT2dSbp#uzoO%Q_H;W1cC0ye45t$7EMKpwQC}S2ZK_M&P!p5|3 z;Cd>FQn@`FZRz#F9qnk{!z1t*{JK4DGPoNa zfXh1=^D8KY+u#9s1h#afCkh)o6DPFqf(-DduJknFZ=jy@72W7j!Sddu1D5yU9>IDz z1G>`d90JqeIC#Gwy)O6`_QAXP=pA09=ePqtg)iaufwVM0y~fk&`JD|Hz)xTxJ-+eK zn;zbg@HcvK|A3q5wcP<5=$V}X`NQaC!Or364Bm$i;fexdegk*IU*X0P=mjnuiC$sr zC@gf4POG5-Xf&gqM?GhHrZUW7KLBaODXJQGb^KH{j>D=YS!^sBq%Ol~)6$ZkgZmU^ zw}^g zTG{7A7=Vb2!5xc#5v9ocPD%297P%2*t5b=x2R;PZ>r}FQu95|0vr`F^MF~?MWVcgE z(+)R*(WzwV2%SK7I+ZXZVHC(#rlfkubhHawL?vfn))v~71P zfgXalK=wP8M6%tf1d`oOC68=&Drsb|d$|+(g6}A0WSf&sPPRDN;ADG~%}us8+1NVu zv~6m#rOAdS+nH=;vX#k3Cfk^7VzPzF1}58=Y+kZ;$;KtymTX$GWi_L;k?m?W`AN2_ zE=Sn5sRooZvPH=TCEL?(N*vjm9-+jMZRye>lvFTssBJr{f0S)2dYip$Ll08&$QHDb z5=XY5qY7+W&-f9<3p?RU_-Z6Fjh|U2 znzQGpHJx!~lh%H2%e#KrX5{!CZT;MG$6nvA?C~|<`ME6^`{Lj|Sr-rVb9*PV)$r0k zz8G_VbY-rYbJPU|@4tS|b$%5lN0}YH1+OP##e+`17J%74L9dAx9(|DB{jEEII!GC1eV*#4y@WqeK$88;Jdj5_-<|ul6rU3 zaA0>gC9u1j)*z{&7U94`EeI^sqJ~MG+A_2WC={ut6Ht4WC@%sfs-Y$-EFdaHpw<{!pbJuiOZqW7H;nU z*gJ6*8e*!_HTSon)xZj|D=T~>c4g6D-IY~we>H9f-jW>-Y)dwQZON`d*L-76IIxX5 z1hz4!hF$YPLr!1N-O@0{iHY8YcDOR^b32 zZbg6(x2iCyacp>vbFkTk1M{`vd3;7pzqF`%%JDh%znEyS`b~|t^zw$)+G2bZV0GR0 zJ@zZCt=qm&=<9ox6E{z4`1j zqkPtj^3AJUPeS!UOwQ&qeCOi34BxqXdAaLIt9a!*H97>|_L3NPvqA`ApALP8-3hyN z=sSINW2e^}LRw5Hyd;hZB^Ud6*|!+#u#1;{%S+=pp`^!#loK104A1ikNf!3`-y&jy zkTS}J);LD4KIx4&zx>VI&3)46v*%@X1)*g+A^I7{b1W;Ye_k9lp@s3Z-owURB8=Ud zCbSImA=LziVZdClO!Yl26&(_a4Tx`)YGfDo39$Nh;kbcS$E@ZPn4Q$>+J$`rw3AvL zt3=$us?((K3CvDvbvt!F0am|FY|3wmpMqvQ1>x5R0pq+h&{OPe?kf#jrsVsP>h<`m z`y5>6-iFA#rRqNiaRaN)bKnzL&7K3F0IT&JNMnArLFfV<62@3Q`BV7aL!wnMGYj|&m;s0*W8-}N8687sJ*kSk=-QF-f4HVaFcyEW{pHsbI zc$z3-zwUt@hJPXL4a3twalMB3b{PJ7(i?`SX%hD99@t^{7s=i*JPi`pYj|&m;cuDn zh7oRp#qws-J;F;V{An$>wh* zKa23uUG=N|xPkc>v7TO$H;Xu5fcOMfvufWbz-m?dd}*7{?^BPHTkU%7;ECcrt$0JN^ku7 z_|f}YAN_fM>jOydZ+&Fx{jCobbk}8n=b{)h9Ogh_S2p7&GyajtKUEWf6w*Np6}`{ zcQsA*JI~BW^9}race zL(ZP1QvpnwY7k%2<$Kp~%Sl~z@8Q$Zzn(wGDcSx$<9D*Y+MDJ6cxGqY@Tzmxnf2M{ zWH#>q=E>FxC)^PYdt3HZ%cFJG6YC#t`0?6r7!aXt`G8)Hnyo*DAs!5tU`A@m^6LE; zGlf7P&Yowo|MQI^v47h2%A6a9zB5T7Fd${{$Vgde#rNs@+(_wcor$Ch57wDosjHga znELQSh2U!B(VovWySZp913V(<&N!|w18JPi@|m9Blc6-;Gwqs;J^bFLS1^c0+loM+ zpmm^smXEgGMs|okGidn4&i%6rYy0FsH#0w%^iv?RrJRexvtCy}q4$ zh*c`O@^3ligx=D%H`L*aJLTK{-B7o$y(C{@d9NCJ%mo9spZeGe@3~0KuFp@$A97?Q zS4dNll>MdXyOHv3ZC0xP(`eBs-6@@^?0s&TdBrGcQ-0i3MRJZ#DxdBxSTbHY!h6*V zo4!9rzpc%>>X++one^4N=~kL58-FBM5snqg$72RfbwYK{JQBF?*yuB(SLDyov!k=F z)GgQcKkoV5v1{xr_3TA*ErP}{NW*2imv(9~fR#!87MmN)_q^FtHyqCGHbzk%9u)gLudHu{wBL|wdmku;v^YHCC zbFlfO*AVks{h_8_a46@7nSJ$#n>lj}%rT1#%uD@7ni;c>Heatk+JqX7HG_tZHGg5H z%#o*$Gw<{p&t!JTm=0MJ&FKv$nPxpEnQP}wHRrWG);u_In)!at4AU=goSB?4%lzfc zIp#kNk2m)%I>D@1e1bV~{E6m*UMHE)^G`Czop_R2)_tzYIAX5(Y}Q=UV)Q)o_rm$+ zFS&(g(qW6urCk@Bi#NcCC1&KbW#(tiPBvF}IoUkDewF#6#TxUUl(nYENo&ob@x^9B zzjY=juf#OUSZ`*H-C$OBJ;i*NbDAj~d75c7<}`Eu;!S2;#_1-w>1pr*Ag5ciwEq^xkaVJ7cpM)!{rdZQOaL^TrEI&ZG;?+5s1tMa4fcONU)- z3fEj}F57si`BV3wnVn01W>RKfZrWyEVG285ZKgK6#{6UKHRitDYfYEJYt1z$TxZrd zz21DDeS;Z1?FQ3r_AkxXqkm<7dBRO*z`|dfo15HXvYOvwe&7GMX3zZJnO=?WFdrX& zr&&AoPV>^tJI(mxwwht7cbUFfcbV_U-DQ5d_AZmtIs=7hqJ&BEM&n)QKy znLB6w%Zx7m#5C>pZ}a(xf176~l$oE_`^=2Y`@(FU`=!Y#`O@q?`lCf)nHf+dc6jI z19!kZpds~-!&{&Mv9D0GYk0kPQ0xxgmBtQ?-OcOK*uk-%^F}mwfNTb3c|?KN;4Xdvx%H1;)^_I7vzG^qAI+5#F_`y9Ll z8eqGNLA4sz?;T|ONppLktp+A*Xuk&B9!;kpcF^rlu`Fxg?H1Sx8i2c}r9HeqKm*(z zj9Z^}L+pUu?z9|Y2jv#Dwg={FQ0@cpM{pOXjvb);5xut9LArmZw$wmfO&9PrXu$4s zL3_~d%k1BTcVKHjfxVY?um|^QN`aR^ zgM4r8Xb<##jQwk%0lzPH!W|lRrOgH%pd)CKJ`Di=2tEdPAn<+NxHsSq2tKbn1A4(7 z7`%u!RS{@_uqNNrAmPrS$@er+crSbp?ttOPY1M24ci`}?y^#^z0mSF@VX{AP2NEyn z%hV0v4k+&3kAcGA4lLGWq?zCjF#e9?z2FWs_AW%NLC1$fcjy6{NKb>18w{jggodEO z$Zx^hpo#M|Vcui#IB3E=4Nkrit^#+Ea$Q=4S_7X`MlpaKazGQ?X(05g@ET}BI}M1w z9&P{)jMfBp8XSEBXaYM8kj^`rSMtybH1xJL1fe~2g09dF+(FcDaJ&oNgx&B@@D8dr z45X%7wgyydx(96(XBL{e%;iSUvCdWW`)aOHIIe$pAM4LAtmHXcZ#B_X0{y4D_rl#1 zPpv*jT2f>4Qmk%%Y`^{P-;XVg6{Y7u=s;m=(=L{Z@|d4II=8PNCls(ICeq|Y<1X!x zHk3)Xb*xSMg3a4DrO-07Hq8)7+_|OzubNbl(ecMIE8fYl+L|>_XC;ig*;nam3I^+c z^fB#BGq%NL1eKDKUN0>*Eu~)S1*e%Hr$cTyRz#eb!Q6c-o!Ry#vp2DX`e^dIOU${0s+q|B_tX^cbTaS|YV;5JXntHkF zbVZ-l8Evn0G}eTl_OImss%hYs^lcgUoBMeX`!T0aF01A(A^>_?W)w|EQIpNNMFi0> z|J=2@Pj9^woAotwC}8V$V8%z-h^jUrm|-t)ydX8K@-WD znu|2Z(MbMJ=eXF(t17dU>x;#S=g^W5m_b!7YaZVJ0GrO67bEGfpvYC;}OOhM+- zFCx|z9Ivj_H3}s*sq(iDdw{&v9tM3I-4gVoAM(Y_iRf1Y)bfS=0wS6Ho|OX zBh0q`8uGspFt-Z#H5)mydDW6_nnE*Z4lUpi$b*)U+^VO6|5BS$&6V>U;LN+{{p#~? zrYz09{qjuHz4LvVTFY$10jml36w?aGXDR5}*bZcS^Dd~4*bB-Byiw#{Gw&9A)x=%c zXR#m6USUmTuiASJdn`ldboRQV7qVCJeHD9I^Gn%d?J--}t17;meN*-ivzHut=CFX6 zAS{`yuB}#~AAgO_*2L5+75U>BQ{&dRDKkvMu*P*#r z{(}C0k8ie)=3H9LIV`MZBB+1Pjx}uTzIcee`s$^i{^%b-Hi4%=Hh~v_FEY#yI0W7X z_5D8p^~?VS>f3(_EkL#e*#c6DM1AdE?7e+{^`YIq{G!!`>sJ=7Dp^pnZ1pP6yM6I7 zW5chXzi+_=$Q}|5$ce^^;|})m}D4>vvuQOEz6E8MVdk+aR>k zuecK19DxB*u2 zCtG|k?CJJuNIF`|6$^Qzu!QS+vjW#*j#qL1DD1DYzAwObDEp!8kSk56@XTD4!~Ly1qxgNZXf-ScwBnrJsZSgW0v*RLz@f9i<5-N_-!2VcaI z_u$v7N1$1?UCQg$m9?x6$l8H7Zqn-~wMJHz2zF~QwoGtk{YM>;wLQHR>Gi`}Bdc<2 zJ|#l={OZc8zLsBEd+?vFM6%{tGQL-7P#{6sw46qYI<0D-C3*T&8PjP9!z=ty7InSN91jWWkLD&rCKDf*0i>J-sSb{ z$}789ZF$}j$=lonEjgd9Me?eZ5Kq6ZywB7Td7JWmsq(>-wMt%lm32faSN^*4ZmT2m zwljxX`u)E+@*ey)&JkAa=GSg;Wqq^`$l4aWwesylwMbT#3x54FSJwOMkgWIAGFkol z53XLf)*)GMuVu3O*^ynnZm9#ZHaG38a^RLYvi=bLhyL`+^5fXQTzPM6USKp6GZf)BCkl!ig)7ptA zZ?5zHcfBKLZIQQcoc4n&Z*iTG*ZzJ%vHC zmJx%(>S<;&cf|~zz+U7Rp)dz?UT2mOvc53t#o0A{FR3l|IX#Kl3G{sO>AmlBx`6Yw zK__c09j+i{W6-F66{3e;R=Vue>e=o|+AEjtbt#tRPbh>9+=^j&u(p_kcsjzc?b<;f>Eh?XnjFWEFskI@WujGEO;dxz6 zEnspNegM{ZGihsR0pyjqgp72*!d6b8PIHQp?t0?_8 za=eWGM@3~>fm6P#ZQkmubB^8c6183WJG#;L4}Q8ir4H*x?M96})RUw6$X0oDlwSoM^+4~^joR9NI+D$? zF61AzeF~`yRC1PBHRA@fV&|y^XlWTK)N`j&R4rb8Pummxp0e0B@MPzEscvy}bVe=F zk!A-~xnhq)jr141&sljrd7rpKD<>^RTT2{Wsn?)(v-IW-KhbkHnNiKkOP%BB>(pAJ zFSiVdS0&n^i>UFBduEA+TeWK+%}HR>Pmg5`6X5BsRf`MWZM81 zqd{q{r==S`b8f4^&8vx?yR|%}dhRrO-mfgLTe^wv&1xRuRcJ=~vY)d^xl|e5G-Rd( z>4cRfe03x1M_s7r?0gfg8|4$V7pqe5H+O8Bc|Qt$tRQzR;ZOFD=(1S4sZ9Q;=ZsNn z{-e-`%G#Cu+3iBRcTu(HCEz?SO@1``SjB7{cDtrJ<;O<)I4VChZ;M~qT37lKcKH!) zG237DPcilx=|=Of`01#w)IZCu_FeqCS!Ie_H&?c;H`JVI=|pq;`st>G^L3&Av2_z& z|3sHIwq_EwTw?oI$2xW@&G_S|8_iQxcXT7`tX5D^Pb^}gO;q~E>LY`hX`}}i4y|MN zd!M?}RqI zf!9EQC^Vm#@*dNNS>M~KjM9AVnyX!9d414)XR7lWLL*QcAr~}bt2t2!i^!?Vvr#M$i#Df$S<>pex8G)g5|(YBqhK`Xo#4?h7W7_pJWK$+8=eT0 zK=00{z*NwC{b?{A^gY6HFcW6MY?uT3{^JBV5%m6LF3f}ZumBc9AuNI-SPV;GDJ+BK za5Ag_m5Zt?R35B>wNMOdcc^|{4;w&jwT&P<)M>B@P6yfX&V;id1ZTrJa4u|y^Wc2A z04{`!;J++l@l*B}!zFMj{0uIG%i#*R60U-u!`1K$xCX9;>)?900e%TL!mpqdZi1WP z*YF#-1%3;+!WOsuAeV{M& zgM8=@17IK=0fS&L90@~UC>#aDU^o5kJ zY~On*an9+ysLZBSue4@NkdjXpI<@Djvb7+`xbf7(V|rGK<$aqS$kF!B{$Kjw?}urP ziVesaavVle0&334>TdPPy>9&4S0kMYRjFPW*1Hx)qfzE4=X}kAEB*2ypl7)wiFY*s}X@ w@`mraM8VO{49iy6VA6E0Rm3UlnbvVH*S*&u^X1@s_h(*r^KEj!e>Cv_0j>YZv;Y7A diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.html b/org.glite.deployment.lb/doc/release_notes/release_notes.html deleted file mode 100644 index 01ee3f4..0000000 --- a/org.glite.deployment.lb/doc/release_notes/release_notes.html +++ /dev/null @@ -1,2712 +0,0 @@ - - - - - -gLite LB Server Release Notes - - - - - - -
- -

gLite Logging & Bookkeeping Server

- -

1. Release Description

- -

This release contains the gLite Logging & Bookkeeping -Server module v. 2.1.1. The following sections provide additional information about -the release content, the module dependencies, the know bugs and issues and a -list of bugs closed since the previous release. For information about -installing and using the gLite Logging & Bookkeeping Server, please refer -to the gLite Installation and User Guides.

- -

2. Changes in this release

- -

2.1. Changes in functionality

- -

There are no functional changes in this -release.

- -

2.2. Changes in Configuration

- -

The following new parameters have been -added to the glite-lb.cfg.xml file:

- -

 

- - - - - - - - - - - - - - - - - - - - - - -
-

Parameter name

-
-

Default value

-
-

Description

-
-

rgma.servicetool.activate

-
-

true

-
-

Turn on/off servicetool for the node.

-

[Example: true ] [Type: 'boolean']

-
-

set.mysql.root.password

-
-

false

-
-

If this parameter is true, then the root - password of the mysql database is set to the value specified in - mysql.root.password if it not yet set. This parameter has       no effect if - the database root password is already set. It can be used to ease automated installation - and configuration of the service, if mysql is not managed in some other way.

-

[Example: false][Type: boolean]

-
-

mysql.max_allowed_packet

-
-

17

-
-

This parameter allows to set the - max_allowed_packet parameter in the mysql configuration file /etc/my.cnf. The - default recommended value for the LB server is 17MB.

-

[Example: 17][Type: Integer][Unit: MB]

-
- -

 

- -

The R-GMA Service Publisher (aka R-GMA -servicetool) parameters are now automatically handled by the configuration -script and do not need to be explicitly set anymore in the configuration file. -The parameters can be set in the configuration file to override the default -values.

- -

 

- -

3. Release contents

- -

3.1. Glite sub-deployment modules

- -

The gLite Logging and Bookkeeping module requires the -following sub-modules:

- -

 

- -

-          -gLite Security Utilities

- -

-          -gLite R-GMA Servicetool

- -

 

- -

The sub-modules are automatically installed with the LB -module. For more information about these sub-modules please refer to the -specific release notes and installation instructions.

- -

3.2. Glite RPMS

- -

The gLite Logging & Bookkeeping Server v. 2.1.1 is -composed of the following gLite components:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Description

-
-

Version

-
-

File

-
-

glite-config

-
-

gLite configuration scripts

-
-

1.6.22

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/noarch/RPMS/glite-config-1.6.22-1.noarch.rpm

-
-

glite-jp-common

-
-

 

-
-

1.1.0

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-jp-common-1.1.0-1.i386.rpm

-
-

glite-jp-primary

-
-

 

-
-

1.1.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-jp-primary-1.1.1-1.i386.rpm

-
-

glite-jp-server-common

-
-

 

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-jp-server-common-1.0.0-1.i386.rpm

-
-

glite-jp-ws-interface

-
-

 

-
-

1.1.0

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-jp-ws-interface-1.1.0-0.i386.rpm

-
-

glite-lb-client-interface

-
-

L&B client library header files

-
-

2.1.0

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-client-interface-2.1.0-1.i386.rpm

-
-

glite-lb-config

-
-

gLite LB Configuration files

-
-

2.1.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-config-2.1.1-1.i386.rpm

-
-

glite-lb-common

-
-

L&B common subroutines library

-
-

3.0.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-common-3.0.1-1.i386.rpm

-
-

glite-lb-logger

-
-

L&B local logger

-
-

1.2.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-logger-1.2.1-1.i386.rpm

-
-

glite-lb-server

-
-

L&B bookkeeping server

-
-

1.3.3

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-server-1.3.3-1.i386.rpm

-
-

glite-lb-server-bones

-
-

L&B server bones

-
-

2.1.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-server-bones-2.1.1-1.i386.rpm

-
-

glite-lb-ws-interface

-
-

 

-
-

2.1.0

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-lb-ws-interface-2.1.0-1.i386.rpm

-
-

glite-rgma-servicetool-config

-
-

gLite R-GMA servicetool installation

-
-

5.2.2

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/noarch/RPMS/glite-rgma-servicetool-config-5.2.2-1.noarch.rpm

-
-

glite-security-gsoap-plugin

-
-

gSOAP plugin and gss libraries

-
-

1.2.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-security-gsoap-plugin-1.2.1-0.i386.rpm

-
-

glite-security-utils-config

-
-

gLite Security Utilities configuration files

-
-

1.2.1

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/noarch/RPMS/glite-security-utils-config-1.2.1-1.noarch.rpm

-
-

glite-security-voms-api-c

-
-

 

-
-

1.6.10

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-security-voms-api-c-1.6.10-0.i386.rpm

-
-

glite-wms-utils-exception

-
-

 

-
-

1.0.3

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.3-1.i386.rpm

-
-

glite-wms-utils-jobid

-
-

 

-
-

1.0.2

-
-

http://glite.web.cern.ch/glite/packages/R1.5/R20051130/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.2-1.i386.rpm

-
- -

4. Dependencies

- -

The gLite Logging & Bookkeeping Server v. 2.1.1 module -has the following dependencies:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Description

-
-

Version

-
-

RPM file name

-
-

c-ares

-
-

A library that performs asynchronous DNS operations

-
-

1.3.0

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/c-ares-1.3.0-1.slc3.i386.rpm

-
-

gpt

-
-

The Grid Packaging Toolkit (GPT)

-
-

VDT1.2.2rh9

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm

-
-

gridsite

-
-

GridSite

-
-

1.1.15

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gridsite-1.1.15-1.i386.rpm

-
-

j2re

-
-

Java JRE

-
-

1.4.2

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/j2re-1_4_2_08-linux-i586.rpm

-
-

myproxy

-
-

Credential repository for the Grid.

-
-

1.14

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

-
-

MySQL-client

-
-

MySQL - Client

-
-

4.1.11

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.1.11-0.i386.rpm

-
-

MySQL-server

-
-

MySQL

-
-

4.1.11

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.1.11-0.i386.rpm

-
-

perl-Expect.pm

-
-

Expect.pm module for perl (./id/A/AU/AUSCHUTZ)

-
-

1.01

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/perl-Expect.pm-1.01-9.i386.rpm

-
-

vdt_globus_essentials

-
-

Virtual Data Toolkit

-
-

VDT1.2.2rh9

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm

-
- -

 

- -

5. Known bugs and issues

- -

This -release has the following bugs and issues. Bug numbers refer to the gLite Bug -Tracking system database hosted on the CERN Savannah system at Hhttps://savannah.cern.ch/bugs/?group=jra1mdwH .

- -

 

- -
    -
  • There is an infinite loop during - the initialization of the LB_Events data structure
  • -
  • No removal procedure is provided - with this release apart from the removal of the RPMS. Any account, group - or other resource created during the module configuration must be manually - cleaned.
  • -
- -

 

- -

Known open bugs:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #7324

-
-

lb-bkserver is running with no - pid

-
-

 

-
-

 #9701

-
-

erroneous rpath in several - shared objects

-
-

 

-
-

 #9777

-
-

unable to get logging-info -2 - info for 1000 jobs

-
-

 

-
-

 #10781

-
-

Missing the timestamps of - 'Scheduled' and 'Running' status

-
-

 

-
-

 #11535

-
-

Job submission extremely slow

-
-

 

-
-

 #13418

-
-

problem in computing status (of - resubmitted jobs)

-
-

 

-
-

 #13492

-
-

Job State Information Log File

-
-

 

-
-

 #13832

-
-

Default mysql configuration - imposes unnecessary limits on LB server

-
-

 

-
-

 #13879

-
-

Some data do not propagate from - lbproxy to bkserver...

-
-

 

-
-

 #13929

-
-

The glite-lb-bkserverd has - wrong default for var directory

-
-

 

-
-

 #13951

-
-

lb proxy sends garbage response - on error

-
-

 

-
-

 #13988

-
-

Failed to start - glite-lb-locallogger on glite 1.4.1

-
-

 

-
-

 #14247

-
-

No events are found querying LB - for events satisfying jobid and source instance

-
-

 

-
-

 #14339

-
-

Wrong computing state when - proxy expires

-
-

 

-
- -

 

- -

Bugs fixed in this or previous releases, but not yet officially -tested:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #7307

-
-

lb config script does _not_ fail - if mysql root password is set

-
-

 

-
-

 #7305

-
-

lb.database.username paramenter in - config file

-
-

 

-
-

 #7300

-
-

update of the lb instructions at - the end of the installer script

-
-

 

-
-

 #7053

-
-

LB configuration fails if the - mysql root pwd is set

-
-

 

-
-

 #13928

-
-

org.glite.lb.server depends on - full VOMS package instead of individual APIs packages

-
-

 

-
-

 #13048

-
-

interlogger does not handle errors - from bookkeeping server

-
-

 

-
-

 #12648

-
-

The memory usage of one LB process - keeps growing

-
-

 

-
-

 #11387

-
-

LBProxy SIGSEGV

-
-

 

-
-

 #11050

-
-

Too heavy locallogger retry - strategy

-
-

 

-
-

 #9183

-
-

Broken connections in LB contect - connection pool

-
-

 

-
-

 #9135

-
-

The interlogd has problem sending - event to the LB server

-
-

 

-
-

 #8630

-
-

EDG_WL_* variables in LB library

-
-

 

-
-

 #7910

-
-

Duplicate apostroph in MySQL calls

-
-

 

-
-

 #11509

-
-

glite-lb-config.py overwrites - HOSTNAME_org.glite.wms.workloadmanager.service with the wrong WMS version

-
-

 

-
-

 #10686

-
-

MySQL library fails on hostnames - containing dashes

-
-

 

-
- -

 

- -

6. Bugs closed since last release

- -

This -release fixes the following bugs and issues. Bug numbers refer to the gLite Bug -Tracking system database hosted on the CERN Savannah system at Hhttps://savannah.cern.ch/bugs/?group=jra1mdwH  

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #6722

-
-

glite-job-status -all doesn't - work

-
-

 

-
-

 #7237

-
-

Intermittent errors with job - submission

-
-

 

-
-

 #9148

-
-

Job stays 'Submitted' forever

-
-

 

-
-

 #10730

-
-

Error on glite-job-submit

-
-

 

-
- -

 

- -
- - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.pdf b/org.glite.deployment.lb/doc/release_notes/release_notes.pdf deleted file mode 100644 index c512e91ddfd865b103c95e44d4642062ba7b9b67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157326 zcmdSB1yogE_b7UhEHmJ; zyZ4Rp-aCxVUVE;bJ=fZ6Z8A9_5n4t%7G$!;rM@9#1V&B<4nhV(8v}D59(plN4pw$T zMn-l{ZF(s)YoNZpnH$iEkda=PkdcFviGyB>kdc+0nTd^FhLD9`mXMK?k%?XjRDlyz zhnE)_Xl(>)2$}G2KV$?Kd!X^po|xE?5g2~{7}*H#Q-s#PU`$M`%>RTjfQR(Ya;$8e z|AMhIGX4|B3>wzIU~G&`|AKL{gNOkB{W%sEW_Ff;!PtKT^FQgr$iT+% zPnt3^vM~LVri`pCEdRuVk&Wr!_%bmt|D~Lxy}p?x&>k59B#nw7;RA^nGb_EEJ<$1H z${1Ma)f9lnijG!<;Cl25Ha3o+A`BpG2o>nXt&MF6nK(hi13w69@)&WlF>^8+b1<<0 z*;$Pk3_y8CtQ<^0HZ~y8kktUl%VT8B3}j_z2O1k0071+(&}U_0F=Pg^Gcz#jGZ`5e z^J;^{8o|L)-`?>-iW!g*$jF3cMUWBxA><$(0P**yB1r+QO&m=L85uYj=tayd9f9`r zB9{7&Kp~)^jS-Mu5R}8p3DzbC7G|&>F)*>yD-yD@a`5sxINAgCtw2gM8LVU>rD%fX zDYkQ2?PN#QWo`85Q)}mK;n8E!O^oM*>0oxs=3wY}LWR zJw-33+RQ7MpcyGEl)u-Ja+6>&8&uSAMhf>fC~8+&)@*-!)4;p8<2rc63Jo9!Silwm zT5P=8uc2*TH9^Sg5ttm|eEGJ<9*&wZVeRkrDlV)o@#_(7Qr-olKSj5fy4m*QphZhH z-F5pBQp88zJop4p0Z_s0=XU1)6G&yDRJ!$+d||^2#b4}_c_^6k+K21Ybx*8G`+~|x zlFQON&Y!xTC=bdna3zku=u;o(p^_E~3Yj=Ugs3@2J&I@h#!)QoW>8bjm~E&-3*Ue~ zcRFhG#1MPnaV)foeRZy37x^1}RFlzBSi7LIxO2nr_y=ttuBWx{Qkr`(&Yl|ch?J^w zd?<}~kj<}aBe^Q!?ob_YnGV4e^*||k)ezN<0&5+yUGtsu8 zFO*y5+xb`u^5-F-uJa`-yXtwUMP72B)ayb{k-#G|6=R?W7RFR8-0JzFx4q5Sp(xSL3+HIkmcv`aM+u`IGZ#lf^5erD z0%T0${7O-KH(7I0v*2QVAX?8-%TMVr`?gTn78lJMT9 zHX1VUp@1*JoUnMJEIRJAyGsYfC7|QKeXcZAQso0#XsDj^xDVC&Wy*2ad%;eo&tHom zR0Ahol~|JUPP}qh4kyZKn`zJfm_E8>`}$-z1x}tgNGR;s9|DbCeu=eQ+0~K)JUS}*+JUF+f~)Nu@N}r>FFJbPllb2ETnL^>%u;* z`=Bahc}pi{$~~#HetLtG*)FU$WaSTBxO>|SA+n($<#Jxw|)SX_ltQ9G7jge!Q4-Aga*9ioQr5}d6%PgB3oKT&efVDn&FzO2THq++LC3mWZ1 zMufend$C1kFEsqROGz=iW;6`@*?42|@lfYX3dd2MuJNtq8~et>dGm6jI#J&F5&^P9AV4eTf;{CI!J2ZaTAM_50Hi~#b&KaI#we+;sr zAouapH2t)y3?OIzV5HcXe`lf|ER~$Ty_EyV6bsr|I$2pefSf+a6dRctI@;J1GBWY< z(yMAR5;74oYSSyZ+5+!wGsp@X0bMkiI5`Lz*%%o>_VZ7RwmrZI0boFCElR@@@zR1d zFgbyH`*P^BxWbDRRmi>tP9FcYecXgr2bafxJS-huJk6-u@ zK<1zI-u%ltIa-1u7!ZK%0dPM+L48MkOB)kUy_2D%l06W3 z?^M9!2ZN=7j`~KRTA*?uHw6O73d-5r*aGbx&46Ia2!SqHdn2H|rZ&BTfT+EVldXd$ z2x(9`Q3p+MU<9rO2FRHK4S`@61*##fZ*KuK0)=9rw3NPsqqL2YnXwtrh*F4)i2>wc z8JU_JWc zAtnkojv%*8$N=KAk(s`Ljf*C@Dl15cI9QmpK{(sk{tKu8bg*%9^l|o zUkRiWa2pRJ{)HL1Z}5o!dIy*Kg#~z|zc2&e!F2eQ_v`*^ zWWUOR;rFBZNexij-~jgzKfwq__y3sPwBjHuYi9UAbDfdxzv22rQ2!6EKk)pY|9{EE zKjFV9`cF8R2ESkrl>hbg-`v4e{5xO3^aaCy-NET!JOHPe!Sgb3?%$~m*8Kl-Y75v{ z8vQS5&GBE*nh88e1&}`fO~b&zfB*eXqaI2<(B#mBmSg4mTIQ){ddo02D{Nwr^HGkQiU-x^P2DV3_-oUVjHo+;dl>*c7 zz9cC3PyYQ;2V4ro)dw5)kpI^{!Q**&{xkLP{A=XkKK?8L!s+k)01FI=ADZ;yf`VYb z0$PUR1dRwJrrLk8S75dK2iN{|9rqqs0PMeMS=l%UX_-MQ7ohM8|#F`$`=sUsm9D;vGq&ol!)zk?w-p5WkQqz88lPSY}h z?AwD0;rj{G+Wvw-5)dxRMoLCOtUU|{~A5&nz4zQ>yrWHRpYW@n^hX8}=+<^KqM zT1M9Y=Lm3bss0-RfEH8!#&IUL{{;blDe&Lf&Inpz`hSb>?0@I`y?OX=&}IWg!?euo zY`+8@Gy}UQ{=K08-C8{$3ktyQdCkbo@fT#-89DwCa#j%keu_CK1M6SKobi7a^ZTy; zlW_kN$v>w6_krLa0WG~EKcTU{r2~*&R_*$U`xlbQ z3Q7yz&&t4I_RnbgPsO^QXgrkuIWGn+jQ?h0{O5F5EWlkwI&@MDwf;(Vm}>H+W$oou zeIPNi9ud0nR|XY2`7(hHhFJy|OzzJ{UN&!#JM8gtxEa$?U{`y*nNXPd6h z>`u3;-=2Gx)1KvKG^!9;ONBF8mHsr>T9Za=#H$5?2p|o_ zv@5)T*xa}d$&9i#aw*fN=RIls*;9V`F~pA9Qv?Cm+i)u|>sg#K$5pTNf_XA9U0QZw zdhsH|yFA?;COUJ`G=5w&nD(&18#bvMhxePUmfhJ>rbxGi7_Op`M;O7(&7)^RC_Ll% z(T=LyhpV$w2?MWjrfm>L=J!1lJ6d*J^|KaaiBNJa!;pH|8!wsZk0wti?QwTMGi6#X zXIt?!x5f9S`_-+Gp>d7BrSN3=_)U7P^u_xN1FrZP=>_dAI%0Px@5FHkUU6tsQ7cv% zCJD)dCU%V%yq;1+Z~9I@(eY*WSO56+|J2jx>l|Z&CP~=8+~27u~Ps{Ap=rn|F&CTET=>V@mi3=IgO# zR0_@-nInmLdHCeuw`M?uo%p&h=%z>(~~ZX!{DqdZb+BYdE>Te&ZXs}tC&*B$;*m`l8DoskFG z=V|XcOKNQrV!`O#Yv?)#)L>@bGSIS9lE+g&WZ#V}GwIQMYLW}K5o^_(q#QqI^W=2{ z_Uqms&M@*+*NxVaOE$Vg2^mgdS9ecXc?fd8*lRbL*VEm68L=)pdmQaJI8`bLx#Fpa z=M%S|2!I42Rczb-c5Uc>$>47)&CdF}wXVOabg=T2%+xDXk3QA!iX#$^6IX6z@6ZL_ ziV-Qb@f;73#?GT{cRjnj!kdB*skBfMmRB+T5zWkO0wWR-@^;a`oc;%Nn2I^1hN%JR z2*P6Jz*w5Z5mNYCT|ttY-9GItYsxzXb3z@6hO`LOJKmzWeRck?C1Ho>2$c@v8+wr@ zkv%!3C<=+MgmAx=hv7GCGK?#vWTksnxNGm>=FQ9kExzO{s5-;zmR`U9AZjO`wixKj z(^*1dEztg4f*AREGfRqJ<)<|_O@Z)yBHErwr#>iWGj-@5pc({*k3%T=+^e3l$(3|X z!DwTev8W>YkEwdw41sV15KcafDPNVlQ=RwBbiUYrh4YTBd&@Gl+&=ZKUr-~xm^3g= z)PKB0!nu}Z>eeY>GmUYU#lFanQqJDoa*e}MNt^A3nsJe`&r?h@_Y?1;_{>OO*M=Fk zb$Z*#wL+ptbl3ym*+w^?)NxhXe3DeHt6fAojaNpjgx^Hf2=AKjOr=Wdo_bR5=7YQ( zBS(^VK=aj!cKeb*NW=%riWZS&C)=^T@oJ*Mk1G^W0!c=^jI`3J#+l4J%IJA$#@SP> z_`A13K}T2Lwx2_3>F8)L%@r&TxZ)zdTCx(En<8B_73k)$czQ^O!p;%aS869(|_ZHz0#+?3E#e>D0$&1K_)cSCaWiKOBZ{(j&0S+iR22RSKM;`voG#sJ^#I0+tGsW%_| z^vZ_WBRW>qP`uc+XN?Hm3@6XVQu0 zO|owlF1kZVujyVUl$NV*Q% zIY|>h-0ZyW_j>c^ROr_dF)Jv7``2r%zv@kda;-H;Z?-QmrrN1WYR*U)w8rhjTD%dR z`4Kd@x{)XclPD)Hu3k{lFvxa}djkSK8JnnSKTJhOGJuByGL zfI?JN9h1D=MNPdA=};XM*A!K zQM62ev&k6Y8(G_o&{0y!axFD*xO$4J9_I>t^EuP=J#6Zhve(11%T{u;=zP-a?MJk_{2(j9gz4G*B_5iA6sb}7H{SX4)oP3k;95r z58G3?4j1m79u03A4jT~*-i|$SYS?>j8f(-B=NI*{Ayfj>O1*_nou8vMxJ+L7uuN=4 z4m;DpN;X9y?sdOn9{Ud0{Px_~QSL})uX&hM{8IB_R2`|`w6Q_lyy&4Ncc>QfYK)%E zP~}_lK3jr=2J{WmwLk_R(eJVjG*1GjsE#AfOiZ&siPNQUim=~EVVX+%FeGO{e^L^9 z9-za#nmNzop~)Di%PZ8YxxL3Sn$$l%6}rB_q0v(wZLoHn6dOLsIl83yJXg++JX5iW z00IVpgS}S!d#V08p#&|C{*r38{}kW_t4Pb@@FUgl74GLN<-ml#Ohj93>hy+GKzXyH z?;W6qUh+vh@N#cUJSH5e^p$;pb3*;;o4y3x8KhPwr(B!HhDwwW5e&#A_sT{j91I^3 z6hEKCcThWq4p7){CfL4=t@U%{erQt5#U(apkTGx%#+Qr!l$fVjI^Ntxi4gl#FaPUp z;?tOV#Q-nZefjs4iJ|&YDfY*VtLGGPak#pPy4r7@ZQb0Qi9F)Ud+nysOiiC5Q*X2j zyrIGV)Ya3fN;z?m1+Olw?S|C1T-k}H-AYUveCxcBa-HG04S+D?{OE_d2;Inz`s z_(qK;$GOn`;rv>Sx$k*(rM&3hGpT?sqv}Dl&H{?kCYUywqy4Jc#?K<7>=ASH zH5$_h6s(;3KSeULVFEKE=bst{q_vtSNyQpQ541pPvig6Q$!S-QMp?4lz#9(>r+DdL zz#*3xRx;q5N}*RwgjU0_XNIPTI1n8NX*)7Pii*=+w{(QITa#V8(I!Fc5_$19FhxYQ zBLhBzbF%!5%rnc-*M87OeOx4YZsw4z`8>kd0Bwc6nBDV&3@HGpF19Q$!Sv@H6jR zeHd8-$i5Eu^k;%4G5NtR5Ct+J`bs*QTL}A5t_OmeiE@}F#9v0n&R)&pVHLl)ne)q) zpco4rrqnZj@H6ieZarRlt86nk4&awa;BzO86~_B|zOC4rT!Gr!RXj3G z#^?Y@c=p`|vu62@Ky~08OF;XqTH65><3FzZ8q%##QE$I^zA~F;tsj};7~fHW*{+dV z9yNzvmOlhhUp|R(%phf(*l}PtUZD3`~d^ zI{qUdXIEcjZ{ms=)$eh}6lRC>l?7-|Lr`I|8&nC}9?7$Vy{sQ%d5-XWBMTqABSxWl zZl{fMPYmj7hcjcHmCJD%OG0vjZ%x<_N~(5xws|H=vcs6eqqI0%Yy69?sZ(jqm&P%k zjLhQTF?KX%ywyjYsNDaWlY+I@@0Zn`QuJ7q1y}t`Vb{KJX;l@MZ~KBOXlFBi_;@siR;%lcEBh};qnF}8;(Lqbu=&(l( zg)M2HR<|r16-ALtJ{G*FnWaV$+z!wBS<-1O_j=t9PGq z;r54*0S#kn%IlBJt9d4+Thhma$ zDf%W!RZujC*U@!WAb}@jvWG4&BtaERNb;gaL;-z{fFyecHCh|}77ir$AEyg`FZX{g ziv5&(R?rgG|2kj^j+B(ekw#KzJ($bg;cC2 z=__Q z;Sh+1biLWS36t9ggRfm>6r2yGIbV;Gixam(8f(!^S*-%eS8GdR)Ga!5`eqP8CCsQ7 zOY19q(6Z@*C_w=hWk7G(Ufg;j!_*@Rf*)eEpWf@E%sH0EPSJer^=i7fxIW#yV$GTj z3hJ@&aGmH~)qY0ws*+=pZ8N|;AO{1N2bs}SlnF0-T8jg%LVykPZUjemsAsa~l_;Ad zN)Mh36B;8qyvm_NJ&&Nu35vH<{Q_T_LzGYLN z7?8g7NRbrdtQ<&`LaGwVN54;tD2=k&;GL*niFuQU@s65e2RGzyy2I}+L<`<+Q=yA@FvNAAx0io=E*i|0Ak!|9LbJ?lxNpYqhO9xYOH+j1De z&5?D!F@JZ#f$Z=)M26raS*2pmH)5=6R*OhYX`*@p3&YlwJ~rha%^mt`^zNRC*80T) zx9OUhmv8EX3kM39X0R;Mqxi_X;Les(yws(O@cdh85xk(W0Op#5G`|(j`*+cQpM|op z{3qdzl9UBS)17-4=nn57dw7j?;fPq@Qm2Us48P<@A)k1w+4&Lo=<*bgo24xlIp4l` zdydB$|1MI!Rq3QHx~ z^)WKK|3qQfhd8ru(GeoiT@%#EB!d2?pe-|BnSZ?Zwv=!=eN>$97-P1Q4`s%3)HQHc z(IV54_u4i(gpOj3fvdr9XlUu%#R#+*w28?Qq8sNAkxq4T{#R_e{t6zHZi@ofBuSW3 zcDthxHi{IVe=vK;<-#>cwdgRLyc>IR9Ye2Bh1Qimr!I8< zlOG;yOy@Q{+!gaT5+}9T_%fT)N>b}j*zJ)wg^C(7Bd4_iiA~BQe*XQWiUP@I>+eE( zt-X|l-#q$kHyPN0%&IP=;u}pOBC#2vpMpclB(R!y7DbMveU<^AdcjRTz(7`WTpOy# zlS)n2h`3T?^Kuk2e5pUq0Eq{+znLI7eS4(>R&r|ZYSLq~(=MapM(mhHJvQx)m}Fn@ z_4I(wYHROli-DW|S@$DpACevU@qB_^Hsh(vSsIu)V}pE{*^9L2b)8QV%min)7md=NF^3o4LD0K48t36{pDl1gp)X>j7U zXglXRIq&F(t=y=;Ru*9*s2YhkiEHU0b~nA>8fpE{qg-uld^rne$loqrZ8 zYx9c{o?N)r;H2HV`}JoUplM(q^3fJf zVB9nX30HHS07mQ0ORoG}*Mt3Gxeh1jTr}0;%nqTuVq2tSS5_ zg>?d%7}iJ4j`)%q;}$|ei#83)>)(E_F5s2fzo`o|$DeV!kf74fEtL1KD#44~^gmz4 za5B*gm^nJg0qq5CtZZ$p@88ORH!l6$p8;O=z2BMfbE}f<{r-wS-i_XGqWE)0dpCYJ z4?vX=5f=eKJc0lif&Kt@O@JqG04+clBm^nt35fMUw zs=>m*qQJqS5MrQVVEk=k>3{QZ*9MUS06;)P-2VVSe-Mu#p+LidgGWF_1w4X)gnR@A z2@M)0sH6ud4*>N98jXmNALgmNJ}j{vI+J%;G8~COaWjU(z&MnGc|Q!{f1MCqXV}%;XJ+E)bSn+zd~`tgw$^U_XF>Ny@T7b^u1{9;5#bA)o&(jQ&9A4}9(>0Z5P# zAhCgb0^kE&(FIZ_Jqo14d7lKGk|mqdiqwmcHdupH6u?}$rKmnD=;kA)Yk%CqAk57| z6J=Hy;!pDNc(X8TZTso`(wWJH0=DXvGO2yV=#dunK{dM7H8Ll?ku$>RGXxapDeud{ zP9}9Tc`^H}ta?}lm#p@Y<0Rv57Lk+KPrR|_F%?l1{H!<^+snd!EvxJ7E~nS!2I9*f zS;DN+ok=3Kt1%SitA>+IM}M?%zvpwQ?~Dvhn(9?EqYINytyKMVBH|8lzEi+ub!8@8 zd8Y1hI=06et`#tKFt*!}XzOL#cL#X2Re1gS4iK1nCE|4ntL?Sac&$ueHhc$ICqTJ{ zx&xfDcw{Qx0g~ML&Y#`^#>b4~gMI&6bdvcF(9gAX2f(`nEM{HFWP+MJ_u8kp0~Dw3 za3$VAF5Cf{5^p;~xB>q={S9R5p>8rS-SUs=p6{IxSG;D@;zY4}!TqL!GwXIJ8`L*1 z!8QCHVA~A2BQx{@w)GC+&36+*;|h^1tXLj%vWoaJ&n|nHd|GrNuv#oBC6E&E>&oa- zmWx{F%v4~X;c-qv%BM435T{+$D<#eAYiv;a)ViNOnD)_1WOWgZCv!3>bdeC>Y;vbg zf&VFwSew+_r&D37$;wjHl*+gO>b>-D+5zSjpy3csC0;Jib?1#(DcR#zJQGkt3%|oXr@xZtX!KI}XqBH#?DDe#j|bN~(!b z)>VMoI0GOhzBo8nc^$x`oaSQKI`(`w+XJKgeT|K4z)}J1QaIqOF#6;UFr}$A>ZDS% z|IBxC2ZEb4T1Op7FnjoUH#D2iUt*(W-eNIvH#KFegxHA$I{SEKzvGKJ3IUInCvh3+ z9YD!qB^1$fe3s0&O=XfGgy(S&SzGRNj~GspXm}1-!`(iPbzu)d9RIhx*oc(e>b4@T z&1X67^SSyOr$HjeW*PnxcClx&+~=Kl0D>5stI%uE8l(SZkk{oZ-|-V2*MrboK9;#N zf{VaoZj=+uJHW|zuXW-E9Qr#z*e>%R!KK8@Ym@6hQ?EeXOL?n<$~c2M=F{Ty+{MQC zvjl@=`_-Bz4OK3y^`_ynG^Q%btv-!xnpwB_G}AMJL<$@{s_+N?i_iQU@LWW%6x*LW z=#EQr35;$%>OwTM?Xu?cYv_Xqet5soTQGASnwY)+($eU*cb0GTmh_sre6&s&E&nY3 zg^qnvuvQMP4FUkNU>4TA>n7utWy=f3aR+Tlu%bA=kUWx9^BpO2vMkoxd2ao_NpRU5 z8fc?#Ta0$@)JDk^%cmA)er4@eQ%LVKi)EWhi={b#PiC_k+5&$w4@h-sk}hjQ1T3a3 ztX7Bqv2>pn4-1A{yrlG;?cf~Q@Tkl2EBa=xyvsYldzKK56?v1ol0a7s2n0kzYvw+; z$-=~21ka%cjIqWAtbNvUzpNVXiojv9fx<7$N)sYygwa9Oj}4!9o|=W}KYY{Wxj92ys1nVqM$aiwawJZm;KjaZQy zs5|1i+!lBgn$2q1%2zR(n_<3{as6sPtVF?fNHZ_2j)cH9)$Rx-xu9`d%7k{Z(OImn35XPo9)|+i9k${Cf>u@?Jj@X|CK0ko+t=0K42Q!udKJX; zh5EjDS>#(N9%Qx^KE7ri$~YVdmT4AIUi-A8AZnZBwKTHBMO)cAH?h=m%4Kvm>Ly&* zNSI*L=s0gwif`|_)Q_v`e>*HcbN%xCXd#q9)Y`ZV_?|8rb+j2$J0CQ&mM$~~^Fkeb%!*O*UVMWraME8Q2+v7qFSay3_SMDz zRPbDUAs%f@Ww@X`NRwOXh%9pNEdsDp}As*&ueT7v!4|Qi}+pu$~v9-&F8CUD!idPr&^wH1NW4HEPi*EI$cO z3rY&|W4-hn|LvYT04aUT+{xzLCF54NmyOp2#JT2e!!F-3+*Ttpd8zZ~+0+{;bNW-S zE60=2cXt33cPf(w0_4qp7YE58x!XQJ-Lm|Wi`Za2%$c!IUK;yelh(Uei;11RI1A}{ zt2l3rKeBi7lje|`bh?X{g}PlDE_}EH1X(TgT|x8T0aBtGjLvsh8WH%+Jt#WA*mg~N zEcm$>o~e-eDH8|-Kn^!&pDCgg`y_mArP1*Yu+Wkt5x$e&=U!HSZnuvpQaoVNICLy& z=Ie^@;64<2^<9S7fQdJ{-Ch^{+G<~NvC@x@B}BKqhFMB3NVDMeRHZR2-b;^CZT3)4 zbQk)inTF6TbB7r%&1RhXv{6+Yer>QK?dMTRCsGD|DKZu{#D!{V~5pI&+`_6lp;8xm|YG zwJwBiZ_V$$*CFAW^PiHxQf%t4oTPZn77oA79e8{hJoHrbsqW<9MEY5z0NOiFBXoIT z*N*02ZcVI}=A##ahRBauN=R%yD|6--Lt>wzT0{wouSVDsxyyzodI=-i(EWFnz4-<| zZ>zF>TpU<5jjx3IQu;-Y$b}HbkJjUn{NWcdX88MC4djPOgB*HSyjJN)oWoA z*gz!$7N*A^Gxs;9ja0uMxFekJ?7Q8XHsEg|d+GJXHSU6_YAZr@RMr>r0 z`MKqm@F1~8k_MSVyk@wZ$Q5a@6^efv@DA>lv&rIH2 zTG(GGSF0b)gf@pxqRbx`n#@~C7do!Ghn7k|{!uT*?CX1+-w5SSf0J}Ax#Yp#=K10P zJw~qNi`&IfCn0c|DNi0Pl`!lF*J?v{N7q$*N`4KPXXls}!5JS-UB0yM|ldG@bT2JI#Rv59Mr%T$6gQCoS1X069NQq$zh3bJp)dC&Y2uXOn1@ChuK0oJ&9;nIT@ zC>Nx)wN&_9P6=4~82cvdLfEqWl@K!v$%r%`yh~2ug4*T9SG>p4m)Z?w7E?mkpWZj7 z$@!?s2*>iHo`*|)cJA_8#0s)|tk7+}-A)Ym6!!uhh4Lv@U*X^~^^S-`H@u=muC-&+ zH#;mTN<7;H+;3}FL zk1c9L>g5oXG~A``4#Q5!O*pbZrd+@#kg+KQ9x_Yf*be)RW_d!i+DfHzwfETf)j1(j zM&At&?sDCI&9@MM?(G4)->b@>XKH?`3g}q$?>1O~PT4cl^Mg+hTZ2yZfHqz_n;8NX zL{_vEy9RBgy^bpKcvM*;TL2vf5(B(M7t#$brCjuE}D4leqMxEeq{JlDX z{~FQ8if>KzCBj=5%);Kw%8Ef+KyV>c)8VRSY|j;d;h+Jp;rxfkd4?+$JC>tf)Ur zxw@E8^+dR(V}^FMW=iENFYJs`55qW>V=7wQDL(ZAj?1#}ja5|{7D5z`!xqsU0uCz? z0V{(5g)-zh@7ZJ8$Z%Mueb%{!+3V>(_{%fJ1>T`lmHe2X&qgbH_Nfilo_)vaj~*pG zBA zMHYbCTj>)flK^c$LKf_%zh5$5zxDcAzx+CsK)#2_{tjM z`E8JGOKp;EwQcHX0Y<`y#KNBj#hJprhlM8vCPgoU9iv&K-DEPt@Vai7q3ns&C3gu? z!p}bOk?E4pku;_hQ5HlnNN@@Bo24DgcTjdxKBF3nP*q}6eif3mDo2yGGfcGUxrx1L zwfXdU$f^)xI&g5fY^987a?dnzD8rO~9k+%;TYx?VXJc!fU@&y3F@;Z`0n0krRD`It zNv(6dm!thW=3qM5V%3nGRq<6uj2YOOom@2qou#|uM({auaaQCU+D-h zGRjjKh1;Usg0YC|1qO|8SR&VcsrUEz=#eP6SY@}!i6BF<2Kj^Phc;b{)2c+3{Vu{T z))~_47|~^T7X=;YLjN<(Sty&1I758X1d~}kUW40!3sQoG+Jp3KYEObY!aJ_J^!M?? z!S4qRLfSopdNBK5SiMN4jf|R!f_+h_-cZ((x0p|z&!!flIa4f>|1zIBe=EOIJ+au+ zsI?TnGHl9m3b(A<3~|bB(s+Vx%2V%6v-9YWS-Jrklgjqph#8VM4IX74?{D7TWS*kn zRy_`TZ0--?--mk}7;VU?hQanOzQY*T3hy&+$VYBm3S3=I_&ED`uDHh>GjvpCVY-GEb*Y zTTF}26uP0lY{QSl*L>M<{O+YMPtQwH9(uQCon{^L!hD@Cb?~#vvl@HydpH6$3?gb2 z(=>613s-5Ej_1KwJf}_vw8t~^Z${6`bwBAw&V8MueIgq1ViOhbsmI#h2K^bqLF4l# zI59X=L=Lolt0dJVCR@$-!b?>U*I)^HcTPgKunnRrIP_&$4+2E)!0@?c;}UVlPTa4{y4@ zfn-p9*mRhE;KxAVdi=nd0gnN-!D&0s$CIFuPEYhJDKv6*a!!2zHnI+MTaH- zrA8TB2|2QD>968Q5|%PN2|{8L;**~o1EYnJ=w!Ysf*?GZ*OYBRAja1`jqOPoO=Yr&n%p?w^NA&6`c~N<#6Vuy^+b<_% z9Sj^U?X6d8)}A}at}-449y+hR>r2#Ht~H%VIf5RA-t-}PpVm^>692w5Xz7`a z29Gwn(y+3lM}VGqYq*1C{udS6o3yX$FKBp`1Sr4JPbePxzR+f)js=NegDMxvmoD}m z0_qeD$UxX`IAG(Uj=GS#*Mx`iJM+{{epjUny$h0Zp_h5L6~x&FZ`w<{kGoN5yz;sW zxsr%1Bv?etajnu%9m_qO1W(A~zZ6Kat3OpK%{CTEOqo+h9HGm8X)wRQr}!**wOSo>>T6_>bOJ6Dta!oV1-xo{X^zS&fhM?b>WM z)-qZxEkIZ%y_vs~Zjb$e4D;A}PHM(-nujyuQWlT~p?UkYDw;I`Lay{x_EKiGa$^s)C<^>g;u4Dbvz4Dt;&4+#x*42uuqmd!1>$ZbM|Fe^YaFWy^N!YTIw;$xhrZ0 zEhlm(v!_<4S7(9e*ymXn92cFJs+Vh5udiXRzur*Y)Z9wmPTyJG-917AoV`1``t8i@ zkJqXE*48$Tpzj@k01BY@q7O&x3GYwTJ-ibA|Hk=v7DDj%fd2n+RQ@mLjebslHQB&N z8WlhXDDQ9gN7WTT-x9cg0)IRTl*e+<0z%e@8~AHaARx!X)6Y*BJe&q4WWVPQA=^V9 z`$L=T4_`uf_^bsX$HNl~cc!gWF_#7|YKOGO#`rVSA_!I$U|*?aw0jz&}oDf`NZ~q0a&O zvc-Sc0F$TMV~z6-W9Ep)9D@`QW9x|sm~=#?jADA zib|>nY|@>jVU!2M`Bym(yYakx&ONag2A!UlW?WY_X5+^**Ur@mdr>31bd(aZgbKiZ^Ni)4+gS~&T_w44;<8}hu1xf5aJOqGA8OPt z-k73kKGgM@ks;MwoGYANI&!w>jFmEBZYGVLk%D?Az`>?j6m%@F&UV!TWmrnT5L0=jo&>J>*99kBV?aR zMAM;f=krPEm`{A&_>LVrcBlr{0vpD^Ut%rAms;jc;VOZ#e}$boV4NO|WcpAkKb*Gb%1x zhp0Npssq9LeQ;FqjzRp3%~=DPqJ7TeYpM(=%C8C+YIow|o#~;BOnZ3j5?Nnus&^He zZetWa6-vF&N5B?6+N>Iz$U4&EPPWo5x+wUjOud!*p2zWBz&lQKikxmtMFZ+(bTToR z9!M3DcW90tjX0xrEbny=kFoOBFazvfxa|rQu!OSRq*{=(KiwdHE%=owhTHBPGa5=4 zlC1)Dx6TMI)l?^PxP$iVfM+}$EQu?oyeo+@Mo3-0Pwe`o{DbQxc@9oDPY`h@_;y?T zC-vZX-jeC5Bks!cM2F~XOIofg%G;sC^(rP9Tq))l2lAiczeHV_=YPeJo(ZV0sPpKF%)33LI*t=x?`IX4O@;J2^&TJhYx{bH zOD(2G)TTGNmt^pa1Od7T0nf-szL5`>oe2amt)2Hu%=JKi+)nM}tzb;#Nz7^0i4m zPmcQoB4M^}R4sQ!ZI4hasU#mcoC~p_h8q4!SiWC;idMq!$q?ZPHo~svwe8QPwEaW5+Ah{TT#2`A93M-s_);%GS%Q&{bqP+>yt#n zF2SdGrIwR4j!AAt+jNh^+NM2Ce@h&txh+%!C!?WUsAa&4J6P8md_by0pyRB{4a@h+_=qFBUEB87J%2Ml`T%vB| zTsI9u!dRvALfb}|k8o;msr8xy*djWu8FS{sU4o)p+BY#zDV!$;PX}-&g^)hAd&?%q z82i$MEA$5gn?h8^564ZO2VEi}d6HFZjGO#GrwD~=egfaEh8w1ZuXE{XFMBa+)SxUh zwv{ApW>`&jLAA#OItQs)#u873SU;+K9P5l&V{LP&SZ$`7d)i|!jfM*)&TZzQtb~@! z5b?gvINii!DEQo@i998>B>5x1W4j!lt8v zgRFtXphdnbCBjv)9p}p347a4B%%WJ<&kDAh))wDmPuC6+g`aAmo1*VgR>X2BiWjY(f+L<=RLeI9+QiIlt3rJn<JKAn}2t}q_X&Q=)w1ekTLlAh)MWeB)2LbE(8Qv zDGp+~LF!dgBuiGMC;f1+aeN3t?^+-VL-F0BN6%s}E~!fWJ#5@gbc)(52ZO|32Lj9nqI3&P~-tR%MPF@0*bo z6;F=GwELC0$EJC~>dm;+rLxi3TH2=ClC^HZD(Hl?2z3E|;;FF%>(~q(5|uP41w5?j z%Qg4mM%QG5dtU0&Jl?-wOQPDuS)(t(iR%X8;6F3+gP#tO2Ya;-;m$xmlzyMeVPXTi z7Tp!Q$GxJHD7$%#sr;pw)0;0ImOF5^p-oOH#5t_qo)V;kM_PgqR#WalHQOD`C~;^) zNcI7ys8_BSJs)hRxX%p06*F&`;RDbT`<9s(1)XUSM#Ib)PwFVN3_DcZgO8WH&#adE zJRyv8H?a)0csP_Oa_#M6h2IF1AU%agQcoCXb@s%J*lxL(G+}72JEg@(`R1p4TlLCsMjWZ#yfT34{YZtT8X*3PawcP5_?>rIBQ{&wLUL^(1_uiD`EVjkR@$AMAPW18+7=v7$A~rnqsx! zG_xPZvBW=00$z8p^l??!y%Gxz*C@dWMQU%&@z5SZX}FM zOHY6cDqPPMq21rRh#88jCZVhi`ZP7O)L~_z5qhaQ8k5HZO`!NZSCnNukh4@FYF=!X zA&ODMt;Yrh(?ojygOw{C<0Lz%X4pB8&Ziar{U4T8kU>lcN>EE;ePac`n-iMyE9yQAcCiUY~f+OhHOze{q^ zIjAc+G%h~Axe<`67iXTe6dNOyNP-h!g~$fK+j#T;$zZoFy9HRx1mDefmS+;2NWorC*1W|+O|FPcvzi*FPZ zfIHPYJO%nZ2&{?3gaCp~aIxTIE+QQo!PMC$D8A{wD+%Wa|0{f*bzDTS)oah{0VPAV zduWnC=p2%~eR`!MpR777xF1RzxED^_sRVf{@htJh3=81VZ@!=pU?6 zaO)b9*}-KUa9)9ekT!weqa1cDyG0F*7FPBUF35 zJUy2?Q!^_Ezit9@P~|+}B)#W$^pEg%BoWnZk1%J1*!j283qK{b8Q$zxpGjFTY(G(1 zFeq(Q6M*(Jc&N-GufD#+uQ=mTWB zeny@Z>ccuG2e3$!K?0$AsEZLQ$RVTo#Kv{Z(n_Hq%FuWUM;yucIa*S7Lmfu=Q;%ll zx%+vl#=^R&6G0X-`Yp+Ya64toiKwQ1$B9>&8 zSnKq&4hu2`uq=Z?_V1Ie&$7j229j)pJgoq$@@=P-D?e)+@f}32(IX4Bv&Yu2mP>d+ zkJs+vE+>hzv+^C}CRtOl`SBM!q@MwLR|!CEEH~xw&;+KRog0wV!!wTwJ2s<%&y{W* z5&t;$|D;}eLiRqA?Jli(!J8%#o@m48P%t@Qul}0ZxLA02$q5O;o3X9Q0!)_xow08| zsaFq8(`ijHQ$3~{WaY4ziO!$jiR}&NVAfD^s|WO5jfJg#VI!V2ypKS8uI6XLHTo@} z=*Q9AXkcx|hjyM1D6rPU&x!AKUqO9=mJ%~(C65hYA=A9X7#4;KT&xm=H$g!cYBVHA zc;&e*M_I6$7GQ9ZA$=si*pfP)H*czxW(r(CrBJNrocOCi{!PSZS^gQC@AFU^ry)iO z3 z+BHnX_oot)CqhU8A=~UY*ocJh&L+T;HOw_<)42q{3@@#gjWCrpOh|q?TP~!q){#OF z`gZOSIo6+=GWJf^i_B*g#B@80FcdrA@|C51Pk-1J6zp+C5w`}(rQYXQ?c|-JP1V~^ zoucB49Ta-nr6g*)=dY6ecA;KAngs5ucs5{;=Pljss%Ha`U;;w7^&HGZlQohx&7l|2 z&b{>dl&kqoxYG%h)fw2Vs9O3WRt*&=u2TTZj6;DRdq_m(Fg>rR&WZ4%zXVerVG z%Jl&zoRk6fKHaw_9oitTw|`z&Jja#_IVSrA_e^7s(7p&J*xytSySOIc-bnGv^&Z%- z(72;1RtB2c)-vLFf7h`I6-_;pGG_y}%vK2?^Y0+@hVIg;0g0spb^sShdoLO6dE8BDR5wziHezOv4RF4( z>#CpB^t$<(fSI;0tgcyA8E|%x=qDctrmWzsNGIjFFW9$1 z<@162|9z{wfByRT*8hb+zb;CZKxMUBJEAs`D<3=3*5l#k;WmdpW6 z8)#xAYi$BdtIVQr7;~nVodpw$}Ez^_eKpdZnHnPtQ;ZSO)kE=l&<+pdm%ppx% z8mNr@X&HYB*+k}Oql<`{Sph+wgvt$kK*5U`@JlP;{)DS1?`^jXa)WEl>k0tE50@-f zhNY;;I&mvhfL@f!scx?DhHic?3@o(Da0VJOW1g zc$d_z`RlvpMD55TSUzvrfPui}=3`)o%CM@0TBOp!+FtfE@VhGP>6y5(c=n*Uh5S+d z3^fRs%0|UpRj8BT_N^Eu@e1bfzFZv5d)4fxR-s6z+WttR_yl7fNXmEbHgSj%)loXQ z9^Wtru|d0*_6stjRoXDB=qq)}pDmUDvhnmrO~2JO$>w??(c72Terj;JvPpsBG& zP?k(DX7K|ckf}(rCr$mVb&m|0?~M@OjNi~7pr9}heoa~5hPhDYOy7!1QQ-MMKp-7d zvB60EW5j=tp-ssbdV{jL!W#4RK%n-HUJk540Fb$Rz=mtLd)C1E&*_&PCcyUU%-i*V zWhNR+^?=nZZwkq<tc@S+40w@u z?CA)zd%w||=G$R)NQ$6yB}_e-)=iRJ>RQ%*|^MEeQSc@y42o_$OO`D#>Csd%Fm^Tb&#*00a)7V ztdV2TC-%9f^0fkt`&QW$n8^cU)~L}<-V_pms_^+%GP%oFavuOQxqUTR0u<9=MN5@( zC%b3go^+!+SG+p{VYGIL2@b5c2?_q@1W^#hIdC68B`%7FwqN zykrroYH}i}8$ea`{_)7_7e??nJv3SN*VWyf0M1&VMdDae&;{$2K$=dK)m_#%bJG}b zyeHJJ3vu#P@8n6c=55I~UZQ@9{L%9S>ZP@1FwtJ{^MspW`NsFvVov9q_k|1s;* zPTm}iB7di9x{oI5#M?eYffF0W4PtpVHAGcrTiTb7xHPY4N$+`)L9T!XKpMhSplb3* z)8HqJdohL(9tdLYn|n5OILs8w&o8QQ>E79?8BWOsS|F4iLFpEISpIF!{IOMXr8A+& z&39KwihRVJ1!BsX$1ytG@K_&!;9N-0ov64e^n&*rb0|Wda9#fF=Z6TfVPR$>udx30gG5z_mSV$PHydN;V-nK!&_xa@nl0J_RxqQAq@+}gItac% zm+I(`w2c6k*>XL2@-ckWPyo z@O)jKJ4Iht?N8Uu9bDM+A@kpX?Z*A%2@lXma=;T}a9;8{iXEDtt=^lz;ii;^ZXV9> zT{kOoI@=eg-JMXJhbsbJ{d9G_pD}A_iF6K@ObUy1tNdlB48jyb(tepOm&$>%GSYCc zz-E!H_)_NTfqd##?l}|kLcEG zUbB|y6-6Ej@kT~ufpnNym#SbFG-%H(QQVHO`XNW{LMMAv}uLO^ZNI?q8@4_MgOuyCgc za!!@wv$uTZX+w0TyX9qb2#giK@~XBp8pn4ne1^-k~sFO zz8~eDHH-jh%K0AGsb@hCde#rTvt-p1a+;cMSoAoifs$d$k9EZOeXbUzu;{KsBN1i8 zTPHg(qxdt0_WMSbb#=5PsY_UOmqM0gTYq8I^c(u2Xs!#wp)hSKCFptHQzP``WI~XW zPY-qe?X5m`dL|{PaR^ZKxi4ob#S8|3=3`Tr9%g8s{v7~Cu{=JDum6e4Ej2RRI z>@aao{lO=~;`drjDYExurLsFp_-b4Ztqj}sT9GS{Qnv)n^RWY+-@O02$N*SOG zb3p|S=l8rsUOFF?68=i_D`}@yKPO5 zPfr{(=@Lxw&@qlrl*Kq$mf2%=P$Ua6GL~VCO*Pu?>Q#8n6e) z#~Buk;5i9Vq`W0#o}KY&+Q}}4Tht#&*ay+nFg+$mKo|@`Nk4YpL<%ptMhatT{$X+L z)m4F+e$b%zoX{Kq@0JfyX22yd3i{ptOycFXH|MKZvXJ%4*^>Bb^~o{L5W_7+@or~` zW zPfw^gt{3IhcHh#DyG_v0hW>D!4@)af0dT=^JJX658rLBn-rq+R+&!*_E3V$S=5;5~ z=)M|;@7*@$E{n@;Bsr9<^{P8a%I^ao{k9;~~Q6-#;Jb;EW zvHs!#yR4$`k|!OMT*rr8ZD|;GSox#t(n}_tbU20x5QAl)0OaVOSL}y~s2Vnp!_lAW zPgJibH_Zn{8ftDO3o?f){VH!RT|I{7WZp1vTW;_XmhI*oD=-k3QY$3y*wmJ322Ka# ztOcQU=^I=ApTD-qOPJ$N+kKdlsA9M}C5KN+{mb^mIe%u4RAPB)i`xt&pob=v%iF21 zjt#eyuawwG7PP#S)8h_1iF<|uIwcfI2mx~h#;!=&=cr#2VUcr6LSVCTZ=_1{Zw?cD z6CHdRm@uh1QQ;ru9bjgWTr1yVh(=^{V}4*&lG#EZjA8*7E1{^E2IYYMg*`gODAdJ_ zh@=K(B!Q`-PCyn#FbpaSXv@Zjr)Tg|w_%v$U9hXsA;*rR@ttS9mX0M&F1=$&@dy|Fb|k`z^&P@Swe4+iq3x{D5*R(o`)hh41+6SmWNtT@M_` zX_dfC0naUwy^lvA9SJCgv&C$!bSv?6fK5ldMVjUrMqQe`1ZnvOuS3&yR-#_o=3KLF zojm1n5pG;cHu~<49Yh4>Jiokr@R5UW5(48c^`*aC{$_)()OKssqB{4qQD>l+9dzgG z*qFLD?cn(A(#cMyn^8_abK7we0<*%&?E1j0&SHlJ0~Wy*}e8mU6+ zIg%VcE;WUH_oDDzyKp8|^SJd79g{hGUDF zME%o!N<3#*eN4`qdjzgR_OjQyb+gWOd?E){%%@#=WLOY2Oj1&3!qKk)X zZS!}^BvKfvf0PO?fIf^DhI$51&#s(SW7t-@20%cF?nZ=D*9afghewj%e`FF*R+D{$$=7dGhE(4z?W7eOo=Uzfp6}91;aG#=;EcuY8d+6xmV-fGWuJM{)SR?hsoU7sv}sy>F?^sy*`JR;UzP+>ae9šv&MT)@eRI7UrV|H!#v6aYXB$UD9uxB0TJ3!h&eYTNE! z?|=2}D3U7#wj*h<_=Wd zYqR+;A2D8$^aR)93ym({l>xuC{w=iv*_+q&{{hzjFLlAcq|<-NnEypO{g+DlKbUl) z6Jpf+Tgm&sma+fnMgI30LYV&_CCUGjOy!9~t3)ulvX9_8(!|Kezpl2Ijx^ z!oS1)N5c1aSdM?2|0S*%{wehQxA%XeqW_0}`fIWKr<;Gwaev$Yz5U-{|HZKWaRB{| z{okwqg{>Hv{^yzg9gXSV82=5O{-5T5gh7A%{x=i!|MTSkX6hfM%ioOr8`HmN6~{kl z6~jNp?(rFz|0neS_WplkRsRX;|Akd?uyg$XZMdpb+xV?Dg5q_eHfeOf%i+)iBH;T9 zL-lj- z|7G8TFtD-qWY4levqHtd?bH2D?QPd5QI*I*NJ^umx(;bu>B!qb9$(K$mC^X>^y=M` zF=dOYwx43q-i_4b{j&9tLN{pq`T@<*>6Rz_B^P!PhAQRx^^TL>l5nyxMxRBQH}rTQ zEK#J4u+ZkJiW`Ntz!!vQ*p6}wnDf);vk(=^NXA|E6%e5+nsbNTkTOR>Rh&br*QGsE z^txwRCm1_1bevIB(j%iQ1OIpH0dNy7c)2}tod?7gp(9z9(zwb%#?X~vvrea8l}kib zr{)ZNvR;>f@6${VsfLu5eut)mICkd7#w;Ni5elQ(;OBzz>s|sP-AaOwbnu5gHy!J< zcX~k1kVsYZ^;M1|f8(+Fbl`a=`7{h&?B-juVbY_d8Qq|BHzn%TwxLXIILqUEq7)E} zblUs+_t+`E(wX2z!@M3IoJkT=QIR~hPyZVN?k^OsR;%cUXhrg|ENN+G8Ih& zot`ynLJSg4J&aMRohq1h@#^IeV0kCc^zDcI*k+Oei%liN0`TmpLH=)ir8H49q&n zWvF@Biq){5QI#^M8_?GvLBrzVCk?QJC}s{f#gKRWgsk+7Nuys{Te@8gZJ20*Pm;vb z*IKfafi$C;Ersh4zf#!3!5}JU&l&REsW}Z`joJlY^ZrrH&2<4oaYGnxfA8YZAMIN! z)Z1*)+r}bnMspiJa}u`Ve1Cta+xzJIXM86N5{~Ey~|uJy>q0B7~(Op z+-LM|qO%$T?Q9Wn@|o}TLv?mSnYV>t^*wD>i*f8J+8tSk4_+o3xzpF*FaJ7)1&<<+ z7rWLx73?%E>;CN^=cTS2*5Xt~r?%p6S6Z5<55u_B-J-km-Mwjcw6;dI+r{q z%>6x6quX<|U(={pjRf-TR0B{qgL(~f(lYn?84ul62s1u{NMC_~Z?6)pPoO?f#bg34 zn5F;s`v-4@>iXd3A=5bFSJ1fs<3U29h}DI}IwAhunV>=3$31-}>{smFYijKu5O+~^ zbs(HtBlYfO^?VHvpr5n=ur%dBIEy@Os|{bSw3%S{zHxv`;uE8M=e6Z%eM>y*skA+0 zSsbT9(OR~&2_d-EkK)Ja0=NS)eH9pxj>|9rW+Di7M0PTu-jiAAIQPDA0PzTGCK_!q zkibOaQe#LGGM>{C>;G0AhC@(&F9HB1KpEqS`_m1$q%_zjpl^K2m`VUI5{(xAZsB znKXAbpW52vCF9r3R!q)AS)oQUE}kq%YS|Lx;t133{pGvtf{L+-iJ0b&=dh9>?$43a zsADNP{5KiJBW-KPc)d9>p|lIg?Onn_0`jzjv!}HQ8S9agSV7i|bd-+;w~+27ZfiIg zfX|?R-^Qp(jMSg_=Yg6a7AcUKRCVOaVg@NLXBLKQ>~R_h8g&-RF-xK(slDAPqWC3O z<%yU`7B!6UbI25&FOO@>R}j(>GE>s{nl{2++s>usLMA4NK)PU|Q9C6yq=y547XqtS z-~(?OSTxwHI@sZZo%^2T4*BhxgJ;gE$#eX4^cphXhk~aU-1205TET=l~Yl$64m8X%(g@(e@=d z6~Xi|O!$m@o; zuPo21!-mF3(-}S~9ksSZ(Ew&YEh91|9-r=uZokAfC7yzqj508~zr7^4>I8+IM={x! ztcZsEj!O6u5p2^QF70FV1UF@k<;uqIa73d`B8|OYJl$dcR*6IF9qx#@pyjNKwIo-=j^PJ?LOWyCsV>Sc#j~3%hyuQxRoMGP zzT^5wBZ38Ie56$Ilml1Jha-kfj4y5kOH1y+&bCn1X`OEWZu7{l;!y(^JkJpEl8Ct) zqJHK;#3nipxI=kXX4NvUaSVNu8s#GCkr%a#OVpk_vrhYRDQO)kf7wNh{lzBXpDaBRD6i#^OLC?NeA4+%4&P${248! zG_qlF_Dd+lEI(6JC!b5tb-VSn7oiSwbG9fNsT2eXw~jDcvCoym$(rE~Xsmk7 ztO)Teub!)=lm2nB_D3XL!ipgS2R1x=S`{BdB!*Fqmj;*_v=y`YvopvVx^`Piqx^`X zXzZvcJ;)>kcLq!7L^kmi3ph=u1+$Z1T{y0gcU6gB-K>0KYQE|k79MMjGjmJV2LXiC zUyl)@`tJxv*ASUSK@Ix_kr+(5Tps5E-4)E2b$N6kBR@GGK^s(?KhKt>1Yq!s zfR8o7C;C4oU7PM3;?d-v*?J5ySomD$AE2wmx3CfjH3>RvkO(03=3()vvxU78of&#L zN#OokEVGepNFsQ5 zCxE}8k7oJt7f5!lJ6XSnWhre`pJvv^WXVJG{jTl7md<| z4-Dpmh@(bFs<}`U{Y=AZq?Z{O&LrdA(@B|qe6xsy0HPvCn$BnUqznIWg5UxW06G?` zznROK0ce*yZFAA0DDj(tKeL64Rm2sNZ*CI2lsV3gq8T;u8L0)}S~lWlJtq;vI;xJq z;}<69;ilK`&5#tL@^0_1q?1*~YKju6Q$*WqiPHqI0+%Xv8U`*hg7NgG4>shcYu-gJ z5*|j(5r2EB8Sug+6=27{A@Bz0AI%hjS`0Vyih6@6gf9g5CMk`kc>~%*J@VYv?k~(7 zP8-&o*pbC=r%&fj?@w#zz-$t`cx2+H>F-0{8uxQL=NC$y4ZR4q^q2Lb;fi><>)D18 zHJB=v)vN(zPSM&|g_hI`w8ok#_H9yMuKSh1CeWg#0*DAkRXHp_D2c0>Grf*kOaW6X zGQL+dKpyrsYO)6|jAAjX)2brMSo(&uhV$vb^3s@-6YWVg4Q7u*P8wv3$r{T^YhpH! z7NR^q4qosx8FOM%Sof4h1A6aU)*UR60S$4d1cRKz9R|bH(0aN}OmsawAcav7SexfeEgH$acXEkGhy>DG!*I!o>4>)WV;P3*n zP}ZO4Ty&i%bSh;?KRr0?24V4=FO*+S9X_vot7a*_qqswdxQb5|^;dd1@TB*R$H4m zn2RUb0`U;>vW8-LrUY?%PLF@OWGTX^MN3dwn^4124$<9lMh{4l6f1oLf5m^lcW@ubhwb_XE=wi z^Cty4XR#dH@R01i%FzZn=?X~Myn+MgVn7EINq%IEp@A@QO)ZYG_Fhydvv=_kn!YLA zd|-wbNj^l2Cq_=_M(*U!qPoS0&+B90VnfMyJkW`|Xjo62ZV;$xRK-eV|NN*$5WJDM zNz){q6xyx|bRGRym-*YVAbjI3i%%*qblGgJb@*1|ahh_zgnDw+7zSw)RBt}?Ml2&= zC8C||kgCSMuVSW1W`lX{_=C{mpK0TIp_v-8{mkDCAn4gBh|>gA_R9s8rF)q-V`9Lf zLRq~p1eiO(^^kgDRgeOa${ zW?z|3c|f`Vi1u;d_B^@2?F?1B%Qy_Pj9C|`xH(R(%yZnHubW(@sXrcL-}&=u6tgH| zDK!s49E+{X++=~vBJh_71Qo)hW4gzV?A-T7K7at{8vTUB$YZ~yA;@1oaYNPq!B!&d zRbn%~`}35%M|$HO>BcSqum}l#1_I1Z+Qr_O`$T2{`E+v$c@aVKLBkng-0ygu+Nzz1 z2nynVA}F~91&`lG6-7KI=B-p0n;CZ7z}#M;ERMddnNo11Sr&_6=_*7YX9Zf;aNE86 z>P9l*3`j#IzlJv7K|Rz5-Ws}KrUR>+-l?LkRS*fGHN|l6ATB1F66IW&h)+at#hjfk zVHInDm{tup8e^vciyv@YMvoskT^AB)!0k@a<|T)|HrgXb^h8qd2%~6i2NL3qhGWf@ zXbuxImh=I`ZemFl@8;F&Mdtv}ZQqb>TI^hpIidU}P+;(M-nwhi0r*;rv-M|$LZfbH z7QJipx^%%}$!uiLR*bYC!$H2ZqKpIWTl>-q{=>O7NE;uxAUeDal(l$jkLvgpG9)^{ z?fDgQht*AO$B?Yhj?${zvAmZipA(^JznDGQK8l57w(mhJu z3Haz;%iO6o2%Q#*fYktFzCZ_X3kfFF%eAUm|C<-pzq+gSDf>&7nb;c0~`h zV&iz>+j(PBb!E!1V{4|x=HY%$&B>>JnrDQJ$(*9>!{jaP%cfyn>ZIQMbXyo*ziqdH zdiphvXTck>Nn9C^(Ui)04>suU_5};)i|g$cTZ5kvs(T*nE59<%mWf4O!kilVs?V{8b>AsQvW|)2?&D@AIjcoAimb0qdspEfy^XN>cKE7Lzs7rqbM9 ztsjf8Vhl(b9-ej6z!y}Fqp zJX&YMh=L*h0cV*BsA3idHY?&2(9F60r5bxon?bE>cKVEhwojVs3ru}3hj z9!9(+1FLSUeh!{dXbyhTnlW(RpJOiToNwPOJ5n;b$z~Z2C0jgN?#vK5jhHS1NsUUC zTqg9HW_KU9oyk4$+91=qc8$tXGuoAlk7M_qJXUcNnV*hSp5{DqXS{&rP_sT}1#g44 z*B$E?{s8rzSyMwPZ~|~N<--@xkNblRa2VK);CJU@ax(=(u?{Er1h0%#F;g(!6*>OtmMJ@%HpN8SvUGIgvNh8)QL&6Bwc(0R}AzBvv zdUQC0D+2nj&a|x=){bM*-z}_|p#ja-X_HitUj4*e?q21|QK<*AB#5Hkux(sc#({Mj zo;yM~EPUTz9}~@Pb%-*{ShHNi8sDXI)NyzY^EsmuMe7hD+<%KVo?CY5U3stcHVI!Z zps(o*fDjJ#f0%YzEHnD|>SaRx39yIMMDlObxnWa#_({;EnXn^fyH(>fgondhRUlt< zh{3{&uI=hp=Y3}+&Ojuw49*T|eD^SWiXEV3E?*<0ix*7L0nPQD6n1IAV;vD#BFn(m z-E4?_k~V1H5kAg!Mb-1{Ts%<`(tc*?lqc{#54~sBb7?6759|caD_=3A&ZU^UbjOJt zW~h@^09CDkXSp=$4OcdL;beWDjvg-e-jAz#>IS(9G+zz^QY^7vg}mKc)q$r(YKt}S zC`ce#5(@hz%Pr>iDeA(t%U+BRypzoe5C0CZM;Fp0{9MRBC}btR*${M%hZUNRVCge&YOs6aUR_y;MTX z%F`DUUK7st-GotOi^gB|AZ1Q(MXK&z1eM2|Gkv0`!#$;Lro49s_Ic5%fFj~Y9&uPdt@Zm<;TLVa6j_Lz+ zx`O^dMrl=vSt`~2?nxsnzYdg!FGBNd`ld=3WUp^`wFK;&r2J}Hq`m>gyt&%_j21zCWlo_yCF+mxr$x!`DZ`JLGoc+=8xW{Z{#@c4E=$17=i~e1MiYZj`BD zV+@>ZZUjf`B{}7G@V)^@4JS60aXs3-9fiat#|5F01vEz&far3X;q>GpSm;{IO;OSQeO6cO z51m_FvL!S2C=d-xM@VFLJgj_eQ$7MQYjYeq9Oc2Nr4P`2g;vae!7S{&6-yK^| zCws@P=23D3&DH35bJP!ab*mf$@$jzxB(JM>h}mX?4sm;yp~>_K3hDjXAtvFTn5Am^ z`7TZ~pG-z5h@!){?Pclyb@8+?D&}xWJn&0v$RR~#>D$ihza0gd$x|xoR^U0AUnoLi zEpKPf3P8%?Y3ukeo>#cIb@s{2-|S{%hO;NUQJqS}aO_wkYxI!BgeT`ne}z!420}t^ zkHeYk+x>1f?}Mtifn9sf1*4m`agAK%$~M3P13sA_B~rRfihlBnjJ^tY6{GW~VW|mS zK@6A>Zgk;f^i}S(HhfyDEaFXwsrPWKyx@3GT~P*P#>pR9S2M7QC?bL>Jp{(N@PLSl zu_~Xan~6+VQATs-7(lKrr_;`eBB-ILAzRfAEftsHTM?`DBA81L04@zNUG36sl!w~u z3{8!MiUu&E22md&Ri3II+TYwY8FcT(csKGwH2J7Bil_>s&N*l=yS%#^=Z(;Y@W3`{ zRD4npEh&%2lcA1p&pnq)4J(&3fG+=rk`6UX?69*yF9B9GAs_qNG z(lOQ`S;ADJH?cM*rx5~LiCv53){NoOBxmgm0PtD*OF4~Mlen^<`Wc^l-Ku9;wqDQF z;-w=n+)@G61%I5@$L)?J{~1X%dt!I&=(wh%5s;>xYCjLC*4}i0P%w3SuxMRM8hGBF z)EJU0uV`>}*VlNy{8J%@TUTguscm1&)*f$IpJy!UylhiITWg(tVBPpr72qJpF-I-O zg2>v2KvJwT8MEF5vyy1gcJy%}hPHuxtiQz5&yO}d$tcowJv1IbIs^bE#(=BObU$?Ua zUSg#Kk*mAP0$9HHB0sX#jP=cZ9Rg-&G|9o?HgkJhz{P#p-Qu3Hv%T>oMcH*FPfmu} zac)`3&CGi052@WR&FKlHMekSBE1c2l;?lu_RPm|VAlG-Pd@EHW*JqKp1-U1qg)xli-hsZ z)`;{jc@4_Eq=OgF-Tw`_t?XU`Fd67swRvo+`s^1I#>J3FCMN1H(P`1O0QcEHp|mEb zK>-8HN6UuhxzqK~PEAetk=PQ+H;%I|y3RZUzTw0_6)y2k%`v3l<#R6YbF=KWIAJAg z@F5A;@O=u=o#KimHduZ4+oL7Q6*hO#MY#L=U9R}x@RYR`wR!By9R8Lc1Eeo;1*P{k zFB&efi&$tf>I@s!^feTSHK{hFlo4USg5*sS$NZQ)>;4uN|7$TpaH%HbF_((M4^5vO!yDk~IiB{`%V zBT8c(`%#a~#uc!U_3vf_@3ulZ1-?1o#CbVuIF|H<`(yb6G)#ILYJL+PS4pEWnI)Gm z-c1|jF9Nkn%5)je+dr3>v?R~9KcdCoLM^!Fj2HDty8}PUj>M;4p^S)5q7aG@1j3M( zk5Sj41e)HD)-3KGECIN)Sp~+=@@;YTSPzT3Xf3ojAbjJ5!9E98VGsJK*J%ncG zFe@@pZrl$Fa+b8g(S&{(Cl5gIx@2@+ma$r1nF4?E3sc(L%a&sWWdYv|YV@4xPillW z6oh2#{aL;AafE--yNL;rZGos=;GO+TA4aUAg$JZ1Nu2J22njT}eIK-3(_i+K<@7>e zz(jo-ud=;zudzL}#S2WGBnp)M_M4<=OL=NCphab%8`SMvM?GLk)fe+-8x!MV(5tcg zM4qIeRr*BEL_^=EIoze?I1~xb*?tlrnGjl5d2A-sezRM@b+rtcQ66(o8@L_i)%1sWBpo zPuRwCR~)GuMST8TYKf2sOtVI>2AJC58WYprJj9z1PlB%cEQ=;2+ciSmijqV{ z7>apPo6l86_D9K7qYd2YtijLy1`^s(hYJVVA$AO^GFzuN!?-e=u!GO3YQn2HR>bJ@ zG`i#ZJ)(Ohe;rx4E~DIVZ&S#SVKV@egNYQ>k&3kF<|7&8twn0KvLy(}PYcaO3#x1+ zl6g67_%D9e27q}XjD@ex*{NmW*-P8vo>e-Vc~!rxd`eOm27NJjdNb^EKQE}I_nad~ z( zJFbp&D0HcULX8DlvMb&ks3{?Z9u+7LqKP6S)n@kLGhboS5=8{D{ebcStULW-*9Zdw zfj|ssjSoHm9;~?rW30GWt$%T&)POvewVnNoK*t!f(qj6tpq$h4eOlm?UD*{)yS)?Y zrjO>6hrUs~Q`0y;nswp#n>a5C{X7DcJ1pzkdWNi9OKR!3W(9C(q?|_2#4@Hv*-#c& zWL-g&M+@KWYh^Pdsk>8laghL+QGVZ=rYY#{tI&eiu97+OXfMr&@x%paIk1_K&`XA$ zk8AlDzh@UrB2VwBZ%%1Z9&l}dWXp0arG7D(nY0n0g#kobF`E^TD?E(%(K7>h#^HK6 zJ$OYsKJl7s09RKY1^9zr`JblX%6?(2`(5ztL}c-?QhW*PWetkhcsqflSu*bee)UUA z;snD}m(S*SHmF)eiDP*U3Vr9Ke3#=TIFhO4#=v_mgyz6R$9j_I-VzQ1v}I2Fknq2i z!y@eWH#u6-IyY3hl_W*tp|f*Y5XM{)-CS31f^{$5Z0-;Xt99_3_HZhPAJuP2&Pu`u zgRDh>t`-AIXR%8^mzdQyvkW*Kb6ZFzWT=_QI0K~Rte1A%QB6f%9Ml8ubbWvI&)Smm zP*bI3?UKxA1jvNj{5={4JW3CMZbU$<(yV9vEZ1CIdCeq*F7cO0%MUfURbD7d_a&~z zkx7`{+cc5*h1hwaQ_*r6j#9rDaL?1PY4*dOjloXI)#84bTan#p2%nsR{0tsSsJ_05 zuo=eP9_D2{eSKw{u_kb$<&#bg7|~dFhcicT*Q`O%%8n(i3MI|cA6XKv=JS8@e9x`WWeEx=HDKo9Mx`GM*acVp?xC z+RU#tmHgG;49dxTy1bHOAj8=;P(-?e+Vc!<%Vd+H>=^Cq_AN|d7~ZxpfnC>-!@}sE z23f)1V5R$9BQZXC0NQHiW>{ZDZxfa~;wLtMuuu9JWjMu2a#WWMCJ`~z^9vi9ezp;w z(i^Q3+cEd7;~*gmr^Ye4`>t-k(;+6Pwi336t6s`9KM&|rZ|bQSfm>#jsD`^dffB^s zN*9NI2p``)B0M8n=g-(IVZBwvaxt_im(14;Q zJ&xbsFLQNuL*~?8*X}M_ZnnZ=%)L1itSBpDu7HMe}!KzK?_E@l!;N7SfE|7y<$&ACaKQYpzfgvYts2^`?8PTLFTb#9vH* zvR0ltk^h!LdEc`;Y~su{A!&4nGo`?<3Eei=DbDMsqx`>^dke6tv+fO4=~hxg1wk4P zC*dHWh;$=@AdRGSw}MDFNK2=*AdPeh2+{~hNQ0y(lJ^HVBQyW`zHvUsd++1($T`G0 z>#V(3ylcICZHl40hV5mj553ST(u_)5 z%dL3Wfv5W}G0*Nrm-S05loGQK^=uCe4tkyix)(Jxt~GtdT~83a$h}WQFX-I5=ju@# z$smz@(I)A#`|d060>_8srFKi5QGV+S3rQEUYX&q*E4KjJYUARp-r;TM&q=q1qnvf@ zO|M?JK5G^eUO(d8z>)psL)m-hC9|fv{!Z76U&fmv=R)%i_Go1Fne90T7oh{P2RenD zh@htCjFije%v#biPY*tR$gtZ^aQLFSPRqiV9~`0y)g^(%RV|vkvIRzMfF*+o2jehv zwTVz!l;Ua@bK0v>A1KGcwdt2P7y7+|f1tT>0z9|Bm>%}+QeVgsLGp;7 zXk~4wt7U?ZBkD7%gsVWTPZrPXc1vAKb}(%RRR}#4d{)3gSr7{ex*Fx-Jy5}*MU&zX zLUF?v#m6_XUtY*rUhbY;$PN>KiT={m+bw}7Q`yN&4|KDSioY=#Sru9rJiPn`5q42w}o9ZLlWUVd=c-(x-z^na!e~Dn* z6@AgV*%`;<@?u;NjjPUikA^oTb9XN%ds!0R7v&AFw(58?d~c5H;*DTU%9?hMrJ{pT zFsVpz_mXTNr@)iasF_>AT3NELE%%f3NKqQRh^_>f(#&f~Xzj@xXJvl*F z{{_;f`+%ttHT%6g%r8Tn@cy)>_u=SD?Z>9~n2CosVD1Gp=RDq8^~&7p#!tAJI!DBN zOU>O$HK_Z=x^563g=vRM54Ek79>{|DdOnvahwiWYM*Oac8k=py! zWRM>5#Ve9YiOK7Y^-DHhuY9k)(6eyZEYJ&B(dpZySHhr@w{)ew=Z(1HzWJ-8rpc{QNoVai5y%cGK-J=@pRDzBUrUKOPq3aoWIPUyp?(!<=cA)vrp$3szSm2GvPM6N@&%xD~!w;LE z9o!?)h>VeW&UV=u8Oid~2JBmt{*(wi8K)K9eJPtdK!2bavaIN9>C6 zSs@CRY3#XO?boIG{hAcVkex22=~@jr%%$jHt_L^VFEEzcTFl5?*4Xz!ia}?ZZENo7E0%O?A$dPWi%a;(e>x^dh(Im*_%IIhr^nZwfklY zu?bdH$inLG?~v#z-J4r67-_I?SLyBZp8Krd;enld`1JNeD-T*ZL$g{z4Ly%hy}}6s zx+E^t0QOjxZXWaCczrN&Dz;tl4bYNU8)Tlz5bpa*QcT6)+uzs6H`={|eD$zJOf>9m zs(OltyE}>)Km2M^QlmkUM+1Q|9ro*4CcMau2lEJHf=V=U95>3Y2=Do-h*YDndDXy( zK%oy#`?u%`xzW%sG=@GJ&0!QfkKITU0KR5?HMP4%FoTO&+0nN^S-{mJJjk*8v+7xx zARTGqtKtdJgj7!$P!$gEWZ4p^b_}YQ3eZdF zx%Q}T>CUvaJ+18O8*2!;sLo8=WNguaYwzlWl|+bSlan@Xr^!>i0b^h9SC;QS4Q84y z=YC!U?NJ4sU)HDIotT7FrY#PvbCh@`XVXFTSBIf6r2d`We)m=GLD%_A*U{R;&h)Mi zbHn)u_hX;O=xi#olI=We;%Gc8EmH5e>3f&MwP3=wc2HBS1JkoSPDennq7N}*B%j^Y z%nBn`6|&<^wyuGXEd(6tyF4pewlt&d5qW0aEByG1ipUC=8EmqwltE{ z=Vpfty^$|2>&wX8F=Lz_OMm*M1-D0C}{-p2Kr8Rj=Wk>EWuMv5r~0QaL`D(m<5d-OgA9m^NZ;i^Z-qtuHY zACXndQPH!n8BoHpF6uio zYRE)wVZb`4@0htzopEG|_>vyb{5FSF8`m1u;!GZm?L@f)QY_?ydeiVlUM!ch&WLo{ z^Ms_t*bSLpm*gXY1chSQyTli+uwHVz;H`-z(7|M_aFs)l?lICS>2WJW&N?i-x$#!b zEWw%RVZ1)LyT|ogSC`xDBhXq&jdJmBZ!om=8AZ$cF~e!Fds}bo-i@KfZVeaP-!W&2 z@T}uxn|y0PpDyWx{%##7I7#lz9jJ2?oNuMzz9guZ!6j-lInpBGzZ0Hoyc()>Yl*MBS5pXzvTD zS=cm{d1m@#PP|wYAu?;QexLZLeZ_VB;N|$|*!bw@c}iQZHFgRwCrFT84IF1oLTo6q zmT%J7?`%6cy?Uu!SbP0Ok^&B2W-yw@h1DBM`)qvG(Bcsh!ig!jPEfe(S@+mEUXAJs zsslTsy=UFRkvGgT&eUB8*N)3%MRk|AI?I@u)eV}(cPPIV3oT8)UDwp5lodtg-RyMD zLFNXjMwdgpfSFB&|CXS_S@-O)ps>oDhOA7aIMJ6gTx+_!CZE^Jy%)d#PAH(9ItX-I zWGk>~9+=3F8$x)q>Y6&Wq8ucI@HLmuM7T#ZVT3>SRX<6g{WlZRa!m{(I6e}0$T8O! zuU=u3$5Q%`;{8TU!N;A2mzR4|3PU)Hc1+9{s#zeFA*AqZVo1y1iGkT(} zFf6eZdGyNg}h^DtKW%jwM__ z)@3B`Xpa;%tk3OS3frxLRpmb`a{e5j6jPVz0r!3kmK9{fI{&0*Jy_wIFieG7%Iq<7 z-jZxDg_Ia}TZot;EA7L!oj3T@&nZb8RV|n=5Y$&J5NR<=p zTt8ZT)SlZL^+J!-+ehk;&1HLD+RxesJCQn9AXiL#p3X8vCeY?Qkk{B@AAwGn$<#=E zv25UEKQyk*dn=K49gi|10>-c%az`<$si5!vYbn;w_K7TE%)i3_@_NNc~!%Ni2(SffY ztKPk{&f~TneR(@cqo1Q%@qXG1{)FMo3MF#uVferh?9*kRO-cCI`%0N@&rrz%vKM=w z7=_)z^zsc3?d_JgpVKy1FS4C|vL`rP;m6p!DpLV@U!fq8H<6W>)N+A{hn@S08sjH{ zlJuR!gZ-y5^;vF0QlKE=YTJ9kPdD{Tmr>eV9^Z6AH!5(Rue2~48Ve@E>s?{2dKPlf z-yj{hN@-ci9LB)07YR0DWt+D%${Sip>YtsPReWgl8?i#ppp&+JG?rlqk+@j_vnyFw%JyaQJw z@Yt4gBFZQ0Gjn_%VDziM;<%4^Db+zBR%s;&=NM6$&+No69Cdy$e!INTYGLuMtFjBP zE1zLa@8psUmCHTO2*yP}%1KZN%EZ}iT2~@Y_VK+JeCLG%cA@c%;iB~6kvH?(MK0xg z4u8B^*=p8T9wLU}nJV48AFhFCTgBzy=!6`>nLRW0tn>??TEVur1_4=x?vxZO-Nn6` zk=@QT6p6bioM6nw#7oj)78B?68(Gg2;Ldxk@qeCcut1`g){)Xaa;IoJBf#bv045u# zzZ~@@+UL#${y98$2?_%e9wp7VLP`=`l4~cumm0)ZD!VgQ)GL*kATc*_!dLAbT^V(&c@_T@=aJ+GCyH zXkU2IVcw53Ws6DLyZJ)s#F@YnS>_rrLavxGt-gg(gNzD-V8yIfM zq0yU@Tn;|hDsSn-o4%jvIk0vhuaRYz5EE!7WVcR{_x6Ht(#uUP?$qR2y&;qlxgwIm z9b$1F>+?=iH!k`xV$*!R&&Pd3y?gzW(@xBmzOXS0u3i$`V?Q5~JGrIo`WytTcrD9(dh}HV#bat?Jz3=o`w9H}FT@E1B5W&Ro{+Sof9_Zcb{I zyVzJfAwGGxujfrE>7o&2x$#~o8+A{#-QA#OwUsbumYCxZx^ktsIU<|yD{Z_Dc$S4%J}qB*Y_v_8QcSRa@0?O1 z_WGE+o;?9a$VEQ>+fd&sndRVd<;F|8S9X}6+&_=sMkmy2MW1z(ThNqN{1Po*a-B7{ zR1$?X@tA;J5Ai3w>cIH((P(^-@NyUjXTp;LdNv;ued;2aAydWr=ff0=U2>)vb6xc2 z56V$YIqbrDS`e084&1A?bIA&8clMZH32C!IA|)f3==RSOfy2%ucvXJvGMIFlW_cz)TV(#?{MX)4CL)x| zA@h>RPB#qxc&6y$@jM*^ zv7S4=KE~jJ^$J>HDrd2pQ*m~lZ`gocpes2 zzEf+za9_)KxZa?Nmb-+FD%Q{JIlFS`6)c_--AppkY(F6rPi+|#YgKXac3F8s-q-gr zpuk0Vml&ktB%SUj(&@`DmVTy}=_q^FgNYUSIVoJyv)j;D?yx8{;2G3}ny2^atIhGQ z!`1TT;eGNiUF@Ux8b(L9CCfw(n5rN3vv1VgNC@ke0`W0>+2K=OpkFGNxc_Bpp=o^c zddI$pf)zC?TLi}r@_JqwUpd7JCGR6YnFG+M$AeM)p~o@-9RFTH>TRxelS&Ve}3~iPNsOoGLi&wYrvXJ9zK8)5*(b!@PSP^a|_X}Yc4phtvqmb{Hvi8izvDHHcOBAxG zq+qxgtKb(9F|A@X3olH_UL`Mh_c5k2gy`YTfZMW83zU&7D6V|?r27gzy-XjLZ71SF z4dZ00BM<_-i!2m(M07A|!-EXjM9OhDF%0^-R`1694wVm6b655l&D<7fFRO15{}H->K2QR3S(vzI| z>ed;a%M7MZV~w7EAvI@h*ZjmYQY50lw{OluNR~cHlb(=tHR~Co%~q8D-CKN)08Nrh zO%xOvLI(z~``SLS#Zz8nxFhC*QHIjD`%pR8hZLUN@QDH(ksCJi((^NYe1&Rpk{df= zTacA6!ggtc)9%AM+uUtNDIB7U{N#;=0fx^yk$bj0u@hFx9F1~`8J@Hb%5G&gWL2G@ z082T&XpI*+BModB5p3;~a->Qdq`Wm}2IPjz_cU~#t5RKDN=@Auj|y{eV#@LK{45l% z$)Z9&(%s6!Y-XlWLW-;ypq|WCb^DN0W!faFEbFXVi*`nW2ZIAsy3RCLbiYDv>GgU^u#r&j zn%X(E>Uv;j{%r3I=!)8n!`ynhyAu3^n~qp-$eN8?3Q^=dxaF?Kh8*Cpi@wL*>QTee zI^+P!x#C{Duj9qIXRjrh0Y0FaU0=WMCHMrQH`Hj^2Hd-{r0RuNzG=VeYkzib?`oNa z@hjRf`thbh%5ICZ+M>G@1vR#}sFJfENjH#c-y%uj^WOkjkQ3pB;;TSPu&n|LUb>ZZ z-pvTSxnGI9wM4RH+-$MM-sD%AcveTXilUzNOuN1JD%H7l9+8Y`qUMVY+opNwHIJn& z&F0R!zK?Ty%w@$f%beNzP$Yv~0#xTXehqA8vu$N59YyoBjOW$!QjU3(p!b|b5f9=` zN`_yk_AcM^hrbyZpc|fMe|1OaK^AO;*G4jL!}d~M=~!G=$=J;*r9mU7{$3-V00ZHR zBGF&_JNrf$78zdguUGpN-K0`boMMY@*ENe6J(!92P4-PLv5we#H*zKIA$=N$#6rH< zf*kX{F7p^;TB*bW1M|nw9s=fSvFE{^FT_A$68BTs+LPH@-!XdOc zIi%L_8w(>$teuI>Z_TbP1?J5NsxpmAjHo5$gj1!P@+Qhbc$ThmcwU<7K3*71m9u5vI)r1}V>Hl_lS=Qo`lHdSk!~X*OUJ%YWW>X6yM``VTzo zc$?UIpR?TX;;;g5K^d#sYIC}laGw`G;>1L~8gCe-{&ZzmVqrGXt?}?>3!6_7i0W>$ z+k*c6IKA1k5f(AJae5S(Rj7{56ZU119vE~K6pjd9XKTl3R?aB}pBe3WO77!mzL}`zK$i+fP7eVVaK93ta4ui7iF*S_Z?$9Ho&w1$8g+gGgNu3J1>|))MQh zU!Tdd;#wP4!u!lU(MD>f9D;^O)3y;?K;>B)K$y2!pL5(Rj8@uhLn=)X{Yy*682lX4S6}5h?hvd05 zBuSsp-gB&>aRx`DbO}&=HF2AhtC5{RpQa|WC*(Ar4asVouDeT{Rh8}UPyh75hmKf8 zE^V7pJtoec+1A>5${Xr{e4C19!_ zO@@$ZGL(CfMig6j$S&h5Nq3?Aeo~V=D4Y4rF;C~&ywG^(Y8KPilEr7qn{rs2zvD7wu2S$S;S2B%y@Y@WGwIN zS{j<_Gl|^?K8m5W12c!buD&7AzjR;{xNoMd%gk}x#@yUk*W~Dv0%9G@`CZ2}$J0bO zZYdpU;grKc zE5~Trn{*hTT6_*N6w$>$HoVctUph_PYDZAgfcBWN1?lyKy`DluM%K{$eR}oCi)WH( z(QRYb7~@nZQTkp6Q#&9T)hE+evv+xHa5n-jy~uzFp4-`Er5hvqz$Gn;O#;V9Ui9Ft zj@mY2K>OOhC%B8CozKm;-I_2DY^J56Bs5C9oDh>jQ+~J!@I98B3Xml)dnyPWoLX@6 zRc#R37iO0&cwAueZ1(j_cG})TxgOhunr9vh8?F4+zC9icbE2Max-x$;Ho)uWJhIU?cov z)dCOhLBEadfqt9%1N}D62iTf`k;&5lru*$H{NyY2WRwo{+n68dZ&QJgCo^@R-=+#d z5#Rp)+YBA(w|PF$-=_+F8>++o?e&hAA9z3T$#5O$Z}Wh@P5e3XO~+G=zFnFI{dS)l z^xHHd=(ll0&~Gz+pwMsc|LtBhDEMR)5cJz*An3Q-(;(l*7(u^X=?48a0|@$UWDu0| zNaY$ckYtUhJ?r|qm8C5IN!pBqp4_oOvb`xjekK0-;*4L(`1>5L>g`Fd znZe5}C8ouSGjm5<^uk9vu#+UNV-ciMp%7%6VEH@sWh zrbt$vnY7V}?m&f~l0z{882!_aJ^iTW(CcBY3Zbs_c4{ECYB6-jUk2ht@$7}RP33lP zc7w3*;9%$F$WhLZUmmLO>#z4NS|=VjCJxNpxD!ZgA){1URuMM9JmXnwQuJUzZPWGP ze5|xOHD^Za_3AowFX|fh7ZC$ApU-zDnTxKF3;L1!D`dtI#*Q>?Y~>Q=6Zky@MaO;$X&aOwKOqmdXda|XONpU{pCdf&`xA~s(STF+{3|l>oe1OB#IN!a%v`Qn(u_B&3Rc+>r0ToWDBYjS&)mO zu?)Y0|14rSQlq$YN-s$;LJJS}=5-R@n#F=;hi-z|QL0 z+md_Nu3FuQj(eS=bxmp7WYUL=L!+i%Njj+VwH8C-9cZ%Ej`poi;fn!sU#B@n&pm$b zF5YrGZ{@n}l-@38t3l=5%JY!$k_z6Bi+;(6#UC4!NbO8EcO&-oP~Hm{Xzq8S;$q;J zUF55KZ#UI=WlW>dYghe|*ib~2w;TR&@2-nhU7Pr-WjEUB+Qik|!I<;`zlKhHCyQ)} zbD`JZWK2O&So6_0!R#zR7C%Mn+W0KT1Zy zX{zo+#s|VH4plC?Jq^LnOw|PB?wZ_gMdQ0~%{#?}go%)_H}LSWbRHah7VLea*4%GH zDaTL`VKlI=YrGhE;qBQtTcAZcQan=W+O8(Di_#hOWk&*&?4qm^IyA3vx17rU07G@- zvOC)Al98$=J7&k7uOujCvRL&BHLU zuQ@TUtKHY9dL{FuXB;y0{O(riYtS2_$^)ZMo{SJFWAY&d>Jptf0$+kB>m|*unuX16 zH+80ov>RlK(XGlSYy#dF-QDIL0*e?qH0VrX5KFl~bOVX+`Q$afm`OsC}%2(S|{}&EYFOUwhzRiLSf-e(4 z;q1q^Ovwoj@fm({t4^$gz2WbfbmlM}Fy4}+piA8d*TN7Nmc7J&nVQ@x)!l9d8>SBy zeM7>RhdTa3^M-pg-oXVjKm4ni6RjUB#5~oVR*PGeVIZm#L#FssboN$SRwVLUaY}ei&ea54E(zKi8wKOS1QsI z2!}tFJ(~*W?CsO{;7sj}mv393QPwH^WSg2gk+o6O)2>`A3T=s+T!k#B#zcZ&!e{h} zq`O@u=lT~RGdbOgUmX_u_F@nQ89iaS-cR2w7W=&utBY)e8KFcBK2XO354Q=6WEamq zAuto36MN^(022F9loG9(6>6p8rQ0aG=Q7yA67>abbR)*&D>I5z?Jhzh=b8w1v|B^| zq%kFigcLIuyHDA@QfK?e`kGI-KE*rR7bu`<^f;|J&|);lX0qdty)g)DIlweb?$qxj zc4U4lov_&Ies9gG?LdL_57mRG$4q?j7}Y~jOfg-kegU3|J@3}Fp9!oAu-d9n6uN~R>b=b3xJJjdwheO{ z!PeBW#Nc!6CJdS{ABd5N3K{j+IwubmjwhKTB)?*_DfwKd%3q+4luyitrTEUG`{Lb_ z$AU)h;&d~L4b^R*e^_y#f7=t2)Iqu(h)HM6Y!EOri0xNv>pnx;f?^pCT-3#tQ`whS zCc&4*U-R7FUvOYXN>S7GlE(u#I$Jp5+lNz49b%#u$xltuIM&}r1h_wPP!2e6tixzR zIN~x`YRnjL6Uu2A(~&-Y+1~ewPdC5J3;q2($WXDRWpRS`SQiPVO`Z6C-`dbAxRb3m zp5nbo6JRhtH>6FLSf#U}Q}r4}TnZHbePVJ>P0MB902`G!*Xj`g!%C_4)$^d%iO#DW zpZV%8Ypz1vBD|lv;8K(h>&1jbg`N5GkqG>-RusiJ*kNM0oeC4HxmHVv2&btSw5S~aiV5`tw& z(paU$1Nm=M2;x@mJlHO8M&F2ieX zYy0>2^x~d}3=E5LHJ!z&uGFXoSG+I z#X@LTv48C020y9w>Ya2m?M{LU_B$=9w?F0Ja$<)XGK39nb;f)Qf3k26yYeFYLEL_S zp7AXiP0}UQ`(QmBy~+(x{S7yDbd(vf;!C$7;;R|Fov(Cb{XcQD;LOtL zWah}YZZHiMzNDC+M!EE9D=@d@@#5sz1C`nfW*T;T7Ya7GKeb-hZ4@BtmN#RHx@4iG zh*{Q<5m5G6M2KRmS9sKcBaGEF)Zd;<$JKvFZ?mBT`N1_j-$h3Lb%0Bd4EaFaZ0fko;5+49U+^Ob8{$cq0|XwO;K?h8H>ZW6z`35 z2%AfMA$GwsvzGe$hR>twFzINr{Qc`o{UyXAq393O;zcZ(S0hDW!to(%9V_)Kyn&Re zaQ4zlxjQgbEm=bD$|9;Y$P zo2h+id*c3^_0PI~<>IX_ym$qMNNKSbt)GhERDrU)z)84dk4#nJQH7$3Tr?edki^0jjb3x;fm^WII)P9E7kzg$4 zw?9CIGW!JM0kQYh?y%j+S;M<*mF}L8f=Pu#-X=)Odl%Z?i|{!q7cG}|p~v_$1;C2e&|~1a zO~$?a8WC76)z8c~wsAdB%}82u6Qz*@)UFPxB*d2W%qR>Vu%?S&r_p%MOXCab_0XFYsIv69f{|w zg^kTa@lNvb_x=u{xSa+r?>*0Qym@zCc%rx=A~oML8vcPqk+4=t(}DD*eMUs%3~~ON ziiDm4vvD;&teC0v>iM*Y@X5ZAA#N7@=rNmyr66(KOxe)H(oVtB?e%&IMT4ZfH+yfb zXD53M;Op@@X!Pvo75R7u{Fi9xSswPxMp~QgL$SM&TaHK0EL&UXcChzHZADw4DFt}cBeO`J;-Uc~EU;fR! zVciS7rP_`GQEtPA;W#bLh1^hZmy1dX&YfViy#UNgG7z^4%F10owy-+|Z+nq3mGuWx z_s)@}n;#fsHv7H%z8m7&y>usSk%L#EX5B5O08MqjSv(z&L| zNwTmBc7w^Bba5x0K1KO$Pnjec14aXcL?PPXwe7R7LC)-glAm>jg`9`p7Qe%gK^-oj z&3elqiz*W2dcSLc$Y45F(X|qk73NZTZ3e-T83xtQ&7*zwqJr!!u}zG&c=iK)!PfEW zpli|dMg1@Hq`6g$?#VG~C^A~fXIxbfa(Hc4=`e4f7fN|A6YAzF8;k)?f`zy{1S00o z&Ezm>4mgTEhFH~gvu#!Rm1MoBmv9H=V9#TE;hbL!#borO(*#D!DX9xJl4GE6It5c# zKguX~x{Jrl??I-<>o*<3bq?}W?t$;Dq4-sSUK;O<&h3CpckTZ%{NE&gTai9VxSM1wmg zi7$C6s;LVjiCHw-Lc}()W3>Ua6Yvj;cz9 zyFdx{o|*cA=8D2bCHHoIcF${ctDLKRJCQw<=*d#VA#{j!jWfKYhGE5>-P1WrrTfVbnI)fxm?iY_vboAjNm5BsdKs$= z#^fwix$gyJ;Xfb*NB0q@L(>s>6lb@jVZMy+yjxngTwHEtOfWqlem?x#1&Ke)54Bd) zy_Hew;^?TFzd}}-r_5`L`6`6HBRYih(0tI0n!3BGGct1Np$5XvZ_APCWvqi!rLG~H zb*$Zo7h5sckjfe*uOEq(NmuHay-k$FwCkK)95%ZhrhIoR zx`o_l19ZVA&81kDj=NPKYYOd+!LP-HsDfH3;hvUP%Z;UN$QffiIw~+P6`aM;5pC6Q zFmBAGlrU<_U|;#d-V=vgvQS4hWMxfbcCSE66Fh)IOk|*6A~;x7ZCs#%MW}Z5alK9w zs%x>$aItOYrcuj^JOin)aEyTMP2q=$DOU*MtHy42c2K4x$Io=>ZjJ!8H*ufd}a4(jxRxGgIc*Q>=nZAtTq{9;!c zh5eofyjhvTluSw!e$iRLvA3LDXoD5{D6CxXsfdcG$2rc>bKBen6E1XD@t>5+O`vCa zq%!KHOwTDX>J=R1=sR|M7erw6jB?H+Q!A#_J_h3a>& zoIQ8$W{O1tZ_XOEab^O7=bR!lflTk0+Lk0?>%@7jmXu!erCaaxZ{ugmV`h}~@nzsT9TU&Zhi<$M&^yBv)RRUe)t*ba21`y=4p6$3)6`u!9*J^D=} zX=Vos!aD^8wM~stxSFCwoTNAAW5y)ZHsXyAxT1tpEI;!4Ufsd|`$=Ly^n@yZ#dyf@K7xPsVXSY;m2-K1-o)m(li`KLnci z6rX|hFz3OF(xJ6rkyEYA$QED+@7Q8TGG@BjI5lGX!Mrx8PzzO}X_>I3;UOBwT%i;P z%eTERhIw7)ZuSn5R*{By+Ky~32z^l-UoO#k)Slg+_n-_`Afi1{@IDv@GXE%5Q?~1= zR5-51Yzd+`*sIjD*P1jp)>IS_ykvW67tVUS*IlV?p~aXX#kN&1hlDb)E!~4U)2g&g z4eyY#+Q@N)(|x|WM%(S8BT@M{HM%dYt(Cz!6S+CEX_|I_`oRdikigi7nwelXUNhLbcgUho96!P`LSd_Ov811_nhs^y$ay= ziKY5%(RS9f6vM^TPb@utzJ5bxw|Vc`GT$Rw@EZ;E$l}OH-h262r1@QcglvPnM~P(yd=8Y>?)w>??{2B)rg! z>dl;%dh>d;HMOPKC%M+);H2GlJP|y#5_2?bE=AfbOujFl9`P&tH-uSy(idIyMl$5g z6$Uj|u9rzR>A0G_>v!E8B8`N9m>LofXceLX87i&~-6UQsAs0;4Nz5}#q*lB7aF%zS zkBPn8R)H&?$ne9QdoY#mo3<8#xw!Jlyp4tnt@}7rE+odX1bj9)XNW%(_U04vqWg0p zQFf>#&lqkN7k~PgE%m(NynMWTo#1erChKI~?xeuD@{1P&TBeUXx}{%RYLq5BBP`;A z7Bf9E9Rtk5;zT#36B)ouw_K~8GJTsaspT3BG1!Of)}%Yo)S(8+#k*fHDP4{i#Wj9( zH?07cPR4$ZZFO}R-+{3s$d}4cO|P%`lcg6zY%|enI|z>CywE3)u`;x2dMM+Tr1;7v zpVGiF0^ysE#rY=Yf-MV0LAEz4c8Je5SBeS+>;*getuSUi8dZ0Sk_2J~R%4aPnkQEA zBIV}f9;>6gb40}ork+-go>qHI>uC;dR&72tAv28HGCgF(2qC-912?^kL`Kz}DdW~^ zg4CKJni*AX=Mw8M9-Oz$Up9>0kDsmaI;hhQY4PoxcIeF=9t&JXBNAXG)wQve-o5n! zagEseUhCR4t{5GQ$ya3;O{I};{DzwwqKuZ0O?p?ww;pW0)K4UwFC1}r3LH_|hXj}2l%A&o5aP`Ijb*URG8%hv!j+Pg z+ZWIiu5DCk1nT)bi`(8^iP7?Kc|gGp^S~C(nsB(QM2~XwY1_p;YbiU_pxlOgt1x7) zAYW*DH75o6vk#u}wyKKa7}1y=ua-Yc8Af1a8N1dG>S;`c9=d|k>}bn8o?nV6a=3Qo z`um#NG}_r4sl2I8P3xu6%Tw0YgPQU8$5R-!8RhW4T7e`j6Xx z95m4I#+;G1>TbT>x_Vcy%74HoQtSegqc1tkCXHs4uCgfiOE)`_h)V_+D7c2?|$rq;TadRjWV><|zH1ZD?=j(!hhX>I~g7C3-+KGgvJep|_}k;qt^ zUB}oEU`U*j3VJLRH~(RcRCFVm5ZnTd&+DLV`V{_om3Zp!~k?Ew4Q+|tlQ%hKU^OaIrU0(``8OC`!7 zc0v<5W|9E(9Ubd?Fen@Z7&jOoHo&=nhcGY<0i!_x-{pdHL4dYD90>;@A)F9Ss2ayj zvm+7^K#BtX0ncs&v>+vbwsh>IPJRX$)NO#y@f)K^($Mq)hX4)NF-rkpMp@eESj%cz z9&@3f-_7or1#zOVzmXBjjR0{Xz`#XEFitKI7~neq%n2Bn69n9S1mWcV-$evIG(e>I zqli%CDG`r;{wvq?$TOIk>KW?)z4aZFM}ACQP)-mxpe`=t=_Li&9w0cNFC_AR*VhT* z<&XM;!B6Syh`{nI^<|~214KA$2XUXfjA!Mp! zb{`-sb0`^_3Yc0M{{H-T4zz%!q1G{L+tAX=TF^ktk_Lb~l3L#%|CYiiSla0R{=%o| z%m{j4%KIAOS1@-1!UaHxP^q3kzDJV3 zlaUJsLI5%XCJzTd3YZ&)1P%|t0Q3$9WaNVX@3}6JJ^x>5d@9$4e=i38os8U^AovL! zJ(7_dfjoj&Z~(q@|0EnexrF$SdW4+9RPbLNXMmE-xAM?Qk@3G|Qi$)^;BWMW;6xn5 zci=R~DgS}s0<;L|3&HghYkGXg^B?tf3cVjg)L&_)|2X|b{CHS^0_8ctLLq<984Uc> zKKJCz%O7=i%HR4kfd6l<=AQ%AKkiK&UsQi0(ci5g;9I$X ztOL;JDYpURhJm0!+QIn~Wsj3%V1HV{Q-?W^kGK7sTKm5?@DEB?$A{d0NMpcxxnqqT z`B|X5#LWo@4!{A2<&G8h6ID{!@o~OC>I;VWzT-K6JQM(>EF`d|zyZHgYl`6J2Eh=V zQ1DM!<;ju6KgxKjHh+Ag@Q0L$;Nk{x9#u?_N^CF?1OWtfAYtML+%b@W{KT$<9wkA4 zs?DEr8^>o9e@H?&0s?{`De({S6b`sHZon|Oej=V8=e2(l5ppV^9-piHAsL}?!2OM-y_7Y>7W4~?^|*3_e=>4v}6BErUc}&zg5Bh#^u2w zfFS@u3y9HhV8d|&{VXsS4IIi1;sSye*H2{VCntUXXdaML89L_=qX^&-F%UxkPcsGr z2LTx!1o;!YkL#}tg!7b}`Ee8hNCO6vCqVP3+{{sv5COQEpFt7FC6zx}2=ug!Ka3)P zbmSQKa{&no1PS8i;sWXsK#2oDV@D|BCvg99)&5U1!cMRCzl|dPZ+QD1SDzI3e~)%2 z_2QG?|I0qjagX)H!~7caJxZSbF?9im1wU%RaG-E`YT>N*uC0L1>Ay8gx~Bj5m40$5UDNWdv)fVgPrd|lTE_2jjD4)^~-w-O*N z{I=14jfMcb{9zgm*LTluy$R03jC@0WA{z){!`B#YN6r4bQ4+#IxqW+5^6sUOop#A`O2tY%? zMf}mTfdLc=xD76#&GNt2NWP87`NJARP9f~$EdJj#)qhieKOPwnoIqFy!vJJ=DqTka zlrCVR421J1g8gx!_fKy3RIEq-cw_+b$!|F9bYy@445OdJVaM&)KS>BVRYydA4-9`} z#Ychvh@yl9x?Yf@JP8Q|zM}%h5kralC%Q}Ae^DJi?Pq=%PCyYrAO+}CM+BVjltL&c zH_)o!g#HWx=h%<@NsF*kO^M@yNIwL)0nl))#iQQgcNt-DfFlQ}k@F`I_sOuOKV~V= zQ$+z_-G0#DK)HbB1-ejxcSS&fnk*D3{?kB_KtT`SWdhWL|JmIf_X+>3##8Qw`-ejc z3|Q);ZtM{%JEcZ0Af)^xDm$5F^(Qr+3Ml}k>j%{c_!|({H@E$r4+et)b-tf<+keq9 zhMw{}#}@T(y6wLxC;!9Z3ip498W5l)%E<}v2H*hc5rEckI2iCuFd*;&eMJNk_%1-B z13VD?XDkHrS3EkdQzim*9{zT1fg&j2))Bzk0>=SPs*gbb6R7naMQ4EO3K;RvR38Bs z0Lbts8$q0M*vGTl{u}0s^rnQ#{b!lA;*>E zKMBcs3T_+^YWpD}0q_U{3O-<<0uBRk5P}=Q4d*%`z5+AcxPC^+zbc1wofh&30?W76 z21*1+=ohg4BX7eA2YfZK2Y@8|r{V8k71I!>@bB^Hy&uvf6dHnK=Ic>K9r2B0lkzgPa|3AEa2O!n`_rIA)8QGgiWV^;iw#UrGiK2Loge*bSzy4`O+_c-tKKJRm0=e*9F57atnxBw1$ zUHxfMszXq}ax}ha>zXB@f(z2iu7MW|eR|ci&IL?_A&*K}vNn zKfTw3_mhx(aM29s-Wbw<_JR9Casia``(XmY1yIo91@%M_u^wE;y}HX!GV=c5UG@)? z!|^VbH*IXKo%bkL5LPK^DXD++E&JHjKPGYCZ4IcwN|5O6HTmux`mlr-);U1K z3z}15O}+=AzjE$XGJaY}9{3<{Z>;#AoTr>1pZy*`!5{j-24Rutf#RpV4#A&<8Do_iDvIDTx=} z-r(rghodBOE?cl2^&$FP`W*bM7G_os&a7rU|1`hgH%w|c741V2aE5d^Py~V_fEPY` z+$+fcv$ew?0RYqi2semF;T;FS>kf)=b0WfKA@J7z8E9JILu^mYNK@RN#oez3NGKLPf)#D4w^w<8WGe?}l9AN)c7A4%5#jD-9z zxyo<&)cXp8!?WNtbSQWhq9#;ccn$qWLiImu=zlSEINmg(g9qLh?4QqEfO-S^h+!Da zVI0rjZsPc{3c?Q`{_l0y|Cv_>RH5(HSGe5>aK8grUqNNy*WCz#-;Ho2>))wzADM*p z<8Z?QoWnvU5hTX^@G0jWz3!iN3Af;&_4+SJp9|zG08)hl{FDo{QNkeogEUNn!1z~P z^1(a*y?&5?mJ)8`?h6UOaSugE1Pjgw9}vOuvk@&goRFa4^c^aK7ZMP64vc5*^|1eR zM)1NP_IotEKhY#yDGW}?Ln(zJ>RjN12ejaL+lVv?7dG*Mt~O9E1}O~uamxpG5vUg* zsFxBn_5W&=kRR6j*DS#fO!cz6;&{c%>Wb;#L%j?guGz7Rm^fHnJ!fQWf5i+o^~>@! z?2Epc(K$|Tem>~0}0XIAZPYLo)|?I0Tdp5lFs|z8~n}To67458nqu5ZMLX*5Cz9ac41$2*`Ckq;r;7{g({_}qN-}(XI$e0INT@F5e1a`R>f_{rI5Atws2q%K50FD89pob&eQE=47 z13etE2P_=oj86juPaYY3v5y}Ip>wsNq2U}J1+!7Al!0|tJw*;oQh zkAssH`Y*uVUdP*E3gBpDuYb+L+R(vH-`LI$c7HHv-}z&lagS5*qd5P;>F|Ll@K>LM zfHwCZo(*shL=Fv({dRz@^ACa_N+y7K=fJVh{*wFuuK~hw%>EMKKdcJk-33Pu`|H^U z`{52|+vsZtr>g#m0EZoQ{I44L z6WZ3dG72AHxdSi^aI^rmogcJkgC-n48a}{shl1o4dXVh(+Xd4M6-)1NT7zNwOz7c_5v*5DRQ97HB92M#KiJhZl6u^Ma;tFjwY4 zts`8Z<@gs{g2Gqte#6Gvwi^yh$%V+?IpLX=U>@VY z8a%uzL8In(RdNF3=L47Dz-UiApn>S1szgMQ0B#hn84-?>^;i7zA7Ud;fXyJtB;mMJ z2Y5IX%t!w<)JDL8`Y(cm4rvYq4?h&d>K_E(_k;&h3ZfL@H{_xHoxuY}`G4OTaK|bS zsOcPZYj7f>dxBysyv^-8;;o<=dJFqhjGGPf&9)EQ*obVhw zuoZu^fnmM{uwM89_W;bN0=^JGaNwCZ05}f1!`b+FVZ$~- z3J%i%1ago#717)vC|rNRw_y9g3P2qHalvtI4(9a`xc%Rm0WlsJmkS1iA3O=+ zLNp(MlLOv+ARyEHhqE4t{43JI^&6%PoCh?ycIIJ3cY9ompM-?MAuU|L;neJF67E!olkqSP^}WpZCmH$SumP^U z^Yp+GC^#$;gy3*Y7({CXw=MT_V_5VB1vBJe(_p}TmY^;Ma$^`{jQ;==(ZQG=1ly7m zK1hV)%p4$M09eznI4P(}{2enL;Mrgn5+b+vTPn*wM#cyF$zY>80G$D3p!@(CgTZAW zNCCASfO!9Rj0{XpM4(?Tc!%;EGRyup-~pl`fJI^VK^-(~MAQrih2IBoT$cZXh5C1w z3Y*aL7nr$^xq{#W;0Ivn0BrogAz-e1cTW7|3OM1Xc5}gTP!J4f_{Zz_e!iakzuv;P zmtUxWYyS3b;R7R$;BMgqCDKFLNL;)KH`4FG=D)L9*lham@E9z9;NS(L$-tQULxIN- z#>_w1=su)z02@W@tM_VE2R;YDLI^^lK&@DIh1|=4@%kJ<_AzX=nv%hl|b+f zgFmpw|LNg}Qo;F$haV2Ff)Ct8{;M4#pjG?_TS1)l9S&;(VJij~f(yX@gWO=Y7C$cn zrR;|T2eHF{c=(~Nf`mEFgixz-kC=mIkOT9VlIbEyK@IBK%zkV6gmQ z9El(bLEtXnm=(WSC%EP!*rxrAt`|0 zVn~<3R~jTq@bwas1bAN-=^~OU_^O1Y$OQlK`#u%n$A7Dzefw~3&`0v^!!OzzI|4aj z$%YF1-ybfHq=qC7K8^-_paS?HmKZi9ka@w<56V4c6klLta5A*q9}G)ViRih;kwgp>thUIIS=(AN*b?1xo| zgn?HN7?b^@FyGYkO_=W!eE${(wlEjLZ`g;!zDfWAe)?!QuF5x);$lZA!jBdLZn60; z#dq`jK1lGJ`F$T~_04#`_uGCK@Hdtu0ka%nK`>!ef7B5i@8vH6zyG+1Oqdho>F{gz zU8KJ?BModscJG5=mZJuiigiy%7x!#R6Y0Wt5oo|GCGh{Kf%kvb+KD_g(1!utq$f-}Rdc{#v7NM*V$_zHR^S8~ht~_T8etd6K_{ zlR%OI+er~@I@m6U*)YtuRl&P3YyOul21mI0TS4E}AJK||s=|*e_D#Uwh;bgQ49u>- zI~^eCw{_Ko-(GO+oIeo+6j$LL(B6*$=YSCFUg-0(2hG&06L4{UCLXQ5-N&bCki05#tH!_QuV7ZI$!sx)kVIg zpy8vYce8L*b2wK<1%RXD<{VHQt&|#O9#c!KE^pofL!>z5T<;U-kxOdMP$F#`Sg`4j zco*RziI7!TBtgVbKX~)Jc_Lqcbd`)#rn9yzAG<^nC*-=uU6uk#4DM zB-cReRmZV;wYO^@#?{`;>PA9V4V@}Lj(CoQncQ%^qa^PwPH?aRis(x`1&X-*Q0&6^ zR@^I}KUDZ0%{Y=nNiwQ1EUKG^f?M4+P!knI^x#pT!OjO==(FSAYZKAAN8e08Ui;wf zeU##L2-qHz#ps6WfTt$zletU=36r+RfL`^8|Nl~0dNC$`A2Cm-#SPLn@E-fg<4fIsQgNHJlDi-@Gnrsxz+DP-1;F z9?3gFMD9Ul(IO-sM*gqvn))kwlhZ*(oIQ>T(_)9U9m|l4x=|Z?ce)0fii!^6<68s$ z@Zk>4T|+ef(+&6{cyTA`I>ei!19<58uPx?sV#`K^`r##V_@Kx}83d9dX$>UbHS#}N zLi>;orSU>4#i_TnVHkK1Fl&%MAlvB0R=+jIDxlqXd<$g?2}e7c{SH17Y1}Dn18)AO z_(Mm%9>~4%pqa1@#O@%yTud5gw?t##${f*tqlxU}_UfSX#+W-9`)YY(?9PN$Oh@tH z&U$2aGFe9>aco~*9d*X7vRLDhF>}75ZpE?`rKn-0_iNTqsY~*12)(yTl{0P0et+9H zvshh#o{kKnpeN?Rms6@-L%EN{*kqB7B|zcQQxA z=Ptv|5W++>)w^#$6R~a=#Hk(=p)_LXsK!bgS8nZ=5)CxWF-5y~Spkja^gTl_{$)IF zKZTe1NF#AR%X5D8arbQ=>4y8{m(X{xHP=FqO|it~+Ynu9fc?<{`+Hm5eHD}fq*K*c zHYgPyG&EQ;C_ed;=fj(1wD{$}(6h!B+Vs~x+#%G6t!_cOPQ)AB!?W_$Bz3xkWXZx61-^!Zp^;Wy;<$K-hE?Ps`pM-bYAAF>qow!bPL9@+Q zC$Gw_ByY~GwWGLi?RCLe-I#lRm4t1%{!q|vRe8LlZ^#N{tZ@mSY1U%P&9(IFr*-q< zO#w9@7U$w2r8mC%yA|cH`u5|&TW*u&w8OSDE)Qawz%^4^D<)0+;_2qo9!9%Ciy$OLsjST z*$3RhCR|)K=3O`K#9gYcRO;)0T{@A$Fmrn_YwcBVR6@^f9XGauPt-5m!zoAEqBECX zt!ouik?F^NoNdg(QGaH1G596Q_2im>NB2F?iDERp?WQ(Bvger_MLsQB#kGNSBc$*? z_G5BvPera&OAg7$@1MQlBN2~(SM#c8zq@e~)tgJX!1`V1DT`$#a zdeBBaajNbU{?KdC#1mI|qY+2rNsO<{+Hls3?6vy!%lg!=o?D%QUFcMasF{uR^N(m_ z&^j*jQW>CRN=uP5;m)wyQAxaxd`oP4`r1*mxc;t-9k@OGjY;Wow8=MWC9XmxWUf*> zJ9tQG_0`6rvh+M78m2S|yIi<9f)oHbQEKmDn#+G0uiQ_b+>r0aj$~&<$-Bq%3WWom zCcg3BmUF>(du<786xTTICtyGHa0b`8Ib z{ZoMs+%`y8*NPgX2e%i}3!c~Co9%yu+$;Dzx!0q+!H;D54Rgzy@fr#Y_*1YIo?qZuvc z^hGmr)*uN&!I*o@s}O=4yKg?oaN|40Ku+Jtkh`za?&^Ox#h<5Lp73>8x}p4~OZCA= zp8B6_S0uzBOBmqCz>Lf(O~(psi$Y@cz2oKC9|fj-qI=dAr*EhE#7#3%k&+U zRfb)qmCl*yM5ixgB(CQ6ozC(e;s;8!TjTfw}qA5SJB z@xZEXNx!}_al7x`6X&mOR}%vR6jzs`>!qM1Z`msuT3_WQ#7dtXBK$<`t`p-H-pLXr zpO2H5Fkx%9s<$eCsx|&m#18DeDMjg){0AnTL4^;lF}1U`3P-j&-cVl6*I{d9YjTgA zO-Zp+YM8Iaft(m~yuIz%gV$MESTM=r+gf&i+0HB~&&s%Vw1>@jsHM6(CB9W)Tqyp- zb>nmX;#XsQh=bXx`Yj{)Q~NJq`#y>MfVr}Coa0&PdQA$0d6q!!CHV!S<_o?R%@j3k z=Gm6M73V56Rdu(5hhmutzvL}Y7N=i!s?5Cgk)mp)Osl{0ewoUpDObJTA&MxctFhu! zuO2U?j`1gGeU=&un$@Vf5f>6r7W-&ypw8ELNRY1q!q>0`UNA6DM7k#v+DSzR>OTpNxsOD?ZSE1w-N zOVkFRqRal8hqyoG+Y8Q5qmLJ|?TiN+`tKMI-C|&FCwK2aD>bgLh)^W55X{Yu^VNCk zTF4!of5lJei_UxS-vV(jT>rF3JQE}!qrp>P`S zaJji=_$2Uo6#JAm+YXgT5zkVtwrZIWJ!F9_WpJX{|FdZcM3c6E^+$KF4e7D zt#}Uy%&C{}#Fh`vSc#-vlbeWhyQx$sPes6XQ^fsUrd4W=23aTXU@W^Kj=ST>^_uki zPp5Qm@z1nu7~jvxnr519o~vdTvvk97>FNKR9G{TI=-{$OvBO~z-uQVVSLEyX8uVSO z`$MGK(XVfBY%9JwU7jnF%vclCd*5J(saiy}F@(J+_VanOuCa|(ZK>^ZTaiL5uK8bG z`5s-kZRPaJxoBueu{>ZWr2WfUz`Tju7LFcD&in!vGRI;k&+QuMZ4ES_R{UGk(*4LX;eMo>*#xwX#ky39WwbN$BfjjU|{fZ_6LQcD|JwSw_8 zQU!DTxC7JtHw*k(*JauKS2F5 zOf_-%G2v;Cz~BxF|6}XEic*Y*EQ_8b2I8Tr)#5&BoOJl*iFT50l#dONqv>DzkD!?_ z8Jy-|Ji_e>HOobt4BVyjhBA7Pwn>eda1fs%AZ;W3bn1Ng>n_bMJcX8KW!yzkemb=y zHF%if6aFWXgSrL%{r!+B)dZg9G1Ep$%Hk@a*_}r*M6(NyrWARQ5sYHj%^=MY_1J); z*cq*j=Q^3!RU8I;vQ_3()1E{dG(n6DsN(em+O zplp7OgnH5opG=YqHspQbzPow;**(T;X#Ihj4E@#qEl(rQh!HBQ7oks|?YCLdn2;~4 z?m2xVY2fk2XciqvF3M!&8p`CeJXN7A0W1^zoE}=v(Fp9j4XVedeIOk48ZtquCk4#c zW8yh9^ef4RaYWdu8%3Pz49^X_x#YXAmyi-=ylRUBmE75av;>o67cu_2E z-MCUxxkNntwlk};5=}ual5H&l3Z@aZR-9p7P zzBS^qG3&zPvHdY*qT$X+-TLd^{I%U1iCRREXMB8RX5H8CAkSyr4ScCYtG}DuxRuvf zXMS?nX^Cs>m5+4NCa-X}U3IrUn(yn6hP`O&TsLt3I3n?AN3ZQgp?8!^qNWVvyfl+HEY6d2^Of0r_;x3> zQ^v1F^iT`hWj`>A2zSFssPiOypj7cW<%yU0%s5udZq9vGJI`S!t3L3&Ay-V>O*kCJAoc51p@k}Rg1`n8gR46`VEIkm6f;fe{W*S?Of z9;o#Fmo-*}6ydck_J*y-n{RJreF?U@SXoZ4%KbJmpniSj^j1K4#oB!NxYyA&Je^~* zY&KW3OZrloiA%V~w5L{?+SSV^9M@h=x);7Rn{>@myGzZtrWA6wb>*|w3h9drkKV|~ zDGaD)W>Naxmkn14r+@A{{4^*iw)~wD_|-eH+Atq9xK>g>cl!QN*J=ra(!210Lfr+U zcg-c2q6XU-O@#e)tumTw8`^aj4Bk1ShIak+Eh}3o4=dlKGM%&9nKnx1UdL5HLG- zMRe77>X*DdQ5JV={Y~P8#vn!KP3ksg0+%ahuI^g~Y`zSYxikXhZWpJP4a!uYJKm#n zug2IX1dd&t7fMSHNa*x7pAt)<5{674n-YW0E*oU?uH0EpjC*x+u^0&z$t3O`GD1hY zkD31EXu(z7f9hzz!xz7EwC{NL9BtISI3@g}C@*JNrLMoMLWh<#^K#~`5RnsGesz0q zYL*>9XrFz;>&)jRv&r_0IORR&EwWnjEwXlsYB$cN_XY|wv}iQP$xu4U#$DAt*=ZxM zg0=8Sad%|}YAmqD zkK}Vl+7O21;v$b9y;H3tarB5?tdnOc>Cxx;1*vvlyRc>LoTN6(AppqL!jL~A3;I}^?7$P`V<9{8Z?oJqCL@zS%= z*U?f9tUg>kqrln{pum5NrSByJ%B#C#^rocVWX3F*$cD{lIHe7mBB4f{_TFtN=LMT8 zTDyqPm=GkKvf<$%?@>d|mohkEBJD?jGpB4RQ>S(nvyBJEj-yxxwq`5)!My)0L&ywGBL(f&T&$*`l?6BjI%^t4i5j@L&sJxlMf9B*Sa!pvH(XdU(O$gS@dE7h-x8x|+7^}NMb z=}z5<{RHP#>`YYMQb_rZ{c)89b?eRE4D~l(X6UYWV$a_vmcL7u3P!GaqfX3j~LS+~0q4FM-Z|64`n4wAz8cs*~OJ z<7?k4o2`kjW3PROimju2cYEG1e7!03{JqdHCG}K&@v_+h=E#>Tkc27d^V!g%DZ8y# zC#eR6M(i4+)GAKY%=vUyc})pO%-$(l+HlF9x8H%r4_6>Z+{nIbUJy!Von@)9EYn1U z|F}IK^_dc;vfv8SlwCrPl>U9}ibsn^8SAtp5y4Lhg=VoQV8tSyl@a zO{U~*$1p8Bag5eI?L|VbxnE@4jFFZ~+46j#w!MhD;9gzjbuA|8n0vMMD(X_wfEV@R z>b9r_eZdEeigO}eH*yQNJkKqAyLP`8*cL6PPRkngr8ZqdO(7I2BrW@Zk!L1CqK~S( zi262>I*>OPT_kjV!xKkjaRI}9)w}!FR8`Rk#_&#cE3>=3hl2=*e$D;%E_9LH3tKgs z6X4I|n>Fk4bI05b2A91Bwi6viOs|QMP(QQNf4xMTHiYvG_G!Hf7!j8jUvk^m;JChW z=Wu6yjV`hXzVXa;?M2l0anu^_n<{T-a2^_MJfvQi(l6#+EFA-%w=Op8-sOs}bn`CT zy4cqH&6*b|*huu-51=vB-qgjohk}4!)Ab@G`OR$g>(l>^oh_q2Y-sqTRkw zT;c*0Rq+f@zizG2@iFKxD~goXL?a z`4;sO2XT~CjgAhHnuw4-`sByYS4D#PxxH889($h^Xc}aBJSOe2{m_QWgdlncDX3eF z*~BZD+B1m)jjY@}bNrIQWyxztOr-oCdcL*ex>rA$fqU{Aj<7eBc&}|xQ61m0*mVi)`CEgh7u?HlugzRp+u%O3a((l*eA*Wu z3tCz-R@&S5wZzSYGd3>7oGh1;(rletXbg@De$6fXmRZ=*)!bRD=BbdxhMe|oANIm{ zE0Me0W4Olm%du|K7IF=r%Wd>I!%F|aw;ZD_1oL^^?1Pnb#g%8-=`SoO$c3{;3y+!1 zKbjzP4JXygE@U9xpt2{7CQ>2q!r8QIDhlm#cBdJ_N#5|(TlduIE3`)jFW)d%ZFxdO zaKWcSB#5^?d{@1{4m1H5aHW}_Z2#d84KqBRr*X=}eqK*09@8)Uv1kVsVimDsOms5_LV7$G&q?`M0 zj^-7X-nDTr@;B919J}dJ#IDsX)lP%=nUCoi+hpgZ%Yo*W6Y z*GX@%^v1At&)lg+jq-Br`zS8m*K((mdg-9<_SPyo~#8@LBSa0(ZQoQ!yi@RF6eoSHWgczZ_UHT{)1>R(tE|X~U+Y zoEX?7H|WAi`XtcEFSUv{&`400L?at17!uKAU->&SG6~M&?U1OpIU|PDy(n<>A?&_gG%`zTb{Y zKNejQQynvL7wuVnESCGJDb==OlqJ=+-9lH#lC8MvxV){~a#>oA(9_A@p}afs>^V1! zdRug}F%EfK3xt)TCyM-}hE8w{Q8vj3YHu{Cr#VZFaoQDJ&Wp8PnGXwE!Z}3;NN% zU-gt%>gCr_sWqbaWy|E}Fo!G4=k*+3SUDv`&Msiprc51JLtM>5`*v-=# z7O@cC#&z=uew3>>_1W;&?s`_s@f1gr=Upe_`W9q|%j16t4QrCB13qKKMaVQ>QUBek{ zA6;7hc&7GMNKVo0{6a%Q683zEYuW=V9M1L0sL12zRd=tp4knq_ecTmv%5=Qhu07A9oy!d+u#+Y;5hAKfRP6aM$32k5u9O{bnOx+0&L$ zO{eRV-^!b?Kddxb4R#Z;xt)YzeY9Ak#KnR13)5P_1of<%x1Ns03$J(AR4N<|)30G( zpg#2l6Psy7OHsB%e3fTNI3j~^=6FfT+w13Cvm(k8Kr$#l)JI0R<)i8Je0Z2t$tro3 zsY`gUl`BjmOcDr ze{a0`%zdecEG-Z`<6En5W|~r?mOVaozES2jWluvLrfa`~FA`T}#L4)uT3vX?!0-HP zIpH$3fsy&HPu=)@Z1$guZm&Igb$8%|?tA4e-T_?;rxL;JwUF7qkk^ANbvsH$U*?BK ztmo@SJAKPTV*8@lU6QcR6$iRlZALv3M3pw1GmS}l@{W%t&{n+4mmNUY`EdJwYEJudx)*{oW7jTPdz zhB|B&ix2*N+<4%}iWw4VwS`aRZ@W1IDJP&kVZICX{gvbCx9SBR6Tk8(eu}zG@9vD9 zd+rFo(g!I;+lDK{_FtYb=O>(^++zIX_avnwEZAXMudhtq?W3OZ`7ijwAL@rIRT!7* zu8Pia(io$#+lO<@=BHjI+0~2Umlyc_rkg`Tx}Lf$%6SVq8&XCbGOaf2QJjz}tT5`^ zC|cMk8i85y@_t<3r>{)QAs~CD^p#XW=;dKe7eB&;04MxYFVFu6US6Zsih>V!n~>_h z{M{Y8SP$B2TgB&iq~TUxIC+&f2rLWk&e3$ef9euN_Q@r@6#awPsDXy=4zq1@diy2C z!opsbn;m}1hRKpCSH@pTamt13aG2xY2#i!kyDIz9=lSWe>RWkatE_|#LKCXk6_V*% z4NW%nB%F;O7%l`ENJnZR<3#joz3G#DJ91A54^s$LYMkSWPZP?C^MN{^SI&1WjxWmi zcX`FA;$e_eF;m#c8u7H%=zM4ZkYF7}o7#wKwGR1XT#oW;EUP9;p{58edKLpKbhelH zQz%c524gzd_6A`t2cvLG^N7~yh^0ZFC*IBW!BBlict=f&#HMY)ASLF_;s9YAQR&r~ zV?7Q=C}jLnB|68K&O~R_q5HQ`83Qi6(ae!a6OQ6((yygSWH1Y9*0UIqVf&6u&5rgb*N*p|CpTsUA&BV=VOr6A+k=^Fjq&Q+n-AL|0 zDah|YWrFG`bRnLZ6la^08)Cz|RFbjfFBxr&*4uMdmbwk>tT+g~Ul4xx;vE1BqdWLs z%v15b+E`c`n_T)h`^s^-uFvY$+EU}!k9}6=SNvw*e-eHtVo~Kuuc6?oVph*~BM%B&xpNY6twD_Y>=HNtA>0uzSxxxT=meUb{j=ylQRx{7!|2NrhuY*64EJ)8HvW zS5`)zC%i=zH@l5L(@w~=iq77%eQkKYshfgC{o*YCFyb}>B{rU*+@2F zmS}yRAgM?LID83HkXEf2OJS1&_cl}M#=wfuqE7k7t)3hD^_@|?pQ3n+30;%! z`wQY!61b-0J;mb*k0MJNOZhNMrs=M{h>Www*B@zCMwRmRvs?_ThpSs-{nhmhjrTBnNZtnrNsTl^BhIiVc%k z2F+A^qBXa}alIbjWw7<*B1rZ3J98xFdbd(n+kNYlik0pjOoyYE8lU|IT zyAN~eRT6J<6)Mc8s&wgKV&TQKeYEv7>A!~uIU921Y(O@zl)BJ1kz|&$*SQC}n9i&h zmAyo{M~~V@^gJ-Ar(x`&XNcy&&KQo!oZ~Tgj4XXmzPnH~P!8`*W|u-sF#Vb2R^6o1 z%Mo5C{h2-&?nF?UDQg&TODq$p9SxOUI4Z3G2@_R7zR4U%DMepIgU9qyi{nb|W~zW( z6UvnaN!`0_Elreo?M4?w_+`;ISaQRgW*JRSJKz%GrY~vGK5G)IsjYSd4{!Kb>HOTK zSm4}lu4ay&H6NpXXO4~rrS-05eiZxDPu88*#k=n^gLwx-67((EM0B%)`)^z2yv}$s zzf!-sIX>x_|8>NuytHDyTTkru>So*Sc>K;SYih;avh8)y*fLM97b&|#E_q|cWo2u1 zvvtE{1*6Da44GdqzAZ<%G}F2*`jaKgJXvf){&TIV-U{_=T74X`%#;mlxs`XRre7rp z4%;?;8&W7T4m?K#R?Q9@R`AN&usoia_ zPuC+YjnF%I8?HeeZNhy|ew1VlvhPW`M_oCivP{<7p(eOB=fxVmT5V~;Wubf}04x8E zX=mS~>-m8}588Wr<&wt4S9L5cCT%-b-;Jwq=xGo2c8~?mKYUU=WpwrawO3JIOLrU8 z>z!Fostlf=?hN81$(hL_dT7LyytDLWIFI-3X!2#&u21CFkYUq`W@k&aO9d3>j#bu! z>ai`|tH;fUU|8~iM*08|C#JF^|{NqWS3mKKBExd z3JPAnX;A4fX6luGj4C!!BR(&Z7jAJ>mh4v7 z5>%{5W96}edelwK*__Cm@5e6B#_H#=^{ev@kh|2}xv|pPS3i`|M;*HyGRy94t~*76 z{XT>d_Ft#7KG9>(ZBE(FN`{ePg2g;~hvw3UNo=yM;X7y6O64cn9!4=-{bW4XTb<0u zGGF1W(&Hrip202Zi+p%(e^TzmaqZ#7#{?@?4au2}xLOZB4qfC;w@|q$_H0ct#>9~p|3x{$`A081{VaAKe>EuZ=;Ru+WRJ-830bx*e%VNPYMHx&EN1i7 z%5A<2TLn&A=*5avUDZ+7TshxQ5nRBW#8B)W5l}n*^mBE(ZLZ?mEctW!qin7@RLRm? zIUOt2R!>xn@kCyGyJI{v##FL9mwPLs7d+c(75gJHrQW%F_u0K&L@{)5Y9APUd$B#< zn@H6)((nD%JIL{M6`%j``?Hu!-9!&=9vjHfq|3XPAn&y^&7cywC=`XZWvQ_1p65{< z8#;=?;E9t>|1w=FR800m9V=#-mj7{c6cNpnUx^KnxS%f@5guv#Ezf@)X<$V8pB-sn zZu#$nby!XR+mV(U6)34ffQg1Y`lX+SH4oI9Ebdzx8qKouk{4{OF+jN^DRCy}pw3AV zUu1;cD;^d;OO8|Jp-m3AQ$&wpmt&4_L&n6~KskAF?xHwzRT`%DDmtUr8#6zxH({#C zZb|99zEN=`y~GThTN5bhcLKc9WmnJ{l1g;$7x0fJv$7R4mFc_`HrM!!vvMido9@IS zM`8&l($mp?A>6hb=K4$+wb{63=W@o)S@%UwqJqOHA7wESJ3;96_= zSTCEr!&!Gtlz>TzSl@s+8XXghqGwm6Sf2M)CY|;e)o3ZAYt-^W?tX5BF6xMO6Wyzd zq1k){@8X4v@$N+fqCq-g8wO7!nq6&<`)ru@v8pe3zueI(p;4AShMHWTzHu>_AQne$ zO*^Xt%4|#>&7i1Vi_g+7B<}hA%uzh#DWB+_Ugn^*V1wKuzhT1ywedSy5$5*ju_4SI z-t8DyH8`m$)CxUv(d|wJsl3Z`pu#HExAP;byi(~)MhM{|KyU9yft-JD{usZ~qEd<> z<}H>SE;QGJr6TvSUzawGwy4kCt$rHGzO$z3r|^pnzoZ+^Jq#fW)1p54WUDaeW!TxJ z^n1?+)XiCOCnaiQV{p3DBV?cO^}43Lq)Lsci&c5X5PiK+ZCvwh1IuTNJ9(0FE=z{% zZY9IJH-)fslp2Rbwgy%2Iz7GJ*w-3$m{{7Sx^ulfGRPR}KKI#|4R8?;I?VDZODYqMt^)!5QQp&>E(`lJnuy+ zkFewH&&^`z1SxUa3C=>6DllL8gAi4=*|Ba@D>bZ zlT%L?vUb-V$GOxs$`C~Jh9j$==W#n3?HWX!O38YbtlK2WwBp3f-k-TxBiVRD*U?(B zB$HlnE{309oP<0MBGnE*I-D)J*kmqC>s*e-StZ#NF1i?rE?zD=O^>^}mC||TmQdLM zy7)EEi+aBHo?V(W1ea-h(8WzWaWy@sD{otYf8R8TX6WkM#o!rw{DnkdW+a+8FB9(W zF%G0bt`S94I2LK=4`BJy*%kk5>~nm&DN`14csC=5-R z3Ai}qZ}^*Lb+2C_SYCswojX@oJ4Yvd!V4oYwLGIE{o}K$5sT&qvTO33aY1(dF@_U4 z+-&(rhn=PA(8it=g<`V#SD$`KFAf=36(sc^h&WDY={bZ?!+)I)iWlc6t6d?h+)!eW zr|zi`?6vTQfQaS81D5F%{E@1)GO=hc3Ag18Ur97;cYj&`l4&_yg0vdyL8L)*4m=uN856I@_vkG;_-m#UY+c`v5fL9Pdpxav_Opl zViG^_J6(ny^$C|$v}@Q0{v+pQ2gnt2Tl|eJqk(Q-2R#Z)fK#Ns|6yo;uC zIr^n&3$wsUjngXWZRQPD}N4l%B-S{ez8d*r*c?HG>xmpd3&nMN6 zoL6NZ5w52vkx`brY>Uq$k^T|o6h?%HG6>AhT&roXKBHKY_%6-#1fjtLx>eC2R#^pQ zL6$x=KWudoT#geh1(J0<9T%^jZ+YR|O-VXfDewxvXmaT0TG^Im&0J?2DZ8x{1xvv5bj6Up1$a zb-PMUd*9ji2}3&!3i-|DLqQ>zEC>vuH`PF@Sh zdEK`;v*K!(6))|;gZp`uLIulE_e5{&$xGsMZn2f5YTIe}FpA`6k5$B` zEv#D#LoS~qw4GXC59RPB5XVmReSGpjg;mn$mT4B&HU2>Sc&D6?SJWHgdh=~4zq&i5 z*AY80P7?+21q7^^xVshVwHs_lwm41|-9MptBCc7x;OhO|5!qQ5p=ueo3p!M)|lJ=i#*a6irr<65cM z+6@ybsBhy$+-azm3)D;eL0>y>f>o#sT?W89Z-lN-= zrx|A<>r{5GtcQN0UZqM7u_4tnU`7sxl489G)#yE?$jV$&v>8~%5 zpHxEojGH%jcO)@}>4I6=&dc;??zcQ1W}LqLWD=DzV|U;tWYb0EeZZzirDcYi2%ZF_ zvp9_^@{aww&m@jZT6@H}ifM;TZtqpZy3IbMZj`Gy?q-P(`CvkrH+W=$(#jvp=^c}y5QydfhMcfBRED*Yb6lCVk;GP|6;B+w zkcC%Hxiw6jp^yUFYcBtpJG|QmpGT-`oi3wXBewHs;<2ot`XD5777mY8ISvk7J(GF zF_m;_rjb43_tF@dWKRt+JtYYZ*9xOfex}@Ld zsY?f*t)EdN)pS)oXT=)-KyF^P1fmtsEoY}?ZPdf7c1x4I$h0jS#q2q{u~@qvrcb}S zZJ=cTb;AcTIHYpeFCDS)v+0u=bze#w7BaGmW>uzyrLP1~5D?Bb(+T^>r|>`ZH_<$8 z)q5K4;Yq42#uR>vc@_qm$n$DGp4!O~XqrkbBwSkH%p=LFOXgRwy=Xm*Es`J|X&5ph zNv3T+gbX!6C$7VYzokv7=$n7P*jkWK{{5Nfd^8J!_gZ_Wh3N!kPJE_|Fkefe>_O(Q zHa7n#e8w1~UQ9PNe2d0j^h9JUeNZo7gWhQrCFICfpTe!`mJ{LL6I{&(UxJ_lNEofg z;Y@SnOoC@%|I&My4@F>+z@Sv&VmVG)r2@YT)|l->dmD0|eD87a?lWD>Q-TrkEjbsv z)2CJKnXANCRxzw^FRuF5uUg{}S322PDMc-upn`4&&c!)}P{@Q(OiMrWuW0l1^X^D8 zR-CmTbIy^NUAaBh%Sb?d_sK}q(ASVw%O~TCW@~|tLUFq816FsR46S}?ozT5k*SwH( zcXM;A)psait!~88$>COR<%TOCg_ZlzJYU_2)$Pi+37|;I_db51i0}3LHEqM|#Uj+V zLrn+YOX>4(%};(@wOU@ucsD*Z*~xqRJ>TrpwWzIIN`BhBLQxl7BHI^7>~fP|hY}SQ zeALmZ7%s>S!tY3t%DB*~H|(1G#=$G$BU(kAevEx>3UyjV?L+%o>LAgAwi>hPojzn! zozdQG)JYRXMjJN)&LWFRdz9B1CsT?FzP~6?j(LTtldm`~%eZ|3@AIYjd+bwu7X(JE zdqP{z#(_8GQSn*roO>`G<7LM1pEfWiwa=jCC^E|3T1qC%FZ#YEtNTSjQLCi}WYeay?Z*)zQ(G)0_mKl{YI%s=suSQG~-zV`G<*U~@tv z^ZEGb+(@elzwq{q5&zdOw@l4MKBY|wwiF9$nYqj;`mXUg74K%9l$-T=G9rB=_dQl8 z3nB4X(>dxAc2;H+r3IJMlXj1CAceOl`6BeL`vVF7im<^L z?LYLc{2YIl-;+xN$lA_=eQ4uDBQ`EtZoEYI5eHmB&~Z_J`O@oWpyNVocPl(jH;XW+ zaIwDd1X0?APD1FmCz@{7G7FiZ^&k!j>aR? zm3c%kGi|OZR+$3NAFtx-qB&Y)xMJY6t%|cuwxljaHDN*h=MnGI$CA+>UcyJqT~Sdq z2w=Ej*lVDy8S3)HT?0><)HsOv{;|-4+B0IbjOAx-ue`OPu!^RkJo`3}>DNXy|GnPDk`B$}lubB~MEGUvyoFUy{(_{xxY(ux$2q^3!Zt)g`=m%r9#I) zB%XXg89~x^7HXbC59Klw3a4Pu5^7f7QmFSVZfDj;s%XFG?QPHo^*3&VLhlhN#T@UB z<`(F>>nCNX$vA=P!K&xz!AnX?5PIRX{0Z@VdJOHx{P7Q&vw7o9271k5q_cOu4a>RZ zgAKLMwU#cXoqS;FSrx4wtdpf$Wmqu8_Ea_|bxF=%V~d6Sq*!N))iJc#umX~r=vFaF z$fQ)~qnEdqQ@0AK@IMJVGO9buz0CBL44hr?jw7_jDGylqJTzF0dgMIzDhbrXm(%^F z5AsQztFG@1lbZ?0uAq3IN@btP+_EhEdcEjkAlBvj-fMRSKe1g)AYNXuC@fhQ&@St8 z)7iO{HN5M-`v2Pd5_l@N?{6v%GNdBP<)Av|Gfy&RN-~d$I5;v7$CwZ*gi@wTRE7pL zNQ!7iWGKmyib8`_gcL>IeRSQMv;BYXy`T60e?Oo1{XF`lr)52R?Y;I|-?i5EoM#n% z-}NL*(US5Folt?P9|-vQ!(C<2(CWkU@$Zf!MMtN6FWbE6{P|QZ*}8BvZA#Cz{q~10 zzww&R#!2SSPsf$3Y`&(+oV@n#O zAG$4jrxlAkeC=p$Ws>@dJE^!NAJGeOmrPyFT)Dj-n&E9Wn(6##Q_y4N z!uhEcuYp@(w#rUrqQz!Y= zD5TWxj@23AW}3%NHW`o0pYG&*c4zFuK=feXsxZ|!J;sfSbiBjFilb8t zggHDUIp@!brE`4#2~YlqSW5W^4>o|aQX?slsmg_KQ9L$q@#4=zmU5iC;))B4?!Dei z4Y}K~Omx?qz|_x!BL$)N_hi$n_BpIQrQCU`V7tXP|Bi#3$!%2GYG0zFwFfhO>S5Uy z$BSQJpBCvfN0du*oD>Ra~7iO2^So zJ25X!%lBl;m{XPXvlT%x=gC~hALv}oYqaqrCfhy^_pH5gQOA0#vOiu+uPjRTfq-wa z;y!8Ky>i^zmQs!_TTHCun@=ngka8JXRAByrN0?E#xT^M9Zk+JeW4WB>skDQ9e1)iF zl52sl{=-*c58Q`~N|L4J4I{_&@18Qcr`&xfIcR-%Rh`7XGzYh8GqS^_AKd393pXwA zh~Kf2r)%GuzRDDouf}IvrMTt2R#pPJE*Wnu`}7`_3AGify-2Wmm$>wu^|I=F&0^V4 zKc>+Z7hApE$CL71jx!x!W7m5Mz2?(f@W>r=RQ+>j#embz+ijVFx~oF>(61` zv>#!7+d8nTd35X4$H`r<3@b*)kG#p*uobi8#O;%j1Is3Uh`8R>;h%gSG33Xm-P|d6G_JlpSSk> z2v&9uoEqAwz0j?@dc3n#J2-TrerxdeH%5DMHeWk=d-dtl&%Xulop7jOoIbWI5sJ!S50}##dZYU>S$Y8V7T~o-VYH@vi_^8C&o=3V`WCG(NW{Y8w#S&=^c$)d~NDl zdE2Li$&cTf$BN2qeBM4kKDt@&z@f?NNgJh>Vxx?Fa(T(>KfbM=#3oE#?Ok!x;Zlj{ zRo9{JW@ehD`(y4!`uZ=M7B)(##Emz=oqv6VUuu1#@BnTl8XHtq#@TzaCggTy zNIy<>i$h3NRZU~ENw0$YIU@sJgOt^)ubTa`j;8CkJ9zI(4%tFe91>i#Ek z?yj|?>L!JczdHCZHl@UsQ}7>V#{^8G>U5?$Q-!V!n3n)X_}waCeQvv>AUj;N^WI!&|L; zD1wji%uTwYy`@PhmZ|S~uiKEE{V@CTI&u`>5z8#i4;4Q(ZGJ|Qh)GImi?Zsz1=gvx z_(-{IU^I*EPW*H#?$3o@wum@%;+MrVsFQ7)a5pB?xrEbmYk5KSTxJ63tP z#)Bn)*&Ea2q~G_hDK%(y#+V=}wO=%2o8t=p;Nom07G72bl$8LIenMM!#7NK6PXY0E zm&`s6d`R7uXXY7PUVp9K?%K|Iy}CTSM?cH2PxT8@sQhTt1H!=37p|7sKL+Z5^e$_xQzn4IS%|>EW9@_Z;~Tyv);O@ zTANRi!qu{_RnjIUoVd*bkM8DP*Dm5J={Rh2>XD-U;6~z!O!t%_l3D7*U6+1x=Slv| zA>C@DDfM0zlvuv@lR(D1TuI&cVdk$lRiZ~%2}sE>)kiz>g>c1|%UAR*O}OpMyY15! z=Ajb8ex41c4>X(ObDs(us;uJKb=HRG{Enf-%MNYVw}>S3Q5&pvQ5?jj!kgku2#s+9 zfwef*OzVm6bdM~8g)$9!+S8oqDA(7Wv&$0ghbD^ffdqGh)=`fqh7BRNCX}|VZnyig+ro`f|3rKDF8jhjrKzj-jTKKK_Q_+~ z`4h(Zk4*Lqj3ia&cFGS06QnOjR8-uwe|S5*va-m2@8tH7f}+h!(>H9lHl%l3c-$%0 zU8;ZGE_s#jcHPU&ikt=1VyUvi;FJSdo-bTAjh-97cxt@bQ(DcdcliGOw8!_w;(E_e zOJ2&4w{&{9>GwVU;W4SMYg1-|r)`)V&)M+f%Z9k(qi`-5a_WFKFq0w@2!2 z6L!d4c&DtP@*DE5Y9XV2`-3ZMD;HaTXW_B?~l7NsiYk6&aX7H`?Lj%4ypM_(4wmm9}Wp?;VpMCebsXR7DsN?gHH`)AKQOT?SHvXU0klGK1Qw0~c}P zMKWfh&s{BfFv$Rk2eZGv600-dJ1|s1BbuaWI_=!6In){%qe2|#ja~mOQMA8bEW^fm zMN-I>{9UfzhYh~eEG-7rn-tD0gJlgY0#n^@`Z*roIf(^6~KZxBXrB8}KRo#POwx@0N?@ zJ3ysK9hyqfG$DW3{2A4}8^C5@7;o#GunB)6i}c?Nn-9F#uuex8GWGay6&~-ousqgZ zC1Unf6{V(}+9QcO=nzA6<=X#K)uL72RP^8`>>?@UqY;G8OZ~0nC%IJ@VuY8M3YG0k zb>dNYKQ(N2W!~aL)|?Ba^CIWzZ0k{fOn#>>ESRd^+R$>xL0{o@-f=UYV=ac8B}#KR zHcE76V$H9lNSo_$$;+y1@EvGzTdt$^+>Yx_!6wBO=lqtv+dq0jiR%jIz1RXBb;ZNx z;&C$aK}LDTmLl$v8CwtQyNoV$j8_OVK4MYr7P&58Ftt9pmAlT!piaFdOlJO@;$yNa z#T(7(e9H_3g*47^7p_fjV6HF^u+W-k?ODv>;3g@ zuv)8H{3gCici?N4?&GyCLgJ@g*I9>|x5Zh9wVdG*SaQJ2qTbUYO+T^P(*MrhYc}(u z8JhF7in{r*Sn19bcQsvIXwhSKLVtTtK`uk1MytBN58p9*QZ(iU0GWL2jt*2D|O$&!$|d9`-K35fYMVaQn7(!@yvKb?5SJ32!XI1SJRVdT#k(j=^9L>eA}ybW7JJncQz>Uyw~KapP_cs1OnI80 zo@93qoSS#YgATN7Uuy8q3-m-amJLYts0J)+j@K7LEg{9zC$YeMDHvs8l=ChEL?o7f7#gk$j9HxLKd!`_h@BB$o7OJ zKaSex`)rl3hsf?+tla&&=Rx&~%4K6RaV%1_(t;Dd%ppL0&fsl&zRFIyJmkFJ;v1Yz z)wv0}4>ez%RS6jC>k*(YzOikZYF?6)-i`^MmGoAzm^Q_=u`@l zmjCIfthViiinm(mo2*+ALbk{EfBU?|eNw-j8M}l7GDGksj}&+QprnoahYQxo#l;^ayXTf04BE zz0=_@8Z`=1Ilt9y^X{a!KiV3#Bge0EPMh=g+oi{9gmm69@JDy#QM zS-cfM+wxOobd~aT2Yj|Y%HH^XnM5_`d_H`0WYi*&=SDTrvEi>G{hlu36%IIbSC=qM zp8qxfyA^ntp?Z((f+4El)sP$UT~`Fm@s3()^Uh*ZjpysmZ*`D=xuDKD$NChHv-m#suL8MO z6S-uo)+_$ew@}F;p{}}CFKVOhtBA;m8{NZRFVS0>59HGw9y7TnR!9Zcgs-j7+E%`$ zSk`=DAJ0;5p0O<)_m}9Kava=hoU%^db>-7qnZxPgG!u23DO+(#8Ht(H`&^9FS9ne^>c>&BUPW;%{{rIhTl&~UP#%j^5*ls9+}u9q;;1sd;??&KZ}-A z1~D7XGEEX}G~|fQ+pydk_t6|%@oR`$C9cb3ogXYP>5kJ`c0yj{?wyg01sd}|7%xk$ zd~n0~NuT!ECR&(-R-UNx9%qw-D7$27VFr1Va^mo&Wt{idF0MPAS6a)jy>fw?H-1q| z^phxomI6XEV_vZ{+4a3>ZU6GL`78HI=_?s+r^#hK$$cw-_48YUku`SYnnv-??<1Za znQt$*_n)VUhm{hKe))WOWE9wBZ#H($0X!_U%c-s`NpxU=J} zP3-S`cvq~9tMNHcd&XZV{d5O z(OT2%=9K-1=f(}@^LDr1@G*4x)_KIh|JJb!ltIgppsOaKIi#Bvwj(3%s^u9^-h3>d z++x)j&|$ZGb!cVt^7Qnk0ejwU^Sln7M}}Xc=hiR}9iBT&QR3R>g36s$O)_nn~5A?V`c;Bez}T7#UXv20cf=?ecQIo|K;O+=Afc zQy%zyOU397yOTZxM?QUf*U7|9Wd{pbmEKx=)qE4uQ|z2Tz?85g<6$ zsYZ5lEY#W3(cSdv{tdqS^?VC=ORTzUE6{LVr6y(qr{Ykzrm3UzsMTTnvG+-Is#f`z zzGcU5M~r;h!FNivobyBDllkW`^Iwgga5|qAmf>s>G0805`r-v;ZCBv&b*2HU8{2g$$Ac7(JZhO7 z^cPPlw43tDzq@7Z+=Xz9k+&vGf-3fkFKWx!+_M&c|7U61O3VDcK^OCWP&!ULD#x{1 zRh7qEpO3pLc-dIML)LMWQgc65*3n7Z^IY7h;N^>wLUN8?+VbXA8SziKJ016VU*1@1 zoxSaRlY(WRkX%55V0ra4d1za}57y^LhzHVd&WW_pC*wean}2$KO!(g)fqYCcNLZ=C z6En3rBFfHU{G6<{kmaSEp3oKidm7@4%JGS(rn*X(-}Euu-rt-e)^*nGJ=*SvsQJ0C zG`+q3();dP-%gV)wRqL+CAj56n#E$$$ob`~_}5$xEn8v4&#(NjGGxHI+h)^q?)J^k ztjfs6<@eGac(;w+0n117+PCJRZU1J9ZT!U$r-G~J zC+aLuUY3zPSuD{U*3f1$p84U>$355f*P$6N;*;w7Bve1#tBPfOF+Q0tU@3m&ab;Ln zp!-Oah)TIpgVRlOw9AdhN)w!222D~rD;%DjM2GySHcHYj)Q~Pf@pwn~or@N3p~mSM zWHv?DExFLrvV`YJPeYyld8Hf#YG@S6#fd$^$dyLIBPQ`LXi3u$T{eo(vbXRF5 z`Kmsa%5>^nmua+~_nq0M%5igZ4Pn)DsPErP_Ii6CtVmMbnEmbKL93eMXX{I!^bYYQ zPu%YPIcQ&6I#n!n_|yLL>xwgKH%r#<_tbaxklc3S|AEYiP+xQqi224}Ws%pMNBD+VKC=>x}RvMJ2{qV=VZ` z96P@`eWCij#SPd6@zEkW+&b$WVlGEt<~&Nzao{oWEO3}-;(3Pk?Vxu;X^;HAM7 z>tpsdIpWDSCOt<}j-5CwZkudvo+EC1=xAntYDT(!YJtP49UR>o&ZOlDMU@2w<%a5x z_B1bD=D@K;vz;;La{qp+-Z0S1e;XFG-kW|Y`0pLgrYXN3d@{pm{q`1r+TTw^{dx^K z5u@+s?EhEy02B*GOi|MVqNW>jo7(+)k+m^>2gCpOk)YrHv-*Yn;x%9d(4FZ4bc|V` zW57;d2FBW8%ik~KQ&tP{r8{{r0#J^O9d6z#=)sEHXq20?3fhWffHm;dWVpI*3S~0P zLJiHGLOq;l&S*7NZe=w(cvT=nA%yO$;4=NPZGRNQ-$_MM({ziDq?#%(w{nP5h?lPy zkc|rQ^7Qss3Q<8%-=hSsS!4_vHO&&>p@OzHFh&LV_;`A_f#wK`pgW!djv$Y6VbZ-A z!9Gk66i$(hW{t^oc2P3b()n{l@IMu_Ye0an5(X0-9IO~jQ1oH$z~E>!8U~BU;PDE8 zL&1NicK|&^!P{R72%MgYoAqC}dHX9)PfF3r#|z_Tjln5mF@H${FI9J9y7>mU`FNvP zlIe~ysi9TkWa8dZT#A>$SBBsvZ6NXOGDB$pX^zQ4_L zmO$_WAdvtx0j`vcnLf^eP7J0BTEmIy<46xcX}S3axOsXqm?*L$79|b(^f~(k`^%tJ zl`*XO{5HQC<@`qaKbYHKTOHr2qPq&2lo4Q2lPxtUKO(}`i=c*sfBOnueFA*^U44B2i)GII_)n8i_MIUpxiaX^o^IX@)oF7yWBC2L z@N`q1(SV^(0K@;+9s%mFi)lX0T%-I??>BV-Z`MvNu>C4%)@CVSaSC|6IgX-4pef<7a#)-a7W<2J zdT7R+tW+gD;dj;z}nz~DbC&dZAhVk|x-tv`)kPwP*Bpb}^VXEGJ9 zfOW(Z6o@X)P6~7)-ARGUz&blSQC#R)0s%Pkue&W7On=}kdRnke;qY@B5_I4Hv=uo! z{iO@vK&Iz3(mFd~fX}mh-5(ed4k*LfNeNhq7ahPP-PhOC&1o70FaX}bTEPzkSRHSE zEmFfXV8(G+xUA$!_uip`4pDGsxX=SV1JJ5Fwzvf_P+K;l%oxldV1ob2yQT-j{4D@n zIsLL{Sfd)Ajtpji4?tIx0b_@!o6npI{(S^+?fiEv_=nT~N7J1(ED+-#=;+RH`cpB# zL(6|P$G>ivYyYQdAYQVt6Z2O*2LD6-U-&|V{3|6R>O$1@uQc$lm=Wtj)b+14@UNH= z>-v97U7&oQDf+=1`c=@uproJkbmQ;mU_rLeO39^vE6gYa(4ZRR?r4za%V4H+e2~M! zT-50d{}AExw789ZkZ0@(hnJf&wctyzVq3}&XD{%f4s<+SZgJ#8x^ zgV6{KaAiqkPYpqf-(MNoUqYs9J0Sd5K`Z@tJ!?B%(6R=bUCjQjvgum(w?=9qOoj_D zHx`AXVX5HXzrIjp5{W=Uv3|z-!cl2>@Khb^3*|jS10?n+z%z=A+`V&|IhlB1{8MTtVZJVLel+@Y-lt(8ZE%E;Mjn z2+;_v*0HnoLIXXBAsX;gh(^W1>tG#j!8AOTeSTytk-%;*WGo5N0T~PXG%z*L zdU5tT$T%!yYh)ZA@)y$6;~={t;|X|Zy?7#o zC1gAqmVu{0wnoO&SiPrb?IoFjgZvk~-;E0M5eYC2I5jjL1)w#%3@U^#z@_225b^L_ zhy+$M;n{O0l0YYLb{ZMpOCoS2h>r$g7@344LVP3wmfg3=BqD_OKq_pzBnoW1z)T@~ zA>&xBk!P=sJl!LRjYcG}`w^K;hA@Imrm)%vv)xO>LF=GkDbRQnJcKWxRWoek6cU6b zWD11+3TgkaTRbuag|KNQ6U?m5pd9W zG$N~K(`*?uGOK?&8;!zh1I$LFL3*KJ!7roO_&_*f~~}}?>Pla zrLpUt0Oz!ToMtsQ_z+fmP>~6Ar|Doa;Z=}qL64%UQ7YW1+*U^C_{1q?n3JYK?>$0LNSj5 zT5v=2Ba@*R3eXw$1u_-NEhuCflnYRR^Fw-OIUKv5DFi4U0jW^Dq<{^E<_wetk4J`b zbP9zE;VFeegK}jG70$0HRFDv{&lzkbq-Ws1(0ZwGO-BK#ErgR)8Wy^j2FD%>4G-l_ z6dD2c4;l%yq-XP08l3Nf-+aS*q0yjRfQrSD*vF${L1M=y1GMjk>>iX0klh0{LwgQF zEwtxUEYLnA0|YpB8V(2L3{>zsb9U^c;s{U;Mg>cQ)`25KH9HkYf#N<$1)#VOGz$4N z6_1DNODdiS<$qK>C|KFohKFlJDrl4r%^8S*?j>NM7)1r{#%{YHbcV2LI*JBL zQ-}{Y$6P=j3&{m}9VC}bra^ol9I@+cO(- zz&I=!ItK>rBPi@SD-KJ8unq^RH+CNcnu5;oa5!*W$EE`iRB`Ne8K6ODS}Yp-84rub z9xnln#9l+NDmusqe`PMS&(RUuv<5)Fi|7T>0k8$c4iFu%AOW!hL5AnDGWAKS1yR!2<*j5ImUC0D=by z9w2xy;|)lDfZzdw2M8V@crc>@1P>5AK=5G38<6|}!2<*j5IjKeU`7K79w2yt;K7VH zAo&4;2M8V@c!1!+j0O-qK=1&;gBfo?@&g195IjKe0KtP94Ip@c-~oaMGv0vY2M8V@ zc!1ymf(J7iK=1&;0|XCdyaCA%5IjKe0Ko$U4`wug-~oaM2p-IM1Ck#gc!1ymf(Hm5 z%xD0?0|XBcJectYBtJm#0Ko$U4-h<<(Ex%62p%AKFyjqKet_Tsf(Hm5Ab2pN0R#^a zJV5YZ#v73Q0Ko$U4-h=~{{s&Km~=N!29uXtSs7#I7Ro^3XjrPMDlfNx0G$~S!eqGc Sa^rAhUhZ}4w2gFlx&If#fv92t diff --git a/org.glite.deployment.lb/project/.cvsignore b/org.glite.deployment.lb/project/.cvsignore deleted file mode 100644 index caf4eaa..0000000 --- a/org.glite.deployment.lb/project/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -glite-lb.sdf.xml diff --git a/org.glite.deployment.lb/project/build.number b/org.glite.deployment.lb/project/build.number deleted file mode 100644 index 306b97f..0000000 --- a/org.glite.deployment.lb/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Mon Mar 13 07:52:27 CET 2006 -module.build=0326 diff --git a/org.glite.deployment.lb/project/build.properties b/org.glite.deployment.lb/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template b/org.glite.deployment.lb/project/glite-lb.sdf.xml.template deleted file mode 100644 index 48d94a7..0000000 --- a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/lxscript-rpm.xsl b/org.glite.deployment.lb/project/lxscript-rpm.xsl deleted file mode 100644 index c661ad7..0000000 --- a/org.glite.deployment.lb/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-lb_installer v. -# -# The glite-lb_installer installs the gLite Logging and Bookkeeping Server -# -# Usage: glite-lb_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-lb - cd glite-lb - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite LB, please create or update the configuration - echo files /opt/glite/etc/config/glite-lb.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-lb-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-lb.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the LB RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the LB RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo - echo The glite-lb_installer installs the gLite Logging and Bookkeeping Server - echo - echo Usage: glite-lb_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.lb/project/lxscript-tgz.xsl b/org.glite.deployment.lb/project/lxscript-tgz.xsl deleted file mode 100644 index 5b55e40..0000000 --- a/org.glite.deployment.lb/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-lb_tgz_installer -# usage: glite-lb_tgz_installer [-u] -# -u uninstall -# -# glite-lb_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.lb/project/properties.xml b/org.glite.deployment.lb/project/properties.xml deleted file mode 100644 index ef87369..0000000 --- a/org.glite.deployment.lb/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/quattor-template.xsl b/org.glite.deployment.lb/project/quattor-template.xsl deleted file mode 100644 index 74f841d..0000000 --- a/org.glite.deployment.lb/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_lb; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-lb Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.lb/project/version.properties b/org.glite.deployment.lb/project/version.properties deleted file mode 100644 index bb1d337..0000000 --- a/org.glite.deployment.lb/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.3.0 -module.age = 0 - \ No newline at end of file diff --git a/org.glite.jp.client/src/jpimporter.c b/org.glite.jp.client/src/jpimporter.c index 445ebd6..02078a2 100644 --- a/org.glite.jp.client/src/jpimporter.c +++ b/org.glite.jp.client/src/jpimporter.c @@ -95,7 +95,7 @@ static struct option opts[] = { { "sandbox-mdir",1, NULL, 's'}, { "pidfile", 1, NULL, 'i'}, { "poll", 1, NULL, 't'}, - { "store", 1, NULL, 'S'}, + { "store", 1, NULL, 's'}, { NULL, 0, NULL, 0} }; @@ -561,11 +561,11 @@ static int sandbox_importer(void) if ( readnew ) ret = edg_wll_MaildirTransStart(sandbox_mdir, &msg, &fname); else ret = edg_wll_MaildirRetryTransStart(sandbox_mdir, (time_t)60, (time_t) 600,&msg, &fname); if ( !ret ) { - readnew = !readnew; + readnew = ~readnew; if ( readnew ) ret = edg_wll_MaildirTransStart(sandbox_mdir, &msg, &fname); else ret = edg_wll_MaildirRetryTransStart(sandbox_mdir, (time_t)60, (time_t) 600,&msg, &fname); if ( !ret ) { - readnew = !readnew; + readnew = ~readnew; return 0; } } diff --git a/org.glite.jp.common/Makefile b/org.glite.jp.common/Makefile index 26977c6..177a143 100644 --- a/org.glite.jp.common/Makefile +++ b/org.glite.jp.common/Makefile @@ -31,8 +31,6 @@ DEBUG:=-g -O0 CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${stagedir}/include \ ${GLOBUSINC} -LDFLAGS:=-L${globus_prefix}/lib - offset=0 version_info:=-version-info ${shell \ perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } @@ -47,40 +45,25 @@ HDRS:=types.h context.h strmd5.h attr.h known_attr.h trio.h escape.h SRCS:=context.c strmd5.c attr.c OBJS:=${SRCS:.c=.lo} -LIBS:=-lcrypto_${nothrflavour} -LIBS_THR:=-lcrypto_${thrflavour} -commonlib:= libglite_jp_common_${nothrflavour}.la -commonlib_thr:= libglite_jp_common_${thrflavour}.la +commonlib:= libglite_jp_common.la TRIO_OBJS:=escape.o trio.o strio.o TRIO_LIB:=libglite_jp_trio.la TRIO_LOBJS:=${TRIO_OBJS:.o=.lo} -TEST_LIBS:=-L${cppunit}/lib -lcppunit -ldl -TEST_INC:=-I${cppunit}/include - - default all: compile -compile: ${commonlib} ${commonlib_thr} ${TRIO_LIB} +compile: ${commonlib} ${TRIO_LIB} ${commonlib}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${LIBS} - -${commonlib_thr}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${LIBS} + ${LINK} -o $@ ${OBJS} ${TRIO_LIB}: ${TRIO_LOBJS} ${LINK} ${version_info} -o $@ ${TRIO_LOBJS} -lm -check: base64_test type_test - ./base64_test base64_test.xml - ./type_test type_test.xml - -type_test base64_test: %: %.cpp compile - ${CXX} -c ${CFLAGS} ${TEST_INC} $< - ${LINKXX} -o $@ $@.o ${commonlib} ${TRIO_LIB} ${TEST_LIBS} +check: + -echo nothing yet doc: @@ -91,7 +74,7 @@ install: -mkdir -p ${PREFIX}/include/${globalprefix}/${jpprefix} cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${jpprefix} -mkdir -p ${PREFIX}/lib - ${INSTALL} -m 755 ${commonlib} ${commonlib_thr} ${TRIO_LIB} ${PREFIX}/lib + ${INSTALL} -m 755 ${commonlib} ${TRIO_LIB} ${PREFIX}/lib dist: distsrc distbin diff --git a/org.glite.jp.common/interface/attr.h b/org.glite.jp.common/interface/attr.h index 6badff7..6ae2cb5 100644 --- a/org.glite.jp.common/interface/attr.h +++ b/org.glite.jp.common/interface/attr.h @@ -1,10 +1,6 @@ #ifndef __GLITE_JP_ATTR #define __GLITE_JP_ATTR -#ifdef __cplusplus -extern "C" { -#endif - void glite_jp_attrval_free(glite_jp_attrval_t *,int); void glite_jp_attrval_copy(glite_jp_attrval_t *,const glite_jp_attrval_t *); @@ -24,9 +20,5 @@ const char *glite_jp_attrval_db_type_index(glite_jp_context_t ctx,const char *at time_t glite_jp_attr2time(const char *); char * glite_jp_time2attr(time_t); -#ifdef __cplusplus -}; -#endif - #endif diff --git a/org.glite.jp.common/interface/context.h b/org.glite.jp.common/interface/context.h index 75a71a3..40ae2eb 100644 --- a/org.glite.jp.common/interface/context.h +++ b/org.glite.jp.common/interface/context.h @@ -1,10 +1,6 @@ #ifndef __GLITE_JP_CONTEXT #define __GLITE_JP_CONTEXT -#ifdef __cplusplus -extern "C" { -#endif - int glite_jp_init_context(glite_jp_context_t *); void glite_jp_free_context(glite_jp_context_t); void glite_jp_free_query_rec(glite_jp_query_rec_t *); @@ -19,8 +15,4 @@ int glite_jp_add_deferred(glite_jp_context_t,int (*)(glite_jp_context_t,void *), int glite_jp_run_deferred(glite_jp_context_t); -#ifdef __cplusplus -}; -#endif - #endif diff --git a/org.glite.jp.common/interface/known_attr.h b/org.glite.jp.common/interface/known_attr.h index b3c80ad..fafeb82 100644 --- a/org.glite.jp.common/interface/known_attr.h +++ b/org.glite.jp.common/interface/known_attr.h @@ -24,18 +24,5 @@ /** Namespace for LB user tags, schemaless, all values are strings */ #define GLITE_JP_LBTAG_NS "http://egee.cesnet.cz/en/WSDL/jp-lbtag" -#define GLITE_JP_JDL_NS "http://jdl" - -/** Namespace for Sandboxes */ -#define GLITE_JP_ISB_NS "http://egee.cesnet.cz/en/Schema/JP/ISB" -#define GLITE_JP_OSB_NS "http://egee.cesnet.cz/en/Schema/JP/OSB" - -/** Namespace for file names listed from tar */ -#define GLITE_JP_ATTR_ISB_FILENAME GLITE_JP_ISB_NS ":filename" -#define GLITE_JP_ATTR_OSB_FILENAME GLITE_JP_OSB_NS ":filename" - -/** Namespace for filenames to be unpacked from sanbox tar */ -#define GLITE_JP_ISB_CONTENT_NS GLITE_JP_ISB_NS ":content" -#define GLITE_JP_OSB_CONTENT_NS GLITE_JP_OSB_NS ":content" #endif diff --git a/org.glite.jp.common/interface/strmd5.h b/org.glite.jp.common/interface/strmd5.h index c354e6d..4ca27a2 100755 --- a/org.glite.jp.common/interface/strmd5.h +++ b/org.glite.jp.common/interface/strmd5.h @@ -1,10 +1,6 @@ #ifndef _GLITE_STRMD5_H #define _GLITE_STRMD5_H -#ifdef __cplusplus -extern "C" { -#endif - #ident "$Header$" /* Compute MD5 sum of the first argument. @@ -32,9 +28,5 @@ char *str2md5base64(const char *src); int base64_encode(const void *enc, int enc_size, char *out, int out_max_size); int base64_decode(const char *enc,char *out,int out_size); -#ifdef __cplusplus -}; -#endif - #endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.jp.common/src/attr.c b/org.glite.jp.common/src/attr.c index 42a5cc6..47c2891 100644 --- a/org.glite.jp.common/src/attr.c +++ b/org.glite.jp.common/src/attr.c @@ -47,118 +47,49 @@ static int fb_cmp(void *ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t return 0; } -/* XXX: depends on specific definition of glite_jp_attr_orig_t */ -static char orig_char[] = "ASUF"; - -/* XXX: don't allocate memory, don't grow more than twice */ -static int escape_colon(const char *in, char *out) -{ - int i,o; - - for (i=o=0; in[i]; i++) switch (in[i]) { - case ':': out[o++] = '\\'; out[o++] = ':'; break; - case '\\': out[o++] = '\\'; out[o++] = '\\'; break; - default: out[o++] = in[i]; break; - } - out[o] = 0; - return o; -} - -/* XXX: read until unescaped colon is found - * allocates output */ -static char * unescape_colon(const char *in,int *rd) -{ - int i,o; - char *out; - - for (i=o=0; in[i] && in[i] != ':'; i++,o++) - if (in[i] == '\\') i++; - - out = malloc(o+1); - - for (i=o=0; in[i] && in[i] != ':'; i++) - if (in[i] == '\\') out[o++] = in[++i]; - else out[o++] = in[i]; - - out[o] = 0; - *rd = i; - return out; -} - static char * fb_to_db_full(void *ctx,const glite_jp_attrval_t *attr) { - - int vsize = attr->binary ? attr->size * 4/3 + 6 : strlen(attr->value)+1, - len; - - /* 4x: + \0 + ASUF + BS + %12d */ - char *db = malloc(19 + (attr->origin_detail ? 2*strlen(attr->origin_detail) : 0) + vsize); - - if (attr->origin < 0 || attr->origin > GLITE_JP_ATTR_ORIG_FILE) { - free(db); return NULL; - } - len = sprintf(db,"%c:%d:%c:",attr->binary ? 'B' : 'S', - attr->timestamp,orig_char[attr->origin]); - - if (attr->origin_detail) len += escape_colon(attr->origin_detail,db+len); - db[len++] = ':'; - + char *db; if (attr->binary) { - vsize = base64_encode(attr->value,attr->size,db+len,vsize-1); - if (vsize < 0) { free(db); return NULL; } - db[len+vsize] = 0; + int osize = attr->size * 4/3 + 6; + db = malloc(osize); + db[0] = 'B'; db[1] = ':'; + osize = base64_encode(attr->value,attr->size,db+2,osize-3); + assert(osize >= 0); + db[osize] = 0; + } + else { + db = malloc(strlen(attr->value)+3); + db[0] = 'S'; db[1] = ':'; + strcpy(db+2,attr->value); } - else strcpy(db+len,attr->value); - return db; } static char * fb_to_db_index(void *ctx,const glite_jp_attrval_t *attr,int len) { - char *s; - -/* XXX: binary values not really handled. Though the formal semantics is not broken */ - if (attr->binary) return strdup("XXX"); - - s = strdup(attr->value); - if (len < strlen(s)) s[len] = 0; - return s; + char *db = fb_to_db_full(ctx,attr); + if (len < strlen(db)) db[len] = 0; + return db; } -static int fb_from_db(void *ctx,const char *str,glite_jp_attrval_t *attr) -{ - int p = 2; - char *colon,*cp; - - if (str[0] != 'B' && str[0] != 'S') return EINVAL; - attr->binary = str[0] == 'B'; - cp = attr->value = strdup(str); - - colon = strchr(cp+p,':'); - if (!colon) return EINVAL; - - *colon++ = 0; - attr->timestamp = (time_t) atol(cp+p); - p = colon-cp; - - for (attr->origin = GLITE_JP_ATTR_ORIG_ANY; orig_char[attr->origin] && orig_char[attr->origin] != cp[p]; attr->origin++); - if (!orig_char[attr->origin]) return EINVAL; - - p += 2; - if (cp[p] == ':') attr->origin_detail = NULL; - else { - int r; - attr->origin_detail = unescape_colon(cp+p,&r); - p += r; +int fb_from_db(void *ctx,const char *str,glite_jp_attrval_t *attr) +{ + int osize; + switch (str[0]) { + case 'B': + attr->value = malloc(osize = strlen(str) * 3/4 + 4); + attr->size = base64_decode(str,str+2,osize); + assert(attr->size >= 0); + attr->binary = 1; + break; + case 'S': + attr->value = strdup(str + 2); + attr->size = 0; + attr->binary = 0; + break; + default: return EINVAL; } - if (cp[p++] != ':') return EINVAL; - - if (attr->binary) { - attr->size = base64_decode(str+p,attr->value,strlen(str)); - if (attr->size < 0) return EINVAL; - } - else strcpy(attr->value,str+p); - return 0; } diff --git a/org.glite.jp.common/src/stdtypes.c b/org.glite.jp.common/src/stdtypes.c new file mode 100644 index 0000000..6995e77 --- /dev/null +++ b/org.glite.jp.common/src/stdtypes.c @@ -0,0 +1,127 @@ +#include +#include +#include + +#include "lb/trio.h" + +#include "types.h" +#include "type_plugin.h" + +static char *namespace = "http://glite.org/wsdl/types/jp_std_attr"; + +static int check_namespace(const glite_jp_attr_t *a) +{ + if (a->namespace && strcmp(a->namespace,namespace)) return -1; + return 0; +} + +static int *cmp( + void *ctx, + const glite_jp_attrval_t *a, + const glite_jp_attrval_t *b, + int *result +{ + struct timeval t; + int r; + + if (check_namespace(&a->attr) || check_namespace(&b->attr)) return -1; + if (glite_jp_attr_cmp(&a->attr,&b->attr)) return -1; + + switch (a->attr.type) { + case GLITE_JP_ATTR_OWNER: + r = strcmp(a->value.s,b->value.s); + break; + case GLITE_JP_ATTR_TIME: + t = a->value.time; + t.tv_sec -= b->value.time.tv_sec; + if ((t.tv_usec -= b->value.time.tv_usec) < 0) { + t.tv_usec += 1000000; + t.tv_sec--; + } + r = t.tv_sec ? t.tv_sec : t.tv_usec; + if (r) r = r > 0 ? 1 : -1; + break; + case GLITE_JP_ATTR_TAG: + if (a->value.tag.binary != b->value.tag.binary) return -1; + if (a->value.tag.binary) { + /* FIXME: I'm lazy. */ + abort(); + } + else r = strcmp(a->value.tag.value,b->value.tag.value); + default: return -1; + } + *result = r; + return 0; +} + +static char *to_xml(void *ctx,const glite_jp_attrval_t *a) +{ + char *out = NULL; + + if (check_namespace(a)) return NULL; + + switch (a->attr.type) { + case GLITE_JP_ATTR_OWNER: + trio_asprintf(&out,"%|Xs",a->value.s); + break; + case GLITE_JP_ATTR_TIME: + /* XXX */ + trio_asprintf(&out,"%ld.06%ld",a->value.time.tv_sec, + a->value.time.tv_usec); + break; + case GLITE_JP_ATTR_TAG: + /* FIXME */ assert(!a->value.tag.binary); + + trio_asprintf(&out,"%d%ld>%|Xs",a->value.tag.sequence,a->value.tag.timestamp,a->value.tag.value); + break; + default: + break; + } + return out; +} + +static glite_jp_attrval_t *from_xml(void *ctx,const char *name,const char *val) +{ + /* FIXME: I'm lazy. */ + abort(); +} + +static char *to_db(void *ctx,const glite_jp_attrval_t *a) +{ + /* FIXME: I'm lazy. */ + abort(); +} + +static glite_jp_attrval_t *from_db(void *ctx,const char *a) +{ + /* FIXME: I'm lazy. */ + abort(); +} + +static const char *db_type(void *ctx,const glite_jp_attr_t *a) +{ + if check_namespace(a) return NULL; + switch (a->type) { + case GLITE_JP_ATTR_OWNER: return "varchar(250) binary"; + case GLITE_JP_ATTR_TIME: return "datetime"; + case GLITE_JP_ATTR_TAG: return "mediumblob"; + default: return NULL; + } +} + +int init( + glite_jp_context_t ctx, + const char *param, + glite_jp_tplug_data *pd +) +{ + pd->namespace = namespace; + pd->cmp = cmp; + pd->to_xml = to_xml; + pd->from_xml = from_xml; + pd->to_db = to_db; + pd->from_db = from_db; + pd->db_type = db_type; + pd->pctx = ctx; +} + diff --git a/org.glite.jp.common/src/strmd5.c b/org.glite.jp.common/src/strmd5.c index b07593f..7a35fb1 100755 --- a/org.glite.jp.common/src/strmd5.c +++ b/org.glite.jp.common/src/strmd5.c @@ -67,7 +67,7 @@ int base64_decode(const char *enc,char *out,int max_out_size) } while (*enc && *enc != '=') { - bits <<= 6; + bits << 6; bits |= b64r[*enc++]; shift += 6; @@ -79,6 +79,14 @@ int base64_decode(const char *enc,char *out,int max_out_size) } } + /* XXX: will it ever happen? */ + if (shift) { + if (out_size >= max_out_size) return -1; + bits <<= 8-shift; + *out = bits & 0xff; + out_size++; + } + return out_size; } diff --git a/org.glite.jp.common/test/base64_test.cpp b/org.glite.jp.common/test/base64_test.cpp deleted file mode 100644 index 55a41c1..0000000 --- a/org.glite.jp.common/test/base64_test.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "strmd5.h" - -class Base64Test: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(Base64Test); - CPPUNIT_TEST(test); - CPPUNIT_TEST_SUITE_END(); -public: - void test(); -}; - -void Base64Test::test() -{ - int i; - unsigned char in[2000], b[4000], out[2000]; - - srandom(0xDEAD); - in[0] = 'x'; - for (i=1; i<2000; i++) { - char s[20]; - int len; - sprintf(s,"%d",i); - in[i] = random() % 256; - - std::cerr << '.'; - - base64_encode(in,i,(char *) b,sizeof b); - len = base64_decode((const char *) b,(char *) out,sizeof out); - - CPPUNIT_ASSERT_MESSAGE(std::string("len"),i == len); - CPPUNIT_ASSERT_MESSAGE(std::string(s),!memcmp(in,out,i)); - } - std::cerr << std::endl; -} - -CPPUNIT_TEST_SUITE_REGISTRATION(Base64Test); - - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} - - - diff --git a/org.glite.jp.common/test/type_test.cpp b/org.glite.jp.common/test/type_test.cpp deleted file mode 100644 index 8669637..0000000 --- a/org.glite.jp.common/test/type_test.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "types.h" -#include "attr.h" -#include "context.h" - - -class TypePluginTest: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(TypePluginTest); - CPPUNIT_TEST(simple); - CPPUNIT_TEST(binary); - CPPUNIT_TEST(origin); - CPPUNIT_TEST(origin2); - CPPUNIT_TEST(index); - CPPUNIT_TEST_SUITE_END(); -public: - void simple(); - void binary(); - void origin(); - void origin2(); - void index(); -}; - -void TypePluginTest::simple() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - "short string", - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!strcmp(attr.value,attr2.value)); - CPPUNIT_ASSERT_MESSAGE(std::string("origin"),attr.origin == attr2.origin); - CPPUNIT_ASSERT_MESSAGE(std::string("timestamp"),attr.timestamp == attr2.timestamp); -} - -void TypePluginTest::binary() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 1,1000, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = (char *) malloc(attr.size); - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("size"),attr.size == attr2.size); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!memcmp(attr.value,attr2.value,attr.size)); -} - -void TypePluginTest::origin() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = "origin test"; - attr.origin_detail = "simple origin"; - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("origin detail"),!strcmp(attr.origin_detail,attr2.origin_detail)); -} - -void TypePluginTest::origin2() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = "origin:test"; - attr.origin_detail = "ftp://some.server:1234/ugly \\file"; - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("origin detail"),!strcmp(attr.origin_detail,attr2.origin_detail)); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!strcmp(attr.value,attr2.value)); -} - -void TypePluginTest::index() -{ - /* TODO: check monotonity */ -} - -CPPUNIT_TEST_SUITE_REGISTRATION(TypePluginTest); - - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} - - - diff --git a/org.glite.jp.index/Makefile b/org.glite.jp.index/Makefile index 34dd4ac..b918109 100644 --- a/org.glite.jp.index/Makefile +++ b/org.glite.jp.index/Makefile @@ -49,8 +49,7 @@ INSTALL:=libtool --mode=install install daemon:=glite-jp-indexd examples:=glite-jpis-test glite-jpis-client test:=run-test.sh -test_files:=dump1.sql simple_query.in simple_query.out complex_query.in complex_query.out authz.out jobid_query.in jobid_query.out origin_query.in origin_query.out - +test_files:=dump1.sql simple_query.in simple_query.out complex_query.in complex_query.out authz.out MANS1:=glite-jpis-client.1 MANS8:=glite-jp-indexd.8 MANS:=${MANS1} ${MANS8} @@ -59,15 +58,27 @@ is_prefix:=jpis_ is_client_prefix:=jpis_client_ ps_prefix:=jpps_ +#<<<<<<< Makefile +# ${is_prefix}Server.c ${is_prefix}C.c\ +# ${ps_prefix}ClientLib.c +#======= SRCS:= conf.c bones_server.c soap_ops.c soap_ps_calls.c \ ws_ps_typeref.c ws_is_typeref.c db_ops.c context.c common_server.c \ - ${is_prefix}ServerLib.c\ + ${is_prefix}ServerLib.c \ ${ps_prefix}ClientLib.c ${ps_prefix}C.c +#>>>>>>> 1.32.2.3 +#<<<<<<< Makefile EXA_TEST_SRCS:=jpis-test.c ${is_prefix}C.c ${is_prefix}Client.c context.c db_ops.c conf.c ws_is_typeref.c EXA_DB_SRCS:=jpis-db-internal.c db_ops.c conf.c context.c ws_is_typeref.c EXA_CLIENT_SRCS:=jpis-client.c common.c \ ${is_client_prefix}C.c ${is_client_prefix}Client.c +#======= +#EXA_TEST_SRCS:=jpis-test.c ${is_prefix}C.c ${is_prefix}Client.c context.c db_ops.c conf.c +#EXA_DB_SRCS:=jpis-db-internal.c db_ops.c conf.c context.c +#EXA_CLIENT_SRCS:=jpis-client.c common.c \ +# ${is_client_prefix}C.c ${is_client_prefix}Client.c +#>>>>>>> 1.32.2.3 # ${is_prefix}C.c OBJS:=${SRCS:.c=.o} @@ -76,7 +87,7 @@ EXA_DB_OBJS:=${EXA_DB_SRCS:.c=.o} EXA_CLIENT_OBJS:=${EXA_CLIENT_SRCS:.c=.o} -COMMONLIB:=-lglite_jp_common_${nothrflavour} +COMMONLIB:=-lglite_jp_common SRVCOMMONLIB:=-lglite_jp_server_common BONESLIB:=-lglite_lb_server_bones TRIOLIB:=-lglite_jp_trio diff --git a/org.glite.jp.index/config/glite-jpis-config.xml b/org.glite.jp.index/config/glite-jpis-config.xml index 9a2bdea..176a470 100644 --- a/org.glite.jp.index/config/glite-jpis-config.xml +++ b/org.glite.jp.index/config/glite-jpis-config.xml @@ -27,7 +27,6 @@ http://egee.cesnet.cz/en/Schema/JP/System:jobId http://egee.cesnet.cz/en/Schema/LB/Attributes:user http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus diff --git a/org.glite.jp.index/config/startup b/org.glite.jp.index/config/startup index 4680b41..a907f0d 100755 --- a/org.glite.jp.index/config/startup +++ b/org.glite.jp.index/config/startup @@ -18,7 +18,6 @@ GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-${GLITE_LOCATION}/var} [ -n "$GLITE_JPIS_LOGFILE" ] || export GLITE_JPIS_LOGFILE=$GLITE_LOCATION_VAR/glite-jp-indexd.log pidfile="$GLITE_JPIS_PIDFILE" -test -n "$GLITE_JPIS_CONFIG" || GLITE_JPIS_CONFIG="$GLITE_LOCATION/etc/glite-jpis-config.xml" test -n "$GLITE_JPIS_PORT" || GLITE_JPIS_PORT=8902 test -n "$GLITE_JPIS_DB" || GLITE_JPIS_DB=jpis/@localhost:jpis test -n "$GLITE_JPIS_QT" || GLITE_JPIS_QT="both" @@ -56,6 +55,11 @@ start() [ -z "$creds" ] && echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 + if test -z "$GLITE_JPIS_PS" ;then + echo 'Error: GLITE_JPIS_PS is not set' + echo FAILED + return 1 + fi if [ ! -d "`dirname $GLITE_JPIS_PIDFILE`" ] then echo "Directory `dirname $GLITE_JPIS_PIDFILE` does not exist!" @@ -71,11 +75,10 @@ start() echo -n Starting glite-jp-indexd ... #su " $GLITE_LOCATION/bin/glite-jp-indexd \ su - $GLITE_USER -c " $GLITE_LOCATION/bin/glite-jp-indexd \ - $GLITE_JPIS_DEBUG \ + -s $GLITE_JPIS_PS $GLITE_JPIS_DEBUG \ -q $GLITE_JPIS_QT $creds $GLITE_JPIS_AUTH \ -m $GLITE_JPIS_DB -p $GLITE_JPIS_PORT \ -i $GLITE_JPIS_PIDFILE -o $GLITE_JPIS_LOGFILE \ - -x $GLITE_JPIS_CONFIG " && echo " done" || echo " FAILED" } diff --git a/org.glite.jp.index/doc/README b/org.glite.jp.index/doc/README index 2261d3c..92ac673 100644 --- a/org.glite.jp.index/doc/README +++ b/org.glite.jp.index/doc/README @@ -70,6 +70,7 @@ some hard-coded options. The index server takes the following options: ./glite-jp-indexd [option] + -s, --ps-server primary storage server address (http://hostname:port) -d, --debug don't run as daemon, additional diagnostics -q, --query-type hist/cont/both (default history) -n, --noauth don't check user identity with result owner @@ -77,10 +78,9 @@ The index server takes the following options: -p, --port port to listen -i, --pidfile file to store master pid -o, --logfile file to store logs - -x, --config file with server configuration -The config file parameter is required. There is the example configuration in -$GLITE_LOCATION/etc/glite-jpis-config.xml. +Other parameters will be configurable in close future. Its +current hard-coded values are in org.glite.jp.index/src/conf.[ch] Starting the daemon @@ -91,8 +91,8 @@ Preferred way of starting the daemon is using start-up script in ~/.glite.conf) where many variables may be set to configure the daemon. The script takes following variables: -GLITE_JPIS_CONFIG - server config file specification - (default is $GLITE_LOCATION//etc/glite-jpis-config.xml) +GLITE_JPIS_PS - location of JP-PS server (_required parameter_) + (for example http://umbar.ics.muni.cz:8901) GLITE_JPIS_DEBUG - setting to '-d' forces the daemon not to daemonize GLITE_JPIS_QT - defines query type 'hist' ... history query diff --git a/org.glite.jp.index/doc/glite-jp-indexd.sgml b/org.glite.jp.index/doc/glite-jp-indexd.sgml index a0713bd..1007bf4 100644 --- a/org.glite.jp.index/doc/glite-jp-indexd.sgml +++ b/org.glite.jp.index/doc/glite-jp-indexd.sgml @@ -22,6 +22,11 @@ --help + + -s + --ps-server + HOST:PORT + -d @@ -58,11 +63,6 @@ --logfile FILE.LOG - - -x - --config - CONFIG.XML - @@ -82,6 +82,14 @@ With no options you get simple usage message as with . + | + +Primary storage server address +(http://HOSTNAME:PORT). + + + + | Don't run as daemon, additional diagnostics. @@ -144,13 +152,6 @@ File to store master pid (default: /var/run/glite-jp-indexd.pid/var/run/glite-jp-indexd.log or $HOME/glite-jp-indexd.log). - - - | - -Configuration file containing information about feeds, primary storages, ... Structure is defined in server_conf.xsd. - - @@ -166,9 +167,9 @@ Preferred way of starting the daemon is using start-up script (config/ - GLITE_JPIS_CONFIG + GLITE_JPIS_PS -Specifying config file. Default is $GLITE_LOCATION/etc/glite-jpis-config.xml +Location of JP-PS server (_required parameter_), for example http://umbar.ics.muni.cz:8901. diff --git a/org.glite.jp.index/examples/jpis-client.c b/org.glite.jp.index/examples/jpis-client.c index f35c670..fb551ce 100644 --- a/org.glite.jp.index/examples/jpis-client.c +++ b/org.glite.jp.index/examples/jpis-client.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -24,7 +23,6 @@ #define soap_serialize__jpisclient__QueryJobsResponse soap_serialize__jpelem__QueryJobsResponse #define DEFAULT_JPIS "http://localhost:8902" -#define USE_GMT 1 /* namespaces[] not used here but needed to prevent linker to complain... */ @@ -138,8 +136,7 @@ static void query_example_fill(struct soap *soap, struct _jpisclient__QueryJobs cond = soap_malloc(soap, sizeof(*cond)); memset(cond, 0, sizeof(*cond)); cond->attr = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - cond->origin = soap_malloc(soap, sizeof(*(cond->origin))); - *(cond->origin) = jptype__attrOrig__SYSTEM; + cond->origin = NULL; cond->__sizerecord = 2; cond->record = soap_malloc(soap, cond->__sizerecord * sizeof(*(cond->record))); @@ -229,18 +226,11 @@ static void query_print(FILE *out, const struct _jpisclient__QueryJobs *in) { fprintf(out, "Conditions:\n"); for (i = 0; i < in->__sizeconditions; i++) { fprintf(out, "\t%s\n", in->conditions[i]->attr); - if (in->conditions[i]->origin) { - for (k = 0; k <= NUMBER_ORIG; k++) - if (origins[k].orig == *(in->conditions[i]->origin)) break; - fprintf(out, "\t\torigin == %s\n", origins[k].name); - } else { - fprintf(out, "\t\torigin IS ANY\n"); - } for (j = 0; j < in->conditions[i]->__sizerecord; j++) { rec = in->conditions[i]->record[j]; for (k = 0; k <= NUMBER_OP; k++) if (operations[k].op == rec->op) break; - fprintf(out, "\t\tvalue %s", operations[k].name); + fprintf(out, "\t\t%s", operations[k].name); if (rec->value) { fprintf(out, " "); value_print(out, rec->value); @@ -325,9 +315,6 @@ static void queryresult_print(FILE *out, const struct _jpelem__QueryJobsRespons struct jptype__attrValue *attr; int i, j, k; -#if USE_GMT - setenv("TZ","UTC",1); tzset(); -#endif fprintf(out, "Result %d jobs:\n", in->__sizejobs); for (j=0; j__sizejobs; j++) { fprintf(out, "\tjobid = %s, owner = %s\n", in->jobs[j]->jobid, in->jobs[j]->owner); diff --git a/org.glite.jp.index/examples/jpis-test.c b/org.glite.jp.index/examples/jpis-test.c index 54395d6..ef926dd 100644 --- a/org.glite.jp.index/examples/jpis-test.c +++ b/org.glite.jp.index/examples/jpis-test.c @@ -42,16 +42,12 @@ int main(int argc,char *argv[]) { glite_jp_db_stmt_t stmt; glite_jp_context_t ctx; - glite_jpis_context_t isctx = NULL; + glite_jpis_context_t isctx; glite_jp_is_conf *conf; glite_jp_init_context(&ctx); glite_jp_get_conf(argc, argv, NULL, &conf); - if (!conf) { - fprintf(stderr, "Can't gather configuration\n"); - goto end; - } if (default_server) strcpy(server, default_server); else snprintf(server, sizeof(server), "http://localhost:%s", conf->port ? conf->port : GLITE_JPIS_DEFAULT_PORT_STR); printf("JP index server: %s\n", server); diff --git a/org.glite.jp.index/examples/query-tests/authz.out b/org.glite.jp.index/examples/query-tests/authz.out index a3d8c20..21458e0 100644 --- a/org.glite.jp.index/examples/query-tests/authz.out +++ b/org.glite.jp.index/examples/query-tests/authz.out @@ -2,8 +2,7 @@ query: using JPIS http://localhost:10000 Conditions: http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Ready + == Ready Attributes: http://egee.cesnet.cz/en/Schema/JP/System:owner http://egee.cesnet.cz/en/Schema/JP/System:jobId @@ -11,4 +10,4 @@ Attributes: http://egee.cesnet.cz/en/Schema/LB/Attributes:user OK - + \ No newline at end of file diff --git a/org.glite.jp.index/examples/query-tests/complex_query.out b/org.glite.jp.index/examples/query-tests/complex_query.out index a16cd61..bc11975 100644 --- a/org.glite.jp.index/examples/query-tests/complex_query.out +++ b/org.glite.jp.index/examples/query-tests/complex_query.out @@ -2,12 +2,10 @@ query: using JPIS http://localhost:10000 Conditions: http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Done - value == Ready + == Done + == Ready http://egee.cesnet.cz/en/Schema/LB/Attributes:user - origin IS ANY - value <> God + <> God Attributes: http://egee.cesnet.cz/en/Schema/JP/System:owner http://egee.cesnet.cz/en/Schema/JP/System:jobId @@ -15,4 +13,4 @@ Attributes: http://egee.cesnet.cz/en/Schema/LB/Attributes:user OK -https://localhost:7846/pokus1/O=CESNET/O=Masaryk University/CN=Milos Mulachttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDone1970-01-01T02:00:01ZFILEhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1970-01-01T02:00:01ZFILEhttp://localhost:8901https://localhost:7846/pokus2OwnerNamehttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusReady1970-01-01T02:00:01ZSYSTEMhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1970-01-01T02:00:01ZSYSTEMhttp://localhost:8901 +https://localhost:7846/pokus1/O=CESNET/O=Masaryk University/CN=Milos Mulachttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDone1969-12-31T23:00:00ZSYSTEMhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1969-12-31T23:00:00ZSYSTEMhttp://localhost:8901https://localhost:7846/pokus2OwnerNamehttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusReady1969-12-31T23:00:00ZSYSTEMhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1969-12-31T23:00:00ZSYSTEMhttp://localhost:8901 \ No newline at end of file diff --git a/org.glite.jp.index/examples/query-tests/dump1.sql b/org.glite.jp.index/examples/query-tests/dump1.sql index 814b5e4..c0a5708 100644 --- a/org.glite.jp.index/examples/query-tests/dump1.sql +++ b/org.glite.jp.index/examples/query-tests/dump1.sql @@ -303,7 +303,7 @@ CREATE TABLE `attr_9892f81a8175c09bd00afcb152f510ad` ( /*!40000 ALTER TABLE `attr_9892f81a8175c09bd00afcb152f510ad` DISABLE KEYS */; LOCK TABLES `attr_9892f81a8175c09bd00afcb152f510ad` WRITE; -INSERT INTO `attr_9892f81a8175c09bd00afcb152f510ad` VALUES ('593e62a063231f8c623b74406b3e12b0','CertSubj','S:7201:F::CertSubj',3),('9276789a0093ad44457655ef03ade36a','CertSubj','S:7201:S::CertSubj',2); +INSERT INTO `attr_9892f81a8175c09bd00afcb152f510ad` VALUES ('593e62a063231f8c623b74406b3e12b0','S:CertSubj','S:CertSubj',1),('9276789a0093ad44457655ef03ade36a','S:CertSubj','S:CertSubj',2); UNLOCK TABLES; /*!40000 ALTER TABLE `attr_9892f81a8175c09bd00afcb152f510ad` ENABLE KEYS */; @@ -352,7 +352,7 @@ CREATE TABLE `attr_a1e9e0a1b7943cc041fefb5da65868f9` ( /*!40000 ALTER TABLE `attr_a1e9e0a1b7943cc041fefb5da65868f9` DISABLE KEYS */; LOCK TABLES `attr_a1e9e0a1b7943cc041fefb5da65868f9` WRITE; -INSERT INTO `attr_a1e9e0a1b7943cc041fefb5da65868f9` VALUES ('593e62a063231f8c623b74406b3e12b0','Done','S:7201:F::Done',3),('9276789a0093ad44457655ef03ade36a','Ready','S:7201:S::Ready',1); +INSERT INTO `attr_a1e9e0a1b7943cc041fefb5da65868f9` VALUES ('593e62a063231f8c623b74406b3e12b0','S:Done','S:Done',1),('9276789a0093ad44457655ef03ade36a','S:Ready','S:Ready',1); UNLOCK TABLES; /*!40000 ALTER TABLE `attr_a1e9e0a1b7943cc041fefb5da65868f9` ENABLE KEYS */; diff --git a/org.glite.jp.index/examples/query-tests/jobid_query.in b/org.glite.jp.index/examples/query-tests/jobid_query.in deleted file mode 100644 index d8a6b35..0000000 --- a/org.glite.jp.index/examples/query-tests/jobid_query.in +++ /dev/null @@ -1,19 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/JP/System:jobId - - EQUAL - - https://localhost:7846/pokus1 - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - diff --git a/org.glite.jp.index/examples/query-tests/jobid_query.out b/org.glite.jp.index/examples/query-tests/jobid_query.out deleted file mode 100644 index 2450fbe..0000000 --- a/org.glite.jp.index/examples/query-tests/jobid_query.out +++ /dev/null @@ -1,14 +0,0 @@ -query: using JPIS http://localhost:12002 - -Conditions: - http://egee.cesnet.cz/en/Schema/JP/System:jobId - origin IS ANY - value == https://localhost:7846/pokus1 -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -https://localhost:7846/pokus1/O=CESNET/O=Masaryk University/CN=Milos Mulachttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDone1970-01-01T02:00:01ZFILEhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1970-01-01T02:00:01ZFILEhttp://localhost:8901 diff --git a/org.glite.jp.index/examples/query-tests/origin_query.in b/org.glite.jp.index/examples/query-tests/origin_query.in deleted file mode 100644 index 47bdec3..0000000 --- a/org.glite.jp.index/examples/query-tests/origin_query.in +++ /dev/null @@ -1,20 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - FILE - - EQUAL - - Done - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - diff --git a/org.glite.jp.index/examples/query-tests/origin_query.out b/org.glite.jp.index/examples/query-tests/origin_query.out deleted file mode 100644 index bd8e3a7..0000000 --- a/org.glite.jp.index/examples/query-tests/origin_query.out +++ /dev/null @@ -1,14 +0,0 @@ -query: using JPIS http://localhost:12002 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin == FILE - value == Done -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -https://localhost:7846/pokus1/O=CESNET/O=Masaryk University/CN=Milos Mulachttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDone1970-01-01T02:00:01ZFILEhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1970-01-01T02:00:01ZFILEhttp://localhost:8901 \ No newline at end of file diff --git a/org.glite.jp.index/examples/query-tests/run-test.sh b/org.glite.jp.index/examples/query-tests/run-test.sh index 0e8ce22..2e27c08 100755 --- a/org.glite.jp.index/examples/query-tests/run-test.sh +++ b/org.glite.jp.index/examples/query-tests/run-test.sh @@ -63,7 +63,6 @@ init() { GLITE_JPIS_TEST_PORT=${GLITE_JPIS_TEST_PORT:-"10000"} GLITE_JPIS_TEST_PIDFILE=${GLITE_JPIS_TEST_PIDFILE:-"/tmp/glite-jp-indexd.pid"} GLITE_JPIS_TEST_LOGFILE=${GLITE_JPIS_TEST_LOGFILE:-"/tmp/glite-jp-indexd.log"} - GLITE_JPIS_TEST_CONFIG=${GLITE_JPIS_TEST_CONFIG:-"$GLITE_LOCATION/etc/glite-jpis-config.xml"} if [ -z "$GLITE_JPIS_TEST_DB" ]; then GLITE_JPIS_TEST_DB="jpis/@localhost:jpis1test" @@ -108,8 +107,7 @@ run_is() { # run index server X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \ $GLITE_LOCATION/bin/glite-jp-indexd -m $GLITE_JPIS_TEST_DB -p $GLITE_JPIS_TEST_PORT \ - -i ${GLITE_JPIS_TEST_PIDFILE} -o ${GLITE_JPIS_TEST_LOGFILE} \ - -x ${GLITE_JPIS_TEST_CONFIG} $1\ + -i ${GLITE_JPIS_TEST_PIDFILE} -o ${GLITE_JPIS_TEST_LOGFILE} $1\ 2>/dev/null @@ -146,7 +144,7 @@ run_test_query() { X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \ $GLITE_LOCATION/examples/glite-jpis-client -f xml -q $1 \ -i http://localhost:$GLITE_JPIS_TEST_PORT &>/tmp/result - DIFF=`diff -b --ignore-matching-lines="query: using JPIS" $2 /tmp/result` + DIFF=`diff --ignore-matching-lines="query: using JPIS" $2 /tmp/result` if [ -z "$DIFF" -a "$?" -eq "0" ] ; then echo "OK." rm /tmp/result @@ -173,8 +171,7 @@ run_test_query() { run_test_feed() { # run the example numok=`X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT}\ - $GLITE_LOCATION/examples/glite-jpis-test -p $GLITE_JPIS_TEST_PORT \ - -m $GLITE_JPIS_TEST_DB -x $GLITE_JPIS_TEST_CONFIG | grep -c OK` + $GLITE_LOCATION/examples/glite-jpis-test -p $GLITE_JPIS_TEST_PORT -m $GLITE_JPIS_TEST_DB ` if [ "$numok" -eq "2" ]; then echo OK. else @@ -222,18 +219,4 @@ run_test_query $GLITE_LOCATION/examples/query-tests/simple_query.in $GLITE_LOCAT drop_db; kill_is; -echo -n "Query jobId test........... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/jobid_query.in $GLITE_LOCATION/examples/query-tests/jobid_query.out; -drop_db; -kill_is; -echo -n "Origin test........... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/origin_query.in $GLITE_LOCATION/examples/query-tests/origin_query.out; -drop_db; -kill_is; diff --git a/org.glite.jp.index/examples/query-tests/simple_query.out b/org.glite.jp.index/examples/query-tests/simple_query.out index 7cd54fb..c3edb73 100644 --- a/org.glite.jp.index/examples/query-tests/simple_query.out +++ b/org.glite.jp.index/examples/query-tests/simple_query.out @@ -2,8 +2,7 @@ query: using JPIS http://localhost:10000 Conditions: http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Ready + == Ready Attributes: http://egee.cesnet.cz/en/Schema/JP/System:owner http://egee.cesnet.cz/en/Schema/JP/System:jobId @@ -11,4 +10,4 @@ Attributes: http://egee.cesnet.cz/en/Schema/LB/Attributes:user OK -https://localhost:7846/pokus2OwnerNamehttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusReady1970-01-01T02:00:01ZSYSTEMhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1970-01-01T02:00:01ZSYSTEMhttp://localhost:8901 +https://localhost:7846/pokus2OwnerNamehttp://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusReady1969-12-31T23:00:00ZSYSTEMhttp://egee.cesnet.cz/en/Schema/LB/Attributes:userCertSubj1969-12-31T23:00:00ZSYSTEMhttp://localhost:8901 \ No newline at end of file diff --git a/org.glite.jp.index/src/conf.c b/org.glite.jp.index/src/conf.c index 4b685bc..3d29aac 100644 --- a/org.glite.jp.index/src/conf.c +++ b/org.glite.jp.index/src/conf.c @@ -9,6 +9,10 @@ #include #include +/* XXX: makes the stuff build, together with #include "jpis_C.h" + * but I have no idea whether it works */ +#define SOAP_FMAC3 static +#define WITH_NOGLOBAL #include #include @@ -16,9 +20,10 @@ #include "db_ops.h" #include "ws_is_typeref.h" +//#include +//#include "soap_version.h" +// #include "jpis_H.h" -#define SOAP_FMAC3 static -#define WITH_NOGLOBAL #include "jpis_C.c" extern SOAP_NMAC struct Namespace jpis__namespaces[]; @@ -103,6 +108,90 @@ int glite_jp_get_conf(int argc, char **argv, char *config_file, glite_jp_is_conf fprintf(stderr,"JP IS configuration file must be specified! "\ "Exiting.\n"); return 1; +/* hardcoded configuration from 3.1 */ +#if 0 + // prefixes & attributes defined in: + // lb.server/build/jp_job_attrs.h (created when build plugin) + // jp.common/interface/known_attr.h + + conf->attrs = calloc(29, sizeof(*conf->attrs)); + conf->attrs[0] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:owner"); + conf->attrs[1] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:jobId"); + conf->attrs[2] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:regtime"); + conf->attrs[3] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); + conf->attrs[4] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:aTag"); + conf->attrs[5] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes"); + conf->attrs[6] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:RB"); + conf->attrs[7] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CE"); + conf->attrs[8] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost"); + conf->attrs[9] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime"); + conf->attrs[10] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:NProc"); + conf->attrs[11] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); + conf->attrs[12] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate"); + conf->attrs[13] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount"); + conf->attrs[14] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType"); + conf->attrs[15] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs"); + conf->attrs[16] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory"); + conf->attrs[17] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory"); + conf->attrs[18] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:parent"); + conf->attrs[19] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_STAGE"); + conf->attrs[20] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_PROGRAM"); + conf->attrs[21] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_INPUT"); + conf->attrs[22] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_OUTPUT"); + conf->attrs[23] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_PARAM"); + conf->attrs[24] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_HEADER"); + conf->attrs[25] = strdup("http://egee.cesnet.cz/en/Schema/JP/Workflow:ancestor"); + conf->attrs[26] = strdup("http://egee.cesnet.cz/en/Schema/JP/Workflow:successor"); + conf->attrs[27] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:host"); + + conf->indexed_attrs = calloc(12, sizeof(*conf->indexed_attrs)); + conf->indexed_attrs[0] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:owner"); + conf->indexed_attrs[1] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:jobId"); + conf->indexed_attrs[2] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); + conf->indexed_attrs[3] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); + conf->indexed_attrs[4] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost"); + conf->indexed_attrs[5] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CE"); + conf->indexed_attrs[6] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:RB"); + conf->indexed_attrs[7] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_PROGRAM"); + conf->indexed_attrs[8] = strdup("http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_OUTPUT"); + conf->indexed_attrs[9] = strdup("http://egee.cesnet.cz/en/Schema/JP/Workflow:successor"); + conf->indexed_attrs[10] = strdup("http://egee.cesnet.cz/en/Schema/JP/Workflow:ancestor"); + + // XXX: some plugin names should come here in future + conf->plugins = NULL; + + if (!ps) { + // No JP PrimaryStrorage server specified in $GLITE_JPIS_PS -> skip feeds + conf->feeds = calloc(1, sizeof(*(conf->feeds))); + *configuration = conf; + return 0; + } + + /* ask for one feed */ + conf->feeds = calloc(2, sizeof(*(conf->feeds))); + + conf->feeds[0] = calloc(1, sizeof(**(conf->feeds))); + conf->feeds[0]->PS_URL = strdup(ps); + + // all job since Epoche + conf->feeds[0]->query = calloc(2,sizeof(*conf->feeds[0]->query)); + conf->feeds[0]->query[0] = calloc(2,sizeof(**conf->feeds[0]->query)); + conf->feeds[0]->query[0][0].attr = strdup("http://egee.cesnet.cz/en/Schema/JP/System:regtime"); + conf->feeds[0]->query[0][0].op = GLITE_JP_QUERYOP_GREATER; + conf->feeds[0]->query[0][0].value = strdup("0"); + + if (qt && !strcmp(qt,"both")) { + conf->feeds[0]->history = 1; + conf->feeds[0]->continuous = 1; + } + else if ( qt && (!strcmp(qt,"continuous") || !strcmp(qt,"cont")) ) { + conf->feeds[0]->history = 0; + conf->feeds[0]->continuous = 1; + } + else if ( qt && (!strcmp(qt,"history") || !strcmp(qt,"hist")) ) { + conf->feeds[0]->history = 1; + conf->feeds[0]->continuous = 0; +#endif } else { read_conf(conf, conf_file); diff --git a/org.glite.jp.index/src/context.c b/org.glite.jp.index/src/context.c index d6f1379..092fe28 100644 --- a/org.glite.jp.index/src/context.c +++ b/org.glite.jp.index/src/context.c @@ -10,28 +10,18 @@ int glite_jpis_init_context(glite_jpis_context_t *isctx, glite_jp_context_t jpctx, glite_jp_is_conf *conf) { char hname[512]; - char *op_args; if ((*isctx = calloc(sizeof(**isctx), 1)) != NULL) { (*isctx)->jpctx = jpctx; (*isctx)->conf = conf; globus_libc_gethostname(hname, sizeof hname); asprintf(&(*isctx)->hname, "https://%s:%s", hname, (conf && conf->port) ? conf->port : GLITE_JPIS_DEFAULT_PORT_STR); - - op_args = (*isctx)->op_args; - op_args[GLITE_JP_QUERYOP_WITHIN] = 2; - op_args[GLITE_JP_QUERYOP_UNDEF] = 0; - op_args[GLITE_JP_QUERYOP_EQUAL] = 1; - op_args[GLITE_JP_QUERYOP_LESS] = 1; - op_args[GLITE_JP_QUERYOP_GREATER] = 1; - op_args[GLITE_JP_QUERYOP_EXISTS] = 0; return 0; } else return ENOMEM; } void glite_jpis_free_context(glite_jpis_context_t ctx) { - if (!ctx) return; free(ctx->hname); free(ctx); } diff --git a/org.glite.jp.index/src/context.h b/org.glite.jp.index/src/context.h index d67445a..cd144fd 100644 --- a/org.glite.jp.index/src/context.h +++ b/org.glite.jp.index/src/context.h @@ -17,8 +17,6 @@ typedef struct _glite_jpis_context { void *param_expires; char *hname; - - char op_args[GLITE_JP_QUERYOP__LAST]; } *glite_jpis_context_t; typedef struct _slave_data_t{ diff --git a/org.glite.jp.index/src/db_ops.c b/org.glite.jp.index/src/db_ops.c index 44649a0..b7b5482 100644 --- a/org.glite.jp.index/src/db_ops.c +++ b/org.glite.jp.index/src/db_ops.c @@ -60,24 +60,23 @@ static int is_indexed(glite_jp_is_conf *conf, const char *attr) { } -static size_t db_arg1_length(glite_jpis_context_t isctx, glite_jp_query_rec_t *query) { +static size_t db_arg2_length(glite_jp_query_rec_t *query) { size_t len; assert(query->op > GLITE_JP_QUERYOP_UNDEF && query->op <= GLITE_JP_QUERYOP__LAST); - if (isctx->op_args[query->op] >= 1) - len = query->binary ? query->size : (query->value ? strlen(query->value) + 1 : 0); - else len = 0; - - return len; -} - -static size_t db_arg2_length(glite_jpis_context_t isctx, glite_jp_query_rec_t *query) { - size_t len; - - assert(query->op > GLITE_JP_QUERYOP_UNDEF && query->op <= GLITE_JP_QUERYOP__LAST); - if (isctx->op_args[query->op] >= 1) - len = query->binary ? query->size2 : (query->value2 ? strlen(query->value2) + 1 : 0); - else len = 0; + len = 0; + switch (query->op) { + case GLITE_JP_QUERYOP_WITHIN: + len = query->binary ? query->size2 : strlen(query->value2) + 1; + case GLITE_JP_QUERYOP_UNDEF: + case GLITE_JP_QUERYOP_EQUAL: + case GLITE_JP_QUERYOP_UNEQUAL: + case GLITE_JP_QUERYOP_LESS: + case GLITE_JP_QUERYOP_GREATER: + case GLITE_JP_QUERYOP_EXISTS: + case GLITE_JP_QUERYOP__LAST: + len = 0; + } return len; } @@ -142,7 +141,7 @@ static void *array_get(void **data, size_t data_len) { } -static int glite_jpis_db_queries_serialize(glite_jpis_context_t isctx, void **blob, size_t *len, glite_jp_query_rec_t **queries) { +static int glite_jpis_db_queries_serialize(void **blob, size_t *len, glite_jp_query_rec_t **queries) { size_t maxlen; glite_jp_query_rec_t *query; int ret; @@ -158,12 +157,12 @@ static int glite_jpis_db_queries_serialize(glite_jpis_context_t isctx, void **bl if ((ret = array_add_long(blob, len, &maxlen, query->op)) != 0) goto fail; if ((ret = array_add_long(blob, len, &maxlen, query->binary ? 1 : 0)) != 0) goto fail; - datalen = db_arg1_length(isctx, query); + datalen = query->binary ? query->size : strlen(query->value) + 1; if ((ret = array_add_long(blob, len, &maxlen, datalen)) != 0) goto fail; if (datalen) if ((ret = array_add(blob, len, &maxlen, query->value, datalen)) != 0) goto fail; - datalen = db_arg2_length(isctx, query); + datalen = db_arg2_length(query); if ((ret = array_add_long(blob, len, &maxlen, datalen)) != 0) goto fail; if (datalen) if ((ret = array_add(blob, len, &maxlen, query->value2, datalen)) != 0) goto fail; @@ -290,7 +289,7 @@ int glite_jpis_initDatabase(glite_jpis_context_t ctx) { // attrs table and attrid_* tables attrs = ctx->conf->attrs; i = 0; - if (attrs) while (attrs[i]) { + while (attrs[i]) { type_full = glite_jp_attrval_db_type_full(jpctx, attrs[i]); type_index = glite_jp_attrval_db_type_index(jpctx, attrs[i], INDEX_LENGTH); @@ -323,12 +322,12 @@ int glite_jpis_initDatabase(glite_jpis_context_t ctx) { if (glite_jp_db_prepare(jpctx, "INSERT INTO feeds (state, locked, source, condition) VALUES (?, ?, ?, ?)", &stmt, param, NULL) != 0) goto fail; feeds = ctx->conf->feeds; i = 0; - if (feeds) while (feeds[i]) { + while (feeds[i]) { state = (feeds[i]->history ? GLITE_JP_IS_STATE_HIST : 0) | (feeds[i]->continuous ? GLITE_JP_IS_STATE_CONT : 0); locked = 0; GLITE_JPIS_PARAM(source, source_len, feeds[i]->PS_URL); - assert(glite_jpis_db_queries_serialize(ctx, &conds, &conds_len, feeds[i]->query) == 0); + assert(glite_jpis_db_queries_serialize(&conds, &conds_len, feeds[i]->query) == 0); assert(conds_len <= sizeof(dbconds)); dbconds_len = conds_len; memcpy(dbconds, conds, conds_len); diff --git a/org.glite.jp.index/src/soap_ops.c b/org.glite.jp.index/src/soap_ops.c index 2c29a25..123fc2e 100644 --- a/org.glite.jp.index/src/soap_ops.c +++ b/org.glite.jp.index/src/soap_ops.c @@ -6,7 +6,6 @@ #include "glite/jp/context.h" #include "glite/jp/strmd5.h" #include "glite/jp/attr.h" -#include "glite/jp/known_attr.h" #include "glite/lb/trio.h" #include "jpis_H.h" @@ -183,8 +182,7 @@ static int checkIndexedConditions(glite_jpis_context_t ctx, struct _jpelem__Quer for (k=0; k < in->__sizeconditions; k++) { for (j=0; j < i; j++) { - char *attr = in->conditions[k]->attr; - if (!strcmp(attr, GLITE_JP_ATTR_JOBID) || !strcmp(attr, indexed_attrs[j])) { + if (!strcmp(in->conditions[k]->attr, indexed_attrs[j])) { ret = 0; goto end; } @@ -247,60 +245,65 @@ static int get_jobids(struct soap *soap, glite_jpis_context_t ctx, struct _jpele int i, j, ret; glite_jp_db_stmt_t stmt; glite_jp_attrval_t attr; - glite_jp_attr_orig_t orig; qwhere = strdup(""); for (i=0; i < in->__sizeconditions; i++) { - { - /* attr name */ - if (strcmp(in->conditions[i]->attr, GLITE_JP_ATTR_JOBID) == 0) { - /* no subset from attr_ table, used jobs table instead */ - attr_md5 = NULL; - qa = strdup("("); - } else { - attr_md5 = str2md5(in->conditions[i]->attr); - - /* origin */ - if (in->conditions[i]->origin) { - glite_jpis_SoapToAttrOrig(soap, in->conditions[i]->origin, &orig); - trio_asprintf(&qb, "attr_%|Ss.origin = %d AND ", attr_md5, orig); - } else - trio_asprintf(&qb, ""); - - /* select given records in attr_ table */ - trio_asprintf(&qa,"%s%s jobs.jobid = attr_%|Ss.jobid AND (", - (i ? "AND" : ""), qb, attr_md5); - - free(qb); - } +/* XXX: deal with jobIds diferently (they are not in attr_X table, but in jobs) + if (strcmp(in->conditions[i]->attr,GLITE_JP_ATTR_JOBID)) { + trio_asprintf(&qa,"%s (", (i ? "AND" : "") ); - /* inside part of the condition: record list (ORs) */ - for (j=0; j < in->conditions[i]->__sizerecord; j++) { + for (j=0; j < in->conditions[i]->__sizerecord; j++) { if (get_op(in->conditions[i]->record[j]->op, &qop)) goto err; - if (attr_md5) add_attr_table(attr_md5, &attr_tables); attr.name = in->conditions[i]->attr; + attr.value = in->conditions[i]->record[j]->value->string; + attr.binary = 0; + glite_jpis_SoapToAttrOrig(soap, + in->conditions[i]->origin, &(attr.origin)); + trio_asprintf(&qb,"%s%sjobs.dg_jobid %s \"%|Ss\"", + qa, (j ? " OR " : ""), attr_md5, qop, + glite_jp_attrval_to_db_index(ctx->jpctx, &attr, 255)); + free(qop); + free(qa); qa = qb; qb = NULL; + + } + else +*/ + { + attr_md5 = str2md5(in->conditions[i]->attr); + trio_asprintf(&qa,"%s jobs.jobid = attr_%|Ss.jobid AND (", + (i ? "AND" : ""), attr_md5); + + for (j=0; j < in->conditions[i]->__sizerecord; j++) { + if (get_op(in->conditions[i]->record[j]->op, &qop)) goto err; + add_attr_table(attr_md5, &attr_tables); + if (in->conditions[i]->record[j]->value->string) { + attr.name = in->conditions[i]->attr; attr.value = in->conditions[i]->record[j]->value->string; attr.binary = 0; - } else { - attr.value = in->conditions[i]->record[j]->value->blob->__ptr; - attr.size = in->conditions[i]->record[j]->value->blob->__size; - attr.binary = 1; - } - glite_jpis_SoapToAttrOrig(soap, - in->conditions[i]->origin, &(attr.origin)); - if (strcmp(in->conditions[i]->attr, GLITE_JP_ATTR_JOBID) == 0) { - trio_asprintf(&qb,"%s%sjobs.dg_jobid %s \"%|Ss\"", - qa, (j ? " OR " : ""), qop, attr.value); - } else { + glite_jpis_SoapToAttrOrig(soap, + in->conditions[i]->origin, &(attr.origin)); trio_asprintf(&qb,"%s%sattr_%|Ss.value %s \"%|Ss\"", qa, (j ? " OR " : ""), attr_md5, qop, glite_jp_attrval_to_db_index(ctx->jpctx, &attr, 255)); + free(qop); + free(qa); qa = qb; qb = NULL; + } + else { + attr.name = in->conditions[i]->attr; + attr.value = in->conditions[i]->record[j]->value->blob->__ptr; + attr.binary = 1; + attr.size = in->conditions[i]->record[j]->value->blob->__size; + glite_jpis_SoapToAttrOrig(soap, + in->conditions[i]->origin, &(attr.origin)); + trio_asprintf(&qb,"%s %s attr_%|Ss.value %s \"%|Ss\"", + qa, (j ? "OR" : ""), attr_md5, qop, + glite_jp_attrval_to_db_index(ctx->jpctx, &attr, 255)); + free(qop); + free(qa); qa = qb; qb = NULL; } - free(qop); - free(qa); qa = qb; qb = NULL; } trio_asprintf(&qb,"%s %s)", qwhere, qa); free(qa); qwhere = qb; qb = NULL; qa = NULL; @@ -316,10 +319,10 @@ static int get_jobids(struct soap *soap, glite_jpis_context_t ctx, struct _jpele } if (ctx->conf->no_auth) { - trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs%s WHERE %s", qa, qwhere); + trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs%s WHERE %s;", qa, qwhere); } else { - trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs,users%s WHERE (jobs.ownerid = users.userid AND users.cert_subj='%s') AND %s", qa, ctx->jpctx->peer, qwhere); + trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs,users%s WHERE (jobs.ownerid = users.userid AND users.cert_subj='%s') AND %s;", qa, ctx->jpctx->peer, qwhere); } printf("Incomming QUERY:\n %s\n", query); free(qwhere); @@ -387,7 +390,7 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch { glite_jp_attrval_t jav; struct jptype__attrValue **av = NULL;; - enum jptype__attrOrig *origin; + //enum jptype__attrOrig *origin; char *query, *fv, *jobid_md5, *attr_md5; int i, ret; glite_jp_db_stmt_t stmt; @@ -429,10 +432,12 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch else { av[i]->value->string = soap_strdup(soap, jav.value); } - av[i]->timestamp = jav.timestamp; - glite_jpis_AttrOrigToSoap(soap, jav.origin, &origin); - av[i]->origin = *origin; soap_dealloc(soap, origin); - av[i]->originDetail = soap_strdup(soap, jav.origin_detail); +// XXX: load timestamp and origin from DB +// need to add columns to DB +// av[i]->timestamp = jav.timestamp; +// glite_jpis_AttrOrigToSoap(soap, jav.origin, &origin); +// av[i]->origin = *origin; free(origin); +// av[i]->originDetail = soap_strdup(soap, jav.origin_detail); i++; freeAttval_t(jav); diff --git a/org.glite.jp.primary/Makefile b/org.glite.jp.primary/Makefile index 44cd51a..9b2efe0 100644 --- a/org.glite.jp.primary/Makefile +++ b/org.glite.jp.primary/Makefile @@ -28,19 +28,11 @@ GLOBUS_LIBS:=-L${globus_prefix}/lib \ -lglobus_common_${nothrflavour} \ -lglobus_gssapi_gsi_${nothrflavour} -ifneq (${classads_prefix},/usr) - classadslib := -L${classads_prefix}/lib -lclassad -endif - -CLASSADPLUGIN_LIBS:= ${classadslib} -lstdc++ - -CLASSADPLUGIN_LOBJS:= classad_plugin.lo - GLOBUS_CFLAGS:=-I${globus_prefix}/include/${nothrflavour} DEBUG:=-g -O0 -DDEBUG -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include ${GLOBUS_CFLAGS} -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql -I${classads_prefix}/include -I${libtar_prefix}/include +CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include ${GLOBUS_CFLAGS} -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql -I${classads_prefix}/include LDFLAGS:=-L${stagedir}/lib LINK:=libtool --mode=link ${CC} ${LDFLAGS} @@ -49,21 +41,24 @@ SOLINK:=libtool --mode=link ${CC} -module ${LDFLAGS} -rpath ${stagedir}/lib LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} INSTALL:=libtool --mode=install install +ifneq (${classads_prefix},/usr) + classadslib := -L${classads_prefix}/lib -lclassad +endif + daemon:=glite-jp-primarystoraged example:=jpps-test dag-deps ps_prefix:=jpps_ is_prefix:=jpis_ sample_jobs:=sample_job_aborted sample_job_cleared sample_job_tagged_done sample_job_waiting -plugins:=glite-jp-ftpdauth.la glite-jp-classad.la glite-jp-sandbox.la +plugins:=glite-jp-tags.la glite-jp-ftpdauth.la HDRS_I=file_plugin.h -HDRS_S=builtin_plugins.h backend.h feed.h utils.h +HDRS_S=builtin_plugins.h backend.h feed.h SRCS:= bones_server.c soap_ops.c \ - new_ftp_backend.c mysql.c file_plugin.c utils.c\ - feed.c authz.c attrs.c \ - tags.c\ + new_ftp_backend.c mysql.c file_plugin.c \ + feed.c authz.c attrs.c\ is_client.c \ soap_switch.c @@ -80,11 +75,10 @@ TEST_OBJS:=${TEST_SRCS:.c=.o} DAG_OBJS:=${DAG_SRCS:.c=.o} dotless_soap_ver:=${shell echo ${gsoap_version} | tr -d . } -COMMONLIB:=-lglite_jp_common_${nothrflavour} +COMMONLIB:=-lglite_jp_common BONESLIB:=-lglite_lb_server_bones GSOAPLIB:=-L${stagedir}/lib -lglite_security_gsoap_plugin_${dotless_soap_ver}_${nothrflavour} TRIOLIB:=-lglite_jp_trio -LIBTARLIB:=-L${libtar_prefix}/lib -ltar ifneq (${mysql_prefix},/usr) ifeq ($(shell test -f ${mysql_prefix}/lib/libmysqlclient.a -o -f ${mysql_prefix}/lib/libmysqlclient.so && echo ok),ok) @@ -109,6 +103,7 @@ jpps-test: ${TEST_OBJS} dag-deps: ${DAG_OBJS} ${LINKXX} -o $@ ${DAG_OBJS} ${classadslib} ${GSOAPLIB} + JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat cp ${stagedir}/interface/JobProvenanceTypes.wsdl . ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< @@ -119,8 +114,6 @@ JobProvenanceIS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< rm -f JobProvenanceTypes.wsdl -glite-jp-classad.la: ${CLASSADPLUGIN_LOBJS} - ${SOLINK} -o $@ ${CLASSADPLUGIN_LOBJS} ${CLASSADPLUGIN_LIBS} ${ps_prefix}Client.c ${ps_prefix}ClientLib.c \ ${ps_prefix}Server.c ${ps_prefix}ServerLib.c \ @@ -203,15 +196,12 @@ simple_server.o soap_ops.o jpps-test.o: ${ps_prefix}H.h # ${CC} -o $@ -c -DWITH_NONAMESPACES -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c # -glite-jp-sandbox.la: sandbox_plugin.lo - ${SOLINK} -o $@ sandbox_plugin.lo ${LIBTARLIB} +glite-jp-tags.la: tags_plugin.lo + ${SOLINK} -o $@ tags_plugin.lo glite-jp-ftpdauth.la: ftpd_auth.lo mysql.lo ${SOLINK} -o $@ ftpd_auth.lo mysql.lo ${COMMONLIB} ${TRIOLIB} ${MYSQLIB} -#glite-jp-classad.lo: classad_plugin.c -# ${LTCOMPILE} -DPLUGIN_DEBUG -o $@ -c $< - %.lo: %.c ${LTCOMPILE} -o $@ -c $< diff --git a/org.glite.jp.primary/config/startup b/org.glite.jp.primary/config/startup index c08da87..e7120ed 100644 --- a/org.glite.jp.primary/config/startup +++ b/org.glite.jp.primary/config/startup @@ -69,7 +69,7 @@ start() echo -n Starting glite-jp-primarystoraged ... su - $GLITE_USER -c " $GLITE_LOCATION/bin/glite-jp-primarystoraged \ $GLITE_JP_DEBUG \ - -P $GLITE_LOCATION/lib/glite-jp-tags.so -P $GLITE_LOCATION/lib/glite_lb_plugin.so -P $GLITE_LOCATION/lib/glite-jp-sandbox.so \ + -P $GLITE_LOCATION/lib/glite-jp-tags.so -P $GLITE_LOCATION/lib/glite_lb_plugin.so \ $creds -a '$GLITE_JP_PRIMARY_PEERS' \ -i '$pidfile' -p $GLITE_JP_PRIMARY_PORT $GLITE_JP_PRIMARY_SPECIAL \ -BI,'$GLITE_JP_PRIMARY_INTERNAL' -BE,'$GLITE_JP_PRIMARY_EXTERNAL' \ diff --git a/org.glite.jp.primary/examples/jpps-test.c b/org.glite.jp.primary/examples/jpps-test.c index 6add9c4..0710c78 100644 --- a/org.glite.jp.primary/examples/jpps-test.c +++ b/org.glite.jp.primary/examples/jpps-test.c @@ -120,15 +120,11 @@ int main(int argc,char *argv[]) soap_register_plugin(soap,glite_gsplugin); - /*while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { + while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { case 's': server = optarg; break; - //case '?': usage(argv[0]); - }*/ - int i; - for (i = 0; i < argc-1; i++) - if (strcmp(argv[i], "-s") == 0) - server = argv[i+1]; + case '?': usage(argv[0]); + } if (server) { argv += 2; @@ -136,7 +132,6 @@ int main(int argc,char *argv[]) } else server = "http://localhost:8901"; - if (!strcasecmp(argv[1],"RegisterJob")) { struct _jpelem__RegisterJob in; struct _jpelem__RegisterJobResponse empty; @@ -285,12 +280,11 @@ int main(int argc,char *argv[]) puts("Attribute values:"); for (i=0; ivalue->string ? out.attrValues[i]->value->string : "binary", orig2str(out.attrValues[i]->origin), - out.attrValues[i]->originDetail, ctime(&out.attrValues[i]->timestamp)); } diff --git a/org.glite.jp.primary/interface/file_plugin.h b/org.glite.jp.primary/interface/file_plugin.h index f322d4d..6bf22d2 100644 --- a/org.glite.jp.primary/interface/file_plugin.h +++ b/org.glite.jp.primary/interface/file_plugin.h @@ -12,26 +12,13 @@ typedef struct _glite_jpps_fplug_op_t { \param[out] handle Handle to the opened file structure, to be passed to other plugin functions. */ int (*open)(void *fpctx,void *bhandle,const char *uri,void **handle); -/** Open from a string. -\param[in] fpctx Context of the plugin, returned by its init. -\param[in] str The string to use. -\param[in] uri URI (type) of the string -\param[in] ns namespace to handle -\param[out] handle Handle to the opened file structure, to be passed to other plugin functions. -*/ - - int (*open_str)(void *fpctx,const char *str,const char *uri,const char *ns,void **handle); /** Close the file. Free data associated to a handle */ int (*close)(void *fpctx,void *handle); -/** "Preprocess" the file -- this function is called once after the file is commited */ - int (*filecom)(void *fpctx,void *handle); - /** Retrieve value(s) of an attribute. \param[in] fpctx Plugin context. \param[in] handle Handle of the opened file. -\param[in] ns Namespace of queried attribute. \param[in] attr Queried attribute. \param[out] attrval GLITE_JP_ATTR_UNDEF-terminated list of value(s) of the attribute. If there are more and there is an interpretation of their order @@ -40,7 +27,7 @@ typedef struct _glite_jpps_fplug_op_t { \retval ENOSYS this attribute is not defined by this type of file \retval ENOENT no value is present */ - int (*attr)(void *fpctx,void *handle, const char *attr,glite_jp_attrval_t **attrval); + int (*attr)(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval); /** File type specific operation. \param[in] fpctx Plugin context. diff --git a/org.glite.jp.primary/project/configure.properties.xml b/org.glite.jp.primary/project/configure.properties.xml index cfa060a..53515a6 100644 --- a/org.glite.jp.primary/project/configure.properties.xml +++ b/org.glite.jp.primary/project/configure.properties.xml @@ -12,9 +12,6 @@ Revision history: $Log$ - Revision 1.7 2006/10/10 17:36:32 akrenek - merge from 3.1 - Revision 1.6.4.1 2006/08/28 18:49:23 akrenek pch06 tool to generate subjob relationships from DAG JDL @@ -79,7 +76,6 @@ cppunit=${with.cppunit.prefix} jpproject=${subsystem.project.dir} project=${component.project.dir} classads_prefix=${with.classads.prefix} -libtar_prefix=${with.libtar.prefix} diff --git a/org.glite.jp.primary/src/attrs.c b/org.glite.jp.primary/src/attrs.c index a25eada..7099dd1 100644 --- a/org.glite.jp.primary/src/attrs.c +++ b/org.glite.jp.primary/src/attrs.c @@ -10,53 +10,50 @@ #include "feed.h" #include "backend.h" #include "attrs.h" -#include "utils.h" #include "file_plugin.h" #include "builtin_plugins.h" static struct { - char *namespace; - glite_jpps_fplug_data_t **plugins; - int nplugins; + char *class,*uri; + glite_jpps_fplug_data_t **plugins; + int nplugins; +} *known_classes; -} *known_namespaces; +static int tags_index; -static void scan_namespaces(glite_jp_context_t ctx) + +static void scan_classes(glite_jp_context_t ctx) { - int i,j,k; - glite_jpps_fplug_data_t *pd; + int i,j,k; + glite_jpps_fplug_data_t *pd; if (!ctx->plugins) return; - for (i=0; ctx->plugins[i]; i++) { - pd = ctx->plugins[i]; - - if (pd->namespaces){ - for (j=0; pd->namespaces[j]; j++) { - for (k=0; known_namespaces && known_namespaces[k].namespace - && strcmp(pd->namespaces[j],known_namespaces[k].namespace); k++) {}; - - if (known_namespaces && known_namespaces[k].namespace) { - printf("Adding new plugin into namespace %s\n", known_namespaces[k].namespace); - known_namespaces[k].plugins = realloc(known_namespaces[k].plugins, - (known_namespaces[k].nplugins + 2) * sizeof(glite_jpps_fplug_data_t *)); - known_namespaces[k].plugins[known_namespaces[k].nplugins++] = pd; - known_namespaces[k].plugins[known_namespaces[k].nplugins] = NULL; - known_namespaces[k].namespace = pd->namespaces[j]; - } - else { - printf("Adding new namespace %s\n", pd->namespaces[j]); - known_namespaces = realloc(known_namespaces,(k+2) * sizeof *known_namespaces); - known_namespaces[k].plugins = malloc(2 * sizeof(glite_jpps_fplug_data_t *)); - known_namespaces[k].plugins[0] = pd; - known_namespaces[k].plugins[1] = NULL; - known_namespaces[k].nplugins = 1; - known_namespaces[k].namespace = pd->namespaces[j]; - memset(known_namespaces+k+1,0,sizeof *known_namespaces); - } - } + pd = ctx->plugins[i]; + + for (j=0; pd->classes[j]; j++) { + for (k=0; known_classes && known_classes[k].class + && strcmp(pd->classes[j],known_classes[k].class); + k++); + if (known_classes && known_classes[k].class) { + known_classes[k].plugins = realloc(known_classes[k].plugins, + (known_classes[k].nplugins + 2) * sizeof(glite_jpps_fplug_data_t *)); + known_classes[k].plugins[known_classes[k].nplugins++] = pd; + known_classes[k].plugins[known_classes[k].nplugins] = NULL; + } + else { + known_classes = realloc(known_classes,(k+2) * sizeof *known_classes); + known_classes[k].class = pd->classes[j]; + known_classes[k].uri = pd->uris[j]; + known_classes[k].plugins = malloc(2 * sizeof(glite_jpps_fplug_data_t *)); + known_classes[k].plugins[0] = pd; + known_classes[k].plugins[1] = NULL; + known_classes[k].nplugins = 1; + memset(known_classes+k+1,0,sizeof *known_classes); + if (!strcmp(known_classes[k].uri,GLITE_JP_FILETYPE_TAGS)) tags_index = k; + } } - } + } } static int merge_attrvals(glite_jp_attrval_t **out,int nout,const glite_jp_attrval_t *in) @@ -68,48 +65,20 @@ static int merge_attrvals(glite_jp_attrval_t **out,int nout,const glite_jp_attrv for (nin=0; in[nin].name; nin++); *out = realloc(*out,(nout+nin+1) * sizeof **out); memcpy(*out + nout,in,(nin+1) * sizeof **out); - memset(*out + nout+nin, 0, sizeof **out); return nout+nin; } -void process_files(glite_jp_context_t ctx, const char *job, glite_jp_attrval_t** out, int* nout, const char* attr, const glite_jpps_fplug_data_t* plugin, const char* class, const char* uri){ - void *ph, *beh; - char** names = NULL; - int nnames = glite_jppsbe_get_names(ctx, job, class, &names); - int n; - glite_jp_error_t *keep_err = NULL; - - for (n = 0; n < nnames; n++) - if (! glite_jppsbe_open_file(ctx,job,class, names[n], O_RDONLY, &beh)) { - if (!plugin->ops.open(plugin->fpctx,beh,uri,&ph)) { - glite_jp_attrval_t* myattr; - // XXX: ignore errors - if (!plugin->ops.attr(plugin->fpctx,ph,attr,&myattr) && myattr) { - int k; - for (k=0; myattr[k].name; k++) { - myattr[k].origin = GLITE_JP_ATTR_ORIG_FILE; - if (!myattr[k].origin_detail) - trio_asprintf(&myattr[k].origin_detail,"%s %s", uri, names[n] ? names[n] : ""); - } - *nout = merge_attrvals(out,*nout,myattr); - free(myattr); - } - keep_err = ctx->error; ctx->error = NULL; - plugin->ops.close(plugin->fpctx, ph); - if (keep_err) { ctx->error = keep_err; keep_err = NULL; } - } - keep_err = ctx->error; ctx->error = NULL; - glite_jppsbe_close_file(ctx,beh); - if (keep_err) { ctx->error = keep_err; keep_err = NULL; } - } -} - glite_jpps_get_attrs(glite_jp_context_t ctx,const char *job,char **attr,int nattr,glite_jp_attrval_t **attrs_out) { - glite_jp_attrval_t *meta = NULL,*out = NULL,*tag_out = NULL; + glite_jp_attrval_t *meta = NULL,*out = NULL; char const **other = NULL; int i,j,nmeta,nother,err = 0,nout = 0; + struct { int class_idx; + char *name; + } *files = NULL; + int nfiles = 0; + nmeta = nother = 0; glite_jp_clear_error(ctx); @@ -133,38 +102,87 @@ glite_jpps_get_attrs(glite_jp_context_t ctx,const char *job,char **attr,int natt /* retrieve the metadata */ if (meta && (err = glite_jppsbe_get_job_metadata(ctx,job,meta))) goto cleanup; - if (!known_namespaces) scan_namespaces(ctx); - -/* loop over the attributes */ - int k, l, m; - void* beh; - for (i = 0; i < nother; i++){ - if (! glite_jppsbe_read_tag(ctx, job, other[i], &tag_out)) { - nout = merge_attrvals(&out, nout, tag_out); - free(tag_out); tag_out = NULL; + if (!known_classes) scan_classes(ctx); + +/* build a list of available files for this job */ + files = malloc(sizeof *files); + files->class_idx = tags_index; + files->name = NULL; + nfiles = 1; + + for (i=0; known_classes[i].class; i++) { + char **names = NULL; + int nnames = + glite_jppsbe_get_names(ctx,job,known_classes[i].class,&names); + if (nnames < 0) continue; /* XXX: error ignored */ + + if (nnames > 0) { + files = realloc(files,(nfiles+nnames+1) * sizeof *files); + for (j=0; jclasses[l]; l++) - process_files(ctx, job, &out, &nout, other[i], known_namespaces[j].plugins[k] - , known_namespaces[j].plugins[k]->classes[l] - , known_namespaces[j].plugins[k]->uris[l]); - break; + free(names); + } + +/* loop over the files */ + for (i=0; iops.open(p->fpctx,beh,known_classes[ci].uri,&ph)) { + + for (j=0; jops.attr(p->fpctx,ph,other[j],&myattr)) { + int k; + for (k=0; myattr[k].name; k++) { + myattr[k].origin = GLITE_JP_ATTR_ORIG_FILE; + trio_asprintf(&myattr[k].origin_detail,"%s %s", + known_classes[ci].uri, + files[i].name ? files[i].name : ""); + } + nout = merge_attrvals(&out,nout,myattr); + free(myattr); + } + + } + p->ops.close(p->fpctx,ph); + } + else { + char *e; + fprintf(stderr,"[%d] %s: %s\n",getpid(),known_classes[ci].class, + e = glite_jp_error_chain(ctx)); + free(e); + } } - free(attr_namespace); + + glite_jppsbe_close_file(ctx,beh); + } + else { + char *e; + fprintf(stderr,"[%d] %s: %s\n",getpid(),known_classes[ci].class, + e = glite_jp_error_chain(ctx)); + free(e); } } nout = merge_attrvals(&out,nout,meta); - free(meta); meta = NULL; - for (i = 0; i < nout; i++) - printf("%s\n", out[i].value); - if (nout) { *attrs_out = out; err = 0; @@ -183,6 +201,8 @@ cleanup: free(other); + if (files) for (i=0; i -#include #include #include "feed.h" @@ -75,12 +74,6 @@ int glite_jppsbe_close_file( void *handle ); -int glite_jppsbe_file_attrs( - glite_jp_context_t ctx, - void *handle, - struct stat *buf -); - int glite_jppsbe_pread( glite_jp_context_t ctx, void *handle, diff --git a/org.glite.jp.primary/src/builtin_plugins.h b/org.glite.jp.primary/src/builtin_plugins.h index 70d900b..3b2c201 100644 --- a/org.glite.jp.primary/src/builtin_plugins.h +++ b/org.glite.jp.primary/src/builtin_plugins.h @@ -1,8 +1,7 @@ -#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags" -#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb" -#define GLITE_JP_FILETYPE_CLASSAD "urn:org.glite.jp.primary:classad" -#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb" -#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb" +#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags" +#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb" +#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb" +#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb" #define GLITE_JP_FPLUG_TAGS_APPEND 0 diff --git a/org.glite.jp.primary/src/classad_plugin.c b/org.glite.jp.primary/src/classad_plugin.c deleted file mode 100644 index b0cde22..0000000 --- a/org.glite.jp.primary/src/classad_plugin.c +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "glite/lb/context.h" -#include "glite/lb/jobstat.h" -#include "glite/lb/events.h" -#include "glite/lb/events_parse.h" -#include "glite/lb/trio.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/attr.h" -#include "glite/jp/known_attr.h" - -#include "file_plugin.h" -#include "builtin_plugins.h" -#include "backend.h" - -//#define INITIAL_NUMBER_EVENTS 100 -//#define INITIAL_NUMBER_STATES EDG_WLL_NUMBER_OF_STATCODES -//#define LB_PLUGIN_NAMESPACE "urn:org.glite.lb" - -//extern int processEvent(intJobStat *, edg_wll_Event *, int, int, char **); - - -typedef struct _classad_handle{ - char* data; - struct cclassad* ad; - time_t timestamp; -} classad_handle; - -static int classad_query(void *fpctx, void *handle, const char *attr, glite_jp_attrval_t **attrval); -static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle); -static int classad_open_str(void *fpctx, const char *str, const char *uri, const char *ns, void **handle); -static int classad_close(void *fpctx, void *handle); -static int classad_filecom(void *fpctx, void *handle); - -int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) { - data->fpctx = ctx; - - data->uris = calloc(2,sizeof *data->uris); - data->uris[0] = strdup(GLITE_JP_FILETYPE_CLASSAD); - - data->classes = calloc(2,sizeof *data->classes); - data->classes[0] = strdup("classad"); - - data->namespaces = calloc(2, sizeof *data->namespaces); - data->namespaces[0] = strdup(GLITE_JP_JDL_NS); - - data->ops.open = classad_open; - data->ops.close = classad_close; - data->ops.attr = classad_query; - data->ops.open_str = classad_open_str; - data->ops.filecom = classad_filecom; - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: init OK\n"); -#endif - - return 0; -} - - -void done(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) { - free(data->uris[0]); - free(data->classes[0]); - free(data->uris); - free(data->classes); - memset(data, 0, sizeof(*data)); -} - - -static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle) { - glite_jp_context_t ctx = (glite_jp_context_t) fpctx; - glite_jp_error_t err; - classad_handle* h; - void* fh; - int retval = 0; - - glite_jp_clear_error(ctx); - h = calloc(1, sizeof(classad_handle)); - h->data = NULL; - struct stat fattr; - glite_jppsbe_file_attrs(ctx, bhandle, &fattr); - h->timestamp = fattr.st_mtime; - - // read the classad file - char buf[1024]; - size_t nbytes; - off_t offset = 0; - - do{ - if (! (retval = glite_jppsbe_pread(ctx, bhandle, buf, sizeof buf, offset, &nbytes))){ - h->data = realloc(h->data, offset + nbytes); - memcpy(h->data + offset, buf, nbytes); - offset += nbytes; - } - else - goto fail; - }while(nbytes); - - h->ad = cclassad_create(h->data); - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: opened\n"); -#endif - - *handle = h; - - return 0; - -fail: - err.code = EIO; - err.desc = NULL; - err.source = __FUNCTION__; - glite_jp_stack_error(ctx,&err); - - return retval; -} - -static int classad_open_str(void *fpctx,const char *str,const char *uri,const char *ns,void **handle){ - classad_handle* h; - - h = calloc(1, sizeof(classad_handle)); - h->data = strdup(str); - h->ad = cclassad_create(h->data); - h->timestamp = 0; - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: opened\n"); -#endif - - *handle = h; - - return 0; - -} - -static int classad_close(void *fpctx,void *handle) { - classad_handle *h = (classad_handle *) handle; - - cclassad_delete(h->ad); - free(h->data); - free(h); - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad plugin: close OK\n"); -#endif - return 0; -} - - -static int classad_query(void *fpctx,void *handle, const char *attr,glite_jp_attrval_t **attrval) { - glite_jp_context_t ctx = (glite_jp_context_t) fpctx; - glite_jp_error_t err; - glite_jp_attrval_t *av = NULL; - classad_handle* h = (classad_handle*)handle; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - char *str = NULL; - - if (! h->ad){ - err.code = ENOENT; - err.desc = strdup("Classad plugin: No classad string, cannot get attr!"); - *attrval = NULL; - printf("Exiting classat_query...\n"); - return glite_jp_stack_error(ctx,&err); - } - - if (cclassad_evaluate_to_string(h->ad, strrchr(attr, ':')+1, &str)) { - //struct stat fattr; - /*XXX ignore error */ - //glite_jppsbe_file_attrs(ctx, h->bhandle, &fattr); - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = strdup(str); - av[0].size = -1; - av[0].timestamp = h->timestamp; - av[0].origin = GLITE_JP_ATTR_ORIG_FILE; - } - else{ - printf("Classad plugin: bad attr!\n"); - } - - if (str) free(str); - - *attrval = av; - - if (av) - return 0; - else{ - err.code = ENOENT; - err.desc = attr; - return glite_jp_stack_error(ctx,&err); - } -} - -static int classad_filecom(void *fpctx, void *handle){ - return -1; -} - diff --git a/org.glite.jp.primary/src/new_ftp_backend.c b/org.glite.jp.primary/src/new_ftp_backend.c index 227c134..27da176 100644 --- a/org.glite.jp.primary/src/new_ftp_backend.c +++ b/org.glite.jp.primary/src/new_ftp_backend.c @@ -1005,24 +1005,6 @@ error_out: } } -int glite_jppsbe_file_attrs(glite_jp_context_t ctx, void *handle, struct stat *buf){ - glite_jp_error_t err; - - assert(handle != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (! fstat(((fhandle)handle)->fd, buf)) { - err.code = errno; - err.desc = "Error calling fstat"; - return -1; - } - - return 0; -} - int glite_jppsbe_pread( glite_jp_context_t ctx, void *handle, @@ -2329,86 +2311,6 @@ cleanup: return err.code; } -int glite_jppsbe_append_tag( - void *fpctx, - char *jobid, - glite_jp_attrval_t *attr -) -{ - void *file_be; - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL, - O_RDWR|O_CREAT,&file_be) - // XXX: tags need reading to check magic number - ) { - err.code = EIO; - err.desc = "cannot open tags file"; - return glite_jp_stack_error(ctx,&err); - } - - if (tag_append(ctx,file_be,attr)) - { - err.code = EIO; - err.desc = "cannot append tag"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_close_file(ctx,file_be)) - { - err.code = EIO; - err.desc = "cannot close tags file"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - - -int glite_jppsbe_read_tag( - void *fpctx, - const char *jobid, - const char *attr, - glite_jp_attrval_t **attrval -) -{ - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - struct tags_handle *h; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - h = malloc(sizeof (*h)); - h->tags = NULL; - h->n = 0; - - if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL, - O_RDONLY,&(h->bhandle)) - // XXX: tags need reading to check magic number - ) { - err.code = EIO; - err.desc = "cannot open tags file"; - return glite_jp_stack_error(ctx,&err); - } - - if (tag_attr(ctx,h,attr,attrval)){ - err.code = EIO; - err.desc = "cannot read tag"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_close_file(ctx,h->bhandle)) - { - err.code = EIO; - err.desc = "cannot close tags file"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} diff --git a/org.glite.jp.primary/src/sandbox_plugin.c b/org.glite.jp.primary/src/sandbox_plugin.c deleted file mode 100644 index 680e277..0000000 --- a/org.glite.jp.primary/src/sandbox_plugin.c +++ /dev/null @@ -1,261 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "file_plugin.h" -#include "builtin_plugins.h" -#include "backend.h" - -#define ALLOC_CHUNK 3 - - -typedef struct _sb_handle { - void *bhandle; - TAR *t; - tartype_t *tt; - char **file_names; -} sb_handle; - -// Global data needed for read/write wrappers -static struct { - void *bhandle; - glite_jp_context_t ctx; - off_t offset; -} global_data; - - -//static int sandbox_append(void *,void *,int,...); -static int sandbox_open(void *,void *,const char *uri,void **); -static int sandbox_close(void *,void *); -static int sandbox_attr(void *,void *,const char *,glite_jp_attrval_t **); -static int sandbox_filecom(void *,void *); - -int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) -{ - data->fpctx = ctx; - global_data.ctx = ctx; - - data->uris = calloc(2,sizeof *data->uris); - data->uris[0] = strdup(GLITE_JP_FILETYPE_ISB); - - data->classes = calloc(2,sizeof *data->classes); - data->classes[0] = strdup("sandbox"); - - data->namespaces = calloc(5, sizeof *data->namespaces); - data->namespaces[0] = strdup(GLITE_JP_ISB_NS); - data->namespaces[1] = strdup(GLITE_JP_OSB_NS); - data->namespaces[2] = strdup(GLITE_JP_ISB_CONTENT_NS); - data->namespaces[3] = strdup(GLITE_JP_OSB_CONTENT_NS); - - data->ops.open = sandbox_open; - data->ops.close = sandbox_close; - data->ops.attr = sandbox_attr; - data->ops.filecom = sandbox_filecom; - - printf("sandbox_plugin: URI: \"%s\"\n",GLITE_JP_FILETYPE_ISB); - - return 0; -} - - -/** -* Wrappers for tar_open -*/ -static int my_open(const char *pathname, int flags, ...) { - // Do not open file, it is opened in ftp_backend - // returned fd does not matter, read/write/close does ftp_backend - return 12345; -} - -static int my_close(int fd) { - // Closed in ftp_backend - return 0; -} - -static ssize_t my_read(int fd, void *buf, size_t count) { - // wrapper around glite_jppsbe_pread - size_t r; - - if (glite_jppsbe_pread(global_data.ctx,global_data.bhandle,buf,count,global_data.offset,&r)) { - errno = global_data.ctx->error->code; - return -1; - } - - global_data.offset += r; - - return r; -} - -static ssize_t my_write(int fd, const void *buf, size_t count) { - // wrapper around glite_jppsbe_pwrite - // just stub, not needed here&now -} - - - -static int sandbox_open(void *fpctx,void *bhandle,const char *uri,void **handle) -{ - sb_handle *h = calloc(1,sizeof *h); - - - printf("sandbox_open() called\n"); - - h->bhandle = bhandle; - global_data.bhandle = bhandle; - global_data.offset = 0; - - h->tt = malloc(sizeof(*h->tt)); - h->tt->openfunc = my_open; - h->tt->closefunc = my_close; - h->tt->readfunc = my_read; - h->tt->writefunc = my_write; - - if (tar_open(&h->t, NULL /* not needed, opened in ftp_backend */, h->tt, O_RDONLY, 0, TAR_GNU) == -1) - printf("tar_open()\n"); //XXX: use glite_jp_stack_error - - *handle = h; - - return 0; -} - - -static int sandbox_close(void *fpctx,void *handle) -{ - int i; - sb_handle *h = handle; - - tar_close(h->t); - free(h->tt); - - for (i=0; h->file_names; i++) free(h->file_names[i]); - free(h->file_names); - - free(h); - - printf("sandbox_close() called\n"); - - return 0; -} - - -static int sandbox_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval) -{ - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - glite_jp_attrval_t *out = NULL; - int i,nout = 0, count = 0; - sb_handle *h = handle; - - - printf("sandbox_attr() called\n"); - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - *attrval = NULL; - - if (!strcmp(attr, GLITE_JP_ATTR_ISB_FILENAME)) { - while ((i = th_read(h->t)) == 0) - { - printf("-- %s\n", th_get_pathname(h->t)); - - if ( !(count % ALLOC_CHUNK) ) { - *attrval = realloc(*attrval, (count + ALLOC_CHUNK + 1) * sizeof(**attrval) ); - memset( (*attrval) + count, 0, (ALLOC_CHUNK + 1) * sizeof(**attrval)); - } - (*attrval)[count].name = strdup(GLITE_JP_ATTR_ISB_FILENAME); - (*attrval)[count].value = strdup(th_get_pathname(h->t)); - (*attrval)[count].origin = GLITE_JP_ATTR_ORIG_FILE; - (*attrval)[count].timestamp = th_get_mtime(h->t); - - count++; - - if (TH_ISREG(h->t) && tar_skip_regfile(h->t) != 0) - { - err.code = EIO; - err.desc = "tar_skip_regfile"; - return glite_jp_stack_error(ctx,&err); - } - } - } - else if (!strcmp(attr, GLITE_JP_ATTR_OSB_FILENAME)) { - printf("Namespace %s not implemented yet\n", GLITE_JP_ATTR_OSB_FILENAME); - } - else if (strstr(attr,GLITE_JP_OSB_CONTENT_NS)) { - printf("Namespace %s not implemented yet\n", GLITE_JP_OSB_CONTENT_NS); - } - else if (strstr(attr,GLITE_JP_ISB_CONTENT_NS)) { - char *fileName = (char *) attr + sizeof(GLITE_JP_ISB_CONTENT_NS); - - printf("untaring file: %s\n", fileName); - - while (th_read(h->t) == 0) - { - if ( !strcmp(fileName, th_get_pathname(h->t)) ) { - /* extract the file */ - int k; - size_t size; - char buf[T_BLOCKSIZE]; - char *value; - - - if (!TH_ISREG(h->t)) assert(0); // not a regular file - - size = th_get_size(h->t); - value = (char *) malloc(size * sizeof(char) + 1); - memset( value, 0, size * sizeof(char) + 1); - - for (i = 0; i < size; i += T_BLOCKSIZE) - { - k = tar_block_read(h->t, buf); - if (k == -1) - { - err.code = errno; - err.desc = "tar_block_read"; - return glite_jp_stack_error(ctx,&err); - } - - // tar_block_read calls glite_jppsbe_pread, which usually - // returns whole block (read from the middle of uploaded - // tar file - // so cut k in order to the last chunk had correct size - if (i + T_BLOCKSIZE > size) { - k = size - i; - } - - strncpy(value + i, buf, k); - } - *attrval = malloc(2 * sizeof(**attrval) ); - memset( (*attrval), 0, 2 * sizeof(**attrval)); - - (*attrval)[0].name = strdup(attr); - (*attrval)[0].value = value; - (*attrval)[0].origin = GLITE_JP_ATTR_ORIG_FILE; - (*attrval)[0].timestamp = th_get_mtime(h->t); - } - else if (TH_ISREG(h->t) && tar_skip_regfile(h->t) != 0) - { - err.code = EIO; - err.desc = "tar_skip_regfile"; - return glite_jp_stack_error(ctx,&err); - } - } - } - - return glite_jp_stack_error(ctx,&err); -} - -static int sandbox_filecom(void *fpctx,void *handle){ - return -1; -} - diff --git a/org.glite.jp.primary/src/soap_ops.c b/org.glite.jp.primary/src/soap_ops.c index ea1970b..d933311 100644 --- a/org.glite.jp.primary/src/soap_ops.c +++ b/org.glite.jp.primary/src/soap_ops.c @@ -182,27 +182,6 @@ SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__CommitUpload( /* XXX: ignore errors but don't fail silenty */ glite_jpps_match_file(ctx,job,class,name); - // apply plugins to commited file - glite_jpps_fplug_data_t *pd; - int i, j; - void *beh, *ph; - if (ctx->plugins) - for (i = 0; ctx->plugins[i]; i++) { - pd = ctx->plugins[i]; - if (pd->classes) - for (j = 0; pd->classes[j]; j++) - if (strcmp(class, pd->classes[j]) == 0){ - if (! glite_jppsbe_open_file(ctx,job,class, name, O_RDONLY, &beh)) { - if (!pd->ops.open(pd->fpctx,beh,pd->uris[j],&ph)) { - pd->ops.filecom(pd->fpctx, ph); - pd->ops.close(pd->fpctx, ph); - } - glite_jppsbe_close_file(ctx,beh); - } - - } - } - free(job); free(class); free(name); return SOAP_OK; @@ -215,6 +194,7 @@ SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RecordTag( { CONTEXT_FROM_SOAP(soap,ctx); void *file_be,*file_p; + glite_jpps_fplug_data_t **pd = NULL; glite_jp_attrval_t attr[2], meta[2]; @@ -247,30 +227,42 @@ SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RecordTag( attr[0].origin_detail = NULL; /* XXX */ attr[1].name = NULL; - /*if (glite_jppsbe_open_file(ctx,in->jobid,"tags",NULL, - O_RDWR|O_CREAT,&file_be) - // XXX: tags need reading to check magic number - ) { - err2fault(ctx,soap); - return SOAP_FAULT; - } + /* XXX: we assume just one plugin and also that TAGS plugin handles + * just one uri/class */ + + if (glite_jpps_fplug_lookup(ctx,GLITE_JP_FILETYPE_TAGS,&pd) + || glite_jppsbe_open_file(ctx,in->jobid,pd[0]->classes[0],NULL, + O_RDWR|O_CREAT,&file_be) + /* XXX: tags need reading to check magic number */ + ) { + free(pd); + err2fault(ctx,soap); + return SOAP_FAULT; + } - if (glite_jppsbe_close_file(ctx,file_be)) + /* XXX: assuming tag plugin handles just one type */ + if (pd[0]->ops.open(pd[0]->fpctx,file_be,GLITE_JP_FILETYPE_TAGS,&file_p) + || pd[0]->ops.generic(pd[0]->fpctx,file_p,GLITE_JP_FPLUG_TAGS_APPEND,attr)) { err2fault(ctx,soap); + if (file_p) pd[0]->ops.close(pd[0]->fpctx,file_p); + glite_jppsbe_close_file(ctx,file_be); + free(pd); return SOAP_FAULT; - }*/ - glite_jppsbe_append_tag(ctx,in->jobid,attr); + } - /*if (tag_append(ctx,file_be,attr)) + if (pd[0]->ops.close(pd[0]->fpctx,file_p) + || glite_jppsbe_close_file(ctx,file_be)) { - err2fault(ctx,soap); - return SOAP_FAULT; - }*/ + err2fault(ctx,soap); + free(pd); + return SOAP_FAULT; + } /* XXX: ignore errors but don't fail silenty */ glite_jpps_match_attr(ctx,in->jobid,attr); + free(pd); return SOAP_OK; err: glite_jp_attrval_free(meta,0); diff --git a/org.glite.jp.primary/src/tags.c b/org.glite.jp.primary/src/tags.c index 1d4f4ae..1f11b4d 100644 --- a/org.glite.jp.primary/src/tags.c +++ b/org.glite.jp.primary/src/tags.c @@ -3,9 +3,6 @@ #include #include #include -#include -#include -#include #include #include "tags.h" @@ -14,10 +11,8 @@ /* magic name_len value_len binary sequence timestamp */ #define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" #define HEADER_SIZE 48 -#define TAGS_MAGIC 0x74c016f2 /* two middle digits encode version, i.e. 01 */ - -/*int glite_jpps_tag_append( +int glite_jpps_tag_append( glite_jp_context_t ctx, void *handle, const glite_jp_tagval_t *tag @@ -132,7 +127,7 @@ int glite_jpps_tag_read( err.desc = "No more tags in the file"; goto error_out; } - // #define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" + /* #define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" */ if (sscanf(hdr, HEADER, &nlen, &vlen, &binary, &sequence, ×tamp) < 5) { err.code = EILSEQ; err.desc = "Incorrect tag header format"; @@ -175,14 +170,14 @@ error_out: free(name); free(value); return glite_jp_stack_error(ctx,&err); -}*/ +} /* int glite_jpps_tag_read(glite_jp_context_t, void *, off_t, glite_jp_tagval_t *, size_t); int glite_jpps_tag_readall(glite_jp_context_t, void *, glite_jp_tagval_t **); */ -/*int glite_jpps_tag_readall( +int glite_jpps_tag_readall( glite_jp_context_t ctx, void *handle, glite_jp_tagval_t **tags_out @@ -235,222 +230,4 @@ error_out: } free(tags); return glite_jp_stack_error(ctx,&err); -}*/ - -int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag) -{ - //va_list ap; - char *hdr,*rec; - glite_jp_context_t ctx = fpctx; - uint32_t magic,hlen,rlen,rlen_n; - size_t r; - glite_jp_error_t err; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - printf("tagappend: %s,%s\n",tag->name,tag->value); - - //assert(oper == GLITE_JP_FPLUG_TAGS_APPEND); - - if (glite_jppsbe_pread(ctx,bhandle,&magic,sizeof magic,0,&r)) { - err.code = EIO; - err.desc = "reading magic number"; - return glite_jp_stack_error(ctx,&err); - } - - if (r == 0) { - magic = htonl(TAGS_MAGIC); - if (glite_jppsbe_pwrite(ctx,bhandle,&magic,sizeof magic,0)) { - err.code = EIO; - err.desc = "writing magic number"; - return glite_jp_stack_error(ctx,&err); - } - } - else if (r != sizeof magic) { - err.code = EIO; - err.desc = "can't read magic number"; - return glite_jp_stack_error(ctx,&err); - } - else if (magic != htonl(TAGS_MAGIC)) { - err.code = EINVAL; - err.desc = "invalid magic number"; - return glite_jp_stack_error(ctx,&err); - } - -/* XXX: origin is always USER, not recorded */ - trio_asprintf(&hdr,"%ld %c", - tag->timestamp,tag->binary ? 'B' : 'S'); - - rlen = strlen(tag->name) + strlen(hdr) + 2 /* \0 after name and after hdr */ + - (r = tag->binary ? tag->size : (tag->value ? strlen(tag->value) : 0)); - - rlen_n = htonl(rlen); - - rec = malloc(rlen + sizeof rlen_n); - *((uint32_t *) rec) = rlen_n; - strcpy(rec + sizeof rlen_n,tag->name); - strcpy(rec + (hlen = sizeof rlen_n + strlen(tag->name) + 1),hdr); - - if (r) memcpy(rec + hlen + strlen(hdr) + 1,tag->value,r); - free(hdr); - -/* record format: - * - 4B length, net byte order - * - attr name, \0 - * - %ld %c \0 (timestamp, B/S) - * - value - */ - if (glite_jppsbe_append(ctx,bhandle,rec,rlen + sizeof rlen_n)) { - err.code = EIO; - err.desc = "writing tag record"; - free(rec); - return glite_jp_stack_error(ctx,&err); - } - - /* XXX: should add tag also to handle->tags, but it is never used - * currently */ - - return 0; } - -int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval) -{ - struct tags_handle *h = handle; - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - glite_jp_attrval_t *out = NULL; - int i,nout = 0; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (!h->tags) tagsread(fpctx,handle); - - if (!h->tags) { - err.code = ENOENT; - err.desc = "no tags for this job"; - return glite_jp_stack_error(ctx,&err); - } - - for (i=0; in; i++) if (!strcmp(h->tags[i].name,attr)) { - out = realloc(out,(nout+2) * sizeof *out); - glite_jp_attrval_copy(out+nout,h->tags+i); - nout++; - memset(out+nout,0,sizeof *out); - } - - if (nout) { - *attrval = out; - return 0; - } - else { - err.code = ENOENT; - err.desc = "no value for this tag"; - return glite_jp_stack_error(ctx,&err); - } -} - -static int tagsread(void *fpctx,struct tags_handle *h) -{ - glite_jp_context_t ctx = fpctx; - uint32_t magic,rlen; - glite_jp_error_t err; - int r; - size_t off = sizeof rlen; - glite_jp_attrval_t *tp; - char *rp; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - glite_jp_clear_error(ctx); - -// read magic number - if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) { - err.code = EIO; - err.desc = "reading magic number"; - return glite_jp_stack_error(ctx,&err); - } - - if (r != sizeof magic) { - err.code = EIO; - err.desc = "can't read magic number"; - return glite_jp_stack_error(ctx,&err); - } - else if (magic != htonl(TAGS_MAGIC)) { - err.code = EINVAL; - err.desc = "invalid magic number"; - return glite_jp_stack_error(ctx,&err); - } - - - while (1) { - char *rec,type; - int rd; - - // read record header - if (glite_jppsbe_pread(ctx,h->bhandle,&rlen,sizeof rlen,off,&r)) { - err.code = EIO; - err.desc = "reading record header"; - return glite_jp_stack_error(ctx,&err); - } - if (r == 0) break; - - if (r != sizeof rlen) { - err.code = EIO; - err.desc = "can't read record header"; - return glite_jp_stack_error(ctx,&err); - } - - off += r; - rec = malloc(rlen = ntohl(rlen)); - - // read whole record body thoroughly - for (rd=0; rdbhandle,rec+rd,rlen-rd,off+rd,&r)) { - err.code = EIO; - err.desc = "reading record body"; - free(rec); - return glite_jp_stack_error(ctx,&err); - } - - off += rlen; - - // parse the record - h->tags = realloc(h->tags,(h->n+2) * sizeof *h->tags); - tp = h->tags+h->n++; - memset(tp,0,sizeof *tp); - - tp->name = strdup(rec); - rp = rec + strlen(rec) + 1; - - sscanf(rp,"%ld %c",&tp->timestamp,&type); - rp += strlen(rp) + 1; - switch (type) { - int i; - - case 'B': tp->binary = 1; break; - case 'S': tp->binary = 0; break; - default: free(rec); - for (i=0; in; i++) - glite_jp_attrval_free(h->tags+i,0); - free(h->tags); - h->tags = NULL; - h->n = 0; - - err.code = EINVAL; - err.desc = "invalid attr type (B/S)"; - return glite_jp_stack_error(ctx,&err); - } - tp->value = malloc((r=rlen - (rp - rec)) + 1); - memcpy(tp->value,rp,r); - if (!tp->binary) tp->value[r] = 0; - tp->origin = GLITE_JP_ATTR_ORIG_USER; - - free(rec); - } - return 0; -} - diff --git a/org.glite.jp.primary/src/tags.h b/org.glite.jp.primary/src/tags.h index 7fd524f..3aade74 100644 --- a/org.glite.jp.primary/src/tags.h +++ b/org.glite.jp.primary/src/tags.h @@ -1,10 +1 @@ -struct tags_handle { - void *bhandle; - int n; - glite_jp_attrval_t *tags; -}; - -int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag); -//int glite_jpps_tag_append(glite_jp_context_t,void *,const char *, const char *); -//int glite_jpps_tag_append(glite_jp_context_t,void *,const glite_jp_tagval_t *); -int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval); +int glite_jpps_tag_append(glite_jp_context_t,void *,const char *, const char *); diff --git a/org.glite.jp.primary/src/tags_plugin.c b/org.glite.jp.primary/src/tags_plugin.c new file mode 100644 index 0000000..953ace9 --- /dev/null +++ b/org.glite.jp.primary/src/tags_plugin.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "file_plugin.h" +#include "builtin_plugins.h" +#include "backend.h" + +static int tagappend(void *,void *,int,...); +static int tagopen(void *,void *,const char *uri,void **); +static int tagclose(void *,void *); +static int tagattr(void *,void *,const char *,glite_jp_attrval_t **); + +struct tags_handle { + void *bhandle; + int n; + glite_jp_attrval_t *tags; +}; + +static int tagsread(void *,struct tags_handle *); + +#define TAGS_MAGIC 0x74c016f2 /* two middle digits encode version, i.e. 01 */ + +static int tagdummy() +{ + puts("tagdummy()"); + return -1; +} + +int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) +{ + data->fpctx = ctx; + + data->uris = calloc(2,sizeof *data->uris); + data->uris[0] = strdup(GLITE_JP_FILETYPE_TAGS); + + data->classes = calloc(2,sizeof *data->classes); + data->classes[0] = strdup("tags"); + + data->ops.open = tagopen; + data->ops.close = tagclose; + data->ops.attr = tagattr; + data->ops.generic = tagappend; + + printf("tags_plugin: URI: \"%s\"; magic number: 0x%08lx\n",GLITE_JP_FILETYPE_TAGS,TAGS_MAGIC); + return 0; +} + +static int tagopen(void *fpctx,void *bhandle,const char *uri,void **handle) +{ + struct tags_handle *h = calloc(1,sizeof *h); + h->n = 0; + h->bhandle = bhandle; + + *handle = h; + + return 0; +} + +static int tagclose(void *fpctx,void *handle) +{ + int i; + struct tags_handle *h = handle; + + for (i=0; in; i++) glite_jp_attrval_free(h->tags+i,0); + free(h->tags); + free(h); + + return 0; +} + +static int tagappend(void *fpctx,void *handle,int oper,...) +{ + glite_jp_attrval_t *tag; + va_list ap; + char *hdr,*rec; + glite_jp_context_t ctx = fpctx; + struct tags_handle *h = handle; + uint32_t magic,hlen,rlen,rlen_n; + size_t r; + glite_jp_error_t err; + + memset(&err,0,sizeof err); + err.source = __FUNCTION__; + glite_jp_clear_error(ctx); + + va_start(ap,oper); + tag = va_arg(ap,glite_jp_attrval_t *); + va_end(ap); + + printf("tagappend: %s,%s\n",tag->name,tag->value); + + assert(oper == GLITE_JP_FPLUG_TAGS_APPEND); + + if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) { + err.code = EIO; + err.desc = "reading magic number"; + return glite_jp_stack_error(ctx,&err); + } + + if (r == 0) { + magic = htonl(TAGS_MAGIC); + if (glite_jppsbe_pwrite(ctx,h->bhandle,&magic,sizeof magic,0)) { + err.code = EIO; + err.desc = "writing magic number"; + return glite_jp_stack_error(ctx,&err); + } + } + else if (r != sizeof magic) { + err.code = EIO; + err.desc = "can't read magic number"; + return glite_jp_stack_error(ctx,&err); + } + else if (magic != htonl(TAGS_MAGIC)) { + err.code = EINVAL; + err.desc = "invalid magic number"; + return glite_jp_stack_error(ctx,&err); + } + +/* XXX: origin is always USER, not recorded */ + trio_asprintf(&hdr,"%ld %c", + tag->timestamp,tag->binary ? 'B' : 'S'); + + rlen = strlen(tag->name) + strlen(hdr) + 2 /* \0 after name and after hdr */ + + (r = tag->binary ? tag->size : (tag->value ? strlen(tag->value) : 0)); + + rlen_n = htonl(rlen); + + rec = malloc(rlen + sizeof rlen_n); + *((uint32_t *) rec) = rlen_n; + strcpy(rec + sizeof rlen_n,tag->name); + strcpy(rec + (hlen = sizeof rlen_n + strlen(tag->name) + 1),hdr); + + if (r) memcpy(rec + hlen + strlen(hdr) + 1,tag->value,r); + free(hdr); + +/* record format: + * - 4B length, net byte order + * - attr name, \0 + * - %ld %c \0 (timestamp, B/S) + * - value + */ + if (glite_jppsbe_append(ctx,h->bhandle,rec,rlen + sizeof rlen_n)) { + err.code = EIO; + err.desc = "writing tag record"; + free(rec); + return glite_jp_stack_error(ctx,&err); + } + + /* XXX: should add tag also to handle->tags, but it is never used + * currently */ + + return 0; +} + +static int tagattr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval) +{ + struct tags_handle *h = handle; + glite_jp_error_t err; + glite_jp_context_t ctx = fpctx; + glite_jp_attrval_t *out = NULL; + int i,nout = 0; + + memset(&err,0,sizeof err); + err.source = __FUNCTION__; + + if (!h->tags) tagsread(fpctx,handle); + + if (!h->tags) { + err.code = ENOENT; + err.desc = "no tags for this job"; + return glite_jp_stack_error(ctx,&err); + } + + for (i=0; in; i++) if (!strcmp(h->tags[i].name,attr)) { + out = realloc(out,(nout+2) * sizeof *out); + glite_jp_attrval_copy(out+nout,h->tags+i); + nout++; + memset(out+nout,0,sizeof *out); + } + + if (nout) { + *attrval = out; + return 0; + } + else { + err.code = ENOENT; + err.desc = "no value for this tag"; + return glite_jp_stack_error(ctx,&err); + } +} + +static int tagsread(void *fpctx,struct tags_handle *h) +{ + glite_jp_context_t ctx = fpctx; + uint32_t magic,rlen; + glite_jp_error_t err; + int r; + size_t off = sizeof rlen; + glite_jp_attrval_t *tp; + char *rp; + + memset(&err,0,sizeof err); + err.source = __FUNCTION__; + + glite_jp_clear_error(ctx); + +/* read magic number */ + if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) { + err.code = EIO; + err.desc = "reading magic number"; + return glite_jp_stack_error(ctx,&err); + } + + if (r != sizeof magic) { + err.code = EIO; + err.desc = "can't read magic number"; + return glite_jp_stack_error(ctx,&err); + } + else if (magic != htonl(TAGS_MAGIC)) { + err.code = EINVAL; + err.desc = "invalid magic number"; + return glite_jp_stack_error(ctx,&err); + } + + + while (1) { + char *rec,type; + int rd; + + /* read record header */ + if (glite_jppsbe_pread(ctx,h->bhandle,&rlen,sizeof rlen,off,&r)) { + err.code = EIO; + err.desc = "reading record header"; + return glite_jp_stack_error(ctx,&err); + } + if (r == 0) break; + + if (r != sizeof rlen) { + err.code = EIO; + err.desc = "can't read record header"; + return glite_jp_stack_error(ctx,&err); + } + + off += r; + rec = malloc(rlen = ntohl(rlen)); + + /* read whole record body thoroughly */ + for (rd=0; rdbhandle,rec+rd,rlen-rd,off+rd,&r)) { + err.code = EIO; + err.desc = "reading record body"; + free(rec); + return glite_jp_stack_error(ctx,&err); + } + + off += rlen; + + /* parse the record */ + h->tags = realloc(h->tags,(h->n+2) * sizeof *h->tags); + tp = h->tags+h->n++; + memset(tp,0,sizeof *tp); + + tp->name = strdup(rec); + rp = rec + strlen(rec) + 1; + + sscanf(rp,"%ld %c",&tp->timestamp,&type); + rp += strlen(rp) + 1; + switch (type) { + int i; + + case 'B': tp->binary = 1; break; + case 'S': tp->binary = 0; break; + default: free(rec); + for (i=0; in; i++) + glite_jp_attrval_free(h->tags+i,0); + free(h->tags); + h->tags = NULL; + h->n = 0; + + err.code = EINVAL; + err.desc = "invalid attr type (B/S)"; + return glite_jp_stack_error(ctx,&err); + } + tp->value = malloc((r=rlen - (rp - rec)) + 1); + memcpy(tp->value,rp,r); + if (!tp->binary) tp->value[r] = 0; + tp->origin = GLITE_JP_ATTR_ORIG_USER; + + free(rec); + } + return 0; +} diff --git a/org.glite.jp.primary/src/utils.c b/org.glite.jp.primary/src/utils.c deleted file mode 100644 index 533e6d1..0000000 --- a/org.glite.jp.primary/src/utils.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/strmd5.h" -#include "glite/jp/known_attr.h" -#include "glite/jp/attr.h" -#include "glite/jp/escape.h" - -#include "feed.h" -#include "tags.h" -#include "db.h" - -#include "utils.h" -#include "backend.h" - -/* - * realloc the line to double size if needed - * - * \return 0 if failed, did nothing - * \return 1 if success - */ -int check_realloc_line(char **line, size_t *maxlen, size_t len) { - void *tmp; - - if (len > *maxlen) { - *maxlen <<= 1; - tmp = realloc(*line, *maxlen); - if (!tmp) return 0; - *line = tmp; - } - - return 1; -} - -/* - * read next line from stream - * - * \return error code - */ -int glite_jppsbe_readline( - glite_jp_context_t ctx, - void *handle, - rl_buffer_t *buffer, - char **line -) -{ - size_t maxlen, len, i; - ssize_t nbytes; - int retval, z, end; - - maxlen = BUFSIZ; - i = 0; - len = 0; - *line = malloc(maxlen); - end = 0; - - do { - /* read next portion */ - if (buffer->pos >= buffer->size) { - buffer->pos = 0; - buffer->size = 0; - if ((retval = glite_jppsbe_pread(ctx, handle, buffer->buf, BUFSIZ, buffer->offset, &nbytes)) == 0) { - if (nbytes < 0) { - retval = EINVAL; - goto fail; - } else { - if (nbytes) { - buffer->size = (size_t)nbytes; - buffer->offset += nbytes; - } else end = 1; - } - } else goto fail; - } - - /* we have buffer->size - buffer->pos bytes */ - i = buffer->pos; - do { - if (i >= buffer->size) z = '\0'; - else { - z = buffer->buf[i]; - if (z == '\n') z = '\0'; - } - len++; - - if (!check_realloc_line(line, &maxlen, len)) { - retval = ENOMEM; - goto fail; - } - (*line)[len - 1] = z; - i++; - } while (z && i < buffer->size); - buffer->pos = i; - } while (len && (*line)[len - 1] != '\0'); - - if ((!len || !(*line)[0]) && end) { - free(*line); - *line = NULL; - } - - return 0; - -fail: - free(*line); - *line = NULL; - return retval; -} - -char* glite_jpps_get_namespace(const char* attr){ - char* namespace = strdup(attr); - char* colon = strrchr(namespace, ':'); - if (colon) - namespace[strrchr(namespace, ':') - namespace] = 0; - else - namespace[0] = 0; - return namespace; -} - diff --git a/org.glite.jp.primary/src/utils.h b/org.glite.jp.primary/src/utils.h deleted file mode 100644 index b350ada..0000000 --- a/org.glite.jp.primary/src/utils.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __GLITE_JP_UTILS -#define __GLITE_JP_UTILS - -#include -#include -#include - -#include "feed.h" - -typedef struct _rl_buffer_t { - char *buf; - size_t pos, size; - off_t offset; -} rl_buffer_t; - -int glite_jppsbe_readline( - glite_jp_context_t ctx, - void *handle, - rl_buffer_t *buffer, - char **line -); - -char* glite_jpps_get_namespace( - const char* attr -); - -#endif - diff --git a/org.glite.jp.server-common/Makefile b/org.glite.jp.server-common/Makefile index ae6a269..4e9f04e 100644 --- a/org.glite.jp.server-common/Makefile +++ b/org.glite.jp.server-common/Makefile @@ -75,7 +75,7 @@ ${LTLIB} ${STATICLIB}: ${OBJS} examples: db-test-int db-test-int: db-test-int.o - ${LINK} -o $@ $+ ${STATICLIB} ${MYSQLIB} -lglite_jp_common_${nothrflavour} ${TRIOLIB} ${GLOBUS_LIBS} + ${LINK} -o $@ $+ ${STATICLIB} ${MYSQLIB} -lglite_jp_common ${TRIOLIB} ${GLOBUS_LIBS} check: -echo nothing yet diff --git a/org.glite.lb-utils.context/.cvsignore b/org.glite.lb-utils.context/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.context/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.context/LICENSE b/org.glite.lb-utils.context/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.context/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.context/build.xml b/org.glite.lb-utils.context/build.xml deleted file mode 100644 index 81cd270..0000000 --- a/org.glite.lb-utils.context/build.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.context/project/build.number b/org.glite.lb-utils.context/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.context/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.context/project/build.properties b/org.glite.lb-utils.context/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils.context/project/configure.properties.xml b/org.glite.lb-utils.context/project/configure.properties.xml deleted file mode 100644 index 0b17304..0000000 --- a/org.glite.lb-utils.context/project/configure.properties.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/org.glite.lb-utils.context/project/properties.xml b/org.glite.lb-utils.context/project/properties.xml deleted file mode 100644 index 86c1f8a..0000000 --- a/org.glite.lb-utils.context/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.context/project/version.properties b/org.glite.lb-utils.context/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.context/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.db/.cvsignore b/org.glite.lb-utils.db/.cvsignore deleted file mode 100755 index ff82493..0000000 --- a/org.glite.lb-utils.db/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -.project -.cdtproject -build -doc -reports diff --git a/org.glite.lb-utils.db/LICENSE b/org.glite.lb-utils.db/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.db/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.db/Makefile b/org.glite.lb-utils.db/Makefile deleted file mode 100644 index 362c7cb..0000000 --- a/org.glite.lb-utils.db/Makefile +++ /dev/null @@ -1,128 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -stagedir=. -distdir=. -globalprefix=glite -lbutilsprefix=lb-utils -package=glite-lb-utils-db -version=0.2.0 -PREFIX=/opt/glite -flavour=gcc32thr - -glite_location=/opt/glite -mysql_prefix=/opt/mysql -mysql_version=4.1.11 -cppunit_prefix=/opt/cppunit -thrflavour=gcc32pthr -nothrflavour=gcc32 - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -CC=gcc - -VPATH=${top_srcdir}/interface:${top_srcdir}/src:${top_srcdir}/examples - -DEBUG:=-g -O0 -Wall - -CFLAGS:= \ - ${DEBUG} \ - -DVERSION=\"${version}\" \ - -I${stagedir}/include -I${top_srcdir}/src -I. \ - -I${top_srcdir}/interface \ - ${COVERAGE_FLAGS} \ - -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql \ - -D_GNU_SOURCE - -ifdef LBS_DB_PROFILE - CFLAGS:=${CFLAGS} -DLBS_DB_PROFILE -endif - -TEST_LIBS:=-L${cppunit_prefix}/lib -lcppunit -TEST_INC:=-I${cppunit_prefix}/include - -LDFLAGS:=-L${stagedir}/lib ${COVERAGE_FLAGS} - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -ifneq (${mysql_prefix},/usr) - ifeq ($(shell echo ${mysql_version} | cut -d. -f1,2),4.1) - mysqlib := -L${mysql_prefix}/lib/mysql - else - mysqlib := -L${mysql_prefix}/lib - endif -endif - -EXT_LIBS:=${mysqlib} -lmysqlclient -lglite_lbu_trio -OBJS:=db.o -TESTOBJS:=dbtest.o -HDRS:=db.h -LOBJS:=${OBJS:.o=.lo} -LTESTOBJS:=${TESTOBJS:.o=.lo} - -libglite_lbu_db.la: ${LOBJS} - ${LINK} -o $@ $< ${EXT_LIBS} - -libglite_lbu_dbtest.la: ${LTESTOBJS} - ${LINK} -o $@ $< ${EXT_LIBS} - -dbtest.lo dbtest.o: db.c db.h - ${COMPILE} -DGLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH=10 -c $< -o $@ - -db_test: db_test.lo libglite_lbu_dbtest.la - ${LINK} -o $@ $+ ${EXT_LIBS} - -default all: compile - -compile: libglite_lbu_db.la - -check: - -echo No checks here yet. - -test_coverage: - -mkdir coverage - cd coverage && $(MAKE) -f ../Makefile top_srcdir=../../ COVERAGE_FLAGS="-fprofile-arcs -ftest-coverage" check - cd coverage && for i in `echo ${OBJS} | tr ' ' '\012' | sort -u`; do gcov $$i ; done - -examples: db_test - -doc: - doxygen C.dox - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/lib - -mkdir -p ${PREFIX}/include/${globalprefix}/${lbutilsprefix} -# ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 755 "libglite_lbu_db.la" "${PREFIX}/lib/libglite_lbu_db.la"; \ - ${INSTALL} -m 644 ${top_srcdir}/interface/${HDRS} ${PREFIX}/include/${globalprefix}/${lbutilsprefix} - -clean: - -%.o %.lo: %.c - ${COMPILE} -c $< - -db.lo: db.c db.h -db_test.lo: libglite_lbu_dbtest.la db.h db_test.c - -.PHONY: default all compile check examples doc stage dist distsrc distbin install clean test_coverage diff --git a/org.glite.lb-utils.db/build.xml b/org.glite.lb-utils.db/build.xml deleted file mode 100644 index 14d4d7e..0000000 --- a/org.glite.lb-utils.db/build.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.db/examples/db_test.c b/org.glite.lb-utils.db/examples/db_test.c deleted file mode 100644 index ec65fbf..0000000 --- a/org.glite.lb-utils.db/examples/db_test.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Example (and quick test) of this DB module. - * - * Requires existing database with appropriate access: - * - * mysqladmin -u root -p create test - * mysql -u root -p -e 'GRANT ALL on test.* to testuset@localhost' - * - * Use CS environment variable when using different user/pwd@machine:dbname. - */ - -#include -#include -#include - -#include "db.h" - -#define CS "testuser/@localhost:test" -#define CREATE_CMD "CREATE TABLE data (\n\ - id INT NOT NULL,\n\ - user VARCHAR(32) NOT NULL,\n\ - info BLOB,\n\ - PRIMARY KEY (id),\n\ - INDEX(user)\n\ -) engine=innodb" -#define DROP_CMD "DROP TABLE data" -#define INSERT_TRIO_CMD "INSERT INTO data (id, user, info) VALUES (%d, %s, %s)" -#define SELECT_TRIO_CMD "SELECT id, user, info FROM data WHERE user = '%s'" -#define INSERT_CMD "INSERT INTO data (id, user, info) VALUES (?, ?, ?)" -#define SELECT_CMD "SELECT id, user, info FROM data WHERE user = ?" - -#define dprintf(ARGS) { printf("%s: ", name); printf ARGS; } - - -static void print_blob(unsigned long len, char *blob) { - int i; - for (i = 0; i < len; i++) printf("%02X ", blob[i]); - printf("(='"); - for (i = 0; i < len; i++) printf("%c", blob[i]); - printf("')"); -} - - -static void print_free_result(const char *name, unsigned long *lens, char **res) { - dprintf((" id='%s'=%d\n", res[0], atoi(res[0]))); - - dprintf((" user='%s'\n", res[1])); - - dprintf((" blob=")); - if (res[2] && lens) print_blob(lens[2], res[2]); - else printf("null"); - printf("\n"); - - free(res[0]); - free(res[1]); - free(res[2]); -} - - -int main(int argn, char *argv[]) { - char *name, *cmd; - const char *cs; - glite_lbu_DBContext ctx; - glite_lbu_Statement stmt; - int caps; - - char blob1[] = "Guess: blob or \000string?"; - char blob2[] = {0, 1, 2, 3, 4, 5}; - - int nr; - char *res[3]; - unsigned long lens[3]; - - if ((name = strrchr(argv[0], '/')) != NULL) name++; - else name = argv[0]; - if ((cs = getenv("CS")) == NULL) cs = CS; - cmd = NULL; - - // init - dprintf(("connecting to %s...\n", cs)); - if (glite_lbu_InitDBContext(&ctx) != 0) goto fail; - if (glite_lbu_DBConnect(ctx, cs) != 0) goto failctx; - if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) goto failcon; - if ((caps & GLITE_LBU_DB_CAP_PREPARED) == 0) { - dprintf(("can't do prepared commands, exiting.")); - goto failcon; - } - // caps - glite_lbu_DBSetCaps(ctx, caps); - dprintf(("capabilities: %d\n", caps)); - // create all needed tables and data - dprintf(("creating tables...\n")); - glite_lbu_ExecSQL(ctx, DROP_CMD, NULL); - if (glite_lbu_ExecSQL(ctx, CREATE_CMD, NULL) == -1) goto failcon; - // trio-insert - dprintf(("trio-insert...\n")); - asprintf(&cmd, INSERT_TRIO_CMD, 1, "'hyperochus'", "NULL"); - if (glite_lbu_ExecSQL(ctx, cmd, NULL) != 1) goto failcon; - free(cmd); cmd = NULL; - // prepared-insert - dprintf(("prepare-insert...\n")); - if (glite_lbu_PrepareStmt(ctx, INSERT_CMD, &stmt) != 0) goto failcon; - dprintf(("execute 1. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 2, - GLITE_LBU_DB_TYPE_VARCHAR, "cicomexocitl.civ", - GLITE_LBU_DB_TYPE_BLOB, blob1, sizeof(blob1) - 1) != 1) goto failstmt; - dprintf(("execute 2. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 3, - GLITE_LBU_DB_TYPE_VARCHAR, "tartarus", - GLITE_LBU_DB_TYPE_NULL) != 1) goto failstmt; - dprintf(("execute 3. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 4, - GLITE_LBU_DB_TYPE_VARCHAR, "harpia", - GLITE_LBU_DB_TYPE_BLOB, blob2, sizeof(blob2)) != 1) goto failstmt; - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); - - // trio-query -{ - const char *user; - - user = "harpia"; - dprintf(("selecting '%s'...\n", user)); - asprintf(&cmd, SELECT_TRIO_CMD, user); - if (glite_lbu_ExecSQL(ctx, cmd, &stmt) == -1) goto failcon; - free(cmd); cmd = NULL; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); - - user = "nobody"; - dprintf(("selecting '%s'...\n", user)); - asprintf(&cmd, SELECT_TRIO_CMD, user); - if (glite_lbu_ExecSQL(ctx, cmd, &stmt) == -1) goto failcon; - free(cmd); cmd = NULL; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); -} - - // "param" queries -{ - const char *user; - - dprintf(("preparing '%s'...\n", user)); - if ((glite_lbu_PrepareStmt(ctx, SELECT_CMD, &stmt)) != 0) goto failcon; - - user = "cicomexocitl.civ"; - dprintf(("executing '%s'...\n", user)); - if (glite_lbu_ExecStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("\n")); - - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); -} - - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); - glite_lbu_FreeDBContext(ctx); - return 0; - -failstmt: - printf("closing stmt...\n"); - glite_lbu_FreeStmt(&stmt); -failcon: - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); -failctx: - glite_lbu_FreeDBContext(ctx); -fail: - free(cmd); - dprintf(("failed\n")); - return 1; -} diff --git a/org.glite.lb-utils.db/interface/db.h b/org.glite.lb-utils.db/interface/db.h deleted file mode 100644 index 0c9002a..0000000 --- a/org.glite.lb-utils.db/interface/db.h +++ /dev/null @@ -1,336 +0,0 @@ -#ifndef GLITE_LBU_DB_H -#define GLITE_LBU_DB_H - -#ident "$Header$" - - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * \file db.h - * \defgroup database Database module - * - * Database modul module API (LB & JP Utils). - * - * There are two ways to access DB here: - * - simple: - * - * SQL commands as single string. All values are incorporated in the SQL command strings. Proper escaping is required. - * - enhanced: - * - * Prepared SQL commands with separated parameters, functions PrepareStmt() and ExecStmt(). All values are delivered in separated buffers. Its faster for multiple using and more secure. - * @{ - */ - - -/** - * Enable transaction support if available. - * - * With disabled transaction can be used transaction functions, they are just ignored. - */ -#define GLITE_LBU_DB_CAP_TRANSACTIONS 1 - -/** - * Check prepared parameters support. - */ -#define GLITE_LBU_DB_CAP_PREPARED 2 - -/** - * Check for getting indexes support. - * - * Needed for QueryIndices call. - */ -#define GLITE_LBU_DB_CAP_INDEX 4 - - -/** - * Database connection context. - */ -typedef struct glite_lbu_DBContext_s *glite_lbu_DBContext; - - -/** - * Prepared statement, used for SQL statement with parameters. - */ -typedef struct glite_lbu_Statement_s *glite_lbu_Statement; - - -/** - * Structure holds date for multi-rows insert. - */ -typedef struct glite_lbu_bufInsert_s *glite_lbu_bufInsert; - - - -/** - * All types of parameteres, they match to the SQL types. - */ -typedef enum { - GLITE_LBU_DB_TYPE_NULL = 0, - GLITE_LBU_DB_TYPE_TINYINT = 1, - GLITE_LBU_DB_TYPE_INT = 2, - GLITE_LBU_DB_TYPE_TINYBLOB = 3, - GLITE_LBU_DB_TYPE_TINYTEXT = 4, - GLITE_LBU_DB_TYPE_BLOB = 5, - GLITE_LBU_DB_TYPE_TEXT = 6, - GLITE_LBU_DB_TYPE_MEDIUMBLOB = 7, - GLITE_LBU_DB_TYPE_MEDIUMTEXT = 8, - GLITE_LBU_DB_TYPE_LONGBLOB = 9, - GLITE_LBU_DB_TYPE_LONGTEXT = 10, - GLITE_LBU_DB_TYPE_VARCHAR = 11, - GLITE_LBU_DB_TYPE_CHAR = 12, - GLITE_LBU_DB_TYPE_DATE = 13, - GLITE_LBU_DB_TYPE_TIME = 14, - GLITE_LBU_DB_TYPE_DATETIME = 15, - GLITE_LBU_DB_TYPE_TIMESTAMP = 16, - GLITE_LBU_DB_TYPE_LAST = 17 -} glite_lbu_DBType; - - - -/** - * Get error state from DB context. - * - * \param[in] ctx context to work with - * \param[out] text error name - * \param[out] desc error description - */ -int glite_lbu_DBError(glite_lbu_DBContext ctx, char **text, char **desc); - - -/** - * Initialize the database context. - * - * \param[out] ctx result context - */ -int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx); - - -/** - * Free database context. - */ -void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx); - - -/** - * Connect to the given database. - * - * \param[out] ctx context to work with - * \param[in] cs connect string user/password\@host:database - * - * \return error code, 0 = OK - */ -int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs); - - -/** - * Close the connection. - * - * \param[in,out] ctx context to work with - */ -void glite_lbu_DBClose(glite_lbu_DBContext ctx); - - -/** - * Check database version and capabilities. - * - * \param[in,out] ctx context to work with - * - * \return capabilities - * \retval -1 error occured - */ -int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx); - - -/** - * Set the database capabilities on already initialized context. - * - * It should be find out by DBQueryCaps() first. - * - * \param[in,out] ctx context to work with - * \param[in] caps capabilities to use, should be found out by QueryCaps() - */ -void glite_lbu_DBSetCaps(glite_lbu_DBContext ctx, int caps); - - -/** - * Start transaction. - */ -int glite_lbu_Transaction(glite_lbu_DBContext ctx); - - -/** - * Commit (end) transaction. - */ -int glite_lbu_Commit(glite_lbu_DBContext ctx); - - -/** - * Cancel transaction. - */ -int glite_lbu_Rollback(glite_lbu_DBContext ctx); - - -/** - * \param[in,out] stmt executed SQL statement - * \param[in] n number of items for sure there is enough space in lengths and results - * \param[out] lengths array with lengths (good for data blobs), may be NULL - * \param[out] results array with results, all items are allocated - * - * \retval >0 number of fields of the retrieved row - * \retval 0 no more rows - * \retval -1 error - */ -int glite_lbu_FetchRow(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); - - -/** - * Free the statement structure and destroy its parameters. - * - * Statement will be set to NULL and multiple calls are allowed. - * - * \param[in,out] stmt statement - */ -void glite_lbu_FreeStmt(glite_lbu_Statement *stmt); - - -/** - * Parse and execute one simple SQL statement. - * All values are incorporated int the SQL command string. - * - * \param[in,out] ctx context to work with - * \param[in] cmd SQL command - * \param[out] stmt statement handle with results (makes sense for selects only) - * - * \return number of rows selected, created or affected by update, -1 on error - */ -int glite_lbu_ExecSQL(glite_lbu_DBContext ctx, const char *cmd, glite_lbu_Statement *stmt); - - -/** - * Query for column names of the statement. - * - * It work only for simple API, so only after ExecSQL(). - * - * \param[in,out] stmt the statement handle - * \param[out] cols result array of names - * - * \return error code - */ -int glite_lbu_QueryColumns(glite_lbu_Statement stmt, char **cols); - - -/** - * Retrieve column names of a query simple SQL statement. - * - * \param[in,out] ctx context to work with - * \param[in] table table name - * \param[out] key_names one-dimensional index names array - * \param[out] column_names two-dimensional column names array - * - * \return 0 if OK, nonzero on error - */ -int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names); - - -/** - * Convert time_t into database-specific time string. - * - * The result string can be used directly in SQL commands. - * - * \param[in] t the converted time - * \param[out] str result allocated string - */ -void glite_lbu_TimeToDB(time_t t, char **str); - - -/** - * Convert database-specific time string to time_t. - * - * String is expected in database for (ISO format). - * - * \param[in] str the converted string - * \return result time - */ -time_t glite_lbu_DBToTime(const char *str); - - -/** - * Init data structure for buffered insert - * - * takes table_name and columns string for future multirow insert - * when insert string oversize size_limit or number of rows to be inserted - * overcome record_limit, the real insert is triggered - */ -int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, void *mysql, const char *table_name, long size_limit, long record_limit, const char * columns); - - -/** - * adds row of n values into n columns into an insert buffer - * if num. of rows or size of data oversteps the limits, real - * multi-row insert is done - */ -int glite_lbu_bufferedInsert(glite_lbu_bufInsert bi, const char *row); - - -/** - * Flush buffered data and free bi structure. - */ -int glite_lbu_bufferedInsertClose(glite_lbu_bufInsert bi); - - -/** - * Prepare the SQL statement. Use glite_lbu_FreeStmt() to free it. - * - * \param[in,out] ctx context to work with - * \param[in] sql SQL command - * \param[out] stmt returned SQL statement - * - * \return error code - */ -int glite_lbu_PrepareStmt(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt); - - -/** - * Execute prepared SQL statement. - * - * \param[in,out] stmt SQL statement - * \param[in] n number of items - * - * Variable parameters (n-times): - * - * always: - * - * \param type DB item type - * - * then one of them: - * - * \param GLITE_LBU_DB_TYPE_TINYINT int c - * \param GLITE_LBU_DB_TYPE_INT long int i - * \param GLITE_LBU_DB_TYPE_...BLOB/TEXT void *b, unsigned long len - * \param GLITE_LBU_DB_TYPE_[VAR]CHAR char *str - * \param GLITE_LBU_DB_TYPE_DATE/TIME/DATETIME time_t t - * \param GLITE_LBU_DB_TYPE_TIMESTAMP time_t t - * \param GLITE_LBU_DB_TYPE_NULL - - * - * \return number of affected rows, -1 on error - */ -int glite_lbu_ExecStmt(glite_lbu_Statement stmt, int n, ...); - - -/** - * @} database group - */ - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.lb-utils.db/project/build.number b/org.glite.lb-utils.db/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.db/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.db/project/build.properties b/org.glite.lb-utils.db/project/build.properties deleted file mode 100755 index 1df02e3..0000000 --- a/org.glite.lb-utils.db/project/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils - diff --git a/org.glite.lb-utils.db/project/configure.properties.xml b/org.glite.lb-utils.db/project/configure.properties.xml deleted file mode 100644 index 276b497..0000000 --- a/org.glite.lb-utils.db/project/configure.properties.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbutilsprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -flavour=${with.globus.thr.flavor} - -glite_location=${with.glite.location} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -cppunit_prefix=${with.cppunit.prefix} - - -PROJECT_NAME = "Glite LB/JP Utils: Database Module" -PROJECT_NUMBER = ${module.version} -OUTPUT_DIRECTORY = ${component.dir}/doc/C -OPTIMIZE_OUTPUT_FOR_C = YES -INPUT = ../interface/db.h -SHOW_DIRECTORIES = NO -FULL_PATH_NAMES = NO -EXTRACT_ALL = YES -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -#PREDEFINED = _EDG_WLL_EVENT_COMMON -HAVE_DOT = NO - - - - diff --git a/org.glite.lb-utils.db/project/properties.xml b/org.glite.lb-utils.db/project/properties.xml deleted file mode 100644 index d01c359..0000000 --- a/org.glite.lb-utils.db/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.db/project/tar_exclude b/org.glite.lb-utils.db/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.lb-utils.db/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.lb-utils.db/project/version.properties b/org.glite.lb-utils.db/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.db/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.db/src/db.c b/org.glite.lb-utils.db/src/db.c deleted file mode 100644 index a8adc57..0000000 --- a/org.glite.lb-utils.db/src/db.c +++ /dev/null @@ -1,1037 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "glite/lb-utils/trio.h" -#include "db.h" - - -#define GLITE_LBU_MYSQL_INDEX_VERSION 40001 -#define GLITE_LBU_MYSQL_PREPARED_VERSION 40102 -#define BUF_INSERT_ROW_ALLOC_BLOCK 1000 -#ifndef GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH -#define GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH 256 -#endif - - -#define CLR_ERR(CTX) lbu_clrerr((CTX)) -#define ERR(CTX, CODE, DESC) lbu_err((CTX), (CODE), (DESC), __FUNCTION__, __LINE__) -#define STATUS(CTX) ((CTX)->err.code) -#define MY_ERR(CTX) myerr((CTX), __FUNCTION__, __LINE__) -#define MY_ERRSTMT(STMT) myerrstmt((STMT), __FUNCTION__, __LINE__) -#define MY_ISOKSTMT(STMT, RETRY) myisokstmt((STMT), __FUNCTION__, __LINE__, (RETRY)) - -#define USE_TRANS(CTX) ((CTX->caps & GLITE_LBU_DB_CAP_TRANSACTIONS) != 0) - - - -struct glite_lbu_DBContext_s { - MYSQL *mysql; - const char *cs; - int have_caps; - int caps; - struct { - int code; - char *desc; - } err; -}; - - -struct glite_lbu_Statement_s { - glite_lbu_DBContext ctx; - - /* for simple commands */ - MYSQL_RES *result; - - /* for prepared commands */ - MYSQL_STMT *stmt; - unsigned long nrfields; -}; - - -struct glite_lbu_bufInsert_s { - glite_lbu_DBContext ctx; - char *table_name; - char *columns; /* names of columns to be inserted into - * (values separated with commas) */ - char **rows; /* each row hold string of one row to be inserted - * (values separated with commas) */ - long rec_num, /* actual number of rows in structure */ - rec_size; /* approx. size of a real insert string */ - long size_limit, /* size and # of records limit which trigger */ - record_limit; /* real insert; zero means unlimitted */ -}; - - -/* - * mapping glite DB types to mysql types - */ -int glite_type_to_mysql[] = { - MYSQL_TYPE_NULL, - MYSQL_TYPE_TINY, - MYSQL_TYPE_LONG, - MYSQL_TYPE_TINY_BLOB, - MYSQL_TYPE_TINY_BLOB, - MYSQL_TYPE_BLOB, - MYSQL_TYPE_BLOB, - MYSQL_TYPE_MEDIUM_BLOB, - MYSQL_TYPE_MEDIUM_BLOB, - MYSQL_TYPE_LONG_BLOB, - MYSQL_TYPE_LONG_BLOB, - MYSQL_TYPE_VAR_STRING, - MYSQL_TYPE_STRING, - MYSQL_TYPE_DATE, - MYSQL_TYPE_TIME, - MYSQL_TYPE_DATETIME, - MYSQL_TYPE_TIMESTAMP, -}; - - - -static int lbu_clrerr(glite_lbu_DBContext ctx); -static int lbu_err(glite_lbu_DBContext ctx, int code, const char *desc, const char *func, int line); -static int myerr(glite_lbu_DBContext ctx, const char *source, int line); -static int myerrstmt(glite_lbu_Statement stmt, const char *source, int line); -static int myisokstmt(glite_lbu_Statement stmt, const char *source, int line, int *retry); -static int db_connect(glite_lbu_DBContext ctx, const char *cs, MYSQL **mysql); -static void db_close(MYSQL *mysql); -static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions); -static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results); -static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); -void set_time(MYSQL_TIME *mtime, const time_t time); -time_t get_time(const MYSQL_TIME *mtime); - - -/* ---- common ---- */ - - -int glite_lbu_DBError(glite_lbu_DBContext ctx, char **text, char **desc) { - if (text) *text = strdup(strerror(ctx->err.code)); - if (desc) { - if (ctx->err.desc) *desc = strdup(ctx->err.desc); - else *desc = NULL; - } - - return ctx->err.code; -} - - -int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx) { - *ctx = calloc(1, sizeof **ctx); - return *ctx == NULL ? ENOMEM : 0; -} - - -void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx) { - if (ctx) { - assert(ctx->mysql == NULL); - free(ctx->err.desc); - free(ctx); - } -} - - -int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs) { - if (db_connect(ctx, cs, &ctx->mysql) != 0) return STATUS(ctx); - return 0; -} - - -void glite_lbu_DBClose(glite_lbu_DBContext ctx) { - db_close(ctx->mysql); - ctx->mysql = NULL; -} - - -int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx) { - MYSQL *m = ctx->mysql; - MYSQL *m2; - int major,minor,sub,version,caps,have_transactions=0; - const char *ver_s; - - if (ctx->have_caps) return ctx->caps; - - caps = 0; - - ver_s = mysql_get_server_info(m); - if (!ver_s || 3 != sscanf(ver_s,"%d.%d.%d",&major,&minor,&sub)) - return ERR(ctx, EINVAL, "problem retreiving MySQL version"); - version = 10000*major + 100*minor + sub; - - if (version >= GLITE_LBU_MYSQL_INDEX_VERSION) caps |= GLITE_LBU_DB_CAP_INDEX; - if (version >= GLITE_LBU_MYSQL_PREPARED_VERSION) caps |= GLITE_LBU_DB_CAP_PREPARED; - - CLR_ERR(ctx); - - if (db_connect(ctx, ctx->cs, &m2) == 0) { - transaction_test(ctx, m2, &have_transactions); - db_close(m2); - } - if (have_transactions) caps |= GLITE_LBU_DB_CAP_TRANSACTIONS; - - if (STATUS(ctx) == 0) { - ctx->have_caps = 1; - return caps; - } else return -1; -} - - -void glite_lbu_DBSetCaps(glite_lbu_DBContext ctx, int caps) { - ctx->caps = caps; -} - - -int glite_lbu_Transaction(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=0", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "BEGIN", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_Commit(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "COMMIT", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_Rollback(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "ROLLBACK", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_FetchRow(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) { - memset(results, 0, n * sizeof(*results)); - if (stmt->result) return FetchRowSimple(stmt->ctx, stmt->result, lengths, results); - else return FetchRowPrepared(stmt->ctx, stmt, n, lengths, results); -} - - -void glite_lbu_FreeStmt(glite_lbu_Statement *stmt) { - if (*stmt) { - if ((*stmt)->result) mysql_free_result((*stmt)->result); - if ((*stmt)->stmt) mysql_stmt_close((*stmt)->stmt); - free(*stmt); - *stmt = NULL; - } -} - - -int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names) { - glite_lbu_Statement stmt = NULL; - - int i,j,ret; - -/* XXX: "show index from" columns. Matches at least MySQL 4.0.11 */ - char *showcol[12]; - int Key_name,Seq_in_index,Column_name,Sub_part; - - char **keys = NULL; - int *cols = NULL; - char **col_names = NULL; - - int nkeys = 0; - - char ***idx = NULL; - - Key_name = Seq_in_index = Column_name = Sub_part = -1; - - if (glite_lbu_ExecSQL(ctx,"show index from states",&stmt)<0) - return STATUS(ctx); - - while ((ret = glite_lbu_FetchRow(stmt,sizeof(showcol)/sizeof(showcol[0]),NULL,showcol)) > 0) { - assert(ret <= sizeof showcol/sizeof showcol[0]); - - if (!col_names) { - col_names = malloc(ret * sizeof col_names[0]); - glite_lbu_QueryColumns(stmt,col_names); - for (i=0; i= 0 && Seq_in_index >= 0 && - Column_name >= 0 && Sub_part >= 0); - - } - - for (i=0; imysql, cmd)) { - /* error occured */ - switch (merr = mysql_errno(ctx->mysql)) { - case 0: - break; - case ER_DUP_ENTRY: - ERR(ctx, EEXIST, mysql_error(ctx->mysql)); - return -1; - break; - case CR_SERVER_LOST: - if (retry_nr <= 0) - do_reconnect = 1; - break; - default: - MY_ERR(ctx); - return -1; - break; - } - } - retry_nr++; - } - - if (stmt) { - *stmt = calloc(1, sizeof(**stmt)); - if (!*stmt) { - ERR(ctx, ENOMEM, NULL); - return -1; - } - (**stmt).ctx = ctx; - (**stmt).result = mysql_store_result(ctx->mysql); - if (!(**stmt).result) { - if (mysql_errno(ctx->mysql)) { - MY_ERR(ctx); - *stmt = NULL; - return -1; - } - } - } else { - MYSQL_RES *r = mysql_store_result(ctx->mysql); - mysql_free_result(r); - } -#ifdef LBS_DB_PROFILE - pid = getpid(); - gettimeofday(&end,NULL); - end.tv_usec -= start.tv_usec; - end.tv_sec -= start.tv_sec; - if (end.tv_usec < 0) { end.tv_sec--; end.tv_usec += 1000000; } - - sum.tv_usec += end.tv_usec; - sum.tv_sec += end.tv_sec + sum.tv_usec / 1000000; - sum.tv_usec -= 1000000 * (sum.tv_usec / 1000000); - fprintf(stderr,"[%d] %s\n[%d] %3ld.%06ld (sum: %3ld.%06ld)\n",pid,txt,pid,end.tv_sec,end.tv_usec,sum.tv_sec,sum.tv_usec); -#endif - - return mysql_affected_rows(ctx->mysql); -} - - -int glite_lbu_QueryColumns(glite_lbu_Statement stmt, char **cols) -{ - int i = 0; - MYSQL_FIELD *f; - - if (!stmt->result) return ERR(stmt->ctx, EINVAL, "QueryColumns implemented only for simple API"); - while ((f = mysql_fetch_field(stmt->result))) cols[i++] = f->name; - return i == 0; -} - - -void glite_lbu_TimeToDB(time_t t, char **str) { - struct tm *tm = gmtime(&t); - - asprintf(str,"'%4d-%02d-%02d %02d:%02d:%02d'",tm->tm_year+1900,tm->tm_mon+1, - tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); -} - - -time_t glite_lbu_DBToTime(const char *str) { - struct tm tm; - - memset(&tm,0,sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - sscanf(str,"%4d-%02d-%02d %02d:%02d:%02d", - &tm.tm_year,&tm.tm_mon,&tm.tm_mday, - &tm.tm_hour,&tm.tm_min,&tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon--; - - return mktime(&tm); -} - -/* ---- prepared --- */ - -int glite_lbu_PrepareStmt(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt) { - int ret, retry; - MYSQL_RES *meta; - - // init - *stmt = calloc(1, sizeof(**stmt)); - (*stmt)->ctx = ctx; - - // create the SQL command - if (((*stmt)->stmt = mysql_stmt_init(ctx->mysql)) == NULL) - return MY_ERRSTMT(*stmt); - - // prepare the SQL command - retry = 1; - do { - mysql_stmt_prepare((*stmt)->stmt, sql, strlen(sql)); - ret = MY_ISOKSTMT(*stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // number of fields (0 for no results) - if ((meta = mysql_stmt_result_metadata((*stmt)->stmt)) != NULL) { - (*stmt)->nrfields = mysql_num_fields(meta); - mysql_free_result(meta); - } else - (*stmt)->nrfields = 0; - - return CLR_ERR(ctx); - -failed: - glite_lbu_FreeStmt(stmt); - return STATUS(ctx); -} - - -int glite_lbu_ExecStmt(glite_lbu_Statement stmt, int n, ...) { - int i; - va_list ap; - glite_lbu_DBType type; - char *pchar; - long int *plint; - MYSQL_TIME *ptime; - glite_lbu_DBContext ctx; - int ret, retry; - MYSQL_BIND *binds = NULL; - void **data = NULL; - unsigned long *lens; - - // gather parameters - if (n) { - binds = calloc(n, sizeof(MYSQL_BIND)); - data = calloc(n, sizeof(void *)); - lens = calloc(n, sizeof(unsigned long *)); - } - va_start(ap, n); - for (i = 0; i < n; i++) { - type = va_arg(ap, glite_lbu_DBType); - switch (type) { - case GLITE_LBU_DB_TYPE_TINYINT: - pchar = binds[i].buffer = data[i] = malloc(sizeof(char)); - *pchar = va_arg(ap, int); - break; - - case GLITE_LBU_DB_TYPE_INT: - plint = binds[i].buffer = data[i] = malloc(sizeof(long int)); - *plint = va_arg(ap, long int); - break; - - case GLITE_LBU_DB_TYPE_TINYBLOB: - case GLITE_LBU_DB_TYPE_TINYTEXT: - case GLITE_LBU_DB_TYPE_BLOB: - case GLITE_LBU_DB_TYPE_TEXT: - case GLITE_LBU_DB_TYPE_MEDIUMBLOB: - case GLITE_LBU_DB_TYPE_MEDIUMTEXT: - case GLITE_LBU_DB_TYPE_LONGBLOB: - case GLITE_LBU_DB_TYPE_LONGTEXT: - binds[i].buffer = va_arg(ap, void *); - binds[i].length = &lens[i]; - lens[i] = va_arg(ap, unsigned long); - break; - - case GLITE_LBU_DB_TYPE_VARCHAR: - case GLITE_LBU_DB_TYPE_CHAR: - binds[i].buffer = va_arg(ap, char *); - binds[i].length = &lens[i]; - lens[i] = binds[i].buffer ? strlen((char *)binds[i].buffer) : 0; - break; - - case GLITE_LBU_DB_TYPE_DATE: - case GLITE_LBU_DB_TYPE_TIME: - case GLITE_LBU_DB_TYPE_DATETIME: - case GLITE_LBU_DB_TYPE_TIMESTAMP: - ptime = binds[i].buffer = data[i] = malloc(sizeof(MYSQL_TIME)); - set_time(ptime, va_arg(ap, time_t)); - break; - - case GLITE_LBU_DB_TYPE_NULL: - break; - - default: - assert("unimplemented parameter assign" == NULL); - break; - } - binds[i].buffer_type = glite_type_to_mysql[type]; - } - va_end(ap); - - // bind parameters - if (mysql_stmt_bind_param(stmt->stmt, binds) != 0) { - MY_ERRSTMT(stmt); - goto failed; - } - - // run - ctx = stmt->ctx; - retry = 1; - do { - mysql_stmt_execute(stmt->stmt); - ret = MY_ISOKSTMT(stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // result - retry = 1; - do { - mysql_stmt_store_result(stmt->stmt); - ret = MY_ISOKSTMT(stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // free params - for (i = 0; i < n; i++) free(data[i]); - free(data); - free(binds); - free(lens); - CLR_ERR(ctx); - return mysql_stmt_affected_rows(stmt->stmt); - -failed: - for (i = 0; i < n; i++) free(data[i]); - free(data); - free(binds); - free(lens); - return -1; -} - - -int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, void *mysql, const char *table_name, long size_limit, long record_limit, const char *columns) -{ - *bi = calloc(1, sizeof(*bi)); - (*bi)->ctx = ctx; - (*bi)->table_name = strdup(table_name); - (*bi)->columns = strdup(columns); - (*bi)->rec_num = 0; - (*bi)->rec_size = 0; - (*bi)->rows = calloc(record_limit, sizeof(*((*bi)->rows)) ); - (*bi)->size_limit = size_limit; - (*bi)->record_limit = record_limit; - - return CLR_ERR(ctx); -} - - -static int flush_bufferd_insert(glite_lbu_bufInsert bi) -{ - char *stmt, *vals, *temp; - long i; - - - if (!bi->rec_num) - return STATUS(bi->ctx); - - asprintf(&vals,"(%s)", bi->rows[0]); - for (i=1; i < bi->rec_num; i++) { - // XXX: use string add (preallocated memory) - asprintf(&temp,"%s,(%s)", vals, bi->rows[i]); - free(vals); vals = temp; temp = NULL; - free(bi->rows[i]); - bi->rows[i] = NULL; - } - - trio_asprintf(&stmt, "insert into %|Ss(%|Ss) values %s;", - bi->table_name, bi->columns, vals); - - if (glite_lbu_ExecSQL(bi->ctx,stmt,NULL) < 0) { - if (STATUS(bi->ctx) == EEXIST) - CLR_ERR(bi->ctx); - } - - /* reset bi counters */ - bi->rec_size = 0; - bi->rec_num = 0; - - free(vals); - free(stmt); - - return STATUS(bi->ctx); -} - - -int glite_lbu_bufferedInsert(glite_lbu_bufInsert bi, const char *row) -{ - bi->rows[bi->rec_num++] = strdup(row); - bi->rec_size += strlen(row); - - if ((bi->size_limit && bi->rec_size >= bi->size_limit) || - (bi->record_limit && bi->rec_num >= bi->record_limit)) - { - if (flush_bufferd_insert(bi)) - return STATUS(bi->ctx); - } - - return CLR_ERR(bi->ctx); -} - - -static void free_buffered_insert(glite_lbu_bufInsert bi) { - long i; - - free(bi->table_name); - free(bi->columns); - for (i=0; i < bi->rec_num; i++) { - free(bi->rows[i]); - } - free(bi->rows); -} - - -int glite_lbu_bufferedInsertClose(glite_lbu_bufInsert bi) -{ - if (flush_bufferd_insert(bi)) - return STATUS(bi->ctx); - free_buffered_insert(bi); - - return CLR_ERR(bi->ctx); -} - - -/* - * helping compatibility function: clear error from the context - */ -static int lbu_clrerr(glite_lbu_DBContext ctx) { - ctx->err.code = 0; - if (ctx->err.desc) { - free(ctx->err.desc); - ctx->err.desc = NULL; - } - return 0; -} - - -/* - * helping compatibility function: sets error on the context - */ -static int lbu_err(glite_lbu_DBContext ctx, int code, const char *desc, const char *func, int line) { - if (code) { - ctx->err.code = code; - free(ctx->err.desc); - ctx->err.desc = desc ? strdup(desc) : NULL; - fprintf(stderr, "[db] %s:%d %s\n", func, line, desc); - return code; - } else - return ctx->err.code; -} - - -/* - * helping function: find oud mysql error and sets on the context - */ -static int myerr(glite_lbu_DBContext ctx, const char *source, int line) { - return lbu_err(ctx, EIO, mysql_error(ctx->mysql), source, line); -} - - -/* - * helping function: find oud mysql stmt error and sets on the context - */ -static int myerrstmt(glite_lbu_Statement stmt, const char *source, int line) { - return lbu_err(stmt->ctx, EIO, mysql_stmt_error(stmt->stmt), source, line); -} - - -/* - * Ehelping function: error handle - * - * \return -1 failed - * \return 0 retry - * \return 1 OK - */ -static int myisokstmt(glite_lbu_Statement stmt, const char *source, int line, int *retry) { - switch (mysql_stmt_errno(stmt->stmt)) { - case 0: - return 1; - break; - case ER_DUP_ENTRY: - lbu_err(stmt->ctx, EEXIST, mysql_stmt_error(stmt->stmt), source, line); - return -1; - break; - case CR_SERVER_LOST: - if (*retry > 0) { - (*retry)--; - return 0; - } else - return -1; - break; - default: - myerrstmt(stmt, source, line); - return -1; - break; - } -} - - -/* - * mysql connect - */ -static int db_connect(glite_lbu_DBContext ctx, const char *cs, MYSQL **mysql) { - char *buf = NULL; - char *host,*user,*pw,*db; - char *slash,*at,*colon; - int ret; - - // needed for SQL result parameters - assert(sizeof(int) >= sizeof(my_bool)); - - if (!cs) return ERR(ctx, EINVAL, "connect string not specified"); - - if (!(*mysql = mysql_init(NULL))) return ERR(ctx, ENOMEM, NULL); - - mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my"); - - host = user = pw = db = NULL; - - buf = strdup(cs); - slash = strchr(buf,'/'); - at = strrchr(buf,'@'); - colon = strrchr(buf,':'); - - if (!slash || !at || !colon) { - free(buf); - db_close(*mysql); - *mysql = NULL; - return ERR(ctx, EINVAL, "Invalid DB connect string"); - } - - *slash = *at = *colon = 0; - host = at+1; - user = buf; - pw = slash+1; - db = colon+1; - - /* ljocha: CLIENT_FOUND_ROWS added to make authorization check - * working in update_notif(). - * Hope it does not break anything else */ - if (!mysql_real_connect(*mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { - free(buf); - ret = MY_ERR(ctx); - glite_lbu_DBClose(ctx); - return ret; - } - free(buf); - - ctx->cs = cs; - return 0; -} - - -/* - * mysql close - */ -static void db_close(MYSQL *mysql) { - if (mysql) mysql_close(mysql); -} - - -/* - * test transactions capability: - * - * 1) with connection 1 create testing table test - * 2) with connection 1 insert a value - * 3) with connection 2 look for a value, transactions are for no error and - * no items found - * 4) with connection 1 commit and drop the table - */ -static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions) { - MYSQL *m1; - char *desc, *cmd_create, *cmd_insert, *cmd_select, *cmd_drop; - int retval; - int err; - pid_t pid; - - ctx->caps |= GLITE_LBU_DB_CAP_TRANSACTIONS; - pid = getpid(); - *have_transactions = 0; - - asprintf(&cmd_create, "CREATE TABLE test%d (item INT)", pid); - asprintf(&cmd_insert, "INSERT INTO test%d (item) VALUES (1)", pid); - asprintf(&cmd_select, "SELECT item FROM test%d", pid); - asprintf(&cmd_drop, "DROP TABLE test%d", pid); - - m1 = ctx->mysql; - glite_lbu_ExecSQL(ctx, cmd_drop, NULL); - if (glite_lbu_ExecSQL(ctx, cmd_create, NULL) != 0) goto err1; - if (glite_lbu_Transaction(ctx) != 0) goto err2; - if (glite_lbu_ExecSQL(ctx, cmd_insert, NULL) != 1) goto err2; - - ctx->mysql = m2; - if ((retval = glite_lbu_ExecSQL(ctx, cmd_select, NULL)) == -1) goto err2; - - ctx->mysql = m1; - if (glite_lbu_Commit(ctx) != 0) goto err2; - if (glite_lbu_ExecSQL(ctx, cmd_drop, NULL) != 0) goto err1; - -#ifdef LBS_DB_PROFILE - fprintf(stderr, "[%d] use_transactions = %d\n", getpid(), USE_TRANS(ctx)); -#endif - - *have_transactions = retval == 0; - goto ok; -err2: - err = ctx->err.code; - desc = ctx->err.desc; - glite_lbu_ExecSQL(ctx, cmd_drop, NULL); - ctx->err.code = err; - ctx->err.desc = desc; -err1: -ok: - free(cmd_create); - free(cmd_insert); - free(cmd_select); - free(cmd_drop); - return STATUS(ctx); -} - - -/* - * simple version of the fetch - */ -static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results) { - MYSQL_ROW row; - int nr, i; - unsigned long *len; - - CLR_ERR(ctx); - - if (!(row = mysql_fetch_row(result))) { - if (mysql_errno((MYSQL *) ctx->mysql)) { - MY_ERR(ctx); - return -1; - } else return 0; - } - - nr = mysql_num_fields(result); - len = mysql_fetch_lengths(result); - for (i=0; inrfields) { - ERR(ctx, EINVAL, "bad number of result fields"); - return -1; - } - - // space for results - if (n) binds = calloc(n, sizeof(MYSQL_BIND)); - if (!lengths) { - lens = calloc(n, sizeof(unsigned long)); - lengths = lens; - } - for (i = 0; i < n; i++) { - binds[i].buffer_type = MYSQL_TYPE_VAR_STRING; - binds[i].buffer_length = GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH - 1; - binds[i].length = &lengths[i]; - binds[i].buffer = results[i] = calloc(1, GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH); - } - if (mysql_stmt_bind_result(stmt->stmt, binds) != 0) goto failedstmt; - - // fetch data, all can be truncated - retry = 1; - do { - switch(mysql_stmt_fetch(stmt->stmt)) { -#ifdef MYSQL_DATA_TRUNCATED - case MYSQL_DATA_TRUNCATED: -#endif - case 0: - ret = 1; break; - case 1: ret = MY_ISOKSTMT(stmt, &retry); break; - case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */ - default: ERR(ctx, EIO, "other fetch error"); goto failed; - } - } while (ret == 0); - if (ret == -1) goto failed; - - // check if all fileds had enough buffer space - for (i = 0; i < n; i++) { - // fetch the rest if needed - if (lengths[i] > binds[i].buffer_length) { - unsigned int fetched; - - fetched = binds[i].buffer_length; - if ((results[i] = realloc(results[i], lengths[i] + 1)) == NULL) { - ERR(ctx, ENOMEM, "insufficient memory for field data"); - goto failed; - } - results[i][lengths[i]] = '\000'; - binds[i].buffer = results[i] + fetched; - binds[i].buffer_length = lengths[i] - fetched; - - retry = 1; - do { - switch (mysql_stmt_fetch_column(stmt->stmt, binds + i, i, fetched)) { - case 0: ret = 1; break; - case 1: ret = MY_ISOKSTMT(stmt, &retry); break; - case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */ - default: ERR(ctx, EIO, "other fetch error"); goto failed; - } - } while (ret == 0); - if (ret == -1) goto failed; - } - } - - CLR_ERR(ctx); - free(binds); - free(lens); - return n; - -failedstmt: - MY_ERRSTMT(stmt); -failed: - ret = -1; -quit: - free(binds); - free(lens); - for (i = 0; i < n; i++) { - free(results[i]); - results[i] = NULL; - } - return ret; -} - - -void set_time(MYSQL_TIME *mtime, const time_t time) { - struct tm tm; - - gmtime_r(&time, &tm); - mtime->year = tm.tm_year + 1900; - mtime->month = tm.tm_mon + 1; - mtime->day = tm.tm_mday; - mtime->hour = tm.tm_hour; - mtime->minute = tm.tm_min; - mtime->second = tm.tm_sec; -} - - -time_t get_time(const MYSQL_TIME *mtime) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - tm.tm_year = mtime->year - 1900; - tm.tm_mon = mtime->month - 1; - tm.tm_mday = mtime->day; - tm.tm_hour = mtime->hour; - tm.tm_min = mtime->minute; - tm.tm_sec = mtime->second; - - return mktime(&tm); -} diff --git a/org.glite.lb-utils.jobid/.cvsignore b/org.glite.lb-utils.jobid/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.jobid/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.jobid/LICENSE b/org.glite.lb-utils.jobid/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.jobid/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.jobid/Makefile b/org.glite.lb-utils.jobid/Makefile deleted file mode 100644 index 986b5e0..0000000 --- a/org.glite.lb-utils.jobid/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-lb-utils-jobid -version=0.0.0 -PREFIX=/opt/glite -lbuprefix=lbu - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/test::${top_srcdir}/doc - -CC=gcc - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} -I${top_srcdir}/src -I${top_srcdir}/interface -I. -D_GNU_SOURCE - -COMPILE:=libtool --mode=compile ${CC} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -OBJS:=cjobid.o strmd5.o -LOBJS:=${OBJS:.o=.lo} - -HDRS:=cjobid.h strmd5.h Exception.h JobId.h JobIdExceptions.h - -STATICLIB:=libglite_lbu_jobid.a -LTLIB:=libglite_lbu_jobid.la - -default: all - -all compile: ${STATICLIB} ${LTLIB} - -# to use libtool versioning correcty, we should have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# -# version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` - -# counted minors: n/a -offset=0 - -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -${STATICLIB}: ${OBJS} - ar crv $@ ${OBJS} - ranlib $@ - -${LTLIB}: ${OBJS} - ${LINK} ${version_info} -o $@ ${LOBJS} - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -check: - @true - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - mkdir -p ${PREFIX}/lib - mkdir -p ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 644 ${LTLIB} ${PREFIX}/lib - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - if [ x${DOSTAGE} = xyes ]; then \ - mkdir -p ${PREFIX}/include/${globalprefix}/${lbuprefix} ; \ - (cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbuprefix}) ; \ - install -m 644 ${STATICLIB} ${PREFIX}/lib; \ - fi - -clean: - -%.o: %.c - ${COMPILE} ${CFLAGS} -c $< diff --git a/org.glite.lb-utils.jobid/build.xml b/org.glite.lb-utils.jobid/build.xml deleted file mode 100644 index e6cc422..0000000 --- a/org.glite.lb-utils.jobid/build.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.jobid/interface/Exception.h b/org.glite.lb-utils.jobid/interface/Exception.h deleted file mode 100644 index 21a9064..0000000 --- a/org.glite.lb-utils.jobid/interface/Exception.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H -#define GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H - -/* - * Exception.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * Contributors are mentioned in the code where appropriate. - */ - -#include -#include -//#include -#include // For logging exceptions to log file -#include // list the exception codes -#include -#include -#include // base ancestor stl::exception - - -namespace glite { - namespace lb_utils { - namespace exception { - -extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog) -#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try { -#define GLITE_STACK_CATCH() } catch (glite::lb_utils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; } catch (std::exception &ex){ glite::lb_utils::exception::Exception exc( __FILE__ , LINE, METHOD, 0, "Standard exception: " + std::string(ex.what()) ); throw exc; } - -/** - * The Exception base classe contains attributes into which are placed exception information and provides - * constructor that beyond the error code take parameters specifying the source file and line number - * (e.g. through __FILE__ and __LINE__) where the error has been generated and string messages, - * allowing an easy way of storing the origin of the exception. - * Moreover it provides methods for getting all the exception information and for logging them either - * in a log file or to the syslog daemon. - * Each of the derived types may contain its private attributes describing the actual error instance in detail. - * Moreover each exception has an attribute representing the exception identifier that is set by the - * class constructor and allows the identification of the original exception. - * - * @version 0.1 - * @date 22 July 2004 - * @author Alessandro Maraschini -*/ - -class Exception : public std::exception{ - public: - /** - * Constructor Update all mandatory fields - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) - * @param exc the previous exception as in the stack trace */ - Exception ( const std::string& source, const std::string& method, Exception *exc); - /** - * Constructor Update all mandatory fields - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) */ - Exception ( const std::string& source, const std::string& method, int code, const std::string& exception); - - /** - * Constructor Update all mandatory fields - * @param source the path of the file that raised the exception - * @param line_number the number of the line in the file that raised the exception - * @param method the name of the method that raised the exception - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception */ - Exception (const std::string& source, int line_number, const std::string& method, int code, const std::string& exception); - /** - * Default Destructor - */ - virtual ~Exception() throw (); - /** - * Return a string debug message containing information about Exception thrown - * Debug message contains all the attributes stored in an exception instance such as the method, the file and the line - * that threw the exception. - *@return the debug message string representation - */ - virtual std::string dbgMessage(); - /** - * Return the error code - * @return The integer representing the code of the error that generated the exception - */ - virtual int getCode(); - - /** - * return the Error Message associated to the Exception - * @return The Exception string message representation - */ - virtual const char* what() const throw (); - - /** - * Print Exception error information into a log file - * @param logfile the file where to log exception information - */ - virtual void log(const std::string& logfile = ""); - /** - * Retrieve the Exception name - * @return the name of the Exception thrown - */ - virtual std::string getExceptionName(); - - /** - * Retrieve the Stack of the exception as a list of previous generated exceptions - *@return the string representation of the stack trace: each line correspond to an exception message - */ - virtual std::string printStackTrace() ; - /** - * Return the list of methods that caused the Exception - */ - virtual std::vector getStackTrace() ; - /** - * Update stack information - */ - virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ; - protected: - /** Empty constructor*/ - Exception(); - /** integer error code representing the cause of the error */ - int error_code; - /** string exception message representation*/ - std::string error_message ; - /** line number where the exception was raised */ - int line; - /** The name of the file where the exception was raised */ - std::string source_file; - /** the name of the exception */ - std::string exception_name; - /** the name of the method where the expceiton was raised */ - std::string method_name ; - /** a string representation of the stacktrace */ - std::string stack; - /** the actual internal stacktrace representation */ - std::vector< std::string> stack_strings ; - /** the name of the ancestor exception */ - std::string ancestor ; -}; //End Exception Class -}}} // Closing namespace -#endif diff --git a/org.glite.lb-utils.jobid/interface/JobId.h b/org.glite.lb-utils.jobid/interface/JobId.h deleted file mode 100644 index b99992d..0000000 --- a/org.glite.lb-utils.jobid/interface/JobId.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_JOBID_H -#define GLITE_WMSUTILS_JOBID_JOBID_H - -/* - * JobId.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * - */ - -#include -#include - -#include "glite/lb-utils/cjobid.h" - -typedef struct _glite_lbu_jobid_s* glite_lbu_jobid_t; - -namespace glite { -namespace lb_utils { -namespace jobid { - -/** - * Managing Identification, checking, retreiving info from a job - * File name: JobId.h - * The JobId class provides a representation of the Datagrid job identifier - * (dg_jobId) and the methods for manipulating it. - * We remind that the format of the dg_jobId is as follows: - * :/ - * - * @ingroup common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini */ - -class JobId { -public: - /**@name Constructors/Destructor */ - //@{ - /** Instantiates an empty JobId object */ - JobId() ; - /** - * Instantiates a JobId object from the passed dg_jobId in string format. - * @param job_id_string a string representig a classAd expression - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const std::string& job_id_string); - JobId(const JobId&); - JobId(const glite_lbu_JobId&); - /** - * Destructor - * Destroy the Job Id instance - */ - ~JobId() ; - //@} - - /**@name Miscellaneous */ - //@{ - /** Unsets the JobId instance. Clear all it's memebers */ - void clear() ; - /** - * Check wheater the jobId has been already created (true) or not (false) - *@return true (jobId created) or false (jobId not yet created) - */ - bool isSet() { return ( m_JobId != 0 ) ; } - /** - * Set the JobId instance according to the LB and RB server addresses and the unique string passed as input parameters. - * @param lb_server Loggin and Bookkeeping server address - * @param port Loggin and Bookkeeping port ( dafault value is 9000 ) - * @param unique A Unique identification ( automatically generatad by md5 protocol ) - * @throws WrongIdException When one parameter has been passed in a wrong format */ - void setJobId(const std::string& lb_server, int port = 0, const std::string& unique = ""); - //@} - /**@name Get Methods */ - //@{ - /** @return the LB address into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getServer() const; - /** @return the Unique string into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getUnique() const; - //@} - /** This method sets the JobId instance from the JobId in string format given - * as input. - * @param dg_JobId the string representing the job - * @throws WrongIdException When a string is passed in a wrong format */ - void fromString ( const std::string& dg_JobId ); - /** Converts the jobId into a string - @return the string representation of a JobId*/ - std::string toString() const; - /** casting operator */ - operator const glite_lbu_JobId() const { return m_JobId; } - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(JobId const &); - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(const glite_lbu_JobId &); - /** Retrieve the internal id reference - *@return the JobId internal reference used by some LB methods */ - glite_lbu_JobId getId() const ; -private: - // This Variable stores the Job unique identification String - glite_lbu_JobId m_JobId; - mutable char* m_pStr; - mutable char* m_pBkserver; - mutable char* m_pUnique; - /** Operator "<"*/ - friend bool operator<(JobId const& lhs, JobId const& rhs); - /** Operator "=="*/ - friend bool operator==(JobId const& lhs, JobId const& rhs); -}; - -inline bool operator<(JobId const& lhs, JobId const& rhs) -{ - return strcmp ( lhs.m_pStr , rhs.m_pStr ) <0 ; -} - -inline bool operator==(JobId const& lhs, JobId const& rhs) -{ -return strcmp ( lhs.m_pStr , rhs.m_pStr ) ==0 ; -} - -std::ostream& operator<<(std::ostream& os, JobId const& id); - -} // namespace jobid -} // namespace lb_utils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_JOBID_H diff --git a/org.glite.lb-utils.jobid/interface/JobIdExceptions.h b/org.glite.lb-utils.jobid/interface/JobIdExceptions.h deleted file mode 100644 index d154adf..0000000 --- a/org.glite.lb-utils.jobid/interface/JobIdExceptions.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_EXCEPTIONS_H -#define GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - -/* - * JobIdExceptions.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - */ - -#include "glite/lb-utils/Exception.h" - -namespace glite { -namespace lb_utils { -namespace jobid { - -/** - * JobIdException - Exception thrown by JobId Class - * @ingroup Common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini -*/ - -class JobIdException : public glite::lb_utils::exception::Exception { -public: - /** - * Update all mandatory Exception Information - */ - JobIdException (const std::string& file, - int line, - const std::string& method, - int code, - const std::string& exception_name) ; -};//End CLass JobIdException - -/** -* WrongIdFieldException -* This Exception is thrown when a Job Id syntax error is found -* A valid Job Identification string should be made as follows: -* :/ */ -class WrongIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The wrong expression catched */ - WrongIdException(const std::string& file, - int line, - const std::string& method, - int code ); -}; //End CLass WrongIdException -/** -* EmptyIdException -* This Exception is thrown when the user tries to get information from a JobId -* which has not been initialized yet, i.e tries to use the get Methods -*/ -class EmptyIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The Empty filed requested for */ - EmptyIdException::EmptyIdException(const std::string& file, - int line, - const std::string& method, - int code , - const std::string& field ); -}; //End CLass EmptyIdException - -} // namespace jobid -} // namespace lb_utils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - diff --git a/org.glite.lb-utils.jobid/interface/cjobid.h b/org.glite.lb-utils.jobid/interface/cjobid.h deleted file mode 100755 index f802ce7..0000000 --- a/org.glite.lb-utils.jobid/interface/cjobid.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _GLITE_JOBID_H -#define _GLITE_JOBID_H - -/*! - * \file cjobid.h - * \brief L&B consumer API - */ - -#ident "$Header$" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _glite_lbu_JobId *glite_lbu_JobId; - -#define GLITE_WMSC_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */ -#define GLITE_WMSC_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */ - - -/* All the pointer functions return malloc'ed objects (or NULL on error) */ - -/** - * Create a Job ID. - * See the lb_draft document for details on its construction and components - * \param bkserver book keeping server hostname - * \param port port for the bk service - * \param jobid new created job id - * \ret al 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdCreate(const char * bkserver, int port, glite_lbu_JobId * jobid); - -/** - * Recreate a Job ID - * \param bkserver bookkeeping server hostname - * \param port port for the bk service - * \param unique string which represent created jobid (if NULL then new - * one is created) - * \param jobid new created job id - * \retval 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdRecreate(const char *bkserver, int port, const char * unique, glite_lbu_JobId * jobid); - -/** - * Create copy of Job ID - * \param in jobid for duplication - * \param jobid duplicated jobid - * \retval 0 for success - * \retval EINVAL invalid jobid - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdDup(const glite_lbu_JobId in, glite_lbu_JobId * jobid); - -/* - * Free jobid structure - * \param jobid for dealocation - */ -void glite_lbu_JobIdFree(glite_lbu_JobId jobid); - -/** - * Parse Job ID string and creates jobid structure - * \param jobidstr string representation of jobid - * \param jobid parsed job id - * \retval 0 for success - * \retval EINVAL jobidstr can't be parsed - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdParse(const char* jobidstr, glite_lbu_JobId * jobid); - -/** - * Unparse Job ID (produce the string form of JobId). - * \param jobid to be converted to string - * \return allocated string which represents jobid - */ -char* glite_lbu_JobIdUnparse(const glite_lbu_JobId jobid); - -/** - * Extract bookkeeping server address (address:port) - * \param jobid from which the bkserver address should be extracted - * \retval pointer to allocated string with bkserver address - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_lbu_JobIdGetServer(const glite_lbu_JobId jobid); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void glite_lbu_JobIdGetServerParts(const glite_lbu_JobId jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_lbu_JobIdGetUnique(const glite_lbu_JobId jobid); - -#ifdef __cplusplus -} -#endif - -#endif /* _GLITE_JOBID_H */ diff --git a/org.glite.lb-utils.jobid/interface/strmd5.h b/org.glite.lb-utils.jobid/interface/strmd5.h deleted file mode 100755 index 27d8544..0000000 --- a/org.glite.lb-utils.jobid/interface/strmd5.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ident "$Header$" - -/* Compute MD5 sum of the first argument. - * The sum is returned in the 16-byte array pointed to by 2nd argument - * (if not NULL) - * - * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f] - * (pointer to static area, changed by subsequent calls) - */ - -#ifdef USE_MBUF -char *strmd5(const char *src, unsigned char *dst); -#endif - -/** - * Returns: allocated 32bytes long ASCII string with md5 sum - * of the first argument - */ -char *str2md5(const char *src); - -/** - * Returns: allocated 22bytes long ASCII string with md5 sum in base64 - * format of the source argument - */ -char *str2md5base64(const char *src); - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.lb-utils.jobid/project/build.number b/org.glite.lb-utils.jobid/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.jobid/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.jobid/project/build.properties b/org.glite.lb-utils.jobid/project/build.properties deleted file mode 100755 index 89232f3..0000000 --- a/org.glite.lb-utils.jobid/project/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -# temporary hack before lb-utils are integrated - -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils diff --git a/org.glite.lb-utils.jobid/project/configure.properties.xml b/org.glite.lb-utils.jobid/project/configure.properties.xml deleted file mode 100644 index 23ba931..0000000 --- a/org.glite.lb-utils.jobid/project/configure.properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbuprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} - - - - diff --git a/org.glite.lb-utils.jobid/project/properties.xml b/org.glite.lb-utils.jobid/project/properties.xml deleted file mode 100644 index 1adf343..0000000 --- a/org.glite.lb-utils.jobid/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.jobid/project/tar_exclude b/org.glite.lb-utils.jobid/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.lb-utils.jobid/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.lb-utils.jobid/project/version.properties b/org.glite.lb-utils.jobid/project/version.properties deleted file mode 100755 index 52a0f68..0000000 --- a/org.glite.lb-utils.jobid/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 1.0.0 -module.age = 0 diff --git a/org.glite.lb-utils.jobid/src/cjobid.c b/org.glite.lb-utils.jobid/src/cjobid.c deleted file mode 100755 index 6d6a73f..0000000 --- a/org.glite.lb-utils.jobid/src/cjobid.c +++ /dev/null @@ -1,260 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "cjobid.h" -#include "strmd5.h" - -struct _glite_lbu_JobId { - char *id; /* unique job identification */ - /* additional information */ - char *BShost;/* bookkeeping server hostname */ - unsigned int BSport; /* bookkeeping server port */ - char *info; /* additional information (after ? in URI) */ -}; - -int glite_lbu_JobIdCreate(const char *bkserver, int port, glite_lbu_JobId *jobId) -{ - return glite_lbu_JobIdRecreate(bkserver, port, NULL, jobId); -} - - -int glite_lbu_JobIdRecreate(const char* bkserver, int port, const char *unique, glite_lbu_JobId *jobId) -{ - glite_lbu_JobId out; - char hostname[200]; /* used to hold string for encrypt */ - struct timeval tv; - int skip; - char* portbeg; - - struct hostent* he; - - if (!bkserver) - return EINVAL; - - if (unique == NULL) { - gethostname(hostname, 100); - he = gethostbyname(hostname); - assert(he->h_length > 0); - gettimeofday(&tv, NULL); - srandom(tv.tv_usec); - - skip = strlen(hostname); - skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d", - *((int*)he->h_addr_list[0]), getpid(), (int)random(), - (int)tv.tv_sec, (int)tv.tv_usec); - } - - *jobId = NULL; - out = (glite_lbu_JobId) malloc (sizeof(*out)); - if (!out) - return ENOMEM; - - memset(out, 0, sizeof(*out)); - - /* check if it begins with prefix */ - /* unsupported */ - if (strncmp(bkserver, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX)-1) == 0) - return EINVAL; - - out->BShost = strdup(bkserver); - portbeg = strchr(out->BShost, ':'); - if (portbeg) { - *portbeg = 0; - /* try to get port number */ - if (port == 0) - port = atoi(portbeg + 1); - } - - if (port == 0) - port = GLITE_WMSC_JOBID_DEFAULT_PORT; - - out->BSport = port; - - out->id = (unique) ? strdup(unique) : str2md5base64(hostname); - //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id); - - if (!out->id || !out->BShost) { - glite_lbu_JobIdFree(out); - return ENOMEM; - } - - *jobId = out; - return 0; -} - - -int glite_lbu_JobIdDup(const glite_lbu_JobId in, glite_lbu_JobId *out) -{ - glite_lbu_JobId jid; - *out = NULL; - if (in == NULL) - return 0; - - jid = malloc(sizeof(*jid)); - if (!jid) - return ENOMEM; - - memset(jid, 0,sizeof(*jid)); - jid->BShost = strdup(in->BShost); - jid->id = strdup(in->id); - if (in->info) - jid->info = strdup(in->info); - - if (jid->BShost == NULL || jid->id == NULL) { - glite_lbu_JobIdFree(jid); - return ENOMEM; - } - - jid->BSport = in->BSport; - *out = jid; - return 0; -} - - -// XXX -// use recreate -// parse name, port, unique -int glite_lbu_JobIdParse(const char *idString, glite_lbu_JobId *jobId) -{ - char *pom, *pom1, *pom2; - glite_lbu_JobId out; - - *jobId = NULL; - - out = (glite_lbu_JobId) malloc (sizeof(*out)); - if (out == NULL ) - return ENOMEM; - - memset(out,0,sizeof(*out)); - - if (strncmp(idString, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1)) { - out->BShost = (char *) NULL; - out->BSport = 0; - - free(out); - return EINVAL; - } - - pom = strdup(idString + sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1); - pom1 = strchr(pom, '/'); - pom2 = strchr(pom, ':'); - - if (!pom1) { free(pom); free(out); return EINVAL; } - - if ( pom2 && (pom1 > pom2)) { - pom[pom2-pom] = '\0'; - out->BShost = strdup(pom); - pom[pom1-pom] = '\0'; - out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10); - } else { - pom[pom1-pom] = '\0'; - out->BShost = strdup(pom); - out->BSport = GLITE_WMSC_JOBID_DEFAULT_PORT; - } - - /* XXX: localhost not supported in jobid - if (!strncmp(out->BShost,"localhost",9) { - free(pom); - free(out->BShost); - free(out); - return EINVAL; - } - */ - - /* additional info from URI */ - pom2 = strchr(pom1+1,'?'); - if (pom2) { - *pom2 = 0; - out->info = strdup(pom2+1); - } - - /* extract the unique part */ - out->id = strdup(pom1+1); - - for (pom1 = out->BShost; *pom1; pom1++) - if (isspace(*pom1)) break; - - for (pom2 = out->id; *pom2; pom2++) - if (isspace(*pom2)) break; - - if (*pom1 || *pom2) { - free(pom); - glite_lbu_JobIdFree(out); - return EINVAL; - } - - free(pom); - *jobId = out; - return 0; -} - - -void glite_lbu_JobIdFree(glite_lbu_JobId job) -{ - if (job) { - free(job->id); - free(job->BShost); - free(job->info); - free(job); - } -} - - -char* glite_lbu_JobIdUnparse(const glite_lbu_JobId jobid) -{ - char *out, port[40]; - - if (!jobid) - return NULL; - - if (jobid->BSport) - sprintf(port,":%d",jobid->BSport); - else - *port = 0; - - asprintf(&out, GLITE_WMSC_JOBID_PROTO_PREFIX"%s%s/%s%s%s", - jobid->BShost,port, - jobid->id, - (jobid->info ? "?" : ""), - (jobid->info ? jobid->info : "")); - - return out; -} - - -char* glite_lbu_JobIdGetServer(const glite_lbu_JobId jobid) -{ - char *bs = NULL; - - if (jobid) - asprintf(&bs, "%s:%u", jobid->BShost, - jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT); - - return bs; -} - - -void glite_lbu_JobIdGetServerParts(const glite_lbu_JobId jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = strdup(jobid->BShost); - *srvPort = jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT; - } -} - - -char* glite_lbu_JobIdGetUnique(const glite_lbu_JobId jobid) -{ - return jobid ? strdup(jobid->id) : NULL; -} diff --git a/org.glite.lb-utils.jobid/src/strmd5.c b/org.glite.lb-utils.jobid/src/strmd5.c deleted file mode 100755 index 775aee8..0000000 --- a/org.glite.lb-utils.jobid/src/strmd5.c +++ /dev/null @@ -1,122 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "strmd5.h" - -#if USE_MBUF /* let's try without it */ -#warning Thread unsafe! -static char mbuf[33]; -#endif - -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - unsigned char* enc_buf = (unsigned char*)enc; - int out_size = 0; - unsigned int bits = 0; - unsigned int shift = 0; - - while ( out_size < out_max_size ) { - if ( enc_size>0 ) { - // Shift in byte - bits <<= 8; - bits |= *enc_buf; - shift += 8; - // Next byte - enc_buf++; - enc_size--; - } else if ( shift>0 ) { - // Pad last bits to 6 bits - will end next loop - bits <<= 6 - shift; - shift = 6; - } else { - // Terminate with Mime style '=' - *out = '='; - out_size++; - - return out_size; - } - - // Encode 6 bit segments - while ( shift>=6 ) { - shift -= 6; - *out = b64[ (bits >> shift) & 0x3F ]; - out++; - out_size++; - } - } - - // Output overflow - return -1; -} - -#ifdef USE_MBUF -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} -#endif - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.lb-utils.server-bones/.cvsignore b/org.glite.lb-utils.server-bones/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.server-bones/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.server-bones/LICENSE b/org.glite.lb-utils.server-bones/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.server-bones/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.server-bones/build.xml b/org.glite.lb-utils.server-bones/build.xml deleted file mode 100644 index efe49ad..0000000 --- a/org.glite.lb-utils.server-bones/build.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.server-bones/project/build.number b/org.glite.lb-utils.server-bones/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.server-bones/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.server-bones/project/build.properties b/org.glite.lb-utils.server-bones/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils.server-bones/project/configure.properties.xml b/org.glite.lb-utils.server-bones/project/configure.properties.xml deleted file mode 100644 index 6ad627b..0000000 --- a/org.glite.lb-utils.server-bones/project/configure.properties.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/org.glite.lb-utils.server-bones/project/properties.xml b/org.glite.lb-utils.server-bones/project/properties.xml deleted file mode 100644 index a76d544..0000000 --- a/org.glite.lb-utils.server-bones/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.server-bones/project/version.properties b/org.glite.lb-utils.server-bones/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.server-bones/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.trio/.cvsignore b/org.glite.lb-utils.trio/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.trio/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.trio/LICENSE b/org.glite.lb-utils.trio/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.trio/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.trio/Makefile b/org.glite.lb-utils.trio/Makefile deleted file mode 100644 index 96a8386..0000000 --- a/org.glite.lb-utils.trio/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-lb-utils-trio -version=0.0.0 -PREFIX=/opt/glite -lbuprefix=lbu - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/test::${top_srcdir}/doc - -CC=gcc - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} -I${top_srcdir}/src -I${top_srcdir}/interface -I. -DDATAGRID_EXTENSION - -COMPILE:=libtool --mode=compile ${CC} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -REPORTS:=${top_srcdir}/reports -TEST_LIBS:=-L${cppunit_prefix}/lib -lcppunit -ldl -TEST_INC:=-I${cppunit_prefix}/include - - -OBJS:=trio.o strio.o escape.o -LOBJS:=${OBJS:.o=.lo} - -HDRS:=trio.h escape.h - -STATICLIB:=libglite_lbu_trio.a -LTLIB:=libglite_lbu_trio.la - -default: all - -all compile: ${STATICLIB} ${LTLIB} - -# to use libtool versioning correcty, we should have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# -# version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` - -# counted minors: n/a -offset=0 - -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -${STATICLIB}: ${OBJS} - ar crv $@ ${OBJS} - ranlib $@ - -${LTLIB}: ${OBJS} - ${LINK} ${version_info} -o $@ ${LOBJS} - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -check: compile mkreports runtest - -mkreports: - -mkdir ${REPORTS} - -runtest: trio_test - ./trio_test ${REPORTS}/trio.xml - -trio_test: trio_test.cpp - ${CXX} -c ${CFLAGS} ${TEST_INC} $< - ${LINKXX} -o $@ trio_test.o ${LTLIB} ${TEST_LIBS} - - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - mkdir -p ${PREFIX}/lib - mkdir -p ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 644 ${LTLIB} ${PREFIX}/lib - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - if [ x${DOSTAGE} = xyes ]; then \ - mkdir -p ${PREFIX}/include/${globalprefix}/${lbuprefix} ; \ - (cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbuprefix}) ; \ - install -m 644 ${STATICLIB} ${PREFIX}/lib; \ - fi - -clean: - -%.o: %.c - ${COMPILE} ${CFLAGS} -c $< diff --git a/org.glite.lb-utils.trio/build.xml b/org.glite.lb-utils.trio/build.xml deleted file mode 100644 index 7e38dda..0000000 --- a/org.glite.lb-utils.trio/build.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.trio/interface/escape.h b/org.glite.lb-utils.trio/interface/escape.h deleted file mode 100644 index 4795f68..0000000 --- a/org.glite.lb-utils.trio/interface/escape.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ -#define __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ -/*! - * \file escape.h - */ - -#ident "$Header$" - - -/*! - * \fn char *glite_lbu_EscapeULM(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string (ULM) escape all ULM_QM, ULM_BS and ULM_LF by ULM_BS - */ - -char *glite_lbu_EscapeULM(const char *); - - -/*! - * \fn char *glite_lbu_UnescapeULM(const char *str) - * \param str a string to unescape - * \return new (allocated) unescaped string - * \brief in given string (ULM) unescape all escaped ULM_QM, ULM_BS and ULM_LF - */ - -char *glite_lbu_UnescapeULM(const char *); - - -/*! - * \fn char *glite_lbu_EscapeXML(const char *str); - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string (XML) escape all unwanted characters - */ - -char *glite_lbu_EscapeXML(const char *); - - -/*! - * \fn char *glite_lbu_UnescapeXML(const char *str) - * \param str a string to unescape - * \return new (allocated) unescaped string - * \brief in given string (XML) unescape all escaped characters - */ - -char *glite_lbu_UnescapeXML(const char *); - - -/*! - * \fn char *glite_lbu_EscapeSQL(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \briefin given string (SQL) escape all unwanted characters - */ - -char *glite_lbu_EscapeSQL(const char *); - -#endif /* __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ */ diff --git a/org.glite.lb-utils.trio/interface/trio.h b/org.glite.lb-utils.trio/interface/trio.h deleted file mode 100644 index 04f133c..0000000 --- a/org.glite.lb-utils.trio/interface/trio.h +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIO_H -#define TRIO_TRIO_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* make utility and C++ compiler in Windows NT fails to find this symbol */ -#if defined(WIN32) && !defined(isascii) -# define isascii ((unsigned)(x) < 0x80) -#endif - -/* - * Error codes. - * - * Remember to add a textual description to trio_strerror. - */ -enum { - TRIO_EOF = 1, - TRIO_EINVAL = 2, - TRIO_ETOOMANY = 3, - TRIO_EDBLREF = 4, - TRIO_EGAP = 5, - TRIO_ENOMEM = 6, - TRIO_ERANGE = 7 -}; - -/* Error macros */ -#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) -#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) -#define TRIO_ERROR_NAME(x) trio_strerror(x) - -const char *trio_strerror(int); - -/************************************************************************* - * Print Functions - */ - -int trio_printf(const char *format, ...); -int trio_vprintf(const char *format, va_list args); -int trio_printfv(const char *format, void **args); - -int trio_fprintf(FILE *file, const char *format, ...); -int trio_vfprintf(FILE *file, const char *format, va_list args); -int trio_fprintfv(FILE *file, const char *format, void **args); - -int trio_dprintf(int fd, const char *format, ...); -int trio_vdprintf(int fd, const char *format, va_list args); -int trio_dprintfv(int fd, const char *format, void **args); - -/* trio_sprintf(target, format, ...) - * trio_snprintf(target, maxsize, format, ...) - * - * Build 'target' according to 'format' and succesive - * arguments. This is equal to the sprintf() and - * snprintf() functions. - */ -int trio_sprintf(char *buffer, const char *format, ...); -int trio_vsprintf(char *buffer, const char *format, va_list args); -int trio_sprintfv(char *buffer, const char *format, void **args); - -int trio_snprintf(char *buffer, size_t max, const char *format, ...); -int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format, - va_list args); -int trio_snprintfv(char *buffer, size_t bufferSize, const char *format, - void **args); - -int trio_snprintfcat(char *buffer, size_t max, const char *format, ...); -int trio_vsnprintfcat(char *buffer, size_t bufferSize, const char *format, - va_list args); - -char *trio_aprintf(const char *format, ...); -char *trio_vaprintf(const char *format, va_list args); - -int trio_asprintf(char **ret, const char *format, ...); -int trio_vasprintf(char **ret, const char *format, va_list args); - -/************************************************************************* - * Scan Functions - */ -int trio_scanf(const char *format, ...); -int trio_vscanf(const char *format, va_list args); -int trio_scanfv(const char *format, void **args); - -int trio_fscanf(FILE *file, const char *format, ...); -int trio_vfscanf(FILE *file, const char *format, va_list args); -int trio_fscanfv(FILE *file, const char *format, void **args); - -int trio_dscanf(int fd, const char *format, ...); -int trio_vdscanf(int fd, const char *format, va_list args); -int trio_dscanfv(int fd, const char *format, void **args); - -int trio_sscanf(const char *buffer, const char *format, ...); -int trio_vsscanf(const char *buffer, const char *format, va_list args); -int trio_sscanfv(const char *buffer, const char *format, void **args); - -/************************************************************************* - * Renaming - */ -#ifdef TRIO_REPLACE_STDIO -/* Replace the functions */ -#ifndef HAVE_PRINTF -# define printf trio_printf -#endif -#ifndef HAVE_VPRINTF -# define vprintf trio_vprintf -#endif -#ifndef HAVE_FPRINTF -# define fprintf trio_fprintf -#endif -#ifndef HAVE_VFPRINTF -# define vfprintf trio_vfprintf -#endif -#ifndef HAVE_SPRINTF -# define sprintf trio_sprintf -#endif -#ifndef HAVE_VSPRINTF -# define vsprintf trio_vsprintf -#endif -#ifndef HAVE_SNPRINTF -# define snprintf trio_snprintf -#endif -#ifndef HAVE_VSNPRINTF -# define vsnprintf trio_vsnprintf -#endif -#ifndef HAVE_SCANF -# define scanf trio_scanf -#endif -#ifndef HAVE_VSCANF -# define vscanf trio_vscanf -#endif -#ifndef HAVE_FSCANF -# define fscanf trio_fscanf -#endif -#ifndef HAVE_VFSCANF -# define vfscanf trio_vfscanf -#endif -#ifndef HAVE_SSCANF -# define sscanf trio_sscanf -#endif -#ifndef HAVE_VSSCANF -# define vsscanf trio_vsscanf -#endif -/* These aren't stdio functions, but we make them look similar */ -#define dprintf trio_dprintf -#define vdprintf trio_vdprintf -#define aprintf trio_aprintf -#define vaprintf trio_vaprintf -#define asprintf trio_asprintf -#define vasprintf trio_vasprintf -#define dscanf trio_dscanf -#define vdscanf trio_vdscanf -#endif - -/* strio compatible names */ -#define StrScan trio_sscanf -#define StrFormat trio_sprintf -#define StrFormatMax trio_snprintf -#define StrFormatAlloc trio_aprintf -#define StrFormatAppendMax trio_snprintfcat - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRIO_TRIO_H */ diff --git a/org.glite.lb-utils.trio/project/build.number b/org.glite.lb-utils.trio/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.trio/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.trio/project/build.properties b/org.glite.lb-utils.trio/project/build.properties deleted file mode 100755 index 89232f3..0000000 --- a/org.glite.lb-utils.trio/project/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -# temporary hack before lb-utils are integrated - -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils diff --git a/org.glite.lb-utils.trio/project/configure.properties.xml b/org.glite.lb-utils.trio/project/configure.properties.xml deleted file mode 100644 index d743f4b..0000000 --- a/org.glite.lb-utils.trio/project/configure.properties.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbuprefix=${subsystem.prefix} -package=${module.package.name} -cppunit_prefix=${with.cppunit.prefix} -PREFIX=${install.dir} - - - - - diff --git a/org.glite.lb-utils.trio/project/properties.xml b/org.glite.lb-utils.trio/project/properties.xml deleted file mode 100644 index e472152..0000000 --- a/org.glite.lb-utils.trio/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.trio/project/version.properties b/org.glite.lb-utils.trio/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.trio/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.trio/src/escape.c b/org.glite.lb-utils.trio/src/escape.c deleted file mode 100644 index 9a1d545..0000000 --- a/org.glite.lb-utils.trio/src/escape.c +++ /dev/null @@ -1,224 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "escape.h" - -#define ULM_QM '"' -#define ULM_BS '\\' -#define ULM_LF '\n' - -/* - *---------------------------------------------------------------------- - * - * \fn char *glite_lbu_EscapeULM(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string escape all ULM_QM, ULM_BS and ULM_LF by ULM_BS - * - * Calls: malloc, strlen - * - * Algorithm: array lookup - * - the new string will be allocated - * - *---------------------------------------------------------------------- - */ - -char *glite_lbu_EscapeULM(const char *str) -{ -unsigned int i,j; -size_t size; -char *ret; - -if (str == NULL) return NULL; -if ((size = strlen(str)) == 0) return strdup(""); - -ret = (char*) malloc(1+2*size*sizeof(char)); - -j = 0; -for (i=0; i',"gt" }, - { '&',"amp" }, - { '"',"quot" }, - { '\'',"apos" }, - { 0, NULL } -}; - -#define XML_ESCAPE_SET "<>&\"'" - -char *glite_lbu_EscapeXML(const char *in) -{ - const char* tmp_in; - char *out; - int cnt,i,j,k; - - if (!in) return NULL; - - for (cnt = 0, tmp_in = in; *tmp_in != '\0'; ++tmp_in) { - if (strchr(XML_ESCAPE_SET, *tmp_in) || - (*tmp_in & 0x7f) < 0x20 /* control character */ || - (*tmp_in == '%')) cnt++; - } - - out = malloc(strlen(in)+1+cnt*5); - - for (i=j=0; in[i]; i++) { - for (k=0; xml_etab[k].c && xml_etab[k].c != in[i]; k++); - if (xml_etab[k].c) { - int l; - - out[j++] = '&'; - memcpy(out+j,xml_etab[k].e,l=strlen(xml_etab[k].e)); - j += l; - out[j++] = ';'; - } else if ((in[i] & 0x7f) < 0x20 || in[i] == '%') { - sprintf(out+j, "%%%02x", (unsigned char)in[i]); - j+=3; - } else { - out[j++] = in[i]; - } - } - out[j] = 0; - return out; -} - -char *glite_lbu_UnescapeXML(const char *in) -{ - char *out; - int i,j,k; - char xtmp[3]; - unsigned char origchar; - - if (!in) return NULL; - out = malloc(strlen(in)+1); - - for (i=j=0; in[i]; j++) if (in[i] == '&') { - char *s = strchr(in+i,';'); - if (s) { - int l = s-in-i+1; - for (k=0; xml_etab[k].c && strncasecmp(in+i+1,xml_etab[k].e,l-2); k++); - if (xml_etab[k].c) { - out[j] = xml_etab[k].c; - i += l; - } else out[j] = in[i++]; - } else out[j] = in[i++]; - } else if (in[i] == '%') { - if (isxdigit(xtmp[0]=in[i+1]) && isxdigit(xtmp[1]=in[i+2])) { - xtmp[2] = '\0'; - origchar = (unsigned char) strtol(xtmp, NULL, 16); - if ((origchar & 0x7f) < 0x20 || origchar == '%') { - out[j] = origchar; - i += 3; - } else out[j] = in[i++]; - } else out[j] = in[i++]; - } else { - out[j] = in[i++]; - } - out[j] = 0; - return out; -} - -char *glite_lbu_EscapeSQL(const char *in) -{ - const char* tmp_in; - char *out = NULL; - int i,j,cnt; - - if (!in) return NULL; - - for (cnt = 0, tmp_in = in; (tmp_in = strchr(tmp_in,'\'')) != NULL; ++tmp_in) { - ++cnt; - } - for (tmp_in = in; (tmp_in = strchr(tmp_in,'\\')) != NULL; ++tmp_in) { - ++cnt; - } - - out = malloc(strlen(in)+1+cnt); - - for (i=j=0; in[i]; i++) { - if (in[i] == '\\') out[j++] = '\\'; - if (in[i] == '\'') out[j++] = '\''; - out[j++] = in[i]; - } - out[j] = 0; - - return out; -} diff --git a/org.glite.lb-utils.trio/src/strio.c b/org.glite.lb-utils.trio/src/strio.c deleted file mode 100644 index f1ab5b8..0000000 --- a/org.glite.lb-utils.trio/src/strio.c +++ /dev/null @@ -1,581 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -/* - * TODO - * - StrToLongDouble - */ - -static const char rcsid[] = "@(#)$Id$"; - -#if defined(unix) || defined(__xlC__) || defined(__QNX__) -# define PLATFORM_UNIX -#elif defined(WIN32) || defined(_WIN32) -# define PLATFORM_WIN32 -#elif defined(AMIGA) && defined(__GNUC__) -# define PLATFORM_UNIX -#endif - -#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L) -# define TRIO_C99 -#endif - -#include "strio.h" -#include -#include -#include -#include -#include -#include -#ifndef DEBUG -# define NDEBUG -#endif -#include - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif - -#define VALID(x) (NULL != (x)) -#define INVALID(x) (NULL == (x)) - -#if defined(PLATFORM_UNIX) -# define USE_STRCASECMP -# define USE_STRNCASECMP -# define USE_STRERROR -# if defined(__QNX__) -# define strcasecmp(x,y) stricmp(x,y) -# define strncasecmp(x,y,n) strnicmp(x,y,n) -# endif -#elif defined(PLATFORM_WIN32) -# define USE_STRCASECMP -# define strcasecmp(x,y) strcmpi(x,y) -#endif - -/************************************************************************* - * StrAppendMax - */ -char *StrAppendMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); - - max -= StrLength(target) + 1; - return (max > 0) ? strncat(target, source, max) : target; -} - -/************************************************************************* - * StrCopyMax - */ -char *StrCopyMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); /* Includes != 0 */ - - target = strncpy(target, source, max - 1); - target[max - 1] = (char)0; - return target; -} - -/************************************************************************* - * StrDuplicate - */ -char *StrDuplicate(const char *source) -{ - char *target; - - assert(VALID(source)); - - target = StrAlloc(StrLength(source) + 1); - if (target) - { - StrCopy(target, source); - } - return target; -} - -/************************************************************************* - * StrDuplicateMax - */ -char *StrDuplicateMax(const char *source, size_t max) -{ - char *target; - size_t len; - - assert(VALID(source)); - assert(max > 0); - - /* Make room for string plus a terminating zero */ - len = StrLength(source) + 1; - if (len > max) - { - len = max; - } - target = StrAlloc(len); - if (target) - { - StrCopyMax(target, len, source); - } - return target; -} - -/************************************************************************* - * StrEqual - */ -int StrEqual(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRCASECMP) - return (0 == strcasecmp(first, second)); -#else - while ((*first != NIL) && (*second != NIL)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - } - return ((*first == NIL) && (*second == NIL)); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrEqualCase - */ -int StrEqualCase(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strcmp(first, second)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualCaseMax - */ -int StrEqualCaseMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strncmp(first, second, max)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualLocale - */ -int StrEqualLocale(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - -#if defined(LC_COLLATE) - return (strcoll(first, second) == 0); -#else - return StrEqual(first, second); -#endif -} - -/************************************************************************* - * StrEqualMax - */ -int StrEqualMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRNCASECMP) - return (0 == strncasecmp(first, second, max)); -#else - /* Not adequately tested yet */ - size_t cnt = 0; - while ((*first != NIL) && (*second != NIL) && (cnt <= max)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - cnt++; - } - return ((cnt == max) || ((*first == NIL) && (*second == NIL))); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrError - */ -const char *StrError(int errorNumber) -{ -#if defined(USE_STRERROR) - return strerror(errorNumber); -#else - return "unknown"; -#endif -} - -/************************************************************************* - * StrFormatDate - */ -size_t StrFormatDateMax(char *target, - size_t max, - const char *format, - const struct tm *datetime) -{ - assert(VALID(target)); - assert(VALID(format)); - assert(VALID(datetime)); - assert(max > 0); - - return strftime(target, max, format, datetime); -} - -/************************************************************************* - * StrHash - */ -unsigned long StrHash(const char *string, int type) -{ - unsigned long value = 0L; - char ch; - - assert(VALID(string)); - - switch (type) - { - case STRIO_HASH_PLAIN: - while ( (ch = *string++) != NIL ) - { - value *= 31; - value += (unsigned long)ch; - } - break; - default: - assert(FALSE); - break; - } - return value; -} - -/************************************************************************* - * StrMatch - */ -int StrMatch(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((toupper((int)*string) != toupper((int)*pattern)) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatch(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrMatchCase - */ -int StrMatchCase(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((*string != *pattern) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatchCase(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrSpanFunction - * - * Untested - */ -size_t StrSpanFunction(char *source, int (*Function)(int)) -{ - size_t count = 0; - - assert(VALID(source)); - assert(VALID(Function)); - - while (*source != NIL) - { - if (Function(*source)) - break; /* while */ - source++; - count++; - } - return count; -} - -/************************************************************************* - * StrSubstringMax - */ -char *StrSubstringMax(const char *string, size_t max, const char *find) -{ - size_t count; - size_t size; - char *result = NULL; - - assert(VALID(string)); - assert(VALID(find)); - - size = StrLength(find); - if (size <= max) - { - for (count = 0; count <= max - size; count++) - { - if (StrEqualMax(find, size, &string[count])) - { - result = (char *)&string[count]; - break; - } - } - } - return result; -} - -/************************************************************************* - * StrToDouble - * - * double ::= [ ] - * ( | - * | - * ) - * [ [ ] ] - * number ::= 1*( ) - * digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) - * exponential ::= ( 'e' | 'E' ) - * sign ::= ( '-' | '+' ) - * decimal_point ::= '.' - */ -double StrToDouble(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtod(source, endp); -#else - /* Preliminary code */ - int isNegative = FALSE; - int isExponentNegative = FALSE; - unsigned long integer = 0; - unsigned long fraction = 0; - unsigned long fracdiv = 1; - unsigned long exponent = 0; - double value = 0.0; - - /* First try hex-floats */ - if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) - { - source += 2; - while (isxdigit((int)*source)) - { - integer *= 16; - integer += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - source++; - } - if (*source == '.') - { - source++; - while (isxdigit((int)*source)) - { - fraction *= 16; - fraction += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - fracdiv *= 16; - source++; - } - if ((*source == 'p') || (*source == 'P')) - { - source++; - if ((*source == '+') || (*source == '-')) - { - isExponentNegative = (*source == '-'); - source++; - } - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - } - else /* Then try normal decimal floats */ - { - isNegative = (*source == '-'); - /* Skip sign */ - if ((*source == '+') || (*source == '-')) - source++; - - /* Integer part */ - while (isdigit((int)*source)) - { - integer *= 10; - integer += (*source - '0'); - source++; - } - - if (*source == '.') - { - source++; /* skip decimal point */ - while (isdigit((int)*source)) - { - fraction *= 10; - fraction += (*source - '0'); - fracdiv *= 10; - source++; - } - } - if ((*source == 'e') || (*source == 'E')) - { - source++; /* Skip exponential indicator */ - isExponentNegative = (*source == '-'); - if ((*source == '+') || (*source == '-')) - source++; - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - - value = (double)integer; - if (fraction != 0) - { - value += (double)fraction / (double)fracdiv; - } - if (exponent != 0) - { - if (isExponentNegative) - value /= pow((double)10, (double)exponent); - else - value *= pow((double)10, (double)exponent); - } - if (isNegative) - value = -value; - - if (endp) - *endp = source; - return value; -#endif -} - -/************************************************************************* - * StrToFloat - */ -float StrToFloat(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtof(source, endp); -#else - return (float)StrToDouble(source, endp); -#endif -} - -/************************************************************************* - * StrToUpper - */ -int StrToUpper(char *target) -{ - int i = 0; - - assert(VALID(target)); - - while (NIL != *target) - { - *target = toupper((int)*target); - target++; - i++; - } - return i; -} diff --git a/org.glite.lb-utils.trio/src/strio.h b/org.glite.lb-utils.trio/src/strio.h deleted file mode 100644 index 68845a3..0000000 --- a/org.glite.lb-utils.trio/src/strio.h +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_STRIO_H -#define TRIO_STRIO_H - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include -#include -#include -#include - -#ifndef STRIO_MALLOC -# define STRIO_MALLOC(n) malloc(n) -#endif -#ifndef STRIO_FREE -# define STRIO_FREE(x) free(x) -#endif - -/* - * StrAppend(target, source) - * StrAppendMax(target, maxsize, source) - * - * Append 'source' to 'target' - * - * target = StrAlloc(size) - * - * Allocate a new string - * - * StrContains(target, substring) - * - * Find out if the string 'substring' is - * contained in the string 'target' - * - * StrCopy(target, source) - * StrCopyMax(target, maxsize, source) - * - * Copy 'source' to 'target' - * - * target = StrDuplicate(source) - * target = StrDuplicateMax(source, maxsize) - * - * Allocate and copy 'source' to 'target' - * - * StrEqual(first, second) - * StrEqualMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second'. - * Case-independent. - * - * StrEqualCase(first, second) - * StrEqualCaseMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second' - * Case-dependent. Please note that the use of the - * word 'case' has the opposite meaning as that of - * strcasecmp(). - * - * StrFormat(target, format, ...) - * StrFormatMax(target, maxsize, format, ...) - * - * Build 'target' according to 'format' and succesive - * arguments. This is equal to the sprintf() and - * snprintf() functions. - * - * StrFormatDate(target, format, ...) - * - * StrFree(target) - * - * De-allocates a string - * - * StrHash(string, type) - * - * Calculates the hash value of 'string' based on the - * 'type'. - * - * StrIndex(target, character) - * StrIndexLast(target, character) - * - * Find the first/last occurrence of 'character' in - * 'target' - * - * StrLength(target) - * - * Return the length of 'target' - * - * StrMatch(string, pattern) - * StrMatchCase(string, pattern) - * - * Find 'pattern' within 'string'. 'pattern' may contain - * wildcards such as * (asterics) and ? (question mark) - * which matches zero or more characters and exactly - * on character respectively - * - * StrScan(source, format, ...) - * - * Equal to sscanf() - * - * StrSubstring(target, substring) - * - * Find the first occurrence of the string 'substring' - * within the string 'target' - * - * StrTokenize(target, list) - * - * Split 'target' into the first token delimited by - * one of the characters in 'list'. If 'target' is - * NULL then next token will be returned. - * - * StrToUpper(target) - * - * Convert all lower case characters in 'target' into - * upper case characters. - */ - -enum { - STRIO_HASH_NONE = 0, - STRIO_HASH_PLAIN, - STRIO_HASH_TWOSIGNED -}; - -#if !defined(DEBUG) || defined(__DECC) -#define StrAlloc(n) (char *)STRIO_MALLOC(n) -#define StrAppend(x,y) strcat((x), (y)) -#define StrContains(x,y) (0 != strstr((x), (y))) -#define StrCopy(x,y) strcpy((x), (y)) -#define StrIndex(x,y) strchr((x), (y)) -#define StrIndexLast(x,y) strrchr((x), (y)) -#define StrFree(x) STRIO_FREE(x) -#define StrLength(x) strlen((x)) -#define StrSubstring(x,y) strstr((x), (y)) -#define StrTokenize(x,y) strtok((x), (y)) -#define StrToLong(x,y,n) strtol((x), (y), (n)) -#define StrToUnsignedLong(x,y,n) strtoul((x), (y), (n)) -#else /* DEBUG */ - /* - * To be able to use these macros everywhere, including in - * if() sentences, the assertions are put first in a comma - * seperated list. - * - * Unfortunately the DECC compiler does not seem to like this - * so it will use the un-asserted functions above for the - * debugging case too. - */ -#define StrAlloc(n) \ - (assert((n) > 0),\ - (char *)STRIO_MALLOC(n)) -#define StrAppend(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcat((x), (y))) -#define StrContains(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - (0 != strstr((x), (y)))) -#define StrCopy(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcpy((x), (y))) -#define StrIndex(x,c) \ - (assert((x) != NULL),\ - strchr((x), (c))) -#define StrIndexLast(x,c) \ - (assert((x) != NULL),\ - strrchr((x), (c))) -#define StrFree(x) \ - (assert((x) != NULL),\ - STRIO_FREE(x)) -#define StrLength(x) \ - (assert((x) != NULL),\ - strlen((x))) -#define StrSubstring(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strstr((x), (y))) -#define StrTokenize(x,y) \ - (assert((y) != NULL),\ - strtok((x), (y))) -#define StrToLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtol((x), (y), (n))) -#define StrToUnsignedLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtoul((x), (y), (n))) -#endif /* DEBUG */ - -char *StrAppendMax(char *target, size_t max, const char *source); -char *StrCopyMax(char *target, size_t max, const char *source); -char *StrDuplicate(const char *source); -char *StrDuplicateMax(const char *source, size_t max); -int StrEqual(const char *first, const char *second); -int StrEqualCase(const char *first, const char *second); -int StrEqualCaseMax(const char *first, size_t max, const char *second); -int StrEqualLocale(const char *first, const char *second); -int StrEqualMax(const char *first, size_t max, const char *second); -const char *StrError(int); -size_t StrFormatDateMax(char *target, size_t max, const char *format, const struct tm *datetime); -unsigned long StrHash(const char *string, int type); -int StrMatch(char *string, char *pattern); -int StrMatchCase(char *string, char *pattern); -size_t StrSpanFunction(char *source, int (*Function)(int)); -char *StrSubstringMax(const char *string, size_t max, const char *find); -float StrToFloat(const char *source, const char **target); -double StrToDouble(const char *source, const char **target); -int StrToUpper(char *target); - -#endif /* TRIO_STRIO_H */ diff --git a/org.glite.lb-utils.trio/src/trio.c b/org.glite.lb-utils.trio/src/trio.c deleted file mode 100644 index 6e4211e..0000000 --- a/org.glite.lb-utils.trio/src/trio.c +++ /dev/null @@ -1,5706 +0,0 @@ - -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * A note to trio contributors: - * - * Avoid heap allocation at all costs to ensure that the trio functions - * are async-safe. The exceptions are the printf/fprintf functions, which - * uses fputc, and the asprintf functions and the modifier, which - * by design are required to allocate form the heap. - * - ************************************************************************/ - -/* - * TODO: - * - Scan is probably too permissive about its modifiers. - * - C escapes in %#[] ? - * - C99 support has not been properly tested. - * - Multibyte characters (done for format parsing, except scan groups) - * - Complex numbers? (C99 _Complex) - * - Boolean values? (C99 _Bool) - * - C99 NaN(n-char-sequence) missing - * - Should we support the GNU %a alloc modifier? GNU has an ugly hack - * for %a, because C99 used %a for other purposes. If specified as - * %as or %a[ it is interpreted as the alloc modifier, otherwise as - * the C99 hex-float. This means that you cannot scan %as as a hex-float - * immediately followed by an 's'. - * - Scanning of collating symbols. - */ - -static const char rcsid[] = "@(#)$Id$"; - -/************************************************************************* - * Trio include files - */ -#include "trio.h" -#include "triop.h" -#include "strio.h" - -#ifdef DATAGRID_EXTENSION -#include "escape.h" -#endif - -/* - * Encode the error code and the position. This is decoded - * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. - */ -#if TRIO_ERRORS -# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8))) -#else -# define TRIO_ERROR_RETURN(x,y) (-1) -#endif - - -/************************************************************************* - * Platform and compiler support detection - */ -#if defined(unix) || defined(__xlC__) || defined(_AIX) || defined(__QNX__) -# define PLATFORM_UNIX -#elif defined(AMIGA) && defined(__GNUC__) -# define PLATFORM_UNIX -#elif defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) -# define PLATFORM_WIN32 -# define TRIO_MSVC_5 1100 -#endif - -#if defined(__STDC__) && defined(__STDC_VERSION__) -# if (__STDC_VERSION__ >= 199409L) -# define TRIO_COMPILER_SUPPORTS_ISO94 -# endif -# if (__STDC_VERSION__ >= 199901L) -# define TRIO_COMPILER_SUPPORTS_C99 -# endif -#endif - -#if defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED) -# define TRIO_COMPILER_SUPPORTS_UNIX98 -#endif - -#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_WIDECHAR -# define TRIO_COMPILER_SUPPORTS_MULTIBYTE -# if !defined(MB_LEN_MAX) -# define MB_LEN_MAX 6 -# endif -#endif - - -/************************************************************************* - * Generic definitions - */ - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include -#include -#if !defined(TRIO_COMPILER_SUPPORTS_C99) && !defined(isblank) -# define isblank(x) (((x)==32) || ((x)==9)) -#endif -#include -#include -#include -#include -#include -#include - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#define BOOLEAN_T int - -/* mincore() can be used for debugging purposes */ -#define VALID(x) (NULL != (x)) - -/* xlC crashes on log10(0) */ -#define guarded_log10(x) (((x) == 0.0) ? -HUGE_VAL : log10(x)) -#define guarded_log16(x) (guarded_log10(x) / log10(16.0)) - - -/************************************************************************* - * Platform specific definitions - */ -#if defined(PLATFORM_UNIX) -# include -# include -# include -# define USE_LOCALE -#endif /* PLATFORM_UNIX */ -#if defined(PLATFORM_WIN32) -# include -# define read _read -# define write _write -#endif /* PLATFORM_WIN32 */ - -#if TRIO_WIDECHAR -# if defined(TRIO_COMPILER_SUPPORTS_ISO94) -# include -# include -# else -typedef char wchar_t; -typedef int wint_t; -# define WEOF EOF -# define iswalnum(x) isalnum(x) -# define iswalpha(x) isalpha(x) -# define iswblank(x) isblank(x) -# define iswcntrl(x) iscntrl(x) -# define iswdigit(x) isdigit(x) -# define iswgraph(x) isgraph(x) -# define iswlower(x) islower(x) -# define iswprint(x) isprint(x) -# define iswpunct(x) ispunct(x) -# define iswspace(x) isspace(x) -# define iswupper(x) isupper(x) -# define iswxdigit(x) isxdigit(x) -# endif -#endif - - -/************************************************************************* - * Compiler dependent definitions - */ - -/* Support for long long */ -#ifndef __cplusplus -# if !defined(USE_LONGLONG) -# if defined(__GNUC__) && !defined(__STRICT_ANSI__) -# define USE_LONGLONG -# elif defined(__SUNPRO_C) -# define USE_LONGLONG -# elif defined(_LONG_LONG) || defined(_LONGLONG) -# define USE_LONGLONG -# endif -# endif -#endif - -/* The extra long numbers */ -#if defined(USE_LONGLONG) -typedef signed long long int trio_longlong_t; -typedef unsigned long long int trio_ulonglong_t; -#elif defined(_MSC_VER) -# if (_MSC_VER >= TRIO_MSVC_5) -typedef signed __int64 trio_longlong_t; -typedef unsigned __int64 trio_ulonglong_t; -# else -typedef signed long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -# endif -#else -typedef signed long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -#endif - -/* Maximal and fixed integer types */ -#if defined(TRIO_COMPILER_SUPPORTS_C99) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(_MSC_VER) && (_MSC_VER >= TRIO_MSVC_5) -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -typedef __int8 trio_int8_t; -typedef __int16 trio_int16_t; -typedef __int32 trio_int32_t; -typedef __int64 trio_int64_t; -#else -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -# if defined(TRIO_INT8_T) -typedef TRIO_INT8_T trio_int8_t; -# else -typedef signed char trio_int8_t; -# endif -# if defined(TRIO_INT16_T) -typedef TRIO_INT16_T trio_int16_t; -# else -typedef signed short trio_int16_t; -# endif -# if defined(TRIO_INT32_T) -typedef TRIO_INT32_T trio_int32_t; -# else -typedef signed int trio_int32_t; -# endif -# if defined(TRIO_INT64_T) -typedef TRIO_INT64_T trio_int64_t; -# else -typedef trio_longlong_t trio_int64_t; -# endif -#endif - - -/************************************************************************* - * Internal definitions - */ - -/* Long double sizes */ -#ifdef LDBL_DIG -# define MAX_MANTISSA_DIGITS LDBL_DIG -# define MAX_EXPONENT_DIGITS 4 -#else -# define MAX_MANTISSA_DIGITS DBL_DIG -# define MAX_EXPONENT_DIGITS 3 -#endif - -/* The maximal number of digits is for base 2 */ -#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT) -/* The width of a pointer. The number of bits in a hex digit is 4 */ -#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(void *) * CHAR_BIT / 4) - -/* Infinite and Not-A-Number for floating-point */ -#define INFINITE_LOWER "inf" -#define INFINITE_UPPER "INF" -#define LONG_INFINITE_LOWER "infinite" -#define LONG_INFINITE_UPPER "INFINITE" -#define NAN_LOWER "nan" -#define NAN_UPPER "NAN" - -/* Various constants */ -enum { - TYPE_PRINT = 1, - TYPE_SCAN = 2, - - /* Flags. Use maximum 32 */ - FLAGS_NEW = 0, - FLAGS_STICKY = 1, - FLAGS_SPACE = 2 * FLAGS_STICKY, - FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, - FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, - FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, - FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, - FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, - FLAGS_LONG = 2 * FLAGS_SHORTSHORT, - FLAGS_QUAD = 2 * FLAGS_LONG, - FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, - FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, - FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, - FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, - FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, - FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, - FLAGS_UPPER = 2 * FLAGS_UNSIGNED, - FLAGS_WIDTH = 2 * FLAGS_UPPER, - FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, - FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, - FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, - FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, - FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, - FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, - FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, - FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, - FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, - FLAGS_ALLOC = 2 * FLAGS_WIDECHAR, - FLAGS_IGNORE = 2 * FLAGS_ALLOC, - FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, - FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, - FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, - /* Reused flags */ - FLAGS_EXCLUDE = FLAGS_SHORT, - FLAGS_USER_DEFINED = FLAGS_IGNORE, - /* Compounded flags */ - FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, - FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, - - NO_POSITION = -1, - NO_WIDTH = 0, - NO_PRECISION = -1, - NO_SIZE = -1, - - NO_BASE = -1, - MIN_BASE = 2, - MAX_BASE = 36, - BASE_BINARY = 2, - BASE_OCTAL = 8, - BASE_DECIMAL = 10, - BASE_HEX = 16, - - /* Maximal number of allowed parameters */ - MAX_PARAMETERS = 64, - /* Maximal number of characters in class */ - MAX_CHARACTER_CLASS = UCHAR_MAX, - - /* Maximal string lengths for user-defined specifiers */ - MAX_USER_NAME = 64, - MAX_USER_DATA = 256, - - /* Maximal length of locale separator strings */ - MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, - /* Maximal number of integers in grouping */ - MAX_LOCALE_GROUPS = 64 -}; - -#define NO_GROUPING ((int)CHAR_MAX) - -/* Fundamental formatting parameter types */ -#define FORMAT_UNKNOWN 0 -#define FORMAT_INT 1 -#define FORMAT_DOUBLE 2 -#define FORMAT_CHAR 3 -#define FORMAT_STRING 4 -#define FORMAT_POINTER 5 -#define FORMAT_COUNT 6 -#define FORMAT_PARAMETER 7 -#define FORMAT_GROUP 8 -#if TRIO_GNU -# define FORMAT_ERRNO 9 -#endif -#if TRIO_EXTENSION -# define FORMAT_USER_DEFINED 10 -#endif - -/* Character constants */ -#define CHAR_IDENTIFIER '%' -#define CHAR_BACKSLASH '\\' -#define CHAR_QUOTE '\"' -#define CHAR_ADJUST ' ' - -/* Character class expressions */ -#define CLASS_ALNUM ":alnum:" -#define CLASS_ALPHA ":alpha:" -#define CLASS_CNTRL ":cntrl:" -#define CLASS_DIGIT ":digit:" -#define CLASS_GRAPH ":graph:" -#define CLASS_LOWER ":lower:" -#define CLASS_PRINT ":print:" -#define CLASS_PUNCT ":punct:" -#define CLASS_SPACE ":space:" -#define CLASS_UPPER ":upper:" -#define CLASS_XDIGIT ":xdigit:" - -/* - * SPECIFIERS: - * - * - * a Hex-float - * A Hex-float - * c Character - * C Widechar character (wint_t) - * d Decimal - * e Float - * E Float - * F Float - * F Float - * g Float - * G Float - * i Integer - * m Error message - * n Count - * o Octal - * p Pointer - * s String - * S Widechar string (wchar_t *) - * u Unsigned - * x Hex - * X Hex - * [] Group - * <> User-defined - * - * Reserved: - * - * D Binary Coded Decimal %D(length,precision) (OS/390) - */ -#define SPECIFIER_CHAR 'c' -#define SPECIFIER_STRING 's' -#define SPECIFIER_DECIMAL 'd' -#define SPECIFIER_INTEGER 'i' -#define SPECIFIER_UNSIGNED 'u' -#define SPECIFIER_OCTAL 'o' -#define SPECIFIER_HEX 'x' -#define SPECIFIER_HEX_UPPER 'X' -#define SPECIFIER_FLOAT_E 'e' -#define SPECIFIER_FLOAT_E_UPPER 'E' -#define SPECIFIER_FLOAT_F 'f' -#define SPECIFIER_FLOAT_F_UPPER 'F' -#define SPECIFIER_FLOAT_G 'g' -#define SPECIFIER_FLOAT_G_UPPER 'G' -#define SPECIFIER_POINTER 'p' -#define SPECIFIER_GROUP '[' -#define SPECIFIER_UNGROUP ']' -#define SPECIFIER_COUNT 'n' -#if TRIO_UNIX98 -# define SPECIFIER_CHAR_UPPER 'C' -# define SPECIFIER_STRING_UPPER 'S' -#endif -#if TRIO_C99 -# define SPECIFIER_HEXFLOAT 'a' -# define SPECIFIER_HEXFLOAT_UPPER 'A' -#endif -#if TRIO_GNU -# define SPECIFIER_ERRNO 'm' -#endif -#if TRIO_EXTENSION -# define SPECIFIER_BINARY 'b' -# define SPECIFIER_BINARY_UPPER 'B' -# define SPECIFIER_USER_DEFINED_BEGIN '<' -# define SPECIFIER_USER_DEFINED_END '>' -# define SPECIFIER_USER_DEFINED_SEPARATOR ':' -#endif - -/* - * QUALIFIERS: - * - * - * Numbers = d,i,o,u,x,X - * Float = a,A,e,E,f,F,g,G - * String = s - * Char = c - * - * - * 9$ Position - * Use the 9th parameter. 9 can be any number between 1 and - * the maximal argument - * - * 9 Width - * Set width to 9. 9 can be any number, but must not be postfixed - * by '$' - * - * h Short - * Numbers: - * (unsigned) short int - * - * hh Short short - * Numbers: - * (unsigned) char - * - * l Long - * Numbers: - * (unsigned) long int - * String: - * as the S specifier - * Char: - * as the C specifier - * - * ll Long Long - * Numbers: - * (unsigned) long long int - * - * L Long Double - * Float - * long double - * - * # Alternative - * Float: - * Decimal-point is always present - * String: - * non-printable characters are handled as \number - * - * Spacing - * - * + Sign - * - * - Alignment - * - * . Precision - * - * * Parameter - * print: use parameter - * scan: no parameter (ignore) - * - * q Quad - * - * Z size_t - * - * w Widechar - * - * ' Thousands/quote - * Numbers: - * Integer part grouped in thousands - * Binary numbers: - * Number grouped in nibbles (4 bits) - * String: - * Quoted string - * - * j intmax_t - * t prtdiff_t - * z size_t - * - * ! Sticky - * @ Parameter (for both print and scan) - * - * I n-bit Integer - * Numbers: - * The following options exists - * I8 = 8-bit integer - * I16 = 16-bit integer - * I32 = 32-bit integer - * I64 = 64-bit integer - */ -#define QUALIFIER_POSITION '$' -#define QUALIFIER_SHORT 'h' -#define QUALIFIER_LONG 'l' -#define QUALIFIER_LONG_UPPER 'L' -#define QUALIFIER_ALTERNATIVE '#' -#define QUALIFIER_SPACE ' ' -#define QUALIFIER_PLUS '+' -#define QUALIFIER_MINUS '-' -#define QUALIFIER_DOT '.' -#define QUALIFIER_STAR '*' -#define QUALIFIER_CIRCUMFLEX '^' -#if TRIO_C99 -# define QUALIFIER_SIZE_T 'z' -# define QUALIFIER_PTRDIFF_T 't' -# define QUALIFIER_INTMAX_T 'j' -#endif -#if TRIO_BSD || TRIO_GNU -# define QUALIFIER_QUAD 'q' -#endif -#if TRIO_GNU -# define QUALIFIER_SIZE_T_UPPER 'Z' -#endif -#if TRIO_MISC -# define QUALIFIER_WIDECHAR 'w' -#endif -#if TRIO_MICROSOFT -# define QUALIFIER_FIXED_SIZE 'I' -#endif -#if TRIO_EXTENSION -# define QUALIFIER_QUOTE '\'' -# define QUALIFIER_STICKY '!' -# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ -# define QUALIFIER_PARAM '@' /* Experimental */ -# define QUALIFIER_COLON ':' /* For scanlists */ -# define QUALIFIER_EQUAL '=' /* For scanlists */ -#endif -#if DATAGRID_EXTENSION -# define QUALIFIER_ESCAPE '|' -#endif - - -/************************************************************************* - * Internal structures - */ - -/* Parameters */ -typedef struct { - int type; - unsigned long flags; - int width; - int precision; - int base; - int varsize; -#ifdef QUALIFIER_ESCAPE - enum dg_escape { ESCAPE_NONE, ESCAPE_ULM, ESCAPE_XML, ESCAPE_SQL } escape; -#endif - int indexAfterSpecifier; - union { - char *string; -#if TRIO_WIDECHAR - wchar_t *wstring; -#endif - void *pointer; - union { - trio_uintmax_t as_signed; - trio_intmax_t as_unsigned; - } number; - double doubleNumber; - double *doublePointer; - long double longdoubleNumber; - long double *longdoublePointer; - int errorNumber; - } data; - /* For the user-defined specifier */ - char user_name[MAX_USER_NAME]; - char user_data[MAX_USER_DATA]; -} parameter_T; - -/* General trio "class" */ -typedef struct _trio_T { - void *location; - void (*OutStream)(struct _trio_T *, int); - void (*InStream)(struct _trio_T *, int *); - /* - * The number of characters that would have been written/read if - * there had been sufficient space. - */ - int processed; - /* - * The number of characters that are actually written/read. - * Processed and committed with only differ for the *nprintf - * and *nscanf functions. - */ - int committed; - int max; - int current; -} trio_T; - -/* References (for user-defined callbacks) */ -typedef struct _reference_T { - trio_T *data; - parameter_T *parameter; -} reference_T; - -/* Registered entries (for user-defined callbacks) */ -typedef struct _userdef_T { - struct _userdef_T *next; - trio_callback_t callback; - char *name; -} userdef_T; - - -/************************************************************************* - * Internal variables - */ - -static const char null[] = "(nil)"; - -#if defined(USE_LOCALE) -static struct lconv *internalLocaleValues = NULL; -#endif - -/* - * UNIX98 says "in a locale where the radix character is not defined, - * the radix character defaults to a period (.)" - */ -static char internalDecimalPoint[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; -static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; -static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; - -static const char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -static const char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static BOOLEAN_T internalDigitsUnconverted = TRUE; -static int internalDigitArray[128]; -#if TRIO_EXTENSION -static BOOLEAN_T internalCollationUnconverted = TRUE; -static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; -#endif - -static volatile trio_callback_t internalEnterCriticalRegion = NULL; -static volatile trio_callback_t internalLeaveCriticalRegion = NULL; -static userdef_T *internalUserDef = NULL; - - -/************************************************************************* - * trio_strerror [public] - */ -const char *trio_strerror(int errorcode) -{ - /* Textual versions of the error codes */ - switch (TRIO_ERROR_CODE(errorcode)) - { - case TRIO_EOF: - return "End of file"; - case TRIO_EINVAL: - return "Invalid argument"; - case TRIO_ETOOMANY: - return "Too many arguments"; - case TRIO_EDBLREF: - return "Double reference"; - case TRIO_EGAP: - return "Reference gap"; - case TRIO_ENOMEM: - return "Out of memory"; - case TRIO_ERANGE: - return "Invalid range"; - default: - return "Unknown"; - } -} - -/************************************************************************* - * TrioIsQualifier [private] - * - * Description: - * Remember to add all new qualifiers to this function. - * QUALIFIER_POSITION must not be added. - */ -static BOOLEAN_T -TrioIsQualifier(const char ch) -{ - /* QUALIFIER_POSITION is not included */ - switch (ch) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case QUALIFIER_PLUS: - case QUALIFIER_MINUS: - case QUALIFIER_SPACE: - case QUALIFIER_DOT: - case QUALIFIER_STAR: - case QUALIFIER_ALTERNATIVE: - case QUALIFIER_SHORT: - case QUALIFIER_LONG: - case QUALIFIER_LONG_UPPER: - case QUALIFIER_CIRCUMFLEX: -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: -#endif -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: -#endif -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: -#endif -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: -#endif -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: -#endif -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: -#endif -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: -#endif -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: -#endif -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: -#endif -#if defined(QUALIFIER_PARAM) - case QUALIFIER_PARAM: -#endif -#if defined(QUALIFIER_FIXED_SIZE) - case QUALIFIER_FIXED_SIZE: -#endif -#ifdef QUALIFIER_ESCAPE - case QUALIFIER_ESCAPE: -#endif - return TRUE; - default: - return FALSE; - } -} - -/************************************************************************* - * TrioGenerateNan [private] - * - * Calculating NaN portably is difficult. Some compilers will emit - * warnings about divide by zero, and others will simply fail to - * generate a NaN. - */ -static double -TrioGenerateNaN(void) -{ -#if defined(TRIO_COMPILER_SUPPORTS_C99) - return nan(NULL); -#elif defined(DBL_QNAN) - return DBL_QNAN; -#elif defined(PLATFORM_UNIX) - double value; - void (*signal_handler)(int); - - signal_handler = signal(SIGFPE, SIG_IGN); - value = 0.0 / 0.0; - signal(SIGFPE, signal_handler); - return value; -#else - return 0.0 / 0.0; -#endif -} - -/************************************************************************* - * TrioIsNan [private] - */ -static int -TrioIsNan(double number) -{ -#ifdef isnan - /* C99 defines isnan() as a macro */ - return isnan(number); -#else - double integral, fraction; - - return (/* NaN is the only number which does not compare to itself */ - (number != number) || - /* Fallback solution if NaN compares to NaN */ - ((number != 0.0) && - (fraction = modf(number, &integral), - integral == fraction))); -#endif -} - -/************************************************************************* - * TrioIsInfinite [private] - */ -static int -TrioIsInfinite(double number) -{ -#ifdef isinf - /* C99 defines isinf() as a macro */ - return isinf(number); -#else - return ((number == HUGE_VAL) ? 1 : ((number == -HUGE_VAL) ? -1 : 0)); -#endif -} - -/************************************************************************* - * TrioSetLocale [private] - */ -#if defined(USE_LOCALE) -static void -TrioSetLocale(void) -{ - internalLocaleValues = (struct lconv *)localeconv(); - if (internalLocaleValues) - { - if ((internalLocaleValues->decimal_point) && - (internalLocaleValues->decimal_point[0] != NIL)) - { - StrCopyMax(internalDecimalPoint, - sizeof(internalDecimalPoint), - internalLocaleValues->decimal_point); - } - if ((internalLocaleValues->thousands_sep) && - (internalLocaleValues->thousands_sep[0] != NIL)) - { - StrCopyMax(internalThousandSeparator, - sizeof(internalThousandSeparator), - internalLocaleValues->thousands_sep); - } - if ((internalLocaleValues->grouping) && - (internalLocaleValues->grouping[0] != NIL)) - { - StrCopyMax(internalGrouping, - sizeof(internalGrouping), - internalLocaleValues->grouping); - } - } -} -#endif /* defined(USE_LOCALE) */ - -/************************************************************************* - * TrioGetPosition [private] - * - * Get the %n$ position. - */ -static int -TrioGetPosition(const char *format, - int *indexPointer) -{ - char *tmpformat; - int number = 0; - int index = *indexPointer; - - number = (int)StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - if ((number != 0) && (QUALIFIER_POSITION == format[index++])) - { - *indexPointer = index; - /* - * number is decreased by 1, because n$ starts from 1, whereas - * the array it is indexing starts from 0. - */ - return number - 1; - } - return NO_POSITION; -} - -/************************************************************************* - * TrioFindNamespace [private] - * - * Find registered user-defined specifier. - * The prev argument is used for optimisation only. - */ -static userdef_T * -TrioFindNamespace(const char *name, userdef_T **prev) -{ - userdef_T *def; - - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - for (def = internalUserDef; def; def = def->next) - { - /* Case-sensitive string comparison */ - if (StrEqualCase(def->name, name)) - break; - - if (prev) - *prev = def; - } - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - - return def; -} - -/************************************************************************* - * TrioPreprocess [private] - * - * Description: - * Parse the format string - */ -static int -TrioPreprocess(int type, - const char *format, - parameter_T *parameters, - va_list arglist, - void **argarray) -{ -#if TRIO_ERRORS - /* Count the number of times a parameter is referenced */ - unsigned short usedEntries[MAX_PARAMETERS]; -#endif - /* Parameter counters */ - int parameterPosition; - int currentParam; - int maxParam = -1; - /* Utility variables */ - unsigned long flags; - int width; - int precision; - int varsize; -#ifdef QUALIFIER_ESCAPE - enum dg_escape escape; -#endif - int base; - int index; /* Index into formatting string */ - int dots; /* Count number of dots in modifier part */ - BOOLEAN_T positional; /* Does the specifier have a positional? */ - BOOLEAN_T got_sticky = FALSE; /* Are there any sticky modifiers at all? */ - /* - * indices specifies the order in which the parameters must be - * read from the va_args (this is necessary to handle positionals) - */ - int indices[MAX_PARAMETERS]; - int pos = 0; - /* Various variables */ - char ch; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int i = -1; - int num; - char *tmpformat; - - -#if TRIO_ERRORS - /* - * The 'parameters' array is not initialized, but we need to - * know which entries we have used. - */ - memset(usedEntries, 0, sizeof(usedEntries)); -#endif - - index = 0; - parameterPosition = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - /* - * Multibyte characters cannot be legal specifiers or - * modifiers, so we skip over them. - */ - charlen = mblen(&format[index], MB_LEN_MAX); - index += (charlen > 0) ? charlen : 1; - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index++]) - { - if (CHAR_IDENTIFIER == format[index]) - { - index++; - continue; /* while */ - } - - flags = FLAGS_NEW; - dots = 0; - currentParam = TrioGetPosition(format, &index); - positional = (NO_POSITION != currentParam); - if (!positional) - { - /* We have no positional, get the next counter */ - currentParam = parameterPosition; - } - if(currentParam >= MAX_PARAMETERS) - { - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index); - } - - if (currentParam > maxParam) - maxParam = currentParam; - - /* Default values */ - width = NO_WIDTH; - precision = NO_PRECISION; - base = NO_BASE; - varsize = NO_SIZE; -#ifdef QUALIFIER_ESCAPE - escape = ESCAPE_NONE; -#endif - - while (TrioIsQualifier(format[index])) - { - ch = format[index++]; - - switch (ch) - { - case QUALIFIER_SPACE: - flags |= FLAGS_SPACE; - break; - - case QUALIFIER_PLUS: - flags |= FLAGS_SHOWSIGN; - break; - - case QUALIFIER_MINUS: - flags |= FLAGS_LEFTADJUST; - flags &= ~FLAGS_NILPADDING; - break; - - case QUALIFIER_ALTERNATIVE: - flags |= FLAGS_ALTERNATIVE; - break; - - case QUALIFIER_DOT: - if (dots == 0) /* Precision */ - { - dots++; - - /* Skip if no precision */ - if (QUALIFIER_DOT == format[index]) - break; - - /* After the first dot we have the precision */ - flags |= FLAGS_PRECISION; - if ((QUALIFIER_STAR == format[index]) || - (QUALIFIER_PARAM == format[index])) - { - index++; - flags |= FLAGS_PRECISION_PARAMETER; - - precision = TrioGetPosition(format, &index); - if (precision == NO_POSITION) - { - parameterPosition++; - if (positional) - precision = parameterPosition; - else - { - precision = currentParam; - currentParam = precision + 1; - } - } - else - { - if (! positional) - currentParam = precision + 1; - if (width > maxParam) - maxParam = precision; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - precision = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - } - } - else if (dots == 1) /* Base */ - { - dots++; - - /* After the second dot we have the base */ - flags |= FLAGS_BASE; - if ((QUALIFIER_STAR == format[index]) || - (QUALIFIER_PARAM == format[index])) - { - index++; - flags |= FLAGS_BASE_PARAMETER; - base = TrioGetPosition(format, &index); - if (base == NO_POSITION) - { - parameterPosition++; - if (positional) - base = parameterPosition; - else - { - base = currentParam; - currentParam = base + 1; - } - } - else - { - if (! positional) - currentParam = base + 1; - if (base > maxParam) - maxParam = base; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - base = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - if (base > MAX_BASE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - index = (int)(tmpformat - format); - } - } - else - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - break; /* QUALIFIER_DOT */ - - case QUALIFIER_PARAM: - type = TYPE_PRINT; - /* FALLTHROUGH */ - case QUALIFIER_STAR: - /* This has different meanings for print and scan */ - if (TYPE_PRINT == type) - { - /* Read with from parameter */ - flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); - width = TrioGetPosition(format, &index); - if (width == NO_POSITION) - { - parameterPosition++; - if (positional) - width = parameterPosition; - else - { - width = currentParam; - currentParam = width + 1; - } - } - else - { - if (! positional) - currentParam = width + 1; - if (width > maxParam) - maxParam = width; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - /* Scan, but do not store result */ - flags |= FLAGS_IGNORE; - } - - break; /* QUALIFIER_STAR */ - - case '0': - if (! (flags & FLAGS_LEFTADJUST)) - flags |= FLAGS_NILPADDING; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - /* &format[index - 1] is used to "rewind" the read - * character from format - */ - width = StrToLong(&format[index - 1], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - break; - - case QUALIFIER_SHORT: - if (flags & FLAGS_SHORTSHORT) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_SHORT) - flags |= FLAGS_SHORTSHORT; - else - flags |= FLAGS_SHORT; - break; - - case QUALIFIER_LONG: - if (flags & FLAGS_QUAD) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_LONG) - flags |= FLAGS_QUAD; - else - flags |= FLAGS_LONG; - break; - - case QUALIFIER_LONG_UPPER: - flags |= FLAGS_LONGDOUBLE; - break; - -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: - flags |= FLAGS_SIZE_T; - /* Modify flags for later truncation of number */ - if (sizeof(size_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(size_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: - flags |= FLAGS_PTRDIFF_T; - if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(ptrdiff_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: - flags |= FLAGS_INTMAX_T; - if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(trio_intmax_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: - flags |= FLAGS_QUAD; - break; -#endif - -#if defined(QUALIFIER_FIXED_SIZE) - case QUALIFIER_FIXED_SIZE: - if (flags & FLAGS_FIXED_SIZE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE | - FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER)) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if ((format[index] == '6') && - (format[index + 1] == '4')) - { - varsize = sizeof(trio_int64_t); - index += 2; - } - else if ((format[index] == '3') && - (format[index + 1] == '2')) - { - varsize = sizeof(trio_int32_t); - index += 2; - } - else if ((format[index] == '1') && - (format[index + 1] == '6')) - { - varsize = sizeof(trio_int16_t); - index += 2; - } - else if (format[index] == '8') - { - varsize = sizeof(trio_int8_t); - index++; - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - flags |= FLAGS_FIXED_SIZE; - break; -#endif - -#ifdef QUALIFIER_ESCAPE - case QUALIFIER_ESCAPE: - switch (format[index++]) { - case 'U': escape = ESCAPE_ULM; break; - case 'X': escape = ESCAPE_XML; break; - case 'S': escape = ESCAPE_SQL; break; - default: return TRIO_ERROR_RETURN(TRIO_EINVAL,index); - } - break; -#endif - - -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: - flags |= FLAGS_WIDECHAR; - break; -#endif - -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: - break; -#endif - -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: - flags |= FLAGS_QUOTE; - break; -#endif - -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: - flags |= FLAGS_STICKY; - got_sticky = TRUE; - break; -#endif - -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: - flags |= FLAGS_VARSIZE_PARAMETER; - parameterPosition++; - if (positional) - varsize = parameterPosition; - else - { - varsize = currentParam; - currentParam = varsize + 1; - } - if (currentParam > maxParam) - maxParam = currentParam; - break; -#endif - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - } /* while qualifier */ - - /* - * Parameters only need the type and value. The value is - * read later. - */ - if (flags & FLAGS_WIDTH_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[width] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[width] = pos; - width = pos++; - } - if (flags & FLAGS_PRECISION_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[precision] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[precision] = pos; - precision = pos++; - } - if (flags & FLAGS_BASE_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[base] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[base] = pos; - base = pos++; - } - if (flags & FLAGS_VARSIZE_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[varsize] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[varsize] = pos; - varsize = pos++; - } - - indices[currentParam] = pos; - - switch (format[index++]) - { -#if defined(SPECIFIER_CHAR_UPPER) - case SPECIFIER_CHAR_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_CHAR: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_CHAR; - break; - -#if defined(SPECIFIER_STRING_UPPER) - case SPECIFIER_STRING_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_STRING: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_STRING; - break; - - - case SPECIFIER_GROUP: - if (TYPE_SCAN == type) - { - int depth = 1; - parameters[pos].type = FORMAT_GROUP; - if (format[index] == QUALIFIER_CIRCUMFLEX) - index++; - if (format[index] == SPECIFIER_UNGROUP) - index++; - if (format[index] == QUALIFIER_MINUS) - index++; - /* Skip nested brackets */ - while (format[index] != NIL) - { - if (format[index] == SPECIFIER_GROUP) - { - depth++; - } - else if (format[index] == SPECIFIER_UNGROUP) - { - if (--depth <= 0) - { - index++; - break; - } - } - index++; - } - } - break; - - case SPECIFIER_INTEGER: - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_UNSIGNED: - flags |= FLAGS_UNSIGNED; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_DECIMAL: - /* Disable base modifier */ - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_DECIMAL; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_OCTAL: - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_OCTAL; - parameters[pos].type = FORMAT_INT; - break; - -#if defined(SPECIFIER_BINARY) - case SPECIFIER_BINARY_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_BINARY: - flags |= FLAGS_NILPADDING; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_BINARY; - parameters[pos].type = FORMAT_INT; - break; -#endif - - case SPECIFIER_HEX_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_HEX: - flags |= FLAGS_UNSIGNED; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_HEX; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_FLOAT_E_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_E: - flags |= FLAGS_FLOAT_E; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_G_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_G: - flags |= FLAGS_FLOAT_G; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_F_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_F: - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_POINTER: - parameters[pos].type = FORMAT_POINTER; - break; - - case SPECIFIER_COUNT: - parameters[pos].type = FORMAT_COUNT; - break; - -#if defined(SPECIFIER_HEXFLOAT) -# if defined(SPECIFIER_HEXFLOAT_UPPER) - case SPECIFIER_HEXFLOAT_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_HEXFLOAT: - base = BASE_HEX; - parameters[pos].type = FORMAT_DOUBLE; - break; -#endif - -#if defined(FORMAT_ERRNO) - case SPECIFIER_ERRNO: - parameters[pos].type = FORMAT_ERRNO; - break; -#endif - -#if defined(SPECIFIER_USER_DEFINED_BEGIN) - case SPECIFIER_USER_DEFINED_BEGIN: - { - unsigned int max; - int without_namespace = TRUE; - - parameters[pos].type = FORMAT_USER_DEFINED; - parameters[pos].user_name[0] = NIL; - tmpformat = (char *)&format[index]; - - while ((ch = format[index])) - { - index++; - if (ch == SPECIFIER_USER_DEFINED_END) - { - if (without_namespace) - { - /* We must get the handle first */ - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = FLAGS_USER_DEFINED; - /* Adjust parameters for insertion of new one */ - pos++; -# if TRIO_ERRORS - usedEntries[currentParam] += 1; -# endif - parameters[pos].type = FORMAT_USER_DEFINED; - currentParam++; - indices[currentParam] = pos; - if (currentParam > maxParam) - maxParam = currentParam; - } - /* Copy the user data */ - max = (unsigned int)(&format[index] - tmpformat); - if (max > MAX_USER_DATA) - max = MAX_USER_DATA; - StrCopyMax(parameters[pos].user_data, - max, - tmpformat); - break; /* while */ - } - if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) - { - without_namespace = FALSE; - /* Copy the namespace for later looking-up */ - max = (int)(&format[index] - tmpformat); - if (max > MAX_USER_NAME) - max = MAX_USER_NAME; - StrCopyMax(parameters[pos].user_name, - max, - tmpformat); - tmpformat = (char *)&format[index]; - } - } - if (ch != SPECIFIER_USER_DEFINED_END) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - break; -#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */ - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - -#if TRIO_ERRORS - /* Count the number of times this entry has been used */ - usedEntries[currentParam] += 1; -#endif - - /* Find last sticky parameters */ - if (got_sticky && !(flags & FLAGS_STICKY)) - { - for (i = pos - 1; i >= 0; i--) - { - if (parameters[i].type == FORMAT_PARAMETER) - continue; - if ((parameters[i].flags & FLAGS_STICKY) && - (parameters[i].type == parameters[pos].type)) - { - /* Do not overwrite current qualifiers */ - flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); - if (width == NO_WIDTH) - width = parameters[i].width; - if (precision == NO_PRECISION) - precision = parameters[i].precision; - if (base == NO_BASE) - base = parameters[i].base; - break; - } - } - } - - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = flags; - parameters[pos].width = width; - parameters[pos].precision = precision; - parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base; - parameters[pos].varsize = varsize; -#ifdef QUALIFIER_ESCAPE - parameters[pos].escape = escape; -#endif - pos++; - - if (! positional) - parameterPosition++; - - } /* if identifier */ - - } /* while format characters left */ - - for (num = 0; num <= maxParam; num++) - { -#if TRIO_ERRORS - if (usedEntries[num] != 1) - { - if (usedEntries[num] == 0) /* gap detected */ - return TRIO_ERROR_RETURN(TRIO_EGAP, num); - else /* double references detected */ - return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); - } -#endif - - i = indices[num]; - - /* - * FORMAT_PARAMETERS are only present if they must be read, - * so it makes no sense to check the ignore flag (besides, - * the flags variable is not set for that particular type) - */ - if ((parameters[i].type != FORMAT_PARAMETER) && - (parameters[i].flags & FLAGS_IGNORE)) - continue; /* for all arguments */ - - /* - * The stack arguments are read according to ANSI C89 - * default argument promotions: - * - * char = int - * short = int - * unsigned char = unsigned int - * unsigned short = unsigned int - * float = double - * - * In addition to the ANSI C89 these types are read (the - * default argument promotions of C99 has not been - * considered yet) - * - * long long - * long double - * size_t - * ptrdiff_t - * intmax_t - */ - switch (parameters[i].type) - { - case FORMAT_GROUP: - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - parameters[i].data.wstring = (argarray == NULL) - ? va_arg(arglist, wchar_t *) - : (wchar_t *)(argarray[num]); - } - else -#endif - { - parameters[i].data.string = (argarray == NULL) - ? va_arg(arglist, char *) - : (char *)(argarray[num]); - } - break; - - case FORMAT_POINTER: - case FORMAT_COUNT: - case FORMAT_USER_DEFINED: - case FORMAT_UNKNOWN: - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, void *) - : argarray[num]; - break; - - case FORMAT_CHAR: - case FORMAT_INT: - if (TYPE_SCAN == type) - { - if (argarray == NULL) - parameters[i].data.pointer = - (trio_uintmax_t *)va_arg(arglist, void *); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.pointer = - (trio_uintmax_t *)((char *)argarray[num]); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.pointer = - (trio_uintmax_t *)((short *)argarray[num]); - else - parameters[i].data.pointer = - (trio_uintmax_t *)((int *)argarray[num]); - } - } - else - { -#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE) - if ((parameters[i].flags & FLAGS_VARSIZE_PARAMETER) || - (parameters[i].flags & FLAGS_FIXED_SIZE)) - { - if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) - { - /* - * Variable sizes are mapped onto the fixed sizes, in - * accordance with integer promotion. - * - * Please note that this may not be portable, as we - * only guess the size, not the layout of the numbers. - * For example, if int is little-endian, and long is - * big-endian, then this will fail. - */ - varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; - } - else - { - /* Used for the I modifiers */ - varsize = parameters[i].varsize; - } - parameters[i].flags &= ~FLAGS_ALL_VARSIZES; - - if (varsize <= (int)sizeof(int)) - ; - else if (varsize <= (int)sizeof(long)) - parameters[i].flags |= FLAGS_LONG; -#if defined(QUALIFIER_INTMAX_T) - else if (varsize <= (int)sizeof(trio_longlong_t)) - parameters[i].flags |= FLAGS_QUAD; - else - parameters[i].flags |= FLAGS_INTMAX_T; -#else - else - parameters[i].flags |= FLAGS_QUAD; -#endif - } -#endif /* defined(QUALIFIER_VARSIZE) */ -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (parameters[i].flags & FLAGS_SIZE_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, size_t) - : (trio_uintmax_t)(*((size_t *)argarray[num])); - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (parameters[i].flags & FLAGS_PTRDIFF_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t) - : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (parameters[i].flags & FLAGS_INTMAX_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t) - : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); - else -#endif - if (parameters[i].flags & FLAGS_QUAD) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t) - : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); - else if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, long) - : (trio_uintmax_t)(*((long *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); - else - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); - } - } - } - break; - - case FORMAT_PARAMETER: - /* - * The parameter for the user-defined specifier is a pointer, - * whereas the rest (width, precision, base) uses an integer. - */ - if (parameters[i].flags & FLAGS_USER_DEFINED) - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, void *) - : argarray[num]; - else - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, int) - : (trio_uintmax_t)(*((int *)argarray[num])); - break; - - case FORMAT_DOUBLE: - if (TYPE_SCAN == type) - { - if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.longdoublePointer = (argarray == NULL) - ? va_arg(arglist, long double *) - : (long double *)((long double *)argarray[num]); - else - { - if (argarray == NULL) - parameters[i].data.doublePointer = - va_arg(arglist, double *); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.doublePointer = - (double *)((float *)argarray[num]); - else - parameters[i].data.doublePointer = - (double *)((double *)argarray[num]); - } - } - } - else - { - if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.longdoubleNumber = (argarray == NULL) - ? va_arg(arglist, long double) - : (long double)(*((long double *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.longdoubleNumber = (long double)va_arg(arglist, double); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.longdoubleNumber = (long double)(*((float *)argarray[num])); - else - parameters[i].data.longdoubleNumber = (long double)(long double)(*((double *)argarray[num])); - } - } - } - break; - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - parameters[i].data.errorNumber = errno; - break; -#endif - - default: - break; - } - } /* for all specifiers */ - return num; -} - - -/************************************************************************* - * - * @FORMATTING - * - ************************************************************************/ - - -/************************************************************************* - * TrioWriteNumber [private] - * - * Description: - * Output a number. - * The complexity of this function is a result of the complexity - * of the dependencies of the flags. - */ -static void -TrioWriteNumber(trio_T *self, - trio_uintmax_t number, - unsigned long flags, - int width, - int precision, - int base) -{ - BOOLEAN_T isNegative; - char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; - char *bufferend; - char *pointer; - const char *digits; - int i; - int length; - char *p; - int charsPerThousand; - int groupingIndex; - int count; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - - isNegative = (flags & FLAGS_UNSIGNED) - ? FALSE - : ((trio_intmax_t)number < 0); - if (isNegative) - number = -number; - - if (flags & FLAGS_QUAD) - number &= (trio_ulonglong_t)-1; - else if (flags & FLAGS_LONG) - number &= (unsigned long)-1; - else - number &= (unsigned int)-1; - - /* Build number */ - pointer = bufferend = &buffer[sizeof(buffer) - 1]; - *pointer-- = NIL; - charsPerThousand = (int)internalGrouping[0]; - groupingIndex = 1; - for (i = 1; i < (int)sizeof(buffer); i++) - { - *pointer-- = digits[number % base]; - number /= base; - if (number == 0) - break; - - if ((flags & FLAGS_QUOTE) - && (charsPerThousand != NO_GROUPING) - && (i % charsPerThousand == 0)) - { - /* - * We are building the number from the least significant - * to the most significant digit, so we have to copy the - * thousand separator backwards - */ - length = StrLength(internalThousandSeparator); - if (((int)(pointer - buffer) - length) > 0) - { - p = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *pointer-- = *p--; - } - - /* Advance to next grouping number */ - switch (internalGrouping[groupingIndex]) - { - case CHAR_MAX: /* Disable grouping */ - charsPerThousand = NO_GROUPING; - break; - case 0: /* Repeat last group */ - break; - default: - charsPerThousand = (int)internalGrouping[groupingIndex++]; - break; - } - } - } - - /* Adjust width */ - width -= (bufferend - pointer) - 1; - - /* Adjust precision */ - if (NO_PRECISION != precision) - { - precision -= (bufferend - pointer) - 1; - if (precision < 0) - precision = 0; - flags |= FLAGS_NILPADDING; - } - - /* Adjust width further */ - if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - width--; - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - case BASE_HEX: - width -= 2; - break; - case BASE_OCTAL: - width--; - break; - default: - break; - } - } - - /* Output prefixes spaces if needed */ - if (! ((flags & FLAGS_LEFTADJUST) || - ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) - { - count = (precision == NO_PRECISION) ? 0 : precision; - while (width-- > count) - self->OutStream(self, CHAR_ADJUST); - } - - /* width has been adjusted for signs and alternatives */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); - break; - - case BASE_OCTAL: - self->OutStream(self, '0'); - break; - - case BASE_HEX: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - break; - - default: - break; - } /* switch base */ - } - - /* Output prefixed zero padding if needed */ - if (flags & FLAGS_NILPADDING) - { - if (precision == NO_PRECISION) - precision = width; - while (precision-- > 0) - { - self->OutStream(self, '0'); - width--; - } - } - - /* Output the number itself */ - while (*(++pointer)) - { - self->OutStream(self, *pointer); - } - - /* Output trailing spaces if needed */ - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -} - -/************************************************************************* - * TrioWriteStringCharacter [private] - * - * Description: - * Output a single character of a string - */ -static void -TrioWriteStringCharacter(trio_T *self, - int ch, - unsigned long flags) -{ - if (flags & FLAGS_ALTERNATIVE) - { - if (! (isprint(ch) || isspace(ch))) - { - /* - * Non-printable characters are converted to C escapes or - * \number, if no C escape exists. - */ - self->OutStream(self, CHAR_BACKSLASH); - switch (ch) - { - case '\007': self->OutStream(self, 'a'); break; - case '\b': self->OutStream(self, 'b'); break; - case '\f': self->OutStream(self, 'f'); break; - case '\n': self->OutStream(self, 'n'); break; - case '\r': self->OutStream(self, 'r'); break; - case '\t': self->OutStream(self, 't'); break; - case '\v': self->OutStream(self, 'v'); break; - case '\\': self->OutStream(self, '\\'); break; - default: - self->OutStream(self, 'x'); - TrioWriteNumber(self, (trio_intmax_t)ch, - FLAGS_UNSIGNED | FLAGS_NILPADDING, - 2, 2, BASE_HEX); - break; - } - } - else if (ch == CHAR_BACKSLASH) - { - self->OutStream(self, CHAR_BACKSLASH); - self->OutStream(self, CHAR_BACKSLASH); - } - else - { - self->OutStream(self, ch); - } - } - else - { - self->OutStream(self, ch); - } -} - -/************************************************************************* - * TrioWriteString [private] - * - * Description: - * Output a string - */ -static void -TrioWriteString(trio_T *self, - const char *string, - unsigned long flags, - int width, - int precision) -{ - int length; - int ch; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - - if (string == NULL) - { - string = null; - length = sizeof(null) - 1; - /* Disable quoting for the null pointer */ - flags &= (~FLAGS_QUOTE); - width = 0; - } - else - { - length = StrLength(string); - } - if ((NO_PRECISION != precision) && - (precision < length)) - { - length = precision; - } - width -= length; - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length-- > 0) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} - -/************************************************************************* - * TrioWriteWideStringCharacter [private] - * - * Description: - * Output a wide string as a multi-byte sequence - */ -#if TRIO_WIDECHAR -static int -TrioWriteWideStringCharacter(trio_T *self, - wchar_t wch, - unsigned long flags, - int width) -{ - int size; - int i; - int ch; - char *string; - char buffer[MB_LEN_MAX + 1]; - - if (width == NO_WIDTH) - width = sizeof(buffer); - - size = wctomb(buffer, wch); - if ((size <= 0) || (size > width) || (buffer[0] == NIL)) - return 0; - - string = buffer; - i = size; - while ((width >= i) && (width-- > 0) && (i-- > 0)) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - return size; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioWriteString [private] - * - * Description: - * Output a wide character string as a multi-byte string - */ -#if TRIO_WIDECHAR -static void -TrioWriteWideString(trio_T *self, - const wchar_t *wstring, - unsigned long flags, - int width, - int precision) -{ - int length; - int size; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - if (wstring == NULL) - { - TrioWriteString(self, NULL, flags, width, precision); - return; - } - - if (NO_PRECISION == precision) - { - length = INT_MAX; - } - else - { - length = precision; - width -= length; - } - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length > 0) - { - size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); - if (size == 0) - break; /* while */ - length -= size; - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioWriteDouble [private] - */ -static void -TrioWriteDouble(trio_T *self, - long double longdoubleNumber, - unsigned long flags, - int width, - int precision, - int base) -{ - int charsPerThousand; - int length; - double number; - double workNumber; - int integerDigits; - int fractionDigits; - int exponentDigits; - int expectedWidth; - int exponent; - unsigned int uExponent = 0; - double dblBase; - BOOLEAN_T isNegative; - BOOLEAN_T isExponentNegative = FALSE; - BOOLEAN_T isHex; - const char *digits; - char numberBuffer[MAX_MANTISSA_DIGITS - * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; - char *numberPointer; - char exponentBuffer[MAX_EXPONENT_DIGITS + 1]; - char *exponentPointer = NULL; - int groupingIndex; - char *work; - int i; - BOOLEAN_T onlyzero; - int zeroes = 0; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert(base == BASE_DECIMAL || base == BASE_HEX); - - number = (double)longdoubleNumber; - - /* Look for infinite numbers and non-a-number first */ - switch (TrioIsInfinite(number)) - { - case 1: - /* Positive infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? INFINITE_UPPER - : INFINITE_LOWER, - flags, width, precision); - return; - - case -1: - /* Negative infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? "-" INFINITE_UPPER - : "-" INFINITE_LOWER, - flags, width, precision); - return; - - default: - /* Finitude */ - break; - } - if (TrioIsNan(number)) - { - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? NAN_UPPER - : NAN_LOWER, - flags, width, precision); - return; - } - - /* Normal numbers */ - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - isHex = (base == BASE_HEX); - dblBase = (double)base; - - if (precision == NO_PRECISION) - precision = FLT_DIG; - - isNegative = (number < 0.0); - if (isNegative) - number = -number; - - if ((flags & FLAGS_FLOAT_G) || isHex) - { - if (precision == 0) - precision = 1; - - if ((number < 1.0e-4) || (number > pow(10.0, (double)precision))) - { - /* Use scientific notation */ - flags |= FLAGS_FLOAT_E; - } - else if (number < 1.0) - { - /* - * Use normal notation. If the integer part of the number is - * zero, then adjust the precision to include leading fractional - * zeros. - */ - workNumber = fabs(guarded_log10(number)); - if (workNumber - floor(workNumber) < 0.001) - workNumber--; - zeroes = (int)floor(workNumber); - } - } - - if (flags & FLAGS_FLOAT_E) - { - /* Scale the number */ - workNumber = guarded_log10(number); - if (workNumber == -HUGE_VAL) - { - exponent = 0; - /* Undo setting */ - if (flags & FLAGS_FLOAT_G) - flags &= ~FLAGS_FLOAT_E; - } - else - { - exponent = (int)floor(workNumber); - number /= pow(10.0, (double)exponent); - isExponentNegative = (exponent < 0); - uExponent = (isExponentNegative) ? -exponent : exponent; - /* No thousand separators */ - flags &= ~FLAGS_QUOTE; - } - } - - /* - * Truncated number. - * - * precision is number of significant digits for FLOAT_G - * and number of fractional digits for others - */ - integerDigits = (floor(number) > DBL_EPSILON) - ? 1 + (int)guarded_log10(floor(number)) - : 1; - fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0)) - ? precision - integerDigits - : zeroes + precision; - - number = floor(0.5 + number * pow(dblBase, (double)fractionDigits)); - workNumber = (isHex - ? guarded_log16(0.5 + number) - : guarded_log10(0.5 + number)); - if ((int)workNumber + 1 > integerDigits + fractionDigits) - { - if (flags & FLAGS_FLOAT_E) - { - /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */ - exponent--; - uExponent -= (isExponentNegative) ? 1 : -1; - number /= dblBase; - } - else - { - /* Adjust if number was rounded up one digit (ie. 99 to 100) */ - integerDigits++; - } - } - - /* Build the fraction part */ - numberPointer = &numberBuffer[sizeof(numberBuffer) - 1]; - *numberPointer = NIL; - onlyzero = TRUE; - for (i = 0; i < fractionDigits; i++) - { - *(--numberPointer) = digits[(int)fmod(number, dblBase)]; - number = floor(number / dblBase); - - if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_ALTERNATIVE)) - { - /* Prune trailing zeroes */ - if (numberPointer[0] != digits[0]) - onlyzero = FALSE; - else if (onlyzero && (numberPointer[0] == digits[0])) - numberPointer++; - } - else - onlyzero = FALSE; - } - - /* Insert decimal point */ - if ((flags & FLAGS_ALTERNATIVE) || ((fractionDigits > 0) && !onlyzero)) - { - i = StrLength(internalDecimalPoint); - while (i> 0) - { - *(--numberPointer) = internalDecimalPoint[--i]; - } - } - /* Insert the integer part and thousand separators */ - charsPerThousand = (int)internalGrouping[0]; - groupingIndex = 1; - for (i = 1; i < integerDigits + 1; i++) - { - *(--numberPointer) = digits[(int)fmod(number, dblBase)]; - number = floor(number / dblBase); - if (number < DBL_EPSILON) - break; - - if ((i > 0) - && ((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE) - && (charsPerThousand != NO_GROUPING) - && (i % charsPerThousand == 0)) - { - /* - * We are building the number from the least significant - * to the most significant digit, so we have to copy the - * thousand separator backwards - */ - length = StrLength(internalThousandSeparator); - integerDigits += length; - if (((int)(numberPointer - numberBuffer) - length) > 0) - { - work = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *(--numberPointer) = *work--; - } - - /* Advance to next grouping number */ - if (charsPerThousand != NO_GROUPING) - { - switch (internalGrouping[groupingIndex]) - { - case CHAR_MAX: /* Disable grouping */ - charsPerThousand = NO_GROUPING; - break; - case 0: /* Repeat last group */ - break; - default: - charsPerThousand = (int)internalGrouping[groupingIndex++]; - break; - } - } - } - } - - /* Build the exponent */ - exponentDigits = 0; - if (flags & FLAGS_FLOAT_E) - { - exponentPointer = &exponentBuffer[sizeof(exponentBuffer) - 1]; - *exponentPointer-- = NIL; - do { - *exponentPointer-- = digits[uExponent % base]; - uExponent /= base; - exponentDigits++; - } while (uExponent); - } - - /* - * Calculate expected width. - * sign + integer part + thousands separators + decimal point - * + fraction + exponent - */ - expectedWidth = StrLength(numberPointer); - if (isNegative || (flags & FLAGS_SHOWSIGN)) - expectedWidth += sizeof("-") - 1; - if (exponentDigits > 0) - expectedWidth += exponentDigits + - ((exponentDigits > 1) ? sizeof("E+") : sizeof("E+0")) - 1; - if (isHex) - expectedWidth += sizeof("0X") - 1; - - /* Output prefixing */ - if (flags & FLAGS_NILPADDING) - { - /* Leading zeros must be after sign */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, '0'); - } - } - } - else - { - /* Leading spaces must be before sign */ - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - } - /* Output number */ - for (i = 0; numberPointer[i]; i++) - { - self->OutStream(self, numberPointer[i]); - } - /* Output exponent */ - if (exponentDigits > 0) - { - self->OutStream(self, - isHex - ? ((flags & FLAGS_UPPER) ? 'P' : 'p') - : ((flags & FLAGS_UPPER) ? 'E' : 'e')); - self->OutStream(self, (isExponentNegative) ? '-' : '+'); - - /* The exponent must contain at least two digits */ - if (exponentDigits == 1) - self->OutStream(self, '0'); - - for (i = 0; i < exponentDigits; i++) - { - self->OutStream(self, exponentPointer[i + 1]); - } - } - /* Output trailing spaces */ - if (flags & FLAGS_LEFTADJUST) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } -} - -/************************************************************************* - * TrioFormatProcess [private] - */ -static int -TrioFormatProcess(trio_T *data, - const char *format, - parameter_T *parameters) - -{ -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int i; - const char *string; - void *pointer; - unsigned long flags; - int width; - int precision; - int base; - int index; - - index = 0; - i = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - while (charlen-- > 0) - { - data->OutStream(data, format[index++]); - } - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - data->OutStream(data, CHAR_IDENTIFIER); - index += 2; - } - else - { - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - - /* Find precision */ - if (flags & FLAGS_PRECISION) - { - precision = parameters[i].precision; - if (flags & FLAGS_PRECISION_PARAMETER) - { - /* Get precision from parameter list */ - precision = (int)parameters[precision].data.number.as_signed; - } - } - else - { - precision = NO_PRECISION; - } - - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_CHAR: - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - if (! (flags & FLAGS_LEFTADJUST)) - { - while (--width > 0) - data->OutStream(data, CHAR_ADJUST); - } -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideStringCharacter(data, - (wchar_t)parameters[i].data.number.as_signed, - flags, - NO_WIDTH); - } - else -#endif - TrioWriteStringCharacter(data, - (int)parameters[i].data.number.as_signed, - flags); - - if (flags & FLAGS_LEFTADJUST) - { - while(--width > 0) - data->OutStream(data, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - - break; /* FORMAT_CHAR */ - - case FORMAT_INT: - if (base == NO_BASE) - base = BASE_DECIMAL; - - TrioWriteNumber(data, - parameters[i].data.number.as_signed, - flags, - width, - precision, - base); - - break; /* FORMAT_INT */ - - case FORMAT_DOUBLE: - TrioWriteDouble(data, - parameters[i].data.longdoubleNumber, - flags, - width, - precision, - base); - break; /* FORMAT_DOUBLE */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideString(data, - parameters[i].data.wstring, - flags, - width, - precision); - } - else -#endif -#ifdef QUALIFIER_ESCAPE - { - char *s = NULL; - static const char* empty = "(null)"; - switch (parameters[i].escape) - { - case ESCAPE_ULM: - s = glite_lbu_EscapeULM(parameters[i].data.string); - break; - case ESCAPE_XML: - s = glite_lbu_EscapeXML(parameters[i].data.string); - break; - case ESCAPE_SQL: - s = glite_lbu_EscapeSQL(parameters[i].data.string); - break; - case ESCAPE_NONE: - s = strdup(parameters[i].data.string ? parameters[i].data.string : empty); - break; - } - TrioWriteString(data,s,flags,width,precision); - free(s); - } -#else - { - TrioWriteString(data, - parameters[i].data.string, - flags, - width, - precision); - } -#endif - break; /* FORMAT_STRING */ - - case FORMAT_POINTER: - { - reference_T reference; - - reference.data = data; - reference.parameter = ¶meters[i]; - trio_print_pointer(&reference, parameters[i].data.pointer); - } - break; /* FORMAT_POINTER */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { - /* - * C99 paragraph 7.19.6.1.8 says "the number of - * characters written to the output stream so far by - * this call", which is data->committed - */ -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->committed; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->committed; - } - else - { - *(int *)pointer = (int)data->committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - string = StrError(parameters[i].data.errorNumber); - if (string) - { - TrioWriteString(data, - string, - flags, - width, - precision); - } - else - { - data->OutStream(data, '#'); - TrioWriteNumber(data, - (trio_intmax_t)parameters[i].data.errorNumber, - flags, - width, - precision, - BASE_DECIMAL); - } - break; /* FORMAT_ERRNO */ -#endif /* defined(FORMAT_ERRNO) */ - -#if defined(FORMAT_USER_DEFINED) - case FORMAT_USER_DEFINED: - { - reference_T reference; - userdef_T *def = NULL; - - if (parameters[i].user_name[0] == NIL) - { - /* Use handle */ - if ((i > 0) || - (parameters[i - 1].type == FORMAT_PARAMETER)) - def = (userdef_T *)parameters[i - 1].data.pointer; - } - else - { - /* Look up namespace */ - def = TrioFindNamespace(parameters[i].user_name, NULL); - } - if (def) { - reference.data = data; - reference.parameter = ¶meters[i]; - def->callback(&reference); - } - } - break; -#endif /* defined(FORMAT_USER_DEFINED) */ - - default: - break; - } /* switch parameter type */ - - /* Prepare for next */ - index = parameters[i].indexAfterSpecifier; - i++; - } - } - else /* not identifier */ - { - data->OutStream(data, format[index++]); - } - } - return data->processed; -} - -/************************************************************************* - * TrioFormatRef [private] - */ -static int -TrioFormatRef(reference_T *reference, - const char *format, - va_list arglist, - void **argarray) -{ - int status; - parameter_T parameters[MAX_PARAMETERS]; - - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - return TrioFormatProcess(reference->data, format, parameters); -} - -/************************************************************************* - * TrioFormat [private] - * - * Description: - * This is the main engine for formatting output - */ -static int -TrioFormat(void *destination, - size_t destinationSize, - void (*OutStream)(trio_T *, int), - const char *format, - va_list arglist, - void **argarray) -{ - int status; - trio_T data; - parameter_T parameters[MAX_PARAMETERS]; - - assert(VALID(OutStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.OutStream = OutStream; - data.location = destination; - data.max = destinationSize; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - return TrioFormatProcess(&data, format, parameters); -} - -/************************************************************************* - * TrioOutStreamFile [private] - */ -static void -TrioOutStreamFile(trio_T *self, - int output) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->processed++; - self->committed++; - (void)fputc(output, file); -} - -/************************************************************************* - * TrioOutStreamFileDescriptor [private] - */ -static void -TrioOutStreamFileDescriptor(trio_T *self, - int output) -{ - int fd = *((int *)self->location); - char ch; - - assert(VALID(self)); - - ch = (char)output; - (void)write(fd, &ch, sizeof(char)); - self->processed++; - self->committed++; -} - -/************************************************************************* - * TrioOutStreamString [private] - */ -static void -TrioOutStreamString(trio_T *self, - int output) -{ - char **buffer = (char **)self->location; - - assert(VALID(self)); - assert(VALID(buffer)); - - **buffer = (char)output; - (*buffer)++; - self->processed++; - self->committed++; -} - -/************************************************************************* - * TrioOutStreamStringMax [private] - */ -static void -TrioOutStreamStringMax(trio_T *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - buffer = (char **)self->location; - assert(VALID(buffer)); - - if (self->processed < self->max) - { - **buffer = (char)output; - (*buffer)++; - self->committed++; - } - self->processed++; -} - -/************************************************************************* - * TrioOutStreamStringDynamic [private] - */ -#define DYNAMIC_START_SIZE 32 -struct dynamicBuffer { - char *buffer; - size_t length; - size_t allocated; -}; - -static void -TrioOutStreamStringDynamic(trio_T *self, - int output) -{ - struct dynamicBuffer *infop; - - assert(VALID(self)); - assert(VALID(self->location)); - - infop = (struct dynamicBuffer *)self->location; - - if (infop->buffer == NULL) - { - /* Start with a reasonable size */ - infop->buffer = (char *)TRIO_MALLOC(DYNAMIC_START_SIZE); - if (infop->buffer == NULL) - return; /* fail */ - - infop->allocated = DYNAMIC_START_SIZE; - self->processed = 0; - self->committed = 0; - } - else if (self->committed + sizeof(NIL) >= infop->allocated) - { - char *newptr; - - /* Allocate increasing chunks */ - newptr = (char *)TRIO_REALLOC(infop->buffer, infop->allocated * 2); - - if (newptr == NULL) - return; - - infop->buffer = newptr; - infop->allocated *= 2; - } - - infop->buffer[self->committed] = (char)output; - self->committed++; - self->processed++; - - infop->length = self->committed; -} - -/************************************************************************* - * printf - */ -int -trio_printf(const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vprintf(const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); -} - -#ifdef __GNUC__ -#define UNUSED_VAR __attribute__((unused)) -#else -#define UNUSED_VAR -#endif - -static void shutup_unitialized(va_list *dummy UNUSED_VAR) { -} - -int -trio_printfv(const char *format, - void ** args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, dummy, args); -} - -/************************************************************************* - * fprintf - */ -int -trio_fprintf(FILE *file, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vfprintf(FILE *file, - const char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); -} - -int -trio_fprintfv(FILE *file, - const char *format, - void ** args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, dummy, args); -} - -/************************************************************************* - * dprintf - */ -int -trio_dprintf(int fd, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vdprintf(int fd, - const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); -} - -int -trio_dprintfv(int fd, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, dummy, args); -} - -/************************************************************************* - * sprintf - */ -int -trio_sprintf(char *buffer, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; /* Terminate with NIL character */ - va_end(args); - return status; -} - -int -trio_vsprintf(char *buffer, - const char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; - return status; -} - -int -trio_sprintfv(char *buffer, - const char *format, - void **args) -{ - int status; - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, dummy, args); - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintf - */ -int -trio_snprintf(char *buffer, - size_t bufferSize, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) - *buffer = NIL; - va_end(args); - return status; -} - -int -trio_vsnprintf(char *buffer, - size_t bufferSize, - const char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) - *buffer = NIL; - return status; -} - -int -trio_snprintfv(char *buffer, - size_t bufferSize, - const char *format, - void **args) -{ - int status; - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, dummy, args); - if (bufferSize > 0) - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintfcat - * Appends the new string to the buffer string overwriting the '\0' - * character at the end of buffer. - */ -int -trio_snprintfcat(char *buffer, - size_t bufferSize, - const char *format, - ...) -{ - int status; - va_list args; - size_t buf_len; - - va_start(args, format); - - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = strlen(buffer); - buffer = &buffer[buf_len]; - - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - va_end(args); - *buffer = NIL; - return status; -} - -int -trio_vsnprintfcat(char *buffer, - size_t bufferSize, - const char *format, - va_list args) -{ - int status; - size_t buf_len; - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = strlen(buffer); - buffer = &buffer[buf_len]; - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - *buffer = NIL; - return status; -} - -/************************************************************************* - * trio_aprintf - */ - -/* Deprecated */ -char * -trio_aprintf(const char *format, - ...) -{ - va_list args; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; -} - -/* Deprecated */ -char * -trio_vaprintf(const char *format, - va_list args) -{ - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; -} - -int -trio_asprintf(char **result, - const char *format, - ...) -{ - va_list args; - int status; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - /* - * If the length is zero, no characters have been written and therefore - * no memory has been allocated, but we must to allocate and return an - * empty string. - */ - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; - - return status; -} - -int -trio_vasprintf(char **result, - const char *format, - va_list args) -{ - int status; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; - - return status; -} - - -/************************************************************************* - * - * @CALLBACK - * - ************************************************************************/ - - -/************************************************************************* - * trio_register [public] - */ -void * -trio_register(trio_callback_t callback, - const char *name) -{ - userdef_T *def; - userdef_T *prev = NULL; - - if (callback == NULL) - return NULL; - - if (name) - { - /* Handle built-in namespaces */ - if (name[0] == ':') - { - if (StrEqual(name, ":enter")) - { - internalEnterCriticalRegion = callback; - } - else if (StrEqual(name, ":leave")) - { - internalLeaveCriticalRegion = callback; - } - return NULL; - } - - /* Bail out if namespace is too long */ - if (StrLength(name) >= MAX_USER_NAME) - return NULL; - - /* Bail out if namespace already is registered */ - def = TrioFindNamespace(name, &prev); - if (def) - return NULL; - } - - def = (userdef_T *)TRIO_MALLOC(sizeof(userdef_T)); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (name) - { - /* Link into internal list */ - if (prev == NULL) - internalUserDef = def; - else - prev->next = def; - } - /* Initialize */ - def->callback = callback; - def->name = (name == NULL) - ? NULL - : StrDuplicate(name); - def->next = NULL; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - return def; -} - -/************************************************************************* - * trio_unregister [public] - */ -void -trio_unregister(void *handle) -{ - userdef_T *self = (userdef_T *)handle; - userdef_T *def; - userdef_T *prev = NULL; - - assert(VALID(self)); - - if (self->name) - { - def = TrioFindNamespace(self->name, &prev); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (prev == NULL) - internalUserDef = NULL; - else - prev->next = def->next; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - StrFree(self->name); - } - TRIO_FREE(self); -} - -/************************************************************************* - * trio_get_format [public] - */ -const char * -trio_get_format(void *ref) -{ - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); - - return (((reference_T *)ref)->parameter->user_data); -} - -/************************************************************************* - * trio_get_argument [public] - */ -void * -trio_get_argument(void *ref) -{ - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); - - return ((reference_T *)ref)->parameter->data.pointer; -} - -/************************************************************************* - * trio_get_width / trio_set_width [public] - */ -int -trio_get_width(void *ref) -{ - return ((reference_T *)ref)->parameter->width; -} - -void -trio_set_width(void *ref, - int width) -{ - ((reference_T *)ref)->parameter->width = width; -} - -/************************************************************************* - * trio_get_precision / trio_set_precision [public] - */ -int -trio_get_precision(void *ref) -{ - return (((reference_T *)ref)->parameter->precision); -} - -void -trio_set_precision(void *ref, - int precision) -{ - ((reference_T *)ref)->parameter->precision = precision; -} - -/************************************************************************* - * trio_get_base / trio_set_base [public] - */ -int -trio_get_base(void *ref) -{ - return (((reference_T *)ref)->parameter->base); -} - -void -trio_set_base(void *ref, - int base) -{ - ((reference_T *)ref)->parameter->base = base; -} - -/************************************************************************* - * trio_get_long / trio_set_long [public] - */ -int -trio_get_long(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LONG); -} - -void -trio_set_long(void *ref, - int is_long) -{ - if (is_long) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONG; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONG; -} - -/************************************************************************* - * trio_get_longlong / trio_set_longlong [public] - */ -int -trio_get_longlong(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_QUAD); -} - -void -trio_set_longlong(void *ref, - int is_longlong) -{ - if (is_longlong) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUAD; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUAD; -} - -/************************************************************************* - * trio_get_longdouble / trio_set_longdouble [public] - */ -int -trio_get_longdouble(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LONGDOUBLE); -} - -void -trio_set_longdouble(void *ref, - int is_longdouble) -{ - if (is_longdouble) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; -} - -/************************************************************************* - * trio_get_short / trio_set_short [public] - */ -int -trio_get_short(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORT); -} - -void -trio_set_short(void *ref, - int is_short) -{ - if (is_short) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORT; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORT; -} - -/************************************************************************* - * trio_get_shortshort / trio_set_shortshort [public] - */ -int -trio_get_shortshort(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORTSHORT); -} - -void -trio_set_shortshort(void *ref, - int is_shortshort) -{ - if (is_shortshort) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORTSHORT; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; -} - -/************************************************************************* - * trio_get_alternative / trio_set_alternative [public] - */ -int -trio_get_alternative(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_ALTERNATIVE); -} - -void -trio_set_alternative(void *ref, - int is_alternative) -{ - if (is_alternative) - ((reference_T *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; -} - -/************************************************************************* - * trio_get_alignment / trio_set_alignment [public] - */ -int -trio_get_alignment(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LEFTADJUST); -} - -void -trio_set_alignment(void *ref, - int is_leftaligned) -{ - if (is_leftaligned) - ((reference_T *)ref)->parameter->flags |= FLAGS_LEFTADJUST; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; -} - -/************************************************************************* - * trio_get_spacing /trio_set_spacing [public] - */ -int -trio_get_spacing(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SPACE); -} - -void -trio_set_spacing(void *ref, - int is_space) -{ - if (is_space) - ((reference_T *)ref)->parameter->flags |= FLAGS_SPACE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SPACE; -} - -/************************************************************************* - * trio_get_sign / trio_set_sign [public] - */ -int -trio_get_sign(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHOWSIGN); -} - -void -trio_set_sign(void *ref, - int is_sign) -{ - if (is_sign) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHOWSIGN; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; -} - -/************************************************************************* - * trio_get_padding / trio_set_padding [public] - */ -int -trio_get_padding(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_NILPADDING); -} - -void -trio_set_padding(void *ref, - int is_padding) -{ - if (is_padding) - ((reference_T *)ref)->parameter->flags |= FLAGS_NILPADDING; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_NILPADDING; -} - -/************************************************************************* - * trio_get_quote / trio_set_quote [public] - */ -int -trio_get_quote(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_QUOTE); -} - -void -trio_set_quote(void *ref, - int is_quote) -{ - if (is_quote) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUOTE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUOTE; -} - -/************************************************************************* - * trio_get_upper / trio_set_upper [public] - */ -int -trio_get_upper(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_UPPER); -} - -void -trio_set_upper(void *ref, - int is_upper) -{ - if (is_upper) - ((reference_T *)ref)->parameter->flags |= FLAGS_UPPER; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_UPPER; -} - -/************************************************************************* - * trio_get_largest / trio_set_largest [public] - */ -#if TRIO_C99 -int -trio_get_largest(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_INTMAX_T); -} - -void -trio_set_largest(void *ref, - int is_largest) -{ - if (is_largest) - ((reference_T *)ref)->parameter->flags |= FLAGS_INTMAX_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; -} -#endif - -/************************************************************************* - * trio_get_ptrdiff / trio_set_ptrdiff [public] - */ -int -trio_get_ptrdiff(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_PTRDIFF_T); -} - -void -trio_set_ptrdiff(void *ref, - int is_ptrdiff) -{ - if (is_ptrdiff) - ((reference_T *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; -} - -/************************************************************************* - * trio_get_size / trio_set_size [public] - */ -#if TRIO_C99 -int -trio_get_size(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SIZE_T); -} - -void -trio_set_size(void *ref, - int is_size) -{ - if (is_size) - ((reference_T *)ref)->parameter->flags |= FLAGS_SIZE_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SIZE_T; -} -#endif - -/************************************************************************* - * trio_print_int [public] - */ -void -trio_print_int(void *ref, - int number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteNumber(self->data, - (trio_intmax_t)number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_uint [public] - */ -void -trio_print_uint(void *ref, - unsigned int number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteNumber(self->data, - (trio_intmax_t)number, - self->parameter->flags | FLAGS_UNSIGNED, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_double [public] - */ -void -trio_print_double(void *ref, - double number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteDouble(self->data, - number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_string [public] - */ -void -trio_print_string(void *ref, - char *string) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteString(self->data, - string, - self->parameter->flags, - self->parameter->width, - self->parameter->precision); -} - -/************************************************************************* - * trio_print_pointer [public] - */ -void -trio_print_pointer(void *ref, - void *pointer) -{ - reference_T *self = (reference_T *)ref; - unsigned long flags; - trio_uintmax_t number; - - if (NULL == pointer) - { - const char *string = null; - while (*string) - self->data->OutStream(self->data, *string++); - } - else - { - /* - * The subtraction of the null pointer is a workaround - * to avoid a compiler warning. The performance overhead - * is negligible (and likely to be removed by an - * optimising compiler). The (char *) casting is done - * to please ANSI C++. - */ - number = (trio_uintmax_t)((char *)pointer - (char *)0); - /* Shrink to size of pointer */ - number &= (trio_uintmax_t)-1; - flags = self->parameter->flags; - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | - FLAGS_NILPADDING); - TrioWriteNumber(self->data, - (trio_intmax_t)number, - flags, - POINTER_WIDTH, - NO_PRECISION, - BASE_HEX); - } -} - -/************************************************************************* - * trio_print_ref [public] - */ -int -trio_print_ref(void *ref, - const char *format, - ...) -{ - int status; - va_list arglist; - - assert(VALID(format)); - - va_start(arglist, format); - status = TrioFormatRef((reference_T *)ref, format, arglist, NULL); - va_end(arglist); - return status; -} - -/************************************************************************* - * trio_vprint_ref [public] - */ -int -trio_vprint_ref(void *ref, - const char *format, - va_list arglist) -{ - assert(VALID(format)); - - return TrioFormatRef((reference_T *)ref, format, arglist, NULL); -} - -/************************************************************************* - * trio_printv_ref [public] - */ -int -trio_printv_ref(void *ref, - const char *format, - void **argarray) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormatRef((reference_T *)ref, format, dummy, argarray); -} - - -/************************************************************************* - * - * @SCANNING - * - ************************************************************************/ - - -/************************************************************************* - * TrioSkipWhitespaces [private] - */ -static int -TrioSkipWhitespaces(trio_T *self) -{ - int ch; - - ch = self->current; - while (isspace(ch)) - { - self->InStream(self, &ch); - } - return ch; -} - -/************************************************************************* - * TrioGetCollation [private] - */ -#if TRIO_EXTENSION -static void -TrioGetCollation() -{ - int i; - int j; - int k; - char first[2]; - char second[2]; - - /* This is computational expensive */ - first[1] = NIL; - second[1] = NIL; - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - { - k = 0; - first[0] = (char)i; - for (j = 0; j < MAX_CHARACTER_CLASS; j++) - { - second[0] = (char)j; - if (StrEqualLocale(first, second)) - internalCollationArray[i][k++] = (char)j; - } - internalCollationArray[i][k] = NIL; - } -} -#endif - -/************************************************************************* - * TrioGetCharacterClass [private] - * - * FIXME: - * multibyte - */ -static int -TrioGetCharacterClass(const char *format, - int *indexPointer, - unsigned long *flagsPointer, - int *characterclass) -{ - int index = *indexPointer; - int i; - char ch; - char range_begin; - char range_end; - - *flagsPointer &= ~FLAGS_EXCLUDE; - - if (format[index] == QUALIFIER_CIRCUMFLEX) - { - *flagsPointer |= FLAGS_EXCLUDE; - index++; - } - /* - * If the ungroup character is at the beginning of the scanlist, - * it will be part of the class, and a second ungroup character - * must follow to end the group. - */ - if (format[index] == SPECIFIER_UNGROUP) - { - characterclass[(int)SPECIFIER_UNGROUP]++; - index++; - } - /* - * Minus is used to specify ranges. To include minus in the class, - * it must be at the beginning of the list - */ - if (format[index] == QUALIFIER_MINUS) - { - characterclass[(int)QUALIFIER_MINUS]++; - index++; - } - /* Collect characters */ - for (ch = format[index]; - (ch != SPECIFIER_UNGROUP) && (ch != NIL); - ch = format[++index]) - { - switch (ch) - { - case QUALIFIER_MINUS: /* Scanlist ranges */ - - /* - * Both C99 and UNIX98 describes ranges as implementation- - * defined. - * - * We support the following behaviour (although this may - * change as we become wiser) - * - only increasing ranges, ie. [a-b] but not [b-a] - * - transitive ranges, ie. [a-b-c] == [a-c] - * - trailing minus, ie. [a-] is interpreted as an 'a' - * and a '-' - * - duplicates (although we can easily convert these - * into errors) - */ - range_begin = format[index - 1]; - range_end = format[++index]; - if (range_end == SPECIFIER_UNGROUP) - { - /* Trailing minus is included */ - characterclass[(int)ch]++; - ch = range_end; - break; /* for */ - } - if (range_end == NIL) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - if (range_begin > range_end) - return TRIO_ERROR_RETURN(TRIO_ERANGE, index); - - for (i = (int)range_begin; i <= (int)range_end; i++) - characterclass[i]++; - - ch = range_end; - break; - -#if TRIO_EXTENSION - - case SPECIFIER_GROUP: - - switch (format[index + 1]) - { - case QUALIFIER_DOT: /* Collating symbol */ - /* - * FIXME: This will be easier to implement when multibyte - * characters have been implemented. Until now, we ignore - * this feature. - */ - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_DOT) - break; /* for */ - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - break; - - case QUALIFIER_EQUAL: /* Equivalence class expressions */ - { - unsigned int j; - unsigned int k; - - if (internalCollationUnconverted) - { - /* Lazy evalutation of collation array */ - TrioGetCollation(); - internalCollationUnconverted = FALSE; - } - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_EQUAL) - break; /* for */ - else - { - /* Mark any equivalent character */ - k = (unsigned int)format[i]; - for (j = 0; internalCollationArray[k][j] != NIL; j++) - characterclass[(int)internalCollationArray[k][j]]++; - } - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - } - break; - - case QUALIFIER_COLON: /* Character class expressions */ - - if (StrEqualMax(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalnum(i)) - characterclass[i]++; - index += sizeof(CLASS_ALNUM) - 1; - } - else if (StrEqualMax(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalpha(i)) - characterclass[i]++; - index += sizeof(CLASS_ALPHA) - 1; - } - else if (StrEqualMax(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (iscntrl(i)) - characterclass[i]++; - index += sizeof(CLASS_CNTRL) - 1; - } - else if (StrEqualMax(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_DIGIT) - 1; - } - else if (StrEqualMax(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isgraph(i)) - characterclass[i]++; - index += sizeof(CLASS_GRAPH) - 1; - } - else if (StrEqualMax(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (islower(i)) - characterclass[i]++; - index += sizeof(CLASS_LOWER) - 1; - } - else if (StrEqualMax(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isprint(i)) - characterclass[i]++; - index += sizeof(CLASS_PRINT) - 1; - } - else if (StrEqualMax(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (ispunct(i)) - characterclass[i]++; - index += sizeof(CLASS_PUNCT) - 1; - } - else if (StrEqualMax(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isspace(i)) - characterclass[i]++; - index += sizeof(CLASS_SPACE) - 1; - } - else if (StrEqualMax(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isupper(i)) - characterclass[i]++; - index += sizeof(CLASS_UPPER) - 1; - } - else if (StrEqualMax(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isxdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_XDIGIT) - 1; - } - else - { - characterclass[(int)ch]++; - } - break; - - default: - characterclass[(int)ch]++; - break; - } - break; - -#endif /* TRIO_EXTENSION */ - - default: - characterclass[(int)ch]++; - break; - } - } - return 0; -} - -/************************************************************************* - * TrioReadNumber [private] - * - * We implement our own number conversion in preference of strtol and - * strtoul, because we must handle 'long long' and thousand separators. - */ -static BOOLEAN_T -TrioReadNumber(trio_T *self, - trio_uintmax_t *target, - unsigned long flags, - int width, - int base) -{ - trio_uintmax_t number = 0; - int digit; - int count; - BOOLEAN_T isNegative = FALSE; - int j; - - assert(VALID(self)); - assert(VALID(self->InStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - if (internalDigitsUnconverted) - { - /* Lazy evaluation of digits array */ - memset(internalDigitArray, -1, sizeof(internalDigitArray)); - for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) - { - internalDigitArray[(int)internalDigitsLower[j]] = j; - internalDigitArray[(int)internalDigitsUpper[j]] = j; - } - internalDigitsUnconverted = FALSE; - } - - TrioSkipWhitespaces(self); - - if (!(flags & FLAGS_UNSIGNED)) - { - /* Leading sign */ - if (self->current == '+') - { - self->InStream(self, NULL); - } - else if (self->current == '-') - { - self->InStream(self, NULL); - isNegative = TRUE; - } - } - - count = self->processed; - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case NO_BASE: - case BASE_OCTAL: - case BASE_HEX: - case BASE_BINARY: - if (self->current == '0') - { - self->InStream(self, NULL); - if (self->current) - { - if ((base == BASE_HEX) && - (toupper(self->current) == 'X')) - { - self->InStream(self, NULL); - } - else if ((base == BASE_BINARY) && - (toupper(self->current) == 'B')) - { - self->InStream(self, NULL); - } - } - } - else - return FALSE; - break; - default: - break; - } - } - - while (((width == NO_WIDTH) || (self->processed - count < width)) && - (! ((self->current == EOF) || isspace(self->current)))) - { - if (isascii(self->current)) - { - digit = internalDigitArray[self->current]; - /* Abort if digit is not allowed in the specified base */ - if ((digit == -1) || (digit >= base)) - break; - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, NULL); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; - - number *= base; - number += digit; - - self->InStream(self, NULL); - } - - /* Was anything read at all? */ - if (self->processed == count) - return FALSE; - - if (target) - *target = (isNegative) ? -number : number; - return TRUE; -} - -/************************************************************************* - * TrioReadChar [private] - */ -static int -TrioReadChar(trio_T *self, - char *target, - unsigned long flags, - int width) -{ - int i; - char ch; - trio_uintmax_t number; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - ch = (char)self->current; - self->InStream(self, NULL); - if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) - { - switch (self->current) - { - case '\\': ch = '\\'; break; - case 'a': ch = '\007'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - default: - if (isdigit(self->current)) - { - /* Read octal number */ - if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) - return 0; - ch = (char)number; - } - else if (toupper(self->current) == 'X') - { - /* Read hexadecimal number */ - self->InStream(self, NULL); - if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) - return 0; - ch = (char)number; - } - else - { - ch = (char)self->current; - } - break; - } - } - - if (target) - target[i] = ch; - } - return i + 1; -} - -/************************************************************************* - * TrioReadString [private] - */ -static BOOLEAN_T -TrioReadString(trio_T *self, - char *target, - unsigned long flags, - int width) -{ - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - i++) - { - if (TrioReadChar(self, &target[i], flags, 1) == 0) - break; /* for */ - } - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadWideChar [private] - */ -#if TRIO_WIDECHAR -static int -TrioReadWideChar(trio_T *self, - wchar_t *target, - unsigned long flags, - int width) -{ - int i; - int j; - int size; - int amount = 0; - wchar_t wch; - char buffer[MB_LEN_MAX + 1]; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - if (isascii(self->current)) - { - if (TrioReadChar(self, buffer, flags, 1) == 0) - return 0; - buffer[1] = NIL; - } - else - { - /* - * Collect a multibyte character, by enlarging buffer until - * it contains a fully legal multibyte character, or the - * buffer is full. - */ - j = 0; - do - { - buffer[j++] = (char)self->current; - buffer[j] = NIL; - self->InStream(self, NULL); - } - while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); - } - if (target) - { - size = mbtowc(&wch, buffer, sizeof(buffer)); - if (size > 0) - target[i] = wch; - } - amount += size; - self->InStream(self, NULL); - } - return amount; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadWideString [private] - */ -#if TRIO_WIDECHAR -static BOOLEAN_T -TrioReadWideString(trio_T *self, - wchar_t *target, - unsigned long flags, - int width) -{ - int i; - int size; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - ) - { - size = TrioReadWideChar(self, &target[i], flags, 1); - if (size == 0) - break; /* for */ - - i += size; - } - if (target) - target[i] = L'\0'; - return TRUE; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadGroup [private] - * - * FIXME: characterclass does not work with multibyte characters - */ -static BOOLEAN_T -TrioReadGroup(trio_T *self, - char *target, - int *characterclass, - unsigned long flags, - int width) -{ - int ch; - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - ch = self->current; - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((ch == EOF) || - (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); - i++) - { - if (target) - target[i] = (char)ch; - self->InStream(self, &ch); - } - - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadDouble [private] - * - * FIXME: - * add long double - */ -static BOOLEAN_T -TrioReadDouble(trio_T *self, - double *target, - unsigned long flags, - int width) -{ - int ch; - char doubleString[512] = ""; - int index = 0; - int start; - int j; - BOOLEAN_T isHex = FALSE; - - if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1)) - width = sizeof(doubleString) - 1; - - TrioSkipWhitespaces(self); - - /* - * Read entire double number from stream. StrToDouble requires a - * string as input, but InStream can be anything, so we have to - * collect all characters. - */ - ch = self->current; - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - width--; - } - - start = index; - switch (ch) - { - case 'n': - case 'N': - /* Not-a-number */ - if (index != 0) - break; - /* FALLTHROUGH */ - case 'i': - case 'I': - /* Infinity */ - while (isalpha(ch) && (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - doubleString[index] = NIL; - - /* Case insensitive string comparison */ - if (StrEqual(&doubleString[start], INFINITE_UPPER) || - StrEqual(&doubleString[start], LONG_INFINITE_UPPER)) - { - *target = ((start == 1 && doubleString[0] == '-')) - ? -HUGE_VAL - : HUGE_VAL; - return TRUE; - } - if (StrEqual(doubleString, NAN_LOWER)) - { - /* NaN must not have a preceeding + nor - */ - *target = TrioGenerateNaN(); - return TRUE; - } - return FALSE; - - default: - break; - } - - if (ch == '0') - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if (toupper(ch) == 'X') - { - isHex = TRUE; - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - } - while ((ch != EOF) && (index - start < width)) - { - /* Integer part */ - if (isHex ? isxdigit(ch) : isdigit(ch)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, &ch); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; /* while */ - } - if (ch == '.') - { - /* Decimal part */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - if (isHex ? (toupper(ch) == 'P') : (toupper(ch) == 'E')) - { - /* Exponent */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - } - } - - if ((index == start) || (*doubleString == NIL)) - return FALSE; - - if (flags & FLAGS_LONGDOUBLE) -/* *longdoublePointer = StrToLongDouble()*/ - return FALSE; /* FIXME: Remove when long double is implemented */ - else - { - *target = StrToDouble(doubleString, NULL); - } - return TRUE; -} - -/************************************************************************* - * TrioReadPointer [private] - */ -static BOOLEAN_T -TrioReadPointer(trio_T *self, - void **target, - unsigned long flags) -{ - trio_uintmax_t number; - char buffer[sizeof(null)]; - - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); - - if (TrioReadNumber(self, - &number, - flags, - POINTER_WIDTH, - BASE_HEX)) - { - /* - * The strange assignment of number is a workaround for a compiler - * warning - */ - if (target) - *target = (char *)0 + number; - return TRUE; - } - else if (TrioReadString(self, - (flags & FLAGS_IGNORE) - ? NULL - : buffer, - 0, - sizeof(null) - 1)) - { - if (StrEqualCase(buffer, null)) - { - if (target) - *target = NULL; - return TRUE; - } - } - return FALSE; -} - -/************************************************************************* - * TrioScan [private] - */ -static int -TrioScan(const void *source, - size_t sourceSize, - void (*InStream)(trio_T *, int *), - const char *format, - va_list arglist, - void **argarray) -{ -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int status; - int assignment; - parameter_T parameters[MAX_PARAMETERS]; - trio_T internalData; - trio_T *data; - int ch; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int cnt; -#endif - int index; /* Index of format string */ - int i; /* Index of current parameter */ - unsigned long flags; - int width; - int base; - void *pointer; - - assert(VALID(InStream)); - assert(VALID(format)); - - memset(&internalData, 0, sizeof(internalData)); - data = &internalData; - data->InStream = InStream; - data->location = (void *)source; - data->max = sourceSize; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioPreprocess(TYPE_SCAN, format, parameters, arglist, argarray); - if (status < 0) - return status; - - assignment = 0; - i = 0; - index = 0; - data->InStream(data, &ch); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - /* Compare multibyte characters in format string */ - for (cnt = 0; cnt < charlen - 1; cnt++) - { - if (ch != format[index + cnt]) - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - data->InStream(data, &ch); - } - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (EOF == ch) - return EOF; - - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - /* Two % in format matches one % in input stream */ - if (CHAR_IDENTIFIER == ch) - { - data->InStream(data, &ch); - index += 2; - continue; /* while format chars left */ - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_INT: - { - trio_uintmax_t number; - - if (0 == base) - base = BASE_DECIMAL; - - if (!TrioReadNumber(data, - &number, - flags, - width, - base)) - return assignment; - assignment++; - - if (!(flags & FLAGS_IGNORE)) - { - pointer = parameters[i].data.pointer; -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)number; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)number; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)number; - else -#endif - if (flags & FLAGS_QUAD) - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; - else if (flags & FLAGS_LONG) - *(long int *)pointer = (long int)number; - else if (flags & FLAGS_SHORT) - *(short int *)pointer = (short int)number; - else - *(int *)pointer = (int)number; - } - } - break; /* FORMAT_INT */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (!TrioReadWideString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - width)) - return assignment; - } - else -#endif - { - if (!TrioReadString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - width)) - return assignment; - } - assignment++; - break; /* FORMAT_STRING */ - - case FORMAT_DOUBLE: - if (!TrioReadDouble(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.doublePointer, - flags, - width)) - return assignment; - assignment++; - break; /* FORMAT_DOUBLE */ - - case FORMAT_GROUP: - { - int characterclass[MAX_CHARACTER_CLASS + 1]; - int rc; - - /* Skip over modifiers */ - while (format[index] != SPECIFIER_GROUP) - { - index++; - } - /* Skip over group specifier */ - index++; - - memset(characterclass, 0, sizeof(characterclass)); - rc = TrioGetCharacterClass(format, - &index, - &flags, - characterclass); - if (rc < 0) - return rc; - - if (!TrioReadGroup(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - characterclass, - flags, - parameters[i].width)) - return assignment; - assignment++; - } - break; /* FORMAT_GROUP */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->committed; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->committed; - } - else - { - *(int *)pointer = (int)data->committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_CHAR: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (TrioReadWideChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - (width == NO_WIDTH) ? 1 : width) > 0) - return assignment; - } - else -#endif - { - if (TrioReadChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - (width == NO_WIDTH) ? 1 : width) > 0) - return assignment; - } - assignment++; - break; /* FORMAT_CHAR */ - - case FORMAT_POINTER: - if (!TrioReadPointer(data, - (flags & FLAGS_IGNORE) - ? NULL - : (void **)parameters[i].data.pointer, - flags)) - return assignment; - assignment++; - break; /* FORMAT_POINTER */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - - default: - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - ch = data->current; - index = parameters[i].indexAfterSpecifier; - i++; - } - else /* Not an % identifier */ - { - if (isspace((int)format[index])) - { - /* Whitespaces may match any amount of whitespaces */ - ch = TrioSkipWhitespaces(data); - } - else if (ch == format[index]) - { - data->InStream(data, &ch); - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - index++; - } - } - return assignment; -} - -/************************************************************************* - * TrioInStreamFile [private] - */ -static void -TrioInStreamFile(trio_T *self, - int *intPointer) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->current = fgetc(file); - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamFileDescriptor [private] - */ -static void -TrioInStreamFileDescriptor(trio_T *self, - int *intPointer) -{ - int fd = *((int *)self->location); - int size; - unsigned char input; - - assert(VALID(self)); - - size = read(fd, &input, sizeof(char)); - self->current = (size == 0) ? EOF : input; - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamString [private] - */ -static void -TrioInStreamString(trio_T *self, - int *intPointer) -{ - unsigned char **buffer; - - assert(VALID(self)); - assert(VALID(self->InStream)); - assert(VALID(self->location)); - - buffer = (unsigned char **)self->location; - self->current = (*buffer)[0]; - if (self->current == NIL) - self->current = EOF; - (*buffer)++; - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * scanf - */ -int -trio_scanf(const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vscanf(const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL); -} - -int -trio_scanfv(const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioScan(stdin, 0, TrioInStreamFile, format, dummy, args); -} - -/************************************************************************* - * fscanf - */ -int -trio_fscanf(FILE *file, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(file, 0, TrioInStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vfscanf(FILE *file, - const char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan(file, 0, TrioInStreamFile, format, args, NULL); -} - -int -trio_fscanfv(FILE *file, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan(file, 0, TrioInStreamFile, format, dummy, args); -} - -/************************************************************************* - * dscanf - */ -int -trio_dscanf(int fd, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vdscanf(int fd, - const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL); -} - -int -trio_dscanfv(int fd, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, dummy, args); -} - -/************************************************************************* - * sscanf - */ -int -trio_sscanf(const char *buffer, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vsscanf(const char *buffer, - const char *format, - va_list args) -{ - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL); -} - -int -trio_sscanfv(const char *buffer, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan(&buffer, 0, TrioInStreamString, format, dummy, args); -} - diff --git a/org.glite.lb-utils.trio/src/triop.h b/org.glite.lb-utils.trio/src/triop.h deleted file mode 100644 index ca49fab..0000000 --- a/org.glite.lb-utils.trio/src/triop.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************ - * - * Private functions, types, etc. used for callback functions. - * - * The ref pointer is an opaque type and should remain as such. - * Private data must only be accessible through the getter and - * setter functions. - * - ************************************************************************/ - -#ifndef TRIO_TRIOP_H -#define TRIO_TRIOP_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef TRIO_C99 -# define TRIO_C99 1 -#endif -#ifndef TRIO_BSD -# define TRIO_BSD 1 -#endif -#ifndef TRIO_GNU -# define TRIO_GNU 1 -#endif -#ifndef TRIO_MISC -# define TRIO_MISC 1 -#endif -#ifndef TRIO_UNIX98 -# define TRIO_UNIX98 1 -#endif -#ifndef TRIO_MICROSOFT -# define TRIO_MICROSOFT 1 -#endif -#ifndef TRIO_EXTENSION -# define TRIO_EXTENSION 1 -#endif -#ifndef TRIO_WIDECHAR -# define TRIO_WIDECHAR 0 -#endif -#ifndef TRIO_ERRORS -# define TRIO_ERRORS 1 -#endif - -#ifndef TRIO_MALLOC -# define TRIO_MALLOC(n) malloc(n) -#endif -#ifndef TRIO_REALLOC -# define TRIO_REALLOC(x,n) realloc((x),(n)) -#endif -#ifndef TRIO_FREE -# define TRIO_FREE(x) free(x) -#endif - -typedef int (*trio_callback_t)(void *ref); - -void *trio_register(trio_callback_t callback, const char *name); -void trio_unregister(void *handle); - -const char *trio_get_format(void *ref); -void *trio_get_argument(void *ref); - -/* Modifiers */ -int trio_get_width(void *ref); -void trio_set_width(void *ref, int width); -int trio_get_precision(void *ref); -void trio_set_precision(void *ref, int precision); -int trio_get_base(void *ref); -void trio_set_base(void *ref, int base); -int trio_get_padding(void *ref); -void trio_set_padding(void *ref, int is_padding); -int trio_get_short(void *ref); /* h */ -void trio_set_shortshort(void *ref, int is_shortshort); -int trio_get_shortshort(void *ref); /* hh */ -void trio_set_short(void *ref, int is_short); -int trio_get_long(void *ref); /* l */ -void trio_set_long(void *ref, int is_long); -int trio_get_longlong(void *ref); /* ll */ -void trio_set_longlong(void *ref, int is_longlong); -int trio_get_longdouble(void *ref); /* L */ -void trio_set_longdouble(void *ref, int is_longdouble); -int trio_get_alternative(void *ref); /* # */ -void trio_set_alternative(void *ref, int is_alternative); -int trio_get_alignment(void *ref); /* - */ -void trio_set_alignment(void *ref, int is_leftaligned); -int trio_get_spacing(void *ref); /* (space) */ -void trio_set_spacing(void *ref, int is_space); -int trio_get_sign(void *ref); /* + */ -void trio_set_sign(void *ref, int is_showsign); -int trio_get_quote(void *ref); /* ' */ -void trio_set_quote(void *ref, int is_quote); -int trio_get_upper(void *ref); -void trio_set_upper(void *ref, int is_upper); -#if TRIO_C99 -int trio_get_largest(void *ref); /* j */ -void trio_set_largest(void *ref, int is_largest); -int trio_get_ptrdiff(void *ref); /* t */ -void trio_set_ptrdiff(void *ref, int is_ptrdiff); -int trio_get_size(void *ref); /* z / Z */ -void trio_set_size(void *ref, int is_size); -#endif - -/* Printing */ -int trio_print_ref(void *ref, const char *format, ...); -int trio_vprint_ref(void *ref, const char *format, va_list args); -int trio_printv_ref(void *ref, const char *format, void **args); - -void trio_print_int(void *ref, int number); -void trio_print_uint(void *ref, unsigned int number); -/* void trio_print_long(void *ref, long number); */ -/* void trio_print_ulong(void *ref, unsigned long number); */ -void trio_print_double(void *ref, double number); -void trio_print_string(void *ref, char *string); -void trio_print_pointer(void *ref, void *pointer); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRIO_TRIOP_H */ diff --git a/org.glite.lb-utils.trio/test/trio_test.cpp b/org.glite.lb-utils.trio/test/trio_test.cpp deleted file mode 100644 index 3ba4b9c..0000000 --- a/org.glite.lb-utils.trio/test/trio_test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include -#include - -#include "trio.h" - -class TrioTest: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(TrioTest); - CPPUNIT_TEST(escapeULM); - CPPUNIT_TEST(escapeXML); - CPPUNIT_TEST(escapeSQL); - CPPUNIT_TEST_SUITE_END(); - -public: - void escapeULM(); - void escapeXML(); - void escapeSQL(); -}; - -void TrioTest::escapeULM() -{ - char *e, *r = "START we have =, \\\", and \\n in the string END"; - - trio_asprintf(&e,"START %|Us END", "we have =, \", and \n in the string"), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape ULM failed",!strcmp(e,r)); -} - -void TrioTest::escapeXML() -{ - char *e, *r = "START there is a <tag> containing &something; </tag> END"; - - trio_asprintf(&e,"START %|Xs END", "there is a containing &something; "), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape XML failed",!strcmp(e,r)); -} - -void TrioTest::escapeSQL() -{ - char *e, *r = "START SQL doesn''t like '' END"; - - trio_asprintf(&e,"START %|Ss END", "SQL doesn't like '"), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape SQL failed",!strcmp(e,r)); -} - -CPPUNIT_TEST_SUITE_REGISTRATION( TrioTest ); - -#include -#include - -#include -#include -#include -#include -#include -#include - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.lb-utils/.cvsignore b/org.glite.lb-utils/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.lb-utils/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.lb-utils/LICENSE b/org.glite.lb-utils/LICENSE deleted file mode 100755 index 259a91f..0000000 --- a/org.glite.lb-utils/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils/build.xml b/org.glite.lb-utils/build.xml deleted file mode 100644 index 85553ce..0000000 --- a/org.glite.lb-utils/build.xml +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - Ant build file to build the lb-utils subsystem. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.lb-utils/project/build.number b/org.glite.lb-utils/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils/project/build.properties b/org.glite.lb-utils/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils/project/dependencies.properties b/org.glite.lb-utils/project/dependencies.properties deleted file mode 100644 index c590a39..0000000 --- a/org.glite.lb-utils/project/dependencies.properties +++ /dev/null @@ -1,13 +0,0 @@ - -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.lb-utils.version = HEAD - -# Component dependencies tag = do not remove this line = -org.glite.lb-utils.db.version = HEAD -#org.glite.lb-utils.jobid.version = HEAD -#org.glite.lb-utils.server-bones.version = HEAD -#org.glite.lb-utils.trio.version = HEAD diff --git a/org.glite.lb-utils/project/glite.lb-utils.csf.xml b/org.glite.lb-utils/project/glite.lb-utils.csf.xml deleted file mode 100644 index 98945b8..0000000 --- a/org.glite.lb-utils/project/glite.lb-utils.csf.xml +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.lb-utils modules have been updated, please rerun the configuration file - - - - - The org.glite and org.glite.lb-utils modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils/project/properties.xml b/org.glite.lb-utils/project/properties.xml deleted file mode 100644 index 5f9597f..0000000 --- a/org.glite.lb-utils/project/properties.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils/project/taskdefs.xml b/org.glite.lb-utils/project/taskdefs.xml deleted file mode 100644 index 7963150..0000000 --- a/org.glite.lb-utils/project/taskdefs.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - diff --git a/org.glite.lb-utils/project/version.properties b/org.glite.lb-utils/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb.common/doc/events.tex.T b/org.glite.lb.common/doc/events.tex.T deleted file mode 100644 index 2cadb43..0000000 --- a/org.glite.lb.common/doc/events.tex.T +++ /dev/null @@ -1,16 +0,0 @@ -@@@{ -gen qq{ -% !! Automatically generated file. Do not edit. -% !! Change the corresponding template file $ARGV -}; -@@@} - -\begin{description} -@@@{ -for my $e (sort { $event->{order}->{$a} <=> $event->{order}->{$b} } - $event->getTypes) { - my $c = getTypeComment $event $e; - gen "\\item\[$e:\] $c\n"; -} -@@@} -\end{description} diff --git a/org.glite.lb.common/doc/status.tex.T b/org.glite.lb.common/doc/status.tex.T deleted file mode 100644 index e38a031..0000000 --- a/org.glite.lb.common/doc/status.tex.T +++ /dev/null @@ -1,15 +0,0 @@ -@@@{ -gen qq{ -% !! Automatically generated file. Do not edit. -% !! Change the corresponding template file $ARGV -}; -@@@} - -\begin{description} -@@@{ -for my $stat ($status->getTypesOrdered) { - my $c = getTypeComment $status $stat; - gen "\\item\[$stat:\] $c\n"; - } -@@@} -\end{description} diff --git a/org.glite.lb/.cvsignore b/org.glite.lb/.cvsignore deleted file mode 100644 index 1df717b..0000000 --- a/org.glite.lb/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb/LICENSE b/org.glite.lb/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.lb/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb/build.xml b/org.glite.lb/build.xml deleted file mode 100755 index 0053fe5..0000000 --- a/org.glite.lb/build.xml +++ /dev/null @@ -1,593 +0,0 @@ - - - - - - - Ant build file to build the GLite Logging and Bookkeping Subsystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.lb/deployment/README b/org.glite.lb/deployment/README deleted file mode 100644 index 9b104e6..0000000 --- a/org.glite.lb/deployment/README +++ /dev/null @@ -1,2 +0,0 @@ -deploy_all.diff - against RC31 -deploy_lb, deploy_jp - older patches diff --git a/org.glite.lb/deployment/deploy_all.diff b/org.glite.lb/deployment/deploy_all.diff deleted file mode 100644 index 6c4fba9..0000000 --- a/org.glite.lb/deployment/deploy_all.diff +++ /dev/null @@ -1,454 +0,0 @@ -Index: org.glite/project/global.dependencies.properties -=================================================================== -RCS file: /cvs/jra1mw/org.glite/project/global.dependencies.properties,v -retrieving revision 1.482.2.279 -diff -u -p -u -r1.482.2.279 global.dependencies.properties ---- org.glite/project/global.dependencies.properties 4 Aug 2006 12:21:59 -0000 1.482.2.279 -+++ org.glite/project/global.dependencies.properties 1 Sep 2006 14:23:09 -0000 -@@ -1819,7 +1819,25 @@ ext.globus-sdk.description = The Globus - ext.globus-sdk.rpm.name = vdt_globus_sdk - ext.globus-sdk.rpm.version = ${ext.vdt.version} - ext.globus-sdk.rpm.age = ${ext.vdt.age} -- -+ -+# Globus vdt data server - grid ftp server -+ext.globus-data-server.name = ${ext.globus.name} -+ext.globus-data-server.vendor = ${ext.globus.vendor} -+ext.globus-data-server.version = ${ext.globus.version} -+ext.globus-data-server.platform = ${platform} -+ext.globus-data-server.subdir = ${ext.globus-data-server.name}/${ext.globus-data-server.version}/${ext.globus-data-server.platform} -+ext.globus-data-server.rep.base = ${jra1.rep.base} -+ext.globus-data-server.rep.file = -+ext.globus-data-server.rep.subdir = -+ext.globus-data-server.rep.url = ${ext.globus-data-server.rep.base}/${ext.globus-data-server.subdir}/${ext.globus-data-server.rep.subdir}/${ext.globus-data-server.rep.file} -+ext.globus-data-server.files = -+ext.globus-data-server.download = http://www.cs.wisc.edu/vdt/releases/1.2.2/installing-rpms.html -+ext.globus-data-server.homepage = http://www.cs.wisc.edu/vdt//index.html -+ext.globus-data-server.description = The Globus Toolkit(R). This is the version packaged by VDT. -+ext.globus-data-server.rpm.name = vdt_globus_data_server -+ext.globus-data-server.rpm.version = ${ext.vdt.version} -+ext.globus-data-server.rpm.age = 1 -+ - # GPT - ext.gpt.name = gpt - ext.gpt.vendor = gpt -Index: org.glite.deployment/build.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/build.xml,v -retrieving revision 1.61.2.2.2.12.2.26 -diff -u -p -u -r1.61.2.2.2.12.2.26 build.xml ---- org.glite.deployment/build.xml 24 Apr 2006 13:39:27 -0000 1.61.2.2.2.12.2.26 -+++ org.glite.deployment/build.xml 1 Sep 2006 14:23:09 -0000 -@@ -1619,6 +1619,39 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1730,6 +1763,8 @@ - wn, - wms, - lb, -+ jpps, -+ jpis, - io-server, - io-client, - ce, -Index: org.glite.deployment/project/dependencies.properties -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/project/dependencies.properties,v -retrieving revision 1.526.2.5.2.127.2.415.2.203 -diff -u -p -u -r1.526.2.5.2.127.2.415.2.203 dependencies.properties ---- org.glite.deployment/project/dependencies.properties 30 Aug 2006 07:41:36 -0000 1.526.2.5.2.127.2.415.2.203 -+++ org.glite.deployment/project/dependencies.properties 1 Sep 2006 14:23:09 -0000 -@@ -47,6 +47,8 @@ - org.glite.deployment.hydra.version = glite-deployment-hydra_R_1_0_3 - org.glite.deployment.io-client.version = glite-deployment-io-client_R_2_2_0 - org.glite.deployment.io-server.version = glite-deployment-io-server_R_2_1_8 -+ org.glite.deployment.jpps.version = HEAD -+ org.glite.deployment.jpis.version = HEAD - org.glite.deployment.lb.version = glite-deployment-lb_R_2_2_4 - org.glite.deployment.lcg-CE_torque.version = glite-deployment-lcg-CE_torque_R_3_0_4 - org.glite.deployment.lcg-CE.version = glite-deployment-lcg-CE_R_3_0_5 -Index: org.glite.deployment/project/glite.deployment.csf.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/project/glite.deployment.csf.xml,v -retrieving revision 1.44.2.1.2.11.2.24 -diff -u -p -u -r1.44.2.1.2.11.2.24 glite.deployment.csf.xml ---- org.glite.deployment/project/glite.deployment.csf.xml 18 Apr 2006 15:42:14 -0000 1.44.2.1.2.11.2.24 -+++ org.glite.deployment/project/glite.deployment.csf.xml 1 Sep 2006 14:23:09 -0000 -@@ -667,6 +667,14 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1571,6 +1579,28 @@ - tag="${org.glite.deployment.lb.version}" /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1667,6 +1697,8 @@ - wn, - wms, - lb, -+ jpis, -+ jpps, - io-server, - io-client, - ce" /> -Index: org.glite.deployment.lb/config/scripts/glite-lb-config.py -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/config/scripts/glite-lb-config.py,v -retrieving revision 1.65.2.4 -diff -u -p -u -r1.65.2.4 glite-lb-config.py ---- org.glite.deployment.lb/config/scripts/glite-lb-config.py 26 May 2006 12:24:22 -0000 1.65.2.4 -+++ org.glite.deployment.lb/config/scripts/glite-lb-config.py 1 Sep 2006 14:23:10 -0000 -@@ -129,7 +129,12 @@ python %s-config [OPTION...]""" % (self. - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') -- -+ -+ -+ #------------------------------------------------------------------- -+ # start bkserver -+ #------------------------------------------------------------------- -+ - pid = glib.getPID('bkserverd') - if pid != 0: - print 'The gLite LB Server service is already running. Restarting...' -@@ -142,7 +147,7 @@ python %s-config [OPTION...]""" % (self. - pid = glib.getPID('bkserverd') - - if (pid != 0): -- print "The gLite LB Server service has been started ", -+ print "The gLite LB Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite LB Server service") -@@ -151,6 +156,36 @@ python %s-config [OPTION...]""" % (self. - return 1 - - #------------------------------------------------------------------- -+ # start jp-importer, if enabled -+ #------------------------------------------------------------------- -+ -+ lb_export = 0 -+ if params.has_key('lb.export.enabled'): -+ if params['lb.export.enabled'] == "true": -+ lb_export = 1 -+ -+ if lb_export: -+ pid = glib.getPID('jp-importer') -+ if pid != 0: -+ print 'The gLite JP Importer service is already running. Restarting...' -+ os.system('%s/etc/init.d/glite-jp-importer stop' % os.environ['GLITE_LOCATION']) -+ else: -+ print 'Starting the gLite JP Importer service...' -+ -+ os.system('%s/etc/init.d/glite-jp-importer start' % os.environ['GLITE_LOCATION']) -+ -+ pid = glib.getPID('jp-importer') -+ -+ if (pid != 0): -+ print "The gLite JP Importer service has been started ", -+ glib.printOkMessage() -+ else: -+ glib.printErrorMessage("Could not start the gLite JP Importer service") -+ glib.printErrorMessage("Please verify and re-run the script "), -+ glib.printFailedMessage() -+ return 1 -+ -+ #------------------------------------------------------------------- - # Start Servicetool - #------------------------------------------------------------------- - -@@ -170,6 +205,10 @@ python %s-config [OPTION...]""" % (self. - if (pid != 0): - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - -+ #------------------------------------------------------------------- -+ # Book Keeping Server -+ #------------------------------------------------------------------- -+ - pid = glib.getPID('bkserverd') - if (pid != 0): - print 'Could not stop the LB Server service ', -@@ -180,6 +219,25 @@ python %s-config [OPTION...]""" % (self. - glib.printOkMessage() - - #------------------------------------------------------------------- -+ # JP Importer -+ #------------------------------------------------------------------- -+ -+ pid = glib.getPID('jp-importer') -+ if (pid != 0): -+ os.system('%s/etc/init.d/glite-jp-importer stop' % os.environ['GLITE_LOCATION']) -+ -+ pid = glib.getPID('jp-importer') -+ if (pid != 0): -+ print 'Could not stop the JP Importer service ', -+ glib.printFailedMessage() -+ error_level = 1 -+ else: -+ if params.has_key('lb.export.enabled'): -+ if params['lb.export.enabled'] == "true": -+ print 'The JP Importer service has been stopped ', -+ glib.printOkMessage() -+ -+ #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - -@@ -204,6 +262,10 @@ python %s-config [OPTION...]""" % (self. - if retval != 0: - error_level = 1 - -+ retval = os.system('%s/etc/init.d/glite-jp-importer status' % os.environ['GLITE_LOCATION']) -+ if retval != 0: -+ error_level = 1 -+ - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- -@@ -334,7 +396,29 @@ python %s-config [OPTION...]""" % (self. - print "\n==> MySQL database %s already exist\n" % params['lb.database.name'] - - self.mysql.stop() -- -+ -+ # ------------------------------------------------------------------ -+ # export from bkserver to cron -+ # ------------------------------------------------------------------ -+ if params['GLITE_LB_EXPORT_ENABLED'] == "true": -+ file = open('%s/etc/glite-lb-export-cron-wrapper.sh' % os.environ['GLITE_LOCATION'], 'w') -+ file.write('#! /bin/sh\n') -+ file.write('. %s\n' % glib.getInstallerExportFile()) -+ file.write('$GLITE_LOCATION/sbin/glite-lb-export.sh\n') -+ file.close() -+ os.system('/bin/chmod 0755 %s/etc/glite-lb-export-cron-wrapper.sh' % os.environ['GLITE_LOCATION']) -+ -+ file = open('/etc/cron.d/glite-lb-export.cron', 'w') -+ file.write('# periodically run purge and export jobs from bkserver\n') -+ file.write('00,30 * * * * %s %s/etc/glite-lb-export-cron-wrapper.sh 1>/dev/null\n' % (params['glite.user.name'], os.environ['GLITE_LOCATION'])) -+ file.close() -+ os.system('/bin/chmod 0644 /etc/cron.d/glite-lb-export.cron') -+ else -+ os.system('/bin/rm -f /etc/cron.d/glite-lb-export.cron') -+ -+ # Touch cron spool directory to cause reloading of the crontabs -+ os.system("/bin/touch /var/spool/cron") -+ - #------------------------------------------------------------------- - # RGMA servicetool: configure servicetool - #------------------------------------------------------------------- -@@ -420,6 +504,19 @@ def set_env(): - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - -+ # LB export -+ glib.export('GLITE_LB_EXPORT_ENABLED', params['lb.export.enabled']); -+ glib.export('GLITE_LB_EXPORT_JPPS', params['lb.export.jpps']); -+ glib.export('GLITE_LB_EXPORT_JPREG_MAILDIR', params['lb.export.jpreg']); -+ glib.export('GLITE_LB_EXPORT_JPDUMP_MAILDIR', params['lb.export.jpdump']); -+ glib.export('GLITE_LB_EXPORT_DUMPDIR', params['lb.export.dump']); -+ glib.export('GLITE_LB_EXPORT_DUMPDIR_KEEP', params['lb.export.dump.keep']); -+ glib.export('GLITE_LB_EXPORT_JOBSDIR', params['lb.export.jobs']); -+ glib.export('GLITE_LB_EXPORT_JOBSDIR_KEEP', params['lb.export.jobs.keep']); -+ glib.export('GLITE_LB_EXPORT_PURGEDIR', params['lb.export.purge']); -+ glib.export('GLITE_LB_EXPORT_PURGEDIR_KEEP', params['lb.export.purge.keep']); -+ glib.export('GLITE_LB_EXPORT_PURGE_ARGS', '%s' % params['lb.export.purgeargs']); -+ - # Set environment - glib.setUserEnv() - -Index: org.glite.deployment.lb/config/templates/glite-lb.cfg.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml,v -retrieving revision 1.21 -diff -u -p -u -r1.21 glite-lb.cfg.xml ---- org.glite.deployment.lb/config/templates/glite-lb.cfg.xml 13 Mar 2006 15:19:21 -0000 1.21 -+++ org.glite.deployment.lb/config/templates/glite-lb.cfg.xml 1 Sep 2006 14:23:10 -0000 -@@ -17,9 +17,16 @@ - parameter. Leave it empty of comment it out to use the same as 'glite.user.name'" - value="changeme"/> - -- -+ -+ -+ -+ -+ - - - -@@ -55,6 +62,12 @@ - [Example: 17M][Type: Integer][Unit: MB]" - value="17M"/> - -+ -+ -+ - - - -@@ -67,7 +80,47 @@ - destination - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -Index: org.glite.deployment.lb/project/glite-lb.sdf.xml.template -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/project/glite-lb.sdf.xml.template,v -retrieving revision 1.38.2.2 -diff -u -p -u -r1.38.2.2 glite-lb.sdf.xml.template ---- org.glite.deployment.lb/project/glite-lb.sdf.xml.template 2 May 2006 10:36:19 -0000 1.38.2.2 -+++ org.glite.deployment.lb/project/glite-lb.sdf.xml.template 1 Sep 2006 14:23:10 -0000 -@@ -57,6 +57,12 @@ - build="@org.glite.lb.server-bones.info.build@" - arch="i386"/> - -+ -+ - - -+ -+ - - # - # Version info: $Id$ --# Release: $Name$ -+# Release: $Name$ - # - # Revision history: - # $Log$ - # Revision 1.3 2006/06/30 11:30:28 mmulac - # actualized patches - # - against org.glite a org.glite.deployment from glite_R_3_0_0 - # -@@ -1562,7 +1562,26 @@ - ext.globus-sdk.rpm.name = vdt_globus_sdk - ext.globus-sdk.rpm.version = ${ext.vdt.version} - ext.globus-sdk.rpm.age = 1 -- -+ -+# Globus vdt data server - grid ftp server -+ext.globus-data-server.name = ${ext.globus.name} -+ext.globus-data-server.vendor = ${ext.globus.vendor} -+ext.globus-data-server.version = ${ext.globus.version} -+ext.globus-data-server.platform = ${platform} -+ext.globus-data-server.subdir = ${ext.globus-data-server.name}/${ext.globus-data-server.version}/${ext.globus-data-server.platform} -+ext.globus-data-server.rep.base = ${jra1.rep.base} -+ext.globus-data-server.rep.file = -+ext.globus-data-server.rep.subdir = -+ext.globus-data-server.rep.url = ${ext.globus-data-server.rep.base}/${ext.globus-data-server.subdir}/${ext.globus-data-server.rep.subdir}/${ext.globus-data-server.rep.file} -+ext.globus-data-server.files = -+ext.globus-data-server.download = http://www.cs.wisc.edu/vdt/releases/1.2.2/installing-rpms.html -+ext.globus-data-server.homepage = http://www.cs.wisc.edu/vdt//index.html -+ext.globus-data-server.description = The Globus Toolkit(R). This is the version packaged by VDT. -+ext.globus-data-server.rpm.name = vdt_globus_data_server -+ext.globus-data-server.rpm.version = ${ext.vdt.version} -+ext.globus-data-server.rpm.age = 1 -+ -+ - # GPT - ext.gpt.name = gpt - ext.gpt.vendor = gpt -@@ -3266,8 +3285,9 @@ - org.glite.dgas.version = glite-dgas_R_1_1_16 - org.glite.gpbox.version = glite-gpbox_R_1_0_15 - org.glite.jdl.version = glite-jdl_R_1_0_0 --org.glite.jp.version = glite-jp_R_1_1_3 --org.glite.lb.version = glite-lb_R_1_2_9 -+org.glite.jp.version = glite-jp_R_1_3_0 -+org.glite.lb.version = glite-lb_R_1_2_11 -+ - org.glite.rgma.version = glite-rgma_R_5_0_26 - org.glite.security.version = glite-security_R_3_0_15 - org.glite.service-discovery.version = glite-service-discovery_R_2_0_12 -Index: org.glite.deployment/build.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/build.xml,v -retrieving revision 1.61.2.2.2.12.2.26 -diff -u -r1.61.2.2.2.12.2.26 build.xml ---- org.glite.deployment/build.xml 24 Apr 2006 13:39:27 -0000 1.61.2.2.2.12.2.26 -+++ org.glite.deployment/build.xml 30 Jun 2006 11:13:49 -0000 -@@ -9,7 +9,7 @@ - Authors: Alberto Di Meglio - Version info: $Id$ - -- Release: $Name$ -+ Release: $Name$ - - Revision history: - $Log$ - Revision 1.3 2006/06/30 11:30:28 mmulac - actualized patches - - against org.glite a org.glite.deployment from glite_R_3_0_0 - -@@ -1619,6 +1619,39 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1730,6 +1763,8 @@ - wn, - wms, - lb, -+ jpps, -+ jpis, - io-server, - io-client, - ce, -Index: org.glite.deployment/project/dependencies.properties -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/project/dependencies.properties,v -retrieving revision 1.526.2.5.2.127.2.415.2.22 -diff -u -r1.526.2.5.2.127.2.415.2.22 dependencies.properties ---- org.glite.deployment/project/dependencies.properties 9 May 2006 12:33:18 -0000 1.526.2.5.2.127.2.415.2.22 -+++ org.glite.deployment/project/dependencies.properties 30 Jun 2006 11:13:49 -0000 -@@ -80,6 +80,10 @@ - - org.glite.deployment.lb.version = glite-deployment-lb_R_2_2_3 - -+ org.glite.deployment.jpis.version = HEAD -+ -+ org.glite.deployment.jpps.version = HEAD -+ - org.glite.deployment.glite-WMSLB.version = glite-deployment-glite-WMSLB_R_2_4_2 - - org.glite.deployment.wn.version = glite-deployment-wn_R_2_3_7 -Index: org.glite.deployment/project/glite.deployment.csf.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment/project/glite.deployment.csf.xml,v -retrieving revision 1.44.2.1.2.11.2.24 -diff -u -r1.44.2.1.2.11.2.24 glite.deployment.csf.xml ---- org.glite.deployment/project/glite.deployment.csf.xml 18 Apr 2006 15:42:14 -0000 1.44.2.1.2.11.2.24 -+++ org.glite.deployment/project/glite.deployment.csf.xml 30 Jun 2006 11:13:50 -0000 -@@ -9,7 +9,7 @@ - Authors: Joachim Flammer - - Version info: $Id$ -- Release: $Name$ -+ Release: $Name$ - - Revision history: - $Log$ - Revision 1.3 2006/06/30 11:30:28 mmulac - actualized patches - - against org.glite a org.glite.deployment from glite_R_3_0_0 - -@@ -667,6 +667,14 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1571,6 +1579,28 @@ - tag="${org.glite.deployment.lb.version}" /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -1667,6 +1697,8 @@ - wn, - wms, - lb, -+ jpis, -+ jpps, - io-server, - io-client, - ce" /> diff --git a/org.glite.lb/deployment/deploy_lb.diff b/org.glite.lb/deployment/deploy_lb.diff deleted file mode 100644 index d6c74e2..0000000 --- a/org.glite.lb/deployment/deploy_lb.diff +++ /dev/null @@ -1,281 +0,0 @@ -This patch was merged to deploy_all.diff, don't use it anymore. - -Index: org.glite.deployment.lb/config/scripts/glite-lb-config.py -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/config/scripts/glite-lb-config.py,v -retrieving revision 1.65.2.3 -diff -u -r1.65.2.3 glite-lb-config.py ---- org.glite.deployment.lb/config/scripts/glite-lb-config.py 2 May 2006 10:36:16 -0000 1.65.2.3 -+++ org.glite.deployment.lb/config/scripts/glite-lb-config.py 30 Jun 2006 09:29:21 -0000 -@@ -127,7 +127,12 @@ - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') -- -+ -+ -+ #------------------------------------------------------------------- -+ # start bkserver -+ #------------------------------------------------------------------- -+ - pid = glib.getPID('bkserverd') - if pid != 0: - print 'The gLite LB Server service is already running. Restarting...' -@@ -140,7 +145,7 @@ - pid = glib.getPID('bkserverd') - - if (pid != 0): -- print "The gLite LB Server service has been started ", -+ print "The gLite LB Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite LB Server service") -@@ -149,6 +154,36 @@ - return 1 - - #------------------------------------------------------------------- -+ # start jp-importer, if enabled -+ #------------------------------------------------------------------- -+ -+ lb_export = 0 -+ if params.has_key('lb.export.enabled'): -+ if params['lb.export.enabled'] == "true": -+ lb_export = 1 -+ -+ if lb_export: -+ pid = glib.getPID('jp-importer') -+ if pid != 0: -+ print 'The gLite JP Importer service is already running. Restarting...' -+ os.system('%s/etc/init.d/glite-jp-importer stop' % os.environ['GLITE_LOCATION']) -+ else: -+ print 'Starting the gLite JP Importer service...' -+ -+ os.system('%s/etc/init.d/glite-jp-importer start' % os.environ['GLITE_LOCATION']) -+ -+ pid = glib.getPID('jp-importer') -+ -+ if (pid != 0): -+ print "The gLite JP Importer service has been started ", -+ glib.printOkMessage() -+ else: -+ glib.printErrorMessage("Could not start the gLite JP Importer service") -+ glib.printErrorMessage("Please verify and re-run the script "), -+ glib.printFailedMessage() -+ return 1 -+ -+ #------------------------------------------------------------------- - # Start Servicetool - #------------------------------------------------------------------- - -@@ -168,6 +203,10 @@ - if (pid != 0): - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - -+ #------------------------------------------------------------------- -+ # Book Keeping Server -+ #------------------------------------------------------------------- -+ - pid = glib.getPID('bkserverd') - if (pid != 0): - print 'Could not stop the LB Server service ', -@@ -178,6 +217,25 @@ - glib.printOkMessage() - - #------------------------------------------------------------------- -+ # JP Importer -+ #------------------------------------------------------------------- -+ -+ pid = glib.getPID('jp-importer') -+ if (pid != 0): -+ os.system('%s/etc/init.d/glite-jp-importer stop' % os.environ['GLITE_LOCATION']) -+ -+ pid = glib.getPID('jp-importer') -+ if (pid != 0): -+ print 'Could not stop the JP Importer service ', -+ glib.printFailedMessage() -+ error_level = 1 -+ else: -+ if params.has_key('lb.export.enabled'): -+ if params['lb.export.enabled'] == "true": -+ print 'The JP Importer service has been stopped ', -+ glib.printOkMessage() -+ -+ #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - -@@ -202,6 +260,10 @@ - if retval != 0: - error_level = 1 - -+ retval = os.system('%s/etc/init.d/glite-jp-importer status' % os.environ['GLITE_LOCATION']) -+ if retval != 0: -+ error_level = 1 -+ - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- -@@ -332,7 +394,27 @@ - print "\n==> MySQL database %s already exist\n" % params['lb.database.name'] - - self.mysql.stop() -- -+ -+ # ------------------------------------------------------------------ -+ # export from bkserver to cron -+ # ------------------------------------------------------------------ -+ if params['GLITE_LB_EXPORT_ENABLED'] == "true": -+ file = open('%s/etc/glite-lb-export-cron-wrapper.sh' % os.environ['GLITE_LOCATION'], 'w') -+ file.write('#! /bin/sh\n') -+ file.write('. %s\n' % glib.getInstallerExportFile()) -+ file.write('$GLITE_LOCATION/examples/glite-lb-export.sh\n') -+ file.close() -+ os.system('/bin/chmod 0755 %s/etc/glite-lb-export-cron-wrapper.sh' % os.environ['GLITE_LOCATION']) -+ -+ file = open('/etc/cron.d/glite-lb-export.cron', 'w') -+ file.write('# periodically run purge and export jobs from bkserver\n') -+ file.write('00,30 * * * * %s %s/etc/glite-lb-export-cron-wrapper.sh\n' % (params['glite.user.name'], os.environ['GLITE_LOCATION'])) -+ file.close() -+ os.system('/bin/chmod 0755 /etc/cron.d/glite-lb-export.cron') -+ -+ # Touch cron spool directory to cause reloading of the crontabs -+ os.system("/bin/touch /var/spool/cron") -+ - #------------------------------------------------------------------- - # RGMA servicetool: configure servicetool - #------------------------------------------------------------------- -@@ -418,6 +500,17 @@ - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - -+ # LB export -+ glib.export('GLITE_LB_EXPORT_ENABLED', params['lb.export.enabled']); -+ glib.export('GLITE_LB_EXPORT_BKSERVER', params['lb.export.bkserver']); -+ glib.export('GLITE_LB_EXPORT_JPPS', params['lb.export.jpps']); -+ glib.export('GLITE_LB_EXPORT_JPREG_MAILDIR', params['lb.export.jpreg']); -+ glib.export('GLITE_LB_EXPORT_JPDUMP_MAILDIR', params['lb.export.jpdump']); -+ glib.export('GLITE_LB_EXPORT_DUMPDIR', params['lb.export.dump']); -+ glib.export('GLITE_LB_EXPORT_DUMPDIR_OLD', params['lb.export.dump.old']); -+ glib.export('GLITE_LB_EXPORT_EXPORTDIR', params['lb.export.export']); -+ glib.export('GLITE_LB_EXPORT_PURGE_ARGS', '"%s"' % params['lb.export.purgeargs']); -+ - # Set environment - glib.setUserEnv() - -Index: org.glite.deployment.lb/config/templates/glite-lb.cfg.xml -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml,v -retrieving revision 1.21 -diff -u -r1.21 glite-lb.cfg.xml ---- org.glite.deployment.lb/config/templates/glite-lb.cfg.xml 13 Mar 2006 15:19:21 -0000 1.21 -+++ org.glite.deployment.lb/config/templates/glite-lb.cfg.xml 30 Jun 2006 09:29:21 -0000 -@@ -17,9 +17,16 @@ - parameter. Leave it empty of comment it out to use the same as 'glite.user.name'" - value="changeme"/> - -- -+ -+ -+ -+ -+ - - - -@@ -55,6 +62,12 @@ - [Example: 17M][Type: Integer][Unit: MB]" - value="17M"/> - -+ -+ -+ - - - -@@ -67,7 +80,42 @@ - destination - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -Index: org.glite.deployment.lb/project/glite-lb.sdf.xml.template -=================================================================== -RCS file: /cvs/jra1mw/org.glite.deployment.lb/project/glite-lb.sdf.xml.template,v -retrieving revision 1.38.2.2 -diff -u -r1.38.2.2 glite-lb.sdf.xml.template ---- org.glite.deployment.lb/project/glite-lb.sdf.xml.template 2 May 2006 10:36:19 -0000 1.38.2.2 -+++ org.glite.deployment.lb/project/glite-lb.sdf.xml.template 30 Jun 2006 09:29:21 -0000 -@@ -57,6 +57,12 @@ - build="@org.glite.lb.server-bones.info.build@" - arch="i386"/> - -+ -+ - - -+ -+ - &1 | tee log - -:) diff --git a/org.glite.lb/doc/copyright.tex b/org.glite.lb/doc/copyright.tex deleted file mode 100644 index d25979d..0000000 --- a/org.glite.lb/doc/copyright.tex +++ /dev/null @@ -1,24 +0,0 @@ -% -% Official text received on October 6, 2004 -% -\vfill{\bf Copyright }\copyright{\bf Members of the EGEE Collaboration. 2004. -See http://eu-egee.org/partners for details on the copyright holders. - -EGEE (``Enabling Grids for E-science in Europe'') is a project funded by -the European Union. For more information on the project, its partners -and contributors please see http://www.eu-egee.org. - -You are permitted to copy and distribute verbatim copies of this -document containing this copyright notice, but modifying this document -is not allowed. You are permitted to copy this document in whole or in -part into other documents if you attach the following reference to the -copied elements: ``Copyright }\copyright{\bf 2004. Members of the EGEE -Collaboration. http://www.eu-egee.org'' - -The information contained in this document represents the views of -EGEE as of the date they are published. EGEE does not guarantee that -any information contained herein is error-free, or up to date. - -EGEE MAKES NO WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, BY -PUBLISHING THIS DOCUMENT.} - diff --git a/org.glite.lb/doc/frontmatter.tex b/org.glite.lb/doc/frontmatter.tex deleted file mode 100644 index 0fba2c5..0000000 --- a/org.glite.lb/doc/frontmatter.tex +++ /dev/null @@ -1,41 +0,0 @@ -\begin{center} -{\bf Delivery Slip} -\end{center} -\begin{tabularx}{\textwidth}{|l|l|l|X|X|} -\hline - & {\bf Name} & {\bf Partner} & {\bf Date} & {\bf Signature} \\ -\hline -{\bf From} & Ale\v s K\v{r}enek et al.& CESNET & May 28, 2005 & \\ -\hline -{\bf Reviewed by} & & & & \\ - -\hline -{\bf Approved by} & & & & \\ -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Log} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|X|} -\hline -{\bf Issue } & {\bf Date } & {\bf Comment } & {\bf Author } \\ \hline -Initial version & Feb 28, 2005 & & A. K\v{r}enek \\ \hline -Reviewer's comments & Mar 25, 2005 & comments reflected & A. K\v{r}enek \\ -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Record} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|} -\hline -{\bf Issue } & {\bf Item } & {\bf Reason for Change } \\ \hline - - -\hline -\end{tabularx} - -\input{copyright} diff --git a/org.glite.lb/doc/perf_clear_proxy b/org.glite.lb/doc/perf_clear_proxy deleted file mode 100644 index 237df95..0000000 --- a/org.glite.lb/doc/perf_clear_proxy +++ /dev/null @@ -1 +0,0 @@ -CLPR=1; for jobid in `./stage/sbin/glite-lb-perftest_logjobs -m scientific.civ.zcu.cz:10000 -f stage/examples/perftest/perf_simple_avg_events.log -n 1000 -p /tmp/perftest_michal.log -s /tmp/proxy_michal.perf|grep https`; do stage/bin/glite-lb-logevent -x -S /tmp/proxy_michal.perfstore.sock -c $SEQCODE -j $jobid -s UserInterface -e Abort --reason Purge; done diff --git a/org.glite.lb/doc/perf_purge b/org.glite.lb/doc/perf_purge deleted file mode 100644 index 4bcc881..0000000 --- a/org.glite.lb/doc/perf_purge +++ /dev/null @@ -1 +0,0 @@ -./stage/sbin/glite-lb-purge -j /tmp/perftest_1000.jobids -m scientific.civ.zcu.cz:10000 -s diff --git a/org.glite.lb/doc/perf_reg_jobs b/org.glite.lb/doc/perf_reg_jobs deleted file mode 100644 index 20923a1..0000000 --- a/org.glite.lb/doc/perf_reg_jobs +++ /dev/null @@ -1 +0,0 @@ - REG=1; for jobid in `./stage/sbin/glite-lb-perftest_logjobs -m scientific.civ.zcu.cz:10000 -f stage/examples/perftest/perf_simple_avg_events.log -n 1000 -p /tmp/perftest_michal.log -s /tmp/proxy_michal.perf|grep https`; do stage/examples/glite-lb-job_reg -j $jobid -s UserInterface ; done diff --git a/org.glite.lb/doc/perf_results/il_sci_09062006.txt b/org.glite.lb/doc/perf_results/il_sci_09062006.txt deleted file mode 100644 index 503966e..0000000 --- a/org.glite.lb/doc/perf_results/il_sci_09062006.txt +++ /dev/null @@ -1,63 +0,0 @@ -./shared/egee/jra1-head/stage/sbin/perftest_il.sh 10 -------------------------------------------- -Logging test: - - events sent through IPC and/or files - - events discarded by IL immediately -------------------------------------------- -a) events sent only by IPC -b) events stored to files and sent by IPC - - small_job big_job small_dag big_dag -a) 154727793 11240340 101479915 621678 -[jobs/day] -b) 11540156 594389 10416164 402240 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events discarded in IL ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 14323607 547755 10158371 375594 -[jobs/day] -b) 6284230 364547 4554967 300055 -[jobs/day] -c) 7540122 412971 3186381 300417 -[jobs/day] -x) 9672327 418137 2567653 297477 -[jobs/day] -d) this test is not yet implemented -e) 9650719 410507 3651840 301687 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events consumed by empty BS ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 2639788 182196 2035014 246654 -[jobs/day] -b) 1170308 45973 759842 74898 -[jobs/day] -c) 1060595 42047 921386 76638 -[jobs/day] -x) 1091863 42247 518302 82129 -[jobs/day] -d) this test is not yet implemented -e) 1147040 41790 489257 76627 -[jobs/day] - diff --git a/org.glite.lb/doc/perf_results/il_sci_09062006_01.txt b/org.glite.lb/doc/perf_results/il_sci_09062006_01.txt deleted file mode 100644 index 04db72b..0000000 --- a/org.glite.lb/doc/perf_results/il_sci_09062006_01.txt +++ /dev/null @@ -1,129 +0,0 @@ -[michal@scientific jra1-head]$ ./stage/sbin/perftest_il.sh 10 -------------------------------------------- -Logging test: - - events sent through IPC and/or files - - events discarded by IL immediately -------------------------------------------- -a) events sent only by IPC -b) events stored to files and sent by IPC - - small_job big_job small_dag big_dag -a) 149765990 10933663 100162299 619924 -[jobs/day] -b) 11857056 479615 2753618 277679 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events discarded in IL ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 13813170 268900 6448242 244203 -[jobs/day] -b) 4525621 255055 6147103 241153 -[jobs/day] -c) 9338319 217855 5497442 248429 -[jobs/day] -x) 9335090 232292 3989195 236341 -[jobs/day] -d) this test is not yet implemented -e) 3283323 216013 7284868 256479 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events consumed by empty BS ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 4019651 44496 766972 95556 -[jobs/day] -b) 1366885 47501 564779 90055 -[jobs/day] -c) 1152594 47656 603774 97465 -[jobs/day] -x) 1049069 48779 607913 88692 -[jobs/day] -d) this test is not yet implemented -e) 942509 46271 523129 91103 -[jobs/day] - - -************************************************************************* - - -[michal@scientific jra1-head]$ ./stage/sbin/perftest_il.sh 100 -------------------------------------------- -Logging test: - - events sent through IPC and/or files - - events discarded by IL immediately -------------------------------------------- -a) events sent only by IPC -b) events stored to files and sent by IPC - - small_job big_job small_dag big_dag -a) 157966907 0 0 620546 -[jobs/day] -b) 13833450 558487 10210340 283454 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events discarded in IL ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 12884330 316703 4447489 151870 -[jobs/day] -b) 7980713 469667 4641283 244463 -[jobs/day] -c) 8458472 556919 5657712 253640 -[jobs/day] -x) 8149836 549678 4765300 257375 -[jobs/day] -d) this test is not yet implemented -e) 9687868 503933 4461079 247092 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events consumed by empty BS ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 9389344 97159 450483 68610 -[jobs/day] -b) 1195400 82681 560118 88216 -[jobs/day] -c) 1351879 88207 830072 102285 -[jobs/day] -x) 1173835 85897 562648 0 -[jobs/day] -d) this test is not yet implemented -e) 1205291 78355 567658 87770 -[jobs/day] diff --git a/org.glite.lb/doc/perf_results/il_sci_12062006.txt b/org.glite.lb/doc/perf_results/il_sci_12062006.txt deleted file mode 100644 index f3a1a79..0000000 --- a/org.glite.lb/doc/perf_results/il_sci_12062006.txt +++ /dev/null @@ -1,65 +0,0 @@ -[michal@scientific jra1-head]$ ./stage/sbin/perftest_il.sh 10 -------------------------------------------- -Logging test: - - events sent through IPC and/or files - - events discarded by IL immediately -------------------------------------------- -a) events sent only by IPC -b) events stored to files and sent by IPC - - small_job big_job small_dag big_dag -a) 153599999 11157889 101479915 539075 -[jobs/day] -b) 10835893 1059003 2577803 351095 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events discarded in IL ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 14148626 772362 11498383 376986 -[jobs/day] -b) 5348851 489142 5558879 292071 -[jobs/day] -c) 9042670 441000 5911613 287842 -[jobs/day] -x) 7730298 414784 6579748 289834 -[jobs/day] -d) this test is not applicable -e) 9288325 365701 7189156 299604 -[jobs/day] ------------------------------------ -Interlogger test: - - events sent through IPC & files - - events consumed by empty BS ------------------------------------ -a) disabled event parsing, the server address (jobid) is hardcoded -b) disabled event synchronization from files -c) disabled recovery thread -x) disabled sync and recovery -d) lazy bkserver connection close -e) normal operation - - small_job big_job small_dag big_dag -a) 2219003 185867 1785164 258615 -[jobs/day] -b) 1795503 48283 309380 77422 -[jobs/day] -c) 1201618 39001 850436 74771 -[jobs/day] -x) 1134249 48039 447017 74244 -[jobs/day] -d) 5335078 207059 2438095 96295 -[jobs/day] -e) 1019269 36465 875966 65565 -[jobs/day] - - diff --git a/org.glite.lb/doc/perf_results/ll_michal_21062006.txt b/org.glite.lb/doc/perf_results/ll_michal_21062006.txt deleted file mode 100644 index c13457f..0000000 --- a/org.glite.lb/doc/perf_results/ll_michal_21062006.txt +++ /dev/null @@ -1,20 +0,0 @@ -michal:~/shared/egee/jra1-head> ./stage/sbin/perftest_ll.sh 10 ----------------- -Locallogger test ----------------- -a) glite-lb-logd-perf-nofile --noParse --noIPC -b) glite-lb-logd-perf-nofile --noIPC -c) glite-lb-logd-perf --noIPC -d) glite-lb-logd-perf - -Number of jobs: 10 - - small_job big_job small_dag big_dag -a) 14.544066 14.590504 14.681760 9.264801 [events/sec] - 125660 8404 97577 25821 [jobs/day] -b) 14.614844 14.408043 14.279216 9.600877 [events/sec] - 126272 8298 94901 26758 [jobs/day] -c) 0.000000 0.000000 0.000000 0.000000 [events/sec] - 0 0 0 0 [jobs/day] -d) 13.331568 13.530218 13.420780 8.363152 [events/sec] - 115184 7793 89196 23308 [jobs/day] diff --git a/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt b/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt deleted file mode 100644 index d0a99c5..0000000 --- a/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt +++ /dev/null @@ -1,20 +0,0 @@ -------------------- -LB chain test -------------------- -- proxy & interlogger (lazy variant) running at umbar -- bkserver running at sci -- test variants: - a) 10 jobs - b) 100 jobs - c) 1000 jobs - - -Results: - - small_job big_job small_dag big_dag ---------------------------------------------------------------- -a) 3.0 x x x [mjobs/day] -b) 1.0 x x x [mjobs/day] -c) 0.6 x x x [mjobs/day] - - diff --git a/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt b/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt deleted file mode 100644 index 8097510..0000000 --- a/org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt +++ /dev/null @@ -1,25 +0,0 @@ -------------------- -LB chain test -------------------- -- proxy & interlogger (lazy variant) running at umbar -- bkserver running at sci -- test variants: - a) 100 jobs, no background queries - b) 1000 jobs, no background queries - c) 10000 jobs, no background queries - d) 100 jobs, 10 parallel queries - e) 1000 jobs, 10 parallel queries, perf interlogger - f) 1000 jobs, 10 parallel queries, normal interlogger -- in d)-f) the server was queried by 10 independent clients for states - of all jobs periodically with random sleep between queries (0-5sec) - -Results: - - small_job big_job small_dag big_dag ---------------------------------------------------------------- -a) 1.0 x x x [mjobs/day] -b) 0.6 x x x [mjobs/day] -c) 0.5 x x x [mjobs/day] -d) 0.8 x x x [mjobs/day] -e) 0.45 x x x [mjobs/day] -f) 0.4 x x x [mjobs/day] diff --git a/org.glite.lb/doc/perf_results/proxy_sci_09062006.txt b/org.glite.lb/doc/perf_results/proxy_sci_09062006.txt deleted file mode 100644 index efa1a41..0000000 --- a/org.glite.lb/doc/perf_results/proxy_sci_09062006.txt +++ /dev/null @@ -1,21 +0,0 @@ ----------------------------------- -LB Proxy test ----------------------------------- -Events are consumed: -1) before parsing -2) after parsing, before storing into database -3) after storing into db, before computing state -4) after computing state, before sending to IL -5) by IL - - small_job big_job small_dag big_dag -1) 43005186.489600 2852512.156800 31859581.824000 502823.721600 -[jobs/day] -2) 37764713.548800 2438483.961600 26108871.523200 340065.648000 -[jobs/day] -3) 1754530.243200 272980.540800 2051218.684800 0.000000 -[jobs/day] -4) 1267110.000000 176052.182400 1506470.486400 0.000000 -[jobs/day] -5) 329471.452800 48787.747200 318152.275200 0.000000 -[jobs/day] diff --git a/org.glite.lb/doc/perf_run_interlogd b/org.glite.lb/doc/perf_run_interlogd deleted file mode 100644 index 00d60ed..0000000 --- a/org.glite.lb/doc/perf_run_interlogd +++ /dev/null @@ -1 +0,0 @@ - ./stage/bin/glite-lb-interlogd -d -s /tmp/perftest_michal.sock --file-prefix=/tmp/perftest_michal.log --lazy diff --git a/org.glite.lb/doc/perf_run_proxy b/org.glite.lb/doc/perf_run_proxy deleted file mode 100644 index 5d88382..0000000 --- a/org.glite.lb/doc/perf_run_proxy +++ /dev/null @@ -1 +0,0 @@ -./stage/bin/glite-lb-proxy -d --silent -p /tmp/proxy_michal.perf --proxy-il-sock /tmp/perftest_michal.sock --proxy-il-fprefix /tmp/perftest_michal.log diff --git a/org.glite.lb/doc/perf_run_server b/org.glite.lb/doc/perf_run_server deleted file mode 100644 index b11eb79..0000000 --- a/org.glite.lb/doc/perf_run_server +++ /dev/null @@ -1 +0,0 @@ -./stage/bin/glite-lb-bkserverd -d --perf-sink=4 -p 10000 -w 10003 -S /tmp/purge_michal -D /tmp/dump_michal --silent diff --git a/org.glite.lb/doc/perf_run_test b/org.glite.lb/doc/perf_run_test deleted file mode 100644 index 2e31b83..0000000 --- a/org.glite.lb/doc/perf_run_test +++ /dev/null @@ -1 +0,0 @@ -TEST=1; ./stage/sbin/glite-lb-perftest_logjobs -d proxy -m scientific.civ.zcu.cz:10000 -f stage/examples/perftest/perf_simple_avg_events.log -n 1000 -p /tmp/perftest_michal.log -s /tmp/proxy_michal.perf diff --git a/org.glite.lb/doc/perftest.tex b/org.glite.lb/doc/perftest.tex deleted file mode 100644 index 241e1af..0000000 --- a/org.glite.lb/doc/perftest.tex +++ /dev/null @@ -1,524 +0,0 @@ -\documentclass{egee} -\usepackage{comment} - -\def\LB{L\&B} - -\title{\LB\ Performance Test Plan} -\author{CESNET EGEE JRA1 team} -\DocIdentifier{EGEE-JRA1-??} -\Date{\today} -\Activity{JRA1: Middleware Engineering and Integration} -\DocStatus{DRAFT} -\Dissemination{PUBLIC} -\DocumentLink{} - -%\def\req{\noindent\textbf{Prerequisities:}} -%\def\how{\noindent\textbf{How to run:}} -%\def\result{\noindent\textbf{Expected result:}} - -\def\path#1{{\normalfont\textsf{#1}}} -\def\code#1{\texttt{#1}} -\def\todo#1{\textbf{TODO:} #1} - -\begin{document} - -\input{frontmatter} -\newpage -\tableofcontents -\newpage - -\section{Rationale} -\todo{} - -\begin{verbatim} - -L&B Performance Testing -======================= - -- all source modifications for tests are in CVS, conditionaly compiled - only with appropriate symbol - -- binaries for all tests are built using special property - for ant target (or environment variable for Makefile), which - compiles sources using the right #define combinations - -- component tests are run by shell scripts located under component - directories, these tests may require binaries from other components, - though - -- all tests use sequence of events for typical jobs (small job, big - job, small DAG, big DAG) prepared beforehand. These events are - stored in files in ULM format in CVS. - -- events are generated by stresslog program, which reads ULM text of - events for particular test job and logs the event sequence directly - by calling *_DoLogEvent. The number of test jobs is - configurable. Stresslog inserts into every event timestamp when the - event was generated and sent.* - -- event are consumed by breaking normal event processing either in the - component being tested or the next component in chain, that is - instrumented to read and discard events immediately. The consumption - itself is done by calling special function which takes current time, - extracts timestamp from event and prints the difference (ie. the - event processing time).* These "break points" are chosen to measure - throughput of the various component parts and to identify possible - bottlenecks within the components. - - * the only exception is test of the logging library itself - -- test jobs are preregistered within the LB if the test includes - bookkeeping server and/or proxy by the test script program and - their id's are stored in separate file to enable re-use by other - load-generating tools (status queries, for example) - -- test results: - - some numbers must be reported by component themselves, not by - the event generator (due to the asynchronous LB nature). The - test script collects those numbers and presents them as the test - result at the end of testing. - - - after completion test scripts print the table described for the - respective tests filled in with measured values (ie. the table - is not filled in manually by human tester) - - - event throughput = 1/(time_delivered - time_arrived) - * only if next event is sent after previous was delivered - -? measure job throughput for event patterns of typical jobs or deduce -job throughput from throughput of selected types of events? - - -I) Component tests - *************** - -- tests of the isolated components on one node -- may require binaries from other components to produce/consume events - --------------------- -Logging library test --------------------- - -* component: - org.glite.lb.client - -* binaries required: - logevent_libtest - -* test shell script: - perftest_loglib - -* input required: - - events - -* test description: - - measures time required to format given events into ULM. Events - are read from file, parsed into components, timestamped and - produced. - - - events produced: - - by calling logging function edg_wll_LogEvent*() - - - events consumed: - - discarded by logging function instead of sending via - appropriate protocol (LogEventMaster) - -* results: - - job type (size) throughput (100k jobs) - ----------------------------------------- - small job - big job - small DAG - big DAG - - - ----------------- -Locallogger test ----------------- - -* component: - org.glite.lb.logger - -* binaries required: - stresslog - glite_lb_logd_perf - glite_lb_logd_perf_nofile - - does not store events in file - glite_lb_interlogd_perf_empty - - consumes immediately after reading event - -* test shell script: - perftest_logd - -* input required: - - client and host certificates - - events - -* test description: - - measures time required for event to be sent from client to - local logger and processed by locallogger. Localloger is - either instructed (by option) or instrumented to skip some - parts of event processing: - a) no parse, no file, no ipc - glite_lb_logd_perf_nofile --noParse --noIPC - b) no file, no ipc - glite_lb_logd_perf_nofile --noIPC - c) no ipc - glite_lb_logd_perf --noIPC - d) normal operation - glite_lb_logd_perf - - no parse - LL does not parse events - no file - LL does not store events into files - no ipc - LL does not send events through socket to IL - - - events produced: - - stresslog sends events to logd using client->logd - protocol (*_DoLogEvent()) - - - events consumed: - i) after storing into files - ii) by "empty" IL - -* results: - - - -i) events stored in files - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - -ii) events sent to IL - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - - - ----------------- -Interlogger test ----------------- - -* component: - org.glite.lb.logger - -* binaries required: - stresslog - glite_lb_interlogd_perf - glite_lb_interlogd_perf_noparse - - does not parse events, server address is hardcoded - glite_lb_interlogd_perf_nosync - - does not call event_store_sync() - glite_lb_interlogd_perf_norecover - - recovery thread disabled - glite_lb_interlogd_perf_nosend - - events are consumed instead of sending - glite_lb_interlogd_perf_lazy - - lazy closing connection to bkserver - glite_lb_bkserverd_perf_empty - - consumes event immediately after receiving - -* test shell script: - perftest_interlogd - -* input required: - - host certificate - - events - -* test description: - - measures time the event travels through interlogger. - Interlogger is instrumented to skip some parts of eventh - processing for particular test, specifically tests include - these variants: - a) disabled event parsing. The server address - (eg. jobid) is hardcoded. - b) disabled event synchronization from files - c) disabled recovery thread - d) lazy bkserver connection close - e) normal operation - - - events produced: - 1) stresslog sends events to interlogger using the unix - domain socket and logd->interlogger protocol, events are - stored in files (stresslog behaves like logd) - TODO: pro toto neni funkce v producerske knihovne - 2) interlogger reads events from event files created by - stresslog (by recovery thread) - 3) stresslog stores events to files and every n-th - (optional argument) is sent also through the unix socket - - - events consumed: - i) discarded instead of being sent - ii) by "empty" bkserver - -* results: - - -i) events discarded -1) events received on socket -(options 2 and 3 are not tested) - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - e) - - -ii) events sent to empty bkserver -1) events received on socket - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - e) - - -2) events recovered from files - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - d) - e) - - -3) events synced from files, every 10th event sent on socket - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - e) - - ------------- -LBProxy test ------------- - -* component: - org.glite.lb.proxy - -* binaries required: - stresslog - glite_lb_proxy_perf_noparse - - consumes events before parsing - glite_lb_proxy_perf_nostore - - consumes events before storing into database - glite_lb_proxy_perf_nostate - - consumes events before computing job status - glite_lb_proxy_perf_nosend - - consumes events before sending to interlogger - glite_lb_interlogd_perf_empty - - consumes immediately after reading event - -* test shell script: - perftest_proxy - -* input required: - - events - -* test description: - - measures time required for processing event by LB proxy. Test - is performed with (a)) and without (b)) checking for duplicit - events. - - - events produced: - - stresslog sends events using the IL protokol on local - socket (using DoLogEventProxy()) - - - events consumed: - i) before parsing - ii) before storing into database - iii) after storing into database - iv) after job status computation - v) normal operation - - - - -* results: - -a) with duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - v) - - -b) without duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - v) - - --------------- -LB server test --------------- - -* component: - org.glite.lb.server - -* binaries required: - stresslog - glite_lb_server_perf_noparse - - consumes events before parsing - glite_lb_server_perf_nostore - - consumes events before storing into database - glite_lb_server_perf_nostate - - consumes events before computing job status - -* test shell script: - perftest_server - -* input required: - - host certificates - - events - -* test description: - - measures time required for processing event by LB server. Test - is performed with (a)) and without (b)) checking for duplicit - events. - - - events produced: - - stresslog sends events using the IL protokol (using DoLogEventDirect()) - - - events consumed: - i) before parsing - ii) before storing into database - iii) after storing into database - iv) normal operation - -* results: - -a) with duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - - -b) without duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - - - ---------------------- -Job registration test ---------------------- - -* component: - org.glite.lb.server - org.glite.lb.proxy - -* binaries required: - stressreg - - generates registration events - glite_lb_bkserverd - glite_lb_proxy - glite_lb_bkserverd_perf_empty - glite_lb_proxy_perf_empty - -* test shell script: - perftest_jobreg - -* input required: - - host & user certificates - -* test description: - - measures time required to register given number of jobs (time - to process registration event). The registration event is - synchronous in principle, so it is possible to get results just - from the client (stressreg). Test variants include: - a) current implementation - b) implementation of connection pool at the client - c) parallel communication with server and proxy - - - - events produced: - - stressreg sends registration events by calling - edg_wll_RegisterJob*() - - - events consumed: - i) normally processed by server & proxy - ii) server replies immediate success - iii) proxy replies immediate success - -* results: - -a) current implementation - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - ii) - iii) - - -b) connection pool - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - ii) - iii) - - -c) parallel communication - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - - - -\end{verbatim} - -\end{document} \ No newline at end of file diff --git a/org.glite.lb/doc/testplan.tex b/org.glite.lb/doc/testplan.tex deleted file mode 100644 index dd468d6..0000000 --- a/org.glite.lb/doc/testplan.tex +++ /dev/null @@ -1,300 +0,0 @@ -\documentclass{egee} -\usepackage{comment} - -\def\LB{L\&B} - -\title{\LB\ Test Plan} -\author{CESNET EGEE JRA1 team} -\DocIdentifier{EGEE-JRA1-??} -\Date{\today} -\Activity{JRA1: Middleware Engineering and Integration} -\DocStatus{DRAFT} -\Dissemination{PUBLIC} -\DocumentLink{} - -\def\req{\noindent\textbf{Prerequisities:}} -\def\how{\noindent\textbf{How to run:}} -\def\result{\noindent\textbf{Expected result:}} - -\def\path#1{{\normalfont\textsf{#1}}} -\def\code#1{\texttt{#1}} - -\def\todo#1{\textbf{TODO:} #1} - - -\specialcomment{hints}{\par\noindent\textbf{Hints: }\begingroup\slshape}{\endgroup} -%\includecomment{hints} - -\begin{document} - -\input{frontmatter} -\newpage -\tableofcontents -\newpage - -\section{Rationale} -\todo{} - -\section{Test Coverage} -\todo{} - -\section{Test Cases} - -\subsection{Event delivery} - -% locallogger -% bez dalsich demonu, registrovat job, vrati EAGAIN, objevi se fajly -\subsubsection{Standalone locallogger -- job registration} -\label{reg} -\req\ running \path{glite-lb-logd} on the test node, don't start either -\path{glite-lb-interlogd} or \path{glite-lb-bkserverd} - -\how\ call \code{edg\_wll\_RegisterJob}. Jobid's should preferably point -to a~remote \LB\ server. - -\result\ The API call returns EAGAIN, but locallogger creates an event file -in its storage. -The file should contain single line RegJob event. - -\begin{hints} -\path{glite-lb-regjob} example can be used. It generates a~unique jobid, -prints it and calls \LB\ API appropriately. -\end{hints} - -% async -- prida do fajlu, OK -% logevent -\subsubsection{Standalone locallogger -- log event} -\label{log} -\req\ running \path{glite-lb-logd} only, files generated in test~\ref{reg}. - -\how\ call \code{edg\_wll\_Log*} for various event types in a~sequence -resebmling real \LB\ usage, using the same jobid's as in test~\ref{reg} - -\result\ API calls return 0, events are added one per line to the locallogger files - -\begin{hints} -\path{glite-lb-logev} client program can be used. - -\path{glite-lb-*.sh} examples may be adapted to produce reasonable seqences -of events. -\end{hints} - -\subsubsection{Interlogger recovery} -\label{recover} -% recover interloggeru -% il & server (remote) -% spustit, protlaci soubory na server, soubory zmizi, lze se dotazat na stav -\req\ running \path{glite-lb-bkserverd} on the machine and port where -jobid's from \ref{reg} point to; files generated in~\ref{log}. - -\how\ Make a~copy of the files created in~\ref{log}, then start -\path{glite-lb-interlogd}. After approx. 10s check the jobs -with \code{edg\_wll\_JobLog} call. - -\result \code{edg\_wll\_JobLog} should return the same events that were -contained in the locallogger files. The files should be removed by -interlogger after approx. 1 min. - -\begin{hints} -\path{glite-lb-joblog} example outputs the events in (almost) the same -format as the locallogger files. -\end{hints} - -% event delivery -% poslat .sh, job log vrati to, co bylo ve fajlech -\subsubsection{Normal event delivery} -\label{normal} -\req\ all \LB\ daemons running (\path{glite-lb-logd}, \path{glite-lb-interlogd}, -\path{glite-lb-bkserverd} - -\how\ -\begin{enumerate} - -\item Register jobs with \code{edg\_wll\_RegsterJob} -\item Log reasonable sequences of events with \code{edg\_wll\_Log*}. -\item Check with \code{edg\_wll\_JobLog} -that the events got delivered afterwards (approx. 10s). -\end{enumerate} - -\result\ API calls should return 0. The same events that were logged must be returned. - -\begin{hints} -\path{glite-lb-*.sh} scripts produce reasonable seqences of events, including -the job initial registration. - -There is approx. 1min time window in which the locallogger files exist. -They can be grabbed and used for comparing the events as in~\ref{recover}. - -\end{hints} - -\subsection{Job state computation} - -% normal event delivery & job state machine -% .sh, dotaz na stav -\subsubsection{Normal job states} -\label{state} -\req\ \path{glite-lb-bkserverd} running, events from \ref{normal} logged. - -\how\ Check state of the jobs with \code{edg\_wll\_JobStatus}. - -\result\ The API call should return 0, the jobs should be in the expected -states. Thorough tests may also cross check the values supplied in the -events (e.g. destination computing element) wrt. the values reported in the job states. - -\begin{hints} -\path{glite-lb-*.sh} scripts produce sequences of events resultning -in the job state same as the `*' part of the script name. -\end{hints} - -\subsubsection{DAG job states} -\todo{} -% specialni stav DAGu, histogram potomku - -\subsection{LB proxy} -\req\ running \path{glite-lb-proxy}, \path{glite-lb-interlogd} and -\path{glite-lb-bkserverd} - -\how\ Register jobs with \code{edg\_wll\_RegisterJobProxy}, log events -using \code{edg\_wll\_LogEventProxy} and check the job states against -both lbproxy (using \code{edg\_wll\_JobStatusProxy}) and bkserver -(using \code{edg\_wll\_JobStatus}). - -\result\ A new job state should be available immediately at the -lbproxy and probably with a small delay also at the bkserver. - -\begin{hints} -There is already a script \path{test.sh} in -\path{org.glite.lb.proxy/examples} that can be used together with -above mentioned scripts \path{glite-lb-*.sh} (they are called from -\path{test.sh}) to test all this. -\end{hints} - -\subsection{WS interface} -\req\ \path{glite-lb-bkserverd} running, events from \ref{normal} logged - -\how\ retrieve both events and job states with the \LB\ WS interface -(operations \code{JobStatus}, \code{QueryEvents}). - -\result\ the returened data should match those returned by the legacy -API calls. - -\begin{hints} -Examples \path{org.glite.lb.server/examples/ws\_*.c} convert the WS -responses back to the legacy \LB\ data structures and print them in -the same form as e.g. \path{glite-lb-jobstat}. -\end{hints} - -\subsection{Notifications} - -% notifikace -% regjob, reg notifikace na vsechno, poslat udalosti, hlidat notif -\subsubsection{Single job, any state change} -\label{notif1} -\req\ All \LB\ services running - -\how -\begin{enumerate} -\item Register a job. -\item Start a~notification client (preferably on another machine), -register with \code{edg\_wll\_NotifNew} for any state changes of the job, -and repeatedly invoke \code{edg\_wll\_NotifReceive}. -\item One by one send events triggering job state change. -\end{enumerate} - -\result\ All the events should trigger notification reported by the running -notification client. - -\begin{hints} -\path{glite-lb-notify} example can be used with its \path{test} command. -\end{hints} - -\subsubsection{Additional notification criteria} -\label{notif-complex} -\req\ All \LB\ services running - -\how\ Like~\ref{notif1} but include additional criteria, -e.g. job is scheduled for a~specific destination. - -\result\ Only notifications matching the criteria should be delivered. - -% rozsireni dotazu o dalsi job -\subsubsection{Include another job} -\label{notif2} -\req\ All \LB\ services running, notification from \ref{notif1} still active - -\how\ -\begin{enumerate} -\item Register another job. -\item Augment the notification registration with the new jobid using -\code{edg\_wll\_NotifChange}. -\item Start notification client, bind to the registration with -\code{edg\_wll\_NotifBind}. -\item Send events for the new job. -\end{enumerate} - -\result\ Notifications should be received by the client. - -\begin{hints} -Commands \path{change} and \path{receive} of \path{glite-lb-notify} -can be used. -\end{hints} - -% notifikace -- zmena adresy/portu -% pak poslat udalost, musi dojit -% uz je v predchozim implicitne - -\subsubsection{Delayed delivery} -% notifikace -- zpozdene doruceni -% registrovat, odpojit, poslat udalosti, pripojit se - -\req\ All \LB\ services running - -\how\ -\begin{enumerate} -\item Register another job. -\item Register a~notification as in~\ref{notif1} but terminate the client -immediately. -\item Log events for the job. -\item Restart the client, binding to the notification and call -\code{edg\_wll\_NotifReceive} repeatedly. -\end{enumerate} - -\result\ Delayed notifications should be received by the client almost -immediately. - -\subsection{Server purge} - -\textbf{WARNING: This test is destructive, it destroys ALL data in an -existing \LB\ database.} - -The test is fairly complex but it does not make too much sense to split it -artificially. - -\req\ All \LB services running, preferably a~dedicated server for this test. - -\how -\begin{enumerate} -\item Purge all data on the server with \path{glite-lb-purge} -\item Log two sets of jobs, separated with delay of at least 60s so -that the sets can be distinguished from each other. -\item \label{purgel} -Using \code{edg\_wll\_JobLog} retrieve events of all the jobs -\item \label{purge1} -Purge the first set of jobs (by specifying appropriate timestamp), -letting the server dump the purged events. -\item \label{purge2} Purge the other set of jobs, also dumping the events. -\item \label{purge3} Run purge once more. -\end{enumerate} - -\result\ The data dumped in steps \ref{purge1}, \ref{purge2} should be the -same as retrieved in~\ref{purgel}. The final purge invocation should -do nothing (i.e. nothing was left in the database). - -% test_purge -\begin{hints} -The example \path{glite-lb-test\_purge} does exactly this sequence of steps, -including the checks. -\end{hints} - - -\end{document} diff --git a/org.glite.lb/lb4vdt/LB_install.sh b/org.glite.lb/lb4vdt/LB_install.sh deleted file mode 100755 index 93924c9..0000000 --- a/org.glite.lb/lb4vdt/LB_install.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/sh - -set -e - -#OFFLINE=true -TOPDIR=${PWD} - -export LB4VDTDIR=${TOPDIR}/org.glite.lb/lb4vdt -export STAGEDIR=${TOPDIR}/stage -mkdir -p ${STAGEDIR} - -if [ ! -f ${LB4VDTDIR}/Makefile.inc ]; then - echo "Error: There is no ${LB4VDTDIR}/Makefile.inc. Exiting." - exit 1 -fi - -if [ -z "${CVSROOT}" ]; then - export CVSROOT=:pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -# export CVSROOT=:ext:jpospi@jra1mw.cvs.cern.ch:/cvs/jra1mw - echo "Using CVSROOT=${CVSROOT}" -fi - -dep_modules="org.glite.wms-utils.jobid -org.gridsite.core" - -modules="org.glite.security.gsoap-plugin -org.glite.lb.client-interface -org.glite.lb.common -org.glite.lb.client -org.glite.lb.logger -org.glite.lb.ws-interface -org.glite.lb.server-bones -org.glite.lb.server -org.glite.lb.proxy" -#org.glite.lb.utils - -for i in $dep_modules; -do - echo "*********************************************************" - echo "* Module $i" - echo "*********************************************************" - cd ${TOPDIR} - if [ -n "${OFFLINE}" ]; then - echo "Working offline" - else - echo "Getting sources from CVS" - cvs co -A $i; - fi - if [ -d $i -a -f ${LB4VDTDIR}/patches/$i.patch -a ! -f .$i.patched ]; then - echo "Patching $i" - patch -p0 < ${LB4VDTDIR}/patches/$i.patch - touch .$i.patched - fi - if [ -d $i ]; then - touch .$i.timestamp - if [ -f ${LB4VDTDIR}/scripts/$i.build ]; then - echo "Building" - sh -x ${LB4VDTDIR}/scripts/$i.build - fi - cd ${TOPDIR} - find ${STAGEDIR} -newer .$i.timestamp > .$i.filelist - else - echo "WARNING: directory $i not found" - fi -done - -for i in $modules; -do - echo "*********************************************************" - echo "* Module $i" - echo "*********************************************************" - cd ${TOPDIR} - if [ -n "${OFFLINE}" ]; then - echo "Working offline" - else - echo "Getting sources from CVS" - cvs co -A $i; - fi - if [ -d $i -a -f ${LB4VDTDIR}/patches/$i.patch -a ! -f .$i.patched ]; then - echo "Patching $i" - patch -p0 < ${LB4VDTDIR}/patches/$i.patch - touch .$i.patched - fi - if [ -d $i ]; then - touch .$i.timestamp - echo "Entering directory ${TOPDIR}/$i" - cd ${TOPDIR}/$i - echo "Copying supporting files" - cp -rv ${TOPDIR}/org.glite.lb/project/{at3,*.T,*.pm} ./project/ - mkdir -p build - echo "Entering directory ${TOPDIR}/$i/build" - cd build - ln -fsv ../Makefile -# ln -fsv ../../Makefile.inc Makefile.inc - ln -fsv ${LB4VDTDIR}/Makefile.inc - echo "Building" - make LB_STANDALONE=yes - make stage LB_STANDALONE=yes - cd ${TOPDIR} - find ${STAGEDIR} -newer .$i.timestamp > .$i.filelist - else - echo "WARNING: directory $i not found" - fi - echo "Done" -done - -cd ${TOPDIR} -echo "Creating filelists" -cat .org.glite.wms-utils.jobid.filelist .org.gridsite.core.filelist .org.glite.security.gsoap-plugin.filelist .org.glite.lb.common.filelist | sort | uniq > LB-common.filelist -cat .org.glite.lb.client-interface.filelist .org.glite.lb.client.filelist | sort | uniq > LB-client.filelist -cat .org.glite.lb.logger.filelist | sort | uniq > LB-logger.filelist -cat .org.glite.lb.logger.filelist .org.glite.lb.server-bones.filelist .org.glite.lb.proxy.filelist | sort | uniq > LB-proxy.filelist -cat .org.glite.lb.ws-interface.filelist .org.glite.lb.server-bones.filelist .org.glite.lb.server.filelist | sort | uniq > LB-server.filelist diff --git a/org.glite.lb/lb4vdt/Makefile.inc b/org.glite.lb/lb4vdt/Makefile.inc deleted file mode 100644 index c9c3072..0000000 --- a/org.glite.lb/lb4vdt/Makefile.inc +++ /dev/null @@ -1,77 +0,0 @@ -# -# common setting -# - -#vdt_location=/home/honik/egee/vdt-1.5.0 -vdt_location=${VDT_LOCATION} - -# missing packages could be for example downloaded to repository from -# http://eticssoft.web.cern.ch/eticssoft/repository/externals - -repository=/home/honik/egee/repository/externals/ -platform=slc3_ia32_gcc323 - - -# -# external dependencies that are already part of VDT (vdt-1.5.0): -# - -#classads_prefix=${repository}/classads/0.9.8/${platform} -classads_prefix=${vdt_location}/classads - -#globus_prefix=${repository}/globus/2.4.3-VDT-1.2.5/${platform} -globus_prefix=${vdt_location}/globus - -#expat_prefix=/usr -expat_prefix=${vdt_location}/expat - -#mysql_prefix=${repository}/mysql-devel/4.1.11/${platform} -mysql_prefix=${vdt_location}/mysql -mysql_version=4.1.21 - -voms_prefix=${vdt_location}/glite -#voms_prefix=/home/honik/egee/glite/stage - - -# -# external dependencies that are NOT (yet) part of VDT (vdt-1.5.0): -# - -#cares_prefix=${repository}/c-ares/1.3.0/${platform} -cares_prefix=/software/cares-1.3 - -# probably not needed (used "only" for unit tests - 'make check'): -#cppunit_prefix=${repository}/cppunit/1.10.2/${platform} -cppunit_prefix=/software/cppunit-1.10.2 - -# probably not needed: -#gridsite_prefix=${stagedir} - -gsoap_default_version=2.7.6b -gsoap_versions=${gsoap_default_version} -#gsoap_prefix=${repository}/gsoap/${gsoap_default_version}/${platform} -gsoap_prefix=/software/gsoap-${gsoap_default_version} - - -# -# some other defaults: -# - -#PREFIX=${vdt_location}/glite -PREFIX=/tmp/lb4vdt -globalprefix=glite -lbprefix=lb - -builddir=build -distdir=${STAGEDIR}/../dist -stagedir=${STAGEDIR} -top_srcdir=.. - -#thrflavour=gcc64dbgpthr -#nothrflavour=gcc64dbg -thrflavour=gcc32dbgpthr -nothrflavour=gcc32dbg - -# needed by org.glite.lb.client: -glite_location=${stagedir} - diff --git a/org.glite.lb/lb4vdt/scripts/org.gridsite.core.build b/org.glite.lb/lb4vdt/scripts/org.gridsite.core.build deleted file mode 100644 index 38258c5..0000000 --- a/org.glite.lb/lb4vdt/scripts/org.gridsite.core.build +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -TOPDIR=${PWD} -source ${LB4VDTDIR}/Makefile.inc -cd org.gridsite.core/src -make build-lib OPENSSL_FLAGS=-I${globus_prefix}/include/${nothrflavour} OPENSSL_LIBS=-L${globus_prefix}/lib FLAVOR_EXT=_${nothrflavour} -make install-lib prefix=${STAGEDIR} -cd ${TOPDIR} - diff --git a/org.glite.lb/project/MultiStruct.pm b/org.glite.lb/project/MultiStruct.pm deleted file mode 100644 index 9cd847c..0000000 --- a/org.glite.lb/project/MultiStruct.pm +++ /dev/null @@ -1,191 +0,0 @@ -package MultiStruct; - -use StructField; - -sub new { - shift; - my $self = {}; - $self->{comments} = {}; # typ->comment - $self->{fields} = {}; # typ->{ name->StructField, ... } - $self->{order} = {}; - - bless $self; -} - -sub selectType { - my $self = shift; - my $type = shift; - $self->{type} = $type; - 1; -} - -sub addType { - my $self = shift; - my $type = shift; - my $comment = shift; - $self->selectType($type); - $self->{comments}->{$type} = $comment; - $self->{fields}->{$type} = {}; - 1; -} - -sub selectField { - my $self = shift; - $self->{field} = shift; - $self->getField; -} - -sub addField { - my $self = shift; - my $field = shift; - - die "unselected type" unless $self->{type}; - $self->{fields}->{$self->{type}}->{$field->{name}} = $field; - $self->selectField($field->{name}); - 1; -} - -sub getField { - my $self = shift; - my $f = $self->{fields}->{$self->{type}}->{$self->{field}}; - return $f ? $f : $self->{fields}->{_common_}->{$self->{field}}; -} - -sub load { - my $self = shift; - my $fh = shift; - local $_; - - while ($_ = <$fh>) { - - chomp; - s/#.*$//; - next if /^\s*$/; - - if (/^\@type\s+(\S+)\s*(.*$)$/) { - $self->addType($1,$2); - $self->{order}->{$1} = $.; - next; - } - - s/^\s*//; - my ($ftype,$fname,$comment) = split /\s+/,$_,3; - if ($ftype eq '_code_') { - my $f = $self->getField(); - addCode $f $fname,$comment; - } - elsif ($ftype eq '_alias_') { - my $f = $self->getField(); - addAlias $f $fname,$comment; - } - elsif ($ftype eq '_special_') { - my $f = $self->getField(); - addSpecial $f $fname; - } - elsif ($ftype eq '_null_') { - my $f = $self->getField(); - setNull $f $fname; - } - elsif ($ftype eq '_optional_') { - my $f = $self->getField(); - $f->{optional} = 1; - } - elsif ($ftype eq '_index_') { - my $f = $self->getField(); - $f->{index} = 1; - } - else { - my $f = new StructField $fname,$ftype,$comment,$.; - $self->addField($f); - } - } -} - -sub getTypes { - my $self = shift; - my @out; - local $_; - - for (keys %{$self->{fields}}) { - push @out,$_ unless $_ eq '_common_'; - } - @out; -} - -sub getTypesOrdered { - my $self = shift; - my @names = getTypes $self; - - sort { - my $oa = $self->{order}->{$a}; - my $ob = $self->{order}->{$b}; - $oa <=> $ob; - } @names; -} - -sub getTypeComment { - my $self = shift; - my $type = shift || $self->{type}; - $self->{comments}->{$type}; -} - -sub getFieldComment { - my $self = shift; - my $fname = shift; - $self->{fields}->{$self->{type}}->{$fname}->{comment}; -} - -sub getFields { - my $self = shift; - keys %{$self->{fields}->{$self->{type}}}; -} - -sub getFieldsOrdered { - my $self = shift; - my @names = $self->getFields; - sort { - my $oa = $self->selectField($a)->{order}; - my $ob = $self->selectField($b)->{order}; - $oa <=> $ob; - } @names; -} - -sub getFieldOccurence { - my $self = shift; - my $fname = shift; - my @out; - local $_; - - for (keys %{$self->{fields}}) { - push @out,$_ if $self->{fields}->{$_}->{$fname}; - } - @out; -} - -sub getAllFields { - my $self = shift; - my %out; - local $_; - - for my $t (values %{$self->{fields}}) { - $out{$_->{name}} = 1 for (values %$t); - } - keys %out; -} - -sub getAllFieldsOrdered { - my $self = shift; - my @names = getAllFields $self; - - sort { - my @occ = $self->getFieldOccurence($a); - $self->selectType($occ[0]); - my $oa = $self->selectField($a)->{order}; - @occ = $self->getFieldOccurence($b); - $self->selectType($occ[0]); - my $ob = $self->selectField($b)->{order}; - $oa <=> $ob; - } @names; -} - -1; diff --git a/org.glite.lb/project/StructField.pm b/org.glite.lb/project/StructField.pm deleted file mode 100644 index 95d33b8..0000000 --- a/org.glite.lb/project/StructField.pm +++ /dev/null @@ -1,116 +0,0 @@ -package StructField; - -$lang = 'C'; -1; - -sub new { - shift; - my $self = {}; - $self->{name} = shift; - $self->{type} = shift; - $self->{comment} = shift; - $self->{order} = shift; - $self->{null} = $main::DefaultNullValue{$self->{type}}; - bless $self; -} - -sub addCode { - my $self = shift; - my $code = shift; - my $comment = shift; - push @{$self->{codes}},{name=>$code,comment=>$comment}; - 1; -} - -sub addSpecial { - my $self = shift; - my $special = shift; - $self->{special} = $special; - 1; -} - -sub addAlias { - my $self = shift; - my $name = shift; - my $lang = shift; - $self->{aliases}->{$lang} = $name; - 1; -} - -sub hasAlias { - my $self = shift; - my $lang = shift; - return $self->{aliases}->{$lang} ? 1 : 0; -} - -sub getName { - my $self = shift; - my $lang = shift || $lang; - $self->{aliases}->{$lang} || $self->{name}; -# return $self->{aliases}->{$lang} ? $self->{aliases}->{$lang} : $self->{name}; -} - -sub getComment { - my $self = shift; - $self->{comment}; -} - -sub getDefaultNullValue { - my $self = shift; - $self->{null}; -} - -sub toString { - my $self = shift; - my $src = shift; - my $dst = shift; - - eval $main::toString{$lang}->{$self->{type}}; -} - -sub fromString { - my $self = shift; - my $src = shift; - my $dst = shift; - - eval $main::fromString{$lang}->{$self->{type}}; -} - -sub isNULL { - my $self = shift; - my $a = shift; - my $b = $self->{null}; - - eval $main::compare{$lang}->{$self->{type}}; -} - -sub isnotNULL { - my $self = shift; - my $src = shift; - - '!('.$self->isNULL($src).')'; -} - -sub compare { - my $self = shift; - my $a = shift; - my $b = shift; - eval $main::compare{$lang}->{$self->{type}}; -} - -sub toFormatString { - my $self = shift; - - eval $main::toFormatString{$lang}->{$self->{type}}; -} - -sub setNull { - my $self = shift; - $self->{null} = shift; -} - -sub getType { - my $self = shift; - - eval $main::types{$lang}->{$self->{type}}; -} diff --git a/org.glite.lb/project/at3 b/org.glite.lb/project/at3 deleted file mode 100755 index 8ff52ec..0000000 --- a/org.glite.lb/project/at3 +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/perl -w - -use File::Basename; -my $dir; -BEGIN{ - $dir = dirname $0; -} - -my $lines = $ENV{AT3_LINES}; - -use lib $dir; -use MultiStruct; -require 'types.T'; - -my $eventsn; -for (@INC) { - if (-f "$_/events.T") { - $eventsn="$_/events.T"; - last; - } -} - -my $statusn; -for (@INC) { - if (-f "$_/status.T") { - $statusn = "$_/status.T"; - last; - } -} - -my $indent = ''; - -my $event = new MultiStruct; -my $status = new MultiStruct; - -sub gen { - local $_ = shift; - - s/^\n!//; - s/\n!/\n/g; - print $_; -} - - -open EVENTS,$eventsn or die "$eventsn: $!\n"; -$event->load(\*EVENTS); -close EVENTS; - -open STATUS,$statusn or die "$statusn: $!\n"; -$status->load(\*STATUS); -close STATUS; - -my $code; -my $startcode; -while (<>) { - chomp; - if (/^\@\@\@LANG: (\S+)$/) { - $StructField::lang = $1; - next; - } - - if ($code) { - if (/^\@\@\@}$/) { - $code .= "1;\n"; - print "#line $startcode \"$ARGV\"\n/* begin */\n" if $lines; - eval $code or warn "eval: $@ at $ARGV:$.\n"; - my $nxtline = $.+1; - print "/* end */\n#line $nxtline \"$ARGV\"\n" if $lines; - undef $code; - } - else { $code .= $_."\n"; } - } - else { - if (/^\@\@\@{$/) { - $startcode = $.; - $code = "\n"; - } - elsif (/^\@\@\@AUTO$/) { - print qq{ - !! Automatically generated file - !! Do not edit, your changes will be discarded upon build - !! Change the corresponding template file $ARGV - -}; - print "#line $. \"$ARGV\"\n" if $lines; - } - else { - print "$_\n"; - } - } -} - -# print $event_common{prog}->copy('bla','hu'); diff --git a/org.glite.lb/project/build.number b/org.glite.lb/project/build.number deleted file mode 100644 index cc27364..0000000 --- a/org.glite.lb/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Aug 18 12:35:01 CEST 2006 -module.build=0242 diff --git a/org.glite.lb/project/build.properties b/org.glite.lb/project/build.properties deleted file mode 100644 index 408f648..0000000 --- a/org.glite.lb/project/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -ext.gsoap.version=2.7.0f -ext.gsoap.rep.file=gSOAP-2.7.0f.tar.gz - diff --git a/org.glite.lb/project/check_version.pl b/org.glite.lb/project/check_version.pl deleted file mode 100644 index a55f821..0000000 --- a/org.glite.lb/project/check_version.pl +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/perl - -# check_version script to be used to compare client-interface and other modules versions -# Usage: -# - set environment variables VERSION and VERSION_AHEAD of the module -# - run against ${stagedir}/include/glite/lb/interface_version.h -# Example: -# ./check_version.pl interface_version.h - -my $version = $ENV{VERSION}; -if ($version =~ /(\d+)\.\d+\.\d+/) { - $version = $1; -} else { - print "error: wrong version format ($version)\n"; - exit 1; -} - -my $ahead = $ENV{VERSION_AHEAD}; -if ($ahead =~ /(\d+)/) { - $ahead = $1; -} else { - print "error: wrong version_ahead format ($ahead)\n"; - exit 1; -} - -my $iface; - -while (<>) { - /#define GLITE_LB_CLIENT_INTERFACE "(\d+)\.\d+\.\d+"/; - $iface = $1; -} - -if ($iface + $ahead != $version) { - print "error: Major version of the interface ($iface + $ahead ahead) DOES NOT match implementation ($version)\n" ; - exit 1; -} diff --git a/org.glite.lb/project/dependencies.properties b/org.glite.lb/project/dependencies.properties deleted file mode 100644 index 510bcf7..0000000 --- a/org.glite.lb/project/dependencies.properties +++ /dev/null @@ -1,20 +0,0 @@ - -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.lb.version = HEAD - -# Component dependencies tag = do not remove this line = -org.glite.lb.client-interface.version = HEAD -org.glite.lb.ws-interface.version = HEAD -org.glite.lb.common.version = HEAD -org.glite.lb.client.version = HEAD -org.glite.lb.server.version = HEAD -org.glite.lb.proxy.version = HEAD -org.glite.lb.server-bones.version = HEAD -org.glite.lb.logger.version = HEAD -org.glite.lb.utils.version = HEAD - -ext.gsoap.version = 2.7.0f diff --git a/org.glite.lb/project/events.T b/org.glite.lb/project/events.T deleted file mode 100644 index f81a989..0000000 --- a/org.glite.lb/project/events.T +++ /dev/null @@ -1,327 +0,0 @@ -@type _common_ - timeval timestamp Time the event was generated. - _alias_ date ULM - timeval arrived Time the event was stored into the bookkeeping server database. - _alias_ arr_date ULM - _optional_ - string host Hostname of the machine where the event was generated. - _alias_ host ULM - int level Logging level (in the range from DEBUG to EMERGENCY). - _alias_ lvl ULM - _code_ EMERGENCY emergency - _code_ ALERT alert - _code_ ERROR error - _code_ WARNING warning - _code_ AUTH authentication - _code_ SECURITY security - _code_ USAGE usage - _code_ SYSTEM system - _code_ IMPORTANT important - _code_ DEBUG debug - int priority Message priority (yet 0 for asynchronous and 1 for synchronous transfers). - _null_ -1 - jobid jobId Grid job id of the job the event belongs to. - string seqcode Sequence code assigned to the event. - string user Identity (certificate subject) of the event sender. - logsrc source Source (software component) which generated this event. -# string prog name of program ("EDG WMS" of name of the application). - string src_instance Instance of source component (e.g. service communication endpoint). - _optional_ - -@type Transfer Start, success, or failure of job transfer to another component. - logsrc destination Destination where the job is being transfered to. - string dest_host Hostname of server that takes over control of the job. - string dest_instance Service (instance) that takes over control of the job. - _optional_ - string job Job description in receiver's language. - int result Result code of the transfer attempt (START, OK, REFUSED or FAIL). - _code_ START The sending component has started or is about to start the transfer. - _code_ OK The job was sent successfully. - _code_ REFUSED The job was refused by the other component. - _code_ FAIL The transfer failed for other reason than explicit refusal (eg. network timeout). - string reason Detailed description of the transfer, especially reason of failure. - _optional_ - string dest_jobid Job id as assigned by the receiving software component. - _optional_ - -@type Accepted Accepting job (successful counterpart to Transfer). - logsrc from The software component the job was received from. - string from_host Hostname of the component the job was received from. - string from_instance Instance of the component the job was received from. - _optional_ - string local_jobid New job id as assigned by the receiving component. - -@type Refused Refusing job (unsuccessful counterpart to Transfer). - logsrc from The software component that tried to send the job. - string from_host Hostname of the component that tried to send the job. - string from_instance Instance of the component that tried to send the job. - _optional_ - string reason Description of the reason why the job was refused. - -@type EnQueued The job has been enqueued in an inter-component queue. - string queue Queue into which the job has been stored for retrieval by another component. - string job Job description in the receiver's language. - int result Result code of the attempt to put job into the queue (START, OK, REFUSED or FAIL). - _code_ START The sending component has started or is about to start enqueuing the job. - _code_ OK The job was enqueued successfully. - _code_ REFUSED The job was refused by the other component. - _code_ FAIL The transfer failed for other reason than explicit refusal. - string reason Detailed description of the attempt to enqueue the job, especially the reason of failure. - -@type DeQueued The job has been dequeued from an inter-component queue. - string queue Name of the queue the job was obtained from. - string local_jobid New job id as assigned by the retreiving component. - -@type HelperCall Helper component is called. - string helper_name Name of the called helper component. - string helper_params Parameters of the call to the helper component. - int src_role The role the event sender is playing in the helper call (CALLING or CALLEE). - _code_ CALLING The logging component is caller. - _code_ CALLED The logging component is callee. - -@type HelperReturn Helper component is returning the control. - string helper_name Name of the called helper component. - string retval Data returned by the call to the helper component. - int src_role The role the event sender is playing in the helper call (CALLING or CALLEE). - _code_ CALLING The logging component is caller. - _code_ CALLED The logging component is callee. - -@type Running Job wrapper started. - string node Worker node on which the job executable is being run. - -@type Resubmission Result of resubmission decision. - int result Result code of the resubmission decision (WILLRESUB or WONTRESUB or SHALLOW). - _code_ WILLRESUB The job will be resubmitted (deep resubmission). - _code_ WONTRESUB The job will not be resubmitted. - _code_ SHALLOW Shallow resubmission (user payload has not started yet) - string reason Reason why the job will or will not be resubmitted. - string tag Value of the attribute on which the decision to resubmit the job was based. - -@type Done Execution terminated (normally or abnormally). - int status_code Reason code for the termination of the job (OK, FAILED or CANCELLED). - _code_ OK The job terminated by itself. - _code_ FAILED The job disappeared from LRMS. - _code_ CANCELLED The job was cancelled by user request. - string reason Detailed description why the job was terminated. - int exit_code Exit code of the job's process. - _null_ -1 - -@type Cancel Cancel operation has been attempted on the job. - int status_code Classification of the attempt to cancel the job (REQ, REFUSE, DONE or ABORT). - _code_ REQ The request was acknowledged. - _code_ REFUSE The request was declined by this component. - _code_ DONE The request was completed by whole WMS. - _code_ ABORT The request was refused by whole WMS. - string reason Detailed description of the attempt to cancel the job, especially the reason of failure. - -@type Abort Job aborted by system. - string reason Reason why the job was aborted by the system. - -@type Clear Job cleared, output sandbox removed - int reason Description of the reason why the job was cleared and the output sandbox removed (USER, TIMEOUT or NOOUTPUT). - _code_ USER User retrieved output sandbox. - _code_ TIMEOUT Timed out, resource forced purge of the sandbox. - _code_ NOOUTPUT No output was generated. - -@type Purge Job is purged from bookkepping server. - -@type Match Matching CE found. - string dest_id Identification of the queue on the CE that the job could be send to. - -@type Pending No matching CE found yet. - string reason Description why the matching CE for the job was not found (yet). - -@type RegJob New job registration. - string jdl Job description of the job being registered. - string ns NetworkServer handling the newly registered job. - jobid parent Grid job id of the parent job registering this new one. - _optional_ - - int jobtype Type of the job being registered (SIMPLE, DAG, PARTITIONABLE or PARTITIONED). - _code_ SIMPLE The job is simple job. - _code_ DAG The job is dag (containing static set of subjobs). - _code_ PARTITIONABLE The job is partitionable (may become partitioned). - _code_ PARTITIONED The job is partitioned (dynamically created dag). - _code_ COLLECTION The job is collection (containing static set of subjobs). - _code_ PBS PBS job - _code_ CONDOR Condor job - - int nsubjobs Number of subjobs this job plans to spawn. - _optional_ - string seed Seed for subjob id generation. - _optional_ - -@type Chkpt Application-specific checkpoint record. - string tag Application specific checkpoint tag. - string classad Application specific checkpoint value. - -@type Listener Listening network port for interactive control. - string svc_name Name of the port instance for interactive job control. - string svc_host Hostname of the interactive job controller. - port svc_port Port number of the interactive job controller. - -@type CurDescr Current state of job processing (optional event). - string descr Description of the current job transformation (output of the helper). - -@type UserTag User tag -- arbitrary name=value pair. - string name Arbitrary user tag name. - string value Arbitrary user tag value. - -@type ChangeACL Management of ACL stored on bookkepping server. - string user_id DN or VOMS parameter (in format VO:group). - int user_id_type Type of information given in user_id (DN or VOMS). - _null_ -1 - int permission ACL permission to change (currently only READ). - _null_ -1 - int permission_type Type of permission requested ('allow', 'deny'). - _null_ -1 - int operation Operation requested to perform with ACL (add, remove). - _null_ -1 - -@type Notification Management of notification service. - notifid notifId Notification id. - string owner Identification of the job owner (certificate subject). - string dest_host Hostname the notification is sent to. - port dest_port Port number the notification is sent to. - string jobstat Status of the job (the notification content). - - -@type ResourceUsage Resource (CPU, memory etc.) consumption. - string resource Resource's name. - int quantity Resources's quantity (how much). - string unit Units (sec, kB, etc.). - -@type ReallyRunning User payload started. - _optional_ - string wn_seq Sequence code on the worker node. - -@type Suspend Job execution (queuing) was suspended. - _optional_ - string reason Reason for the suspend. - -@type Resume Job execution (queuing) was resumed. - _optional_ - string reason Reason for the resume. - -@type CollectionState State of the collection. - string state New collection state. - _optional_ - int done_code In case of (state == Done) contains done code - _null_ -1 - string histogram User readable histogram; useful for debugging. - jobid child JobId of subjob, which triggered the state change. - string child_event Event which triggered the state change. - - -@type PBSQueued Job enqued - string queue Queue name - string owner Job owner - string name Job name - -@type PBSMatch Scheduler created exec_host - string dest_host Aka exec_host - -@type PBSPending Scheduler is not able to find exec_host, or some error occured - string reason Reasons of job pendation or errors - -@type PBSRun Job attempted to be run by the logging component - string scheduler Scheduler ID - _optional_ - string dest_host Where to run the job - _optional_ - int pid Actual process ID - _optional_ - -@type PBSRerun Job rerun requested - -@type PBSDone Job terminated - int exit_status Exit status - _optional_ Bypass need of 'null value' - -@type PBSDequeued Job dequeued - -@type PBSResourceUsage Resources requested/consumed - int usage Type of record - _code_ REQUESTED Requested value - _code_ USED Consumed quantity - string name Name of resource - int quantity The quantity - _optional_ Bypass need of 'null value' - string unit Units (sec, kB, etc.) - -@type PBSError Any error occured - string error_desc Error reason - -@type CondorSubmit Job SUBMITed to Condor - string universe Condor Universe - string submit_host Submitting machine - string condor_id Condor ID - -@type CondorMatch Job MATCHed - string condor_id Condor ID - string owner Owner - string matched_host Matched host - string preempting Preempting - _optional_ - -@type CondorRun Condor EXECUTEed - string condor_id Condor ID - string universe Condor Universe - string scheduler Scheduler ID - _optional_ - string dest_host Where to run the job - _optional_ - int pid Actual process ID - _optional_ - -@type CondorChkpt - string info Some useful info - -@type CondorEvict - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorTerminate - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorAbort - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorSuspend - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorUnsuspend - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorHold - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorRelease - int shadow_exit_status Condor shadow exit status - string reason reason - -@type CondorNodeExecute - string info Some useful info - -@type CondorNodeTerminate - string info Some useful info - -@type CondorPostSctiptTerminate - string info Some useful info - -@type CondorGlobusSubmit - int status_code - _code_ OK The job was submitted successfully - _code_ FAIL Job submission failed - string info Some useful info - -@type CondorGlobusResource - int status_code Status code - _code_ UP Resource UP - _code_ DOWN Resource DOWM - string info Some useful info diff --git a/org.glite.lb/project/glite.lb.csf.xml b/org.glite.lb/project/glite.lb.csf.xml deleted file mode 100644 index 7d77350..0000000 --- a/org.glite.lb/project/glite.lb.csf.xml +++ /dev/null @@ -1,398 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.lb modules have been updated, please rerun the configuration file - - - - The org.glite and org.glite.lb modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb/project/properties.xml b/org.glite.lb/project/properties.xml deleted file mode 100755 index 0d0291a..0000000 --- a/org.glite.lb/project/properties.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/org.glite.lb/project/run-workspace b/org.glite.lb/project/run-workspace deleted file mode 100644 index 03a3381..0000000 --- a/org.glite.lb/project/run-workspace +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -cd ../.. - -cvs co org.glite -cvs co org.glite.lb - -cd org.glite.lb/project -ant -f glite.lb.csf.xml - diff --git a/org.glite.lb/project/status.T b/org.glite.lb/project/status.T deleted file mode 100644 index cae5f17..0000000 --- a/org.glite.lb/project/status.T +++ /dev/null @@ -1,111 +0,0 @@ -@type _common_ -jobid jobId Id of the job -string owner Job owner -_index_ - -int jobtype Type of job - _null_ -1 - _code_ SIMPLE simple job - _code_ DAG composite job - _code_ COLLECTION parent of collection of jobs - _code_ PBS PBS job - _code_ CONDOR Condor job -jobid parent_job parent job of subjob - -string seed string used for generation of subjob IDs -int children_num number of subjobs -strlist children list of subjob IDs - _special_ XMLstructured -intlist children_hist summary (histogram) of children job states - _special_ XMLstructured -stslist children_states full status information of the children - _special_ XMLstructured - -string condorId Id within Condor-G -string globusId Globus allocated Id -string localId Id within LRMS - -string jdl User submitted job description -string matched_jdl Full job description after matchmaking -string destination ID of CE where the job is being sent -_index_ -string condor_jdl ClassAd passed to Condor-G for last job execution -string rsl Job RSL sent to Globus - -string reason Reason of being in this status, if any - -string location Where the job is being processed -_index_ -string ce_node Worker node where the job is executed -string network_server Network server handling the job - -bool subjob_failed Subjob failed (the parent job will fail too) -int done_code Return code - _null_ -1 - _code_ OK Finished correctly - _code_ FAILED Execution failed - _code_ CANCELLED Cancelled by user -int exit_code Unix exit code -bool resubmitted The job was resubmitted - -bool cancelling Cancellation request in progress -string cancelReason Reason of cancel - -int cpuTime Consumed CPU time - _null_ -1 - -taglist user_tags List of pairs (user_tag, user_value) - _special_ XMLstructured - -timeval stateEnterTime When entered this status -timeval lastUpdateTime Last known event of the job - -intlist stateEnterTimes When all previous states were entered - _special_ XMLstructured - -bool expectUpdate Some logged information has not arrived yet -string expectFrom Sources of the missing information -string acl ACL of the job - -bool payload_running User payload started -strlist possible_destinations Possible job destinations - _special_ XMLstructured -strlist possible_ce_nodes CE nodes matching to possible_destinations - _special_ XMLstructured - -bool suspended Job is suspended -string suspend_reason Reason for the suspend - -string pbs_state Job state which would probably return PBS qstat (Q/R/C/....) -string pbs_queue Name of queue in which is job queued -string pbs_owner Owner of job -string pbs_name Name of job -string pbs_reason Glued reasons/errors leading to pending events -string pbs_scheduler Name of pbs scheduler -string pbs_dest_host Hostname of node where job is running -int pbs_pid PID of running job -string pbs_resource_usage Glued resource usage -int pbs_exit_status Job exit status -string pbs_error_desc Glued error descriptions from error events - -string condor_status Condor job status -string condor_universe Condor job Universe (in job ClassAds) -string condor_owner Job owner -string condor_pid PID of running job -int condor_notification Condor notification -int condor_job_exit_status Job exit status -int condor_starter_exit_status Condor starter exit status -int condor_shadow_exit_status Condor shadow exit status (see h/exit.h) - - -@type Submitted Entered by the user to the User Interface or registered by Job Partitioner. -@type Waiting Accepted by WMS, waiting for resource allocation. -@type Ready Matching resources found. -@type Scheduled Accepted by LRMS queue. -@type Running Executable is running. -@type Done Execution finished, output is available. -@type Cleared Output transfered back to user and freed. -@type Aborted Aborted by system (at any stage). -@type Cancelled Cancelled by user. -@type Unknown Status cannot be determined. -@type Purged Job has been purged from bookkeeping server (for LB->RGMA interface). diff --git a/org.glite.lb/project/taskdefs.xml b/org.glite.lb/project/taskdefs.xml deleted file mode 100755 index 251f790..0000000 --- a/org.glite.lb/project/taskdefs.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.glite.lb/project/types.T b/org.glite.lb/project/types.T deleted file mode 100644 index 015b4e1..0000000 --- a/org.glite.lb/project/types.T +++ /dev/null @@ -1,127 +0,0 @@ -%types = ( - C=>{ - bool=>'"int"', - string=>'"char *"', - strlist=>'"char **"', - intlist=>'"int *"', - taglist=>'"edg_wll_TagValue *"', - stslist=>'"struct _edg_wll_JobStat *"', - timeval=>'"struct timeval"', - jobid=>'"edg_wlc_JobId"', - notifid=>'"edg_wll_NotifId"', - logsrc=>'"edg_wll_Source"', - port=>'"uint16_t"', -# level=>'"enum edg_wll_Level"', - int=>'"int"' - }, - 'C++'=>{ - string=>'"std::string"', - timeval=>'"struct timeval"', - jobid=>'"edg::workload::common::jobid::JobId"', - bool=>'"int"', - intlist=>'"std::vector"', - strlist=>'"std::vector"', - taglist=>'"std::vector>"', - stslist=>'"std::vector"', - logsrc=>'"int"', - port=>'"int"', - int=>'"int"' - }, - 'wsdl'=>{ - bool=>'"xsd:boolean"', - string=>'"xsd:string"', - int=>'"xsd:int"', - jobid=>'"xsd:string"', - jobstat=>'"jobStatus"', - usertag=>'"tagValue"', - timeval=>'"timeval"', - logsrc=>'"eventSource"', - notifid=>'"xsd:string"', - port=>'"xsd:int"', - } -); - -%baseTypes = ( - intlist=>'int', - strlist=>'string', - stslist=>'jobstat', - taglist=>'usertag' -); - -%toString = ( - C=>{ - int=>'qq{asprintf(&$dst,"%d",$src);}', - port=>'qq{asprintf(&$dst,"%d",(int) $src);}', - bool=>'qq{asprintf(&$dst,"%d",$src);}', - string=>'qq{$dst = $src?strdup($src):NULL;}', - timeval=>'qq{edg_wll_ULMTimevalToDate(($src).tv_sec,($src).tv_usec,$dst);}', - jobid=>'qq{$dst = edg_wlc_JobIdUnparse($src);}', - notifid=>'qq{$dst = edg_wll_NotifIdUnparse($src);}', -# level=>'qq{$dst = edg_wll_LevelToString($src);}', - logsrc=>'qq{$dst = edg_wll_SourceToString($src);}', -# strlist, intlist, stslist are used only in consumer API, they don't need toString method - } -); - -%ULMasString = ( - logsrc=>1 -); - -%fromString = ( - C=>{ - int=>'qq{$dst = atoi($src);}', - port=>'qq{$dst = (uint16_t) atoi($src);}', - bool=>'qq{$dst = atoi($src);}', - string=>'qq{$dst = strdup($src);}', - timeval=>'qq{edg_wll_ULMDateToTimeval($src,&$dst);}', - jobid=>'qq{edg_wlc_JobIdParse($src,&$dst);}', - notifid=>'qq{edg_wll_NotifIdParse($src,&$dst);}', -# level=>'qq{$dst = edg_wll_StringToLevel($src);}', - logsrc=>'qq{$dst = edg_wll_StringToSource($src);}', -# strlist, intlist, stslist are used only in consumer API, they don't need fromString method - } -); - -%DefaultNullValue = ( - int=>0, - port=>0, -# level=>'EDG_WLL_LEVEL_UNDEFINED', - bool=>0, - string=>'NULL', - jobid=>'NULL', - notifid=>'NULL', - logsrc=>'EDG_WLL_SOURCE_NONE', - timeval=>'null_timeval', - strlist=>'NULL', - intlist=>'NULL', - taglist=>'NULL', - stslist=>'NULL', -); - -%compare = ( - C=>{ - int=>'"($a == $b)"', - port=>'"($a == $b)"', -# level=>'"($a == $b)"', - bool=>'"(($a || !$b) && ($b || !$a))"', - string=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp($a,$b))"', - jobid=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp(edg_wlc_JobIdUnparse($a),edg_wlc_JobIdUnparse($b)))"', - notifid=>'"($a) == ($b)"', - logsrc=>'"($a) == ($b)"', - timeval=>'"($a).tv_sec == ($b).tv_sec && ($a).tv_usec == ($b).tv_usec"', - } -); - -%toFormatString = ( - C=>{ - int=>'"%d"', - port=>'"%d"', - bool=>'"%d"', -# level=>'"%s"', - string=>'"%|Us"', - jobid=>'"%s"', - notifid=>'"%s"', - logsrc=>'"%s"', - timeval=>'"%s"', - } -); diff --git a/org.glite.lb/project/version.properties b/org.glite.lb/project/version.properties deleted file mode 100644 index 8dac816..0000000 --- a/org.glite.lb/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Sep 02 14:19:10 CEST 2005 -module.version=1.3.3 -module.age=0 diff --git a/org.glite.security.gsoap-plugin/Makefile b/org.glite.security.gsoap-plugin/Makefile index e16d870..82ce398 100644 --- a/org.glite.security.gsoap-plugin/Makefile +++ b/org.glite.security.gsoap-plugin/Makefile @@ -17,7 +17,8 @@ gsoap_prefix=/opt/gsoap CC=gcc -gsoap_versions?=2.6.2 2.7.0 2.7.6b +gsoap_versions?=2.6.2 2.7.0f 2.7.6b 2.7.9b +gsoap_versions:=${shell if ! echo $gsoap_versions | grep "\<${gsoap_default_version}\>" >/dev/null; then echo "${gsoap_default_version} "; else echo ne; fi} ${gsoap_versions} -include Makefile.inc -include ../Makefile.inc @@ -32,7 +33,13 @@ version_info:=-version-info ${shell \ # version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` +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} VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/examples @@ -85,7 +92,7 @@ ARES_LIBS:=-L${cares_prefix}/lib -lcares EX_LIBS:= ${GLOBUS_LIBS} ${ARES_LIBS} EX_THRLIBS := ${GLOBUS_THR_LIBS} ${ARES_LIBS} -HDRS:=glite_gss.h glite_gsplugin.h +HDRS:=glite_gss.h glite_gsplugin.h glite_gscompat.h GSS_OBJS:=glite_gss.o GSS_LOBJS:=${GSS_OBJS:.o=.lo} @@ -164,7 +171,7 @@ ${THRLTLIB_S}: ${THROBJS_S} all compile: \ ${GSS_STATICLIB} ${GSS_LTLIB} ${GSS_THRSTATICLIB} ${GSS_THRLTLIB} \ ${STATICLIB} ${LTLIB} ${THRSTATICLIB} ${THRLTLIB} \ - all-libs-with-soap + all-libs-with-soap examples check: compile check.gss @@ -187,25 +194,25 @@ all-libs-with-soap: for v in ${gsoap_versions}; do \ dir=`echo $$v | tr -d .`; \ mkdir $$dir; \ - ( cd $$dir && ${MAKE} -f ../Makefile gsoap_version=$$v top_srcdir=../.. libs-with-soap examples) ; \ + ( cd $$dir && ${MAKE} -f ../Makefile gsoap_version=$$v top_srcdir=../.. libs-with-soap) ; \ done libs-with-soap: ${LTLIB_S} ${THRLTLIB_S} ${STATICLIB_S} ${THRSTATICLIB_S} +gsoap_srcname=gsoap-`echo ${gsoap_version} | cut -d. -f1,2` + link-gsoap: if [ -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 ${repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.c ]; then \ - ln -sf ${repository}/${gsoap_name}/${gsoap_version}/src/stdsoap2.[ch] .; \ - elif [ -f ${repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/stdsoap2.c ]; then \ - ln -sf ${repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform}/stdsoap2.[ch] .; \ - elif [ -f ${gsoap_prefix}/stdsoap2.c ]; then \ - ln -sf ${gsoap_prefix}/stdsoap2.[ch] .; \ - elif [ -f ${gsoap_prefix}/src/stdsoap2.c ]; then \ - ln -sf ${gsoap_prefix}/src/stdsoap2.[ch] .; \ - elif [ -f ${gsoap_prefix}/devel/stdsoap2.c ]; then \ - ln -sf ${gsoap_prefix}/devel/stdsoap2.[ch] .; \ + 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}/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 @@ -229,7 +236,6 @@ wscalc_srv_ex2: ${WSCALC_SRV2_OBJS} ${LTLIB_S} ${LINK} -o $@ ${WSCALC_SRV2_OBJS} ${LTLIB_S} -gsoap_prefix?=${repository}/${gsoap_name}/${gsoap_version}/${gsoap_platform} soapcpp:=${shell if [ -x ${gsoap_prefix}/bin/soapcpp2 ]; then \ echo ${gsoap_prefix}/bin/soapcpp2; \ else echo ${gsoap_prefix}/soapcpp2; \ @@ -267,7 +273,7 @@ install: ${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 ${GSS_STATICLIB} ${GSS_THRSTATICLIB} ${STATICLIB} ${THRSTATICLIB} ${PREFIX}/lib; \ + install -m 644 ${GSS_STATICLIB} ${GSS_THRSTATICLIB} ${PREFIX}/lib; \ fi for v in ${gsoap_versions}; do \ (cd `echo $$v | tr -d .` && ${MAKE} -f ../Makefile install-soaplib gsoap_version=$$v PREFIX=${PREFIX} ); \ diff --git a/org.glite.security.gsoap-plugin/build.xml b/org.glite.security.gsoap-plugin/build.xml index 1bfdeed..a5ccbb2 100755 --- a/org.glite.security.gsoap-plugin/build.xml +++ b/org.glite.security.gsoap-plugin/build.xml @@ -84,20 +84,25 @@ - - + + - + + + + + + diff --git a/org.glite.security.gsoap-plugin/interface/glite_gscompat.h b/org.glite.security.gsoap-plugin/interface/glite_gscompat.h new file mode 100644 index 0000000..38b7d96 --- /dev/null +++ b/org.glite.security.gsoap-plugin/interface/glite_gscompat.h @@ -0,0 +1,78 @@ +#ifndef GLIE_SECURITY_GSCOMPAT_H +#define GLIE_SECURITY_GSCOMPAT_H + +#ident "$Header: " + +#ifndef GSOAP_VERSION + #error GSOAP_VERSION required +#endif + +#if GSOAP_VERSION >= 20709 + #define GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, ITEM, TYPENAME, TYPENO) ((CHOICE)->union_##TYPENAME.ITEM) + #define GLITE_SECURITY_GSOAP_CHOICE_SETTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) ((CHOICE)->__union_##TYPENAME) = SOAP_UNION__##NS##__union_##TYPENAME##_##ITEM + #define GLITE_SECURITY_GSOAP_CHOICE_ISTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) (((CHOICE)->__union_##TYPENAME) == SOAP_UNION__##NS##__union_##TYPENAME##_##ITEM) +#elif GSOAP_VERSION >= 20706 + #define GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, ITEM, TYPENAME, TYPENO) ((CHOICE)->union_##TYPENO.ITEM) + #define GLITE_SECURITY_GSOAP_CHOICE_SETTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) ((CHOICE)->__union_##TYPENO) = SOAP_UNION_##NS##__union_##TYPENO##_##ITEM + #define GLITE_SECURITY_GSOAP_CHOICE_ISTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) (((CHOICE)->__union_##TYPENO) == SOAP_UNION_##NS##__union_##TYPENO##_##ITEM) +#else + #define GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, ITEM, TYPENAME, TYPENO) ((CHOICE)->ITEM) + #define GLITE_SECURITY_GSOAP_CHOICE_SETTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) + #define GLITE_SECURITY_GSOAP_CHOICE_ISTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO) (((CHOICE)->ITEM) != NULL) +#endif +#define GLITE_SECURITY_GSOAP_CHOICE_SET(CHOICE, ITEM, NS, TYPENAME, TYPENO, VALUE) do { \ + memset((CHOICE), 0, sizeof(*(CHOICE))); \ + GLITE_SECURITY_GSOAP_CHOICE_SETTYPE(CHOICE, ITEM, NS, TYPENAME, TYPENO); \ + GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, ITEM, TYPENAME, TYPENO) = (VALUE); \ +} while(0) + +#if GSOAP_VERSION >= 20706 + #define GLITE_SECURITY_GSOAP_REASON2(SOAP) ((SOAP)->fault->SOAP_ENV__Reason ? (SOAP)->fault->SOAP_ENV__Reason->SOAP_ENV__Text : "(no reason)") + #define GLITE_SECURITY_GSOAP_TRUE xsd__boolean__true_ + #define GLITE_SECURITY_GSOAP_FALSE xsd__boolean__false_ +#else + #define GLITE_SECURITY_GSOAP_REASON2(SOAP) ((SOAP)->fault->SOAP_ENV__Reason) + #define GLITE_SECURITY_GSOAP_TRUE true_ + #define GLITE_SECURITY_GSOAP_FALSE false_ +#endif + +#define GLITE_SECURITY_GSOAP_DETAIL(SOAP) ((SOAP)->version == 2 ? (SOAP)->fault->SOAP_ENV__Detail : (SOAP)->fault->detail) +#define GLITE_SECURITY_GSOAP_REASON(SOAP) ((SOAP)->version == 2 ? GLITE_SECURITY_GSOAP_REASON2((SOAP)) : (SOAP)->fault->faultstring) + +#if GSOAP_VERSION >= 20709 + #define GLITE_SECURITY_GSOAP_LIST_CREATE0(SOAP, LIST, SIZE, TYPE, N) do { \ + if ((N) != 0) (LIST) = soap_malloc((SOAP), (N) * sizeof(TYPE)); \ + else (LIST) = NULL; \ + (SIZE) = (N); \ +} while (0) + #define GLITE_SECURITY_GSOAP_LIST_DESTROY0(SOAP, LIST, SIZE) do { \ + if ((LIST) && (SIZE) != 0) soap_dealloc((SOAP), (LIST)); \ + (LIST) = NULL; \ +} while (0) + #define GLITE_SECURITY_GSOAP_LIST_GET(LIST, INDEX) (&(LIST)[INDEX]) + #define GLITE_SECURITY_GSOAP_LIST_TYPE(NS, LIST) struct NS##__##LIST * +#else + #define GLITE_SECURITY_GSOAP_LIST_CREATE0(SOAP, LIST, SIZE, TYPE, N) do { \ + int ilist; \ + \ + if ((N) != 0) (LIST) = soap_malloc((SOAP), (N) * sizeof(void *)); \ + else (LIST) = NULL; \ + (SIZE) = (N); \ + for (ilist = 0; ilist < (N); ilist++) { \ + (LIST)[ilist] = soap_malloc((SOAP), sizeof(TYPE)); \ + } \ +} while (0) + #define GLITE_SECURITY_GSOAP_LIST_DESTROY0(SOAP, LIST, SIZE) do { \ + int ilist; \ + \ + for (ilist = 0; ilist < (SIZE); ilist++) soap_dealloc((SOAP), (LIST)[ilist]); \ + if ((LIST) && (SIZE) != 0) soap_dealloc((SOAP), (LIST)); \ + (LIST) = NULL; \ +} while (0) + #define GLITE_SECURITY_GSOAP_LIST_GET(LIST, INDEX) ((LIST)[INDEX]) + #define GLITE_SECURITY_GSOAP_LIST_TYPE(NS, LIST) struct NS##__##LIST ** +#endif +#define GLITE_SECURITY_GSOAP_LIST_CREATE(SOAP, CONTAINER, LIST, TYPE, N) GLITE_SECURITY_GSOAP_LIST_CREATE0(SOAP, (CONTAINER)->LIST, (CONTAINER)->__size##LIST, TYPE, N) +#define GLITE_SECURITY_GSOAP_LIST_DESTROY(SOAP, CONTAINER, LIST) GLITE_SECURITY_GSOAP_LIST_DESTROY0(SOAP, (CONTAINER)->LIST, (CONTAINER)->__size##LIST) + +#endif diff --git a/org.glite.security.gsoap-plugin/project/version.properties b/org.glite.security.gsoap-plugin/project/version.properties index ee52aa9..4dae1ef 100644 --- a/org.glite.security.gsoap-plugin/project/version.properties +++ b/org.glite.security.gsoap-plugin/project/version.properties @@ -1,2 +1,2 @@ -module.version=1.4.0 -module.age=0 +module.version=1.4.2 +module.age=3 diff --git a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c b/org.glite.security.gsoap-plugin/src/glite_gsplugin.c index ace9384..c7cc361 100644 --- a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c +++ b/org.glite.security.gsoap-plugin/src/glite_gsplugin.c @@ -168,7 +168,7 @@ glite_gsplugin(struct soap *soap, struct soap_plugin *p, void *arg) soap->fconnect = glite_gsplugin_connect; soap->fclose = glite_gsplugin_close; #if GSOAP_VERSION >= 20700 - soap->fclosesocket = glite_gsplugin_close; + soap->fclosesocket = NULL; #endif soap->faccept = glite_gsplugin_accept; soap->fsend = glite_gsplugin_send; @@ -236,6 +236,7 @@ glite_gsplugin_connect( || (GSOAP_VERSION == 20700 && (strlen(GSOAP_MIN_VERSION) < 1 || GSOAP_MIN_VERSION[1] < 'e')) ) { fprintf(stderr, "Client connect will work only with gSOAP v2.7.0e and later"); + soap->errnum = ENOSYS; return ENOSYS; } #endif @@ -265,17 +266,21 @@ glite_gsplugin_connect( goto err; } + soap->errnum = 0; return 0; err: pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect() error!\n")); switch ( ret ) { + case EDG_WLL_GSS_ERROR_GSS: ret = SOAP_CLI_FAULT; break; case EDG_WLL_GSS_ERROR_HERRNO: - case EDG_WLL_GSS_ERROR_ERRNO: return errno; - case EDG_WLL_GSS_ERROR_EOF: return ECONNREFUSED; - case EDG_WLL_GSS_ERROR_TIMEOUT: return ETIMEDOUT; + case EDG_WLL_GSS_ERROR_ERRNO: ret = errno; break; + case EDG_WLL_GSS_ERROR_EOF: ret = ECONNREFUSED; break; + case EDG_WLL_GSS_ERROR_TIMEOUT: ret = ETIMEDOUT; break; + default: break; } + soap->errnum = ret; return ret; } @@ -311,7 +316,7 @@ glite_gsplugin_accept(struct soap *soap, int s, struct sockaddr *a, int *n) edg_wll_GssStatus gss_code; int conn; - + soap->errnum = 0; pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_accept()\n")); ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; if ( (conn = accept(s, (struct sockaddr *)&a, n)) < 0 ) return conn; @@ -320,6 +325,7 @@ glite_gsplugin_accept(struct soap *soap, int s, struct sockaddr *a, int *n) if ( edg_wll_gss_accept(ctx->cred, conn, ctx->timeout, ctx->connection, &gss_code)) { pdprintf(("GSLITE_GSPLUGIN: Client authentication failed, closing.\n")); edg_wll_gss_get_error(&gss_code, "Client authentication failed", &ctx->error_msg); + soap->errnum = SOAP_SVR_FAULT; return -1; } diff --git a/org.glite.security.gsoap-plugin/src/glite_gss.c b/org.glite.security.gsoap-plugin/src/glite_gss.c index eda6021..8617f1e6 100644 --- a/org.glite.security.gsoap-plugin/src/glite_gss.c +++ b/org.glite.security.gsoap-plugin/src/glite_gss.c @@ -591,6 +591,17 @@ end: 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 */ + int edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port, struct timeval *timeout, edg_wll_GssConnection *connection, @@ -604,6 +615,7 @@ edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port, 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)); @@ -637,6 +649,8 @@ edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port, /* 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 */ @@ -678,6 +692,27 @@ edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port, /* 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; diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c new file mode 100644 index 0000000..b4750a4 --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c @@ -0,0 +1,12026 @@ +/* + +stdsoap2.c[pp] 2.7.0f + +Runtime environment. + +gSOAP XML Web services tools +Copyright (C) 2000-2004, Robert van Engelen, Genivia, Inc., All Rights Reserved. + +Contributors: + +Wind River Systems, Inc., for the following additions (marked WR[...]): + - vxWorks compatible + - Support for IPv6. + +-------------------------------------------------------------------------------- + + This software is released under one of the following three licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. + +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2004, Robert van Engelen, Genivia, Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- + +Installation note: + +Win32 build needs winsock.dll (Visual C++ "wsock32.lib") +To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link" +tab (the project file needs to be selected in the file view) and add +"wsock32.lib" to the "Object/library modules" entry + +On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with +-fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack +when locally allocated data exceeds 64K. + +*/ + +#include "stdsoap2.h" + +#ifdef __cplusplus +SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.0f 2005-02-28 12:00:00 GMT") +extern "C" { +#else +SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.0f 2005-02-28 12:00:00 GMT") +#endif + +/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale) */ +#ifndef SOAP_UNKNOWN_CHAR +#define SOAP_UNKNOWN_CHAR (127) +#endif + +/* EOF=-1 */ +#define SOAP_LT (soap_wchar)(-2) /* XML character '<' */ +#define SOAP_TT (soap_wchar)(-3) /* XML character '' */ +#define SOAP_QT (soap_wchar)(-5) /* XML character '"' */ +#define SOAP_AP (soap_wchar)(-6) /* XML character ''' */ + +#define SOAP_BOM (soap_wchar)(0xFEFF) /* UTF BOM is Unicode FEFF */ + +#define soap_blank(c) ((c) >= 0 && (c) <= 32) +#define soap_notblank(c) ((c) > 32) +#define soap_hash_ptr(p) (((unsigned long)(p) >> 3) & (SOAP_PTRHASH - 1)) + +static int soap_isxdigit(int); +static soap_wchar soap_char(struct soap*); + +#ifndef WITH_NOIDREF +static void soap_update_ptrs(struct soap*, char*, char*, long); +static int soap_has_copies(struct soap*, const char*, const char*); +static struct soap_ilist *soap_hlookup(struct soap*, const char*); +static void soap_init_iht(struct soap*); +static void soap_free_iht(struct soap*); +static void soap_init_pht(struct soap*); +static void soap_free_pht(struct soap*); +#endif + +static int soap_set_error(struct soap*, const char*, const char*, const char*, int); +static int soap_copy_fault(struct soap*, const char*, const char*, const char*); +static int soap_getattrval(struct soap*, char*, size_t, soap_wchar); +static void soap_set_local_namespaces(struct soap*); +static void *fplugin(struct soap*, const char*); + +#ifndef WITH_LEAN +static const char *soap_set_validation_fault(struct soap*, const char*, const char*); +static int soap_isnumeric(struct soap*, const char*); +static time_t soap_timegm(struct tm*); +#endif + +#ifdef SOAP_DEBUG +static void soap_init_logs(struct soap*); +static void soap_close_logfile(struct soap*, int); +static void soap_set_logfile(struct soap*, int, const char*); +#endif + +#ifdef WITH_FAST +static int soap_append_lab(struct soap*, const char*, size_t); +#endif + +#ifndef WITH_LEANER +static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t); +static int soap_putdimefield(struct soap*, const char*, size_t); +static char *soap_getdimefield(struct soap*, size_t); +static void soap_select_mime_boundary(struct soap*); +static int soap_valid_mime_boundary(struct soap*); +#endif + +#ifdef WITH_GZIP +static int soap_getgziphdr(struct soap*); +#endif + +#ifdef WITH_OPENSSL +static int ssl_auth_init(struct soap*); +static int ssl_verify_callback(int, X509_STORE_CTX*); +static int ssl_password(char*, int, int, void *); +static const char *ssl_error(struct soap*, int); +/* This callback is included for future references. It should not be deleted +static DH *ssl_tmp_dh(SSL*, int, int); +*/ +#endif + +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +static const char *soap_decode(char*, size_t, const char*, const char*); +#endif + +#ifndef WITH_NOHTTP +static soap_wchar soap_getchunkchar(struct soap*); +static const char *http_error(struct soap*, int); +static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t); +static int http_get(struct soap*); +static int http_send_header(struct soap*, const char*); +static int http_post_header(struct soap*, const char*, const char*); +static int http_response(struct soap*, int, size_t); +static int http_parse(struct soap*); +static int http_parse_header(struct soap*, const char*, const char*); +#endif + +#ifndef WITH_NOIO +static int fsend(struct soap*, const char*, size_t); +static size_t frecv(struct soap*, char*, size_t); +static int tcp_init(struct soap*); +static const char *tcp_error(struct soap*); +static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr); +static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port); +static int tcp_accept(struct soap*, int, struct sockaddr*, int*); +static int tcp_disconnect(struct soap*); +static int tcp_closesocket(struct soap*, SOAP_SOCKET); +static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int); +static const char *soap_strerror(struct soap*); +#endif + +/* WR[ */ +#ifdef VXWORKS +static int vx_nonblocking = TRUE; /* ioctl argument */ +#endif +/* ]WR */ + +#if defined(PALM) && !defined(PALM_2) +unsigned short errno; +#endif + +#ifndef PALM_1 +static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/"; +static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/"; +static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope"; +static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding"; +static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc"; +#endif + +#ifndef PALM_1 +const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF}; +static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63"; +#endif + +static const char soap_padding[3] = "\0\0"; +#define SOAP_STR_PADDING (soap_padding) +#define SOAP_STR_EOS (soap_padding) + +#ifndef WITH_LEAN +static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */ +{ { 160, "nbsp" }, + { 161, "iexcl" }, + { 162, "cent" }, + { 163, "pound" }, + { 164, "curren" }, + { 165, "yen" }, + { 166, "brvbar" }, + { 167, "sect" }, + { 168, "uml" }, + { 169, "copy" }, + { 170, "ordf" }, + { 171, "laquo" }, + { 172, "not" }, + { 173, "shy" }, + { 174, "reg" }, + { 175, "macr" }, + { 176, "deg" }, + { 177, "plusmn" }, + { 178, "sup2" }, + { 179, "sup3" }, + { 180, "acute" }, + { 181, "micro" }, + { 182, "para" }, + { 183, "middot" }, + { 184, "cedil" }, + { 185, "sup1" }, + { 186, "ordm" }, + { 187, "raquo" }, + { 188, "frac14" }, + { 189, "frac12" }, + { 190, "frac34" }, + { 191, "iquest" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acirc" }, + { 195, "Atilde" }, + { 196, "Auml" }, + { 197, "Aring" }, + { 198, "AElig" }, + { 199, "Ccedil" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecirc" }, + { 203, "Euml" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icirc" }, + { 207, "Iuml" }, + { 208, "ETH" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocirc" }, + { 213, "Otilde" }, + { 214, "Ouml" }, + { 215, "times" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucirc" }, + { 220, "Uuml" }, + { 221, "Yacute" }, + { 222, "THORN" }, + { 223, "szlig" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acirc" }, + { 227, "atilde" }, + { 228, "auml" }, + { 229, "aring" }, + { 230, "aelig" }, + { 231, "ccedil" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecirc" }, + { 235, "euml" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icirc" }, + { 239, "iuml" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocirc" }, + { 245, "otilde" }, + { 246, "ouml" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucirc" }, + { 252, "uuml" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "yuml" }, + { 0, NULL } +}; +#endif + +#ifndef WITH_NOIO +#ifndef WITH_LEAN +static const struct soap_code_map h_error_codes[] = +{ +#ifdef HOST_NOT_FOUND + { HOST_NOT_FOUND, "Host not found" }, +#endif +#ifdef TRY_AGAIN + { TRY_AGAIN, "Try Again" }, +#endif +#ifdef NO_RECOVERY + { NO_RECOVERY, "No Recovery" }, +#endif +#ifdef NO_DATA + { NO_DATA, "No Data" }, +#endif +#ifdef NO_ADDRESS + { NO_ADDRESS, "No Address" }, +#endif + { 0, NULL } +}; +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN +static const struct soap_code_map h_http_error_codes[] = +{ { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Time-out" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Large" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested range not satisfiable" }, + { 417, "Expectation Failed" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Time-out" }, + { 505, "HTTP Version not supported" }, + { 0, NULL } +}; +#endif +#endif + +#ifdef WITH_OPENSSL +static const struct soap_code_map h_ssl_error_codes[] = +{ +#define _SSL_ERROR(e) { e, #e } + _SSL_ERROR(SSL_ERROR_SSL), + _SSL_ERROR(SSL_ERROR_ZERO_RETURN), + _SSL_ERROR(SSL_ERROR_WANT_READ), + _SSL_ERROR(SSL_ERROR_WANT_WRITE), + _SSL_ERROR(SSL_ERROR_WANT_CONNECT), + _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP), + _SSL_ERROR(SSL_ERROR_SYSCALL), + { 0, NULL } +}; +#endif + +#ifndef WITH_LEANER +static const struct soap_code_map mime_codes[] = +{ { SOAP_MIME_7BIT, "7bit" }, + { SOAP_MIME_8BIT, "8bit" }, + { SOAP_MIME_BINARY, "binary" }, + { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" }, + { SOAP_MIME_BASE64, "base64" }, + { SOAP_MIME_IETF_TOKEN, "ietf-token" }, + { SOAP_MIME_X_TOKEN, "x-token" }, + { 0, NULL } +}; +#endif + +#ifdef WIN32 +static int tcp_done = 0; +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +fsend(struct soap *soap, const char *s, size_t n) +{ register int nwritten; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->os) + { soap->os->write(s, n); + if (soap->os->good()) + return SOAP_OK; + return SOAP_EOF; + } +#endif + while (n) + { if (soap_valid_socket(soap->socket)) + { +#ifndef WITH_LEAN + if (soap->send_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->send_timeout > 0) + { timeout.tv_sec = soap->send_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->send_timeout/1000000; + timeout.tv_usec = -soap->send_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + return SOAP_EOF; + } + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + nwritten = SSL_write(soap->ssl, s, n); + else +#endif +#ifndef PALM + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); +#else + nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags); +#endif + if (nwritten <= 0) + { +#ifdef WITH_OPENSSL + int err; + if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return SOAP_EOF; +#endif + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EWOULDBLOCK && soap_socket_errno != SOAP_EAGAIN) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + else + { +#ifdef WITH_FASTCGI + nwritten = fwrite((void*)s, 1, n, stdout); + fflush(stdout); +#else +#ifdef UNDER_CE + nwritten = fwrite(s, 1, n, soap->sendfd); +#else +/* WR[ */ +#ifdef VXWORKS +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + { httpBlockPut(soap->rpmreqid, s, n); + nwritten = n; + } + else + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#else + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#endif /* WMW_RPM_IO */ +#else +/* ]WR */ + nwritten = write((SOAP_SOCKET)soap->sendfd, s, n); +/* WR[ */ +#endif +/* ]WR */ +#endif +#endif + if (nwritten <= 0) + { if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK && soap_errno != SOAP_EAGAIN) + { soap->errnum = soap_errno; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + n -= nwritten; + s += nwritten; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush_raw(struct soap *soap, const char *s, size_t n) +{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { register char *t; + if (!(t = (char*)soap_push_block(soap, n))) + return soap->error = SOAP_EOM; + memcpy(t, s, n); +#ifndef WITH_LEANER + if (soap->fpreparesend) + return soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { char t[16]; + sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n); + DBGMSG(SENT, t, strlen(t)); + if ((soap->error = soap->fsend(soap, t, strlen(t)))) + return soap->error; + soap->chunksize += n; + } + DBGMSG(SENT, s, n); +#endif + return soap->error = soap->fsend(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush(struct soap *soap) +{ if (soap->bufidx) + { +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->d_stream.next_in = (Byte*)soap->buf; + soap->d_stream.avail_in = (unsigned int)soap->bufidx; +#ifdef WITH_GZIP + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->bufidx); +#endif + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in)); + if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } + if (!soap->d_stream.avail_out) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN)) + return soap->error; + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (soap->d_stream.avail_in); + } + else +#endif + if (soap_flush_raw(soap, soap->buf, soap->bufidx)) + return soap->error; + soap->bufidx = 0; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_raw(struct soap *soap, const char *s, size_t n) +{ if (!n) + return SOAP_OK; + if (soap->mode & SOAP_IO_LENGTH) + { soap->count += n; +#ifndef WITH_LEANER + if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } + if (soap->mode & SOAP_IO) + { register size_t i = SOAP_BUFLEN - soap->bufidx; + while (n >= i) + { memcpy(soap->buf + soap->bufidx, s, i); + soap->bufidx = SOAP_BUFLEN; + if (soap_flush(soap)) + return soap->error; + s += i; + n -= i; + i = SOAP_BUFLEN; + } + memcpy(soap->buf + soap->bufidx, s, n); + soap->bufidx += n; + return SOAP_OK; + } + return soap_flush_raw(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send(struct soap *soap, const char *s) +{ if (s) + return soap_send_raw(soap, s, strlen(s)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send2(struct soap *soap, const char *s1, const char *s2) +{ if (soap_send(soap, s1)) + return soap->error; + return soap_send(soap, s2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3) +{ if (soap_send(soap, s1) + || soap_send(soap, s2)) + return soap->error; + return soap_send(soap, s3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static size_t +frecv(struct soap *soap, char *s, size_t n) +{ register int r; + soap->errnum = 0; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->is) + { if (soap->is->good()) + return soap->is->read(s, n).gcount(); + return 0; + } +#endif + if (soap_valid_socket(soap->socket)) + { for (;;) + { +#ifndef WITH_LEAN + if (soap->recv_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->recv_timeout > 0) + { timeout.tv_sec = soap->recv_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->recv_timeout/1000000; + timeout.tv_usec = -soap->recv_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r > 0) + break; + if (r == 0 || soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return 0; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + { int err; + r = SSL_read(soap->ssl, s, n); + if ((err = SSL_get_error(soap->ssl, r)) == SSL_ERROR_NONE) + return (size_t)r; + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return 0; + } + else +#endif + { r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + if (r >= 0) + return (size_t)r; + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN && soap_socket_errno != SOAP_EWOULDBLOCK) + { soap->errnum = soap_socket_errno; + return 0; + } + } +#ifndef WITH_LEAN + { struct timeval timeout; + fd_set fd; + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); +#ifdef WITH_OPENSSL + if (soap->ssl && SSL_get_error(soap->ssl, r) == SSL_ERROR_WANT_WRITE) + r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#endif + if (r < 0 && soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return 0; + } + } +#endif + } + } +#ifdef WITH_FASTCGI + return fread(s, 1, n, stdin); +#else +#ifdef UNDER_CE + return fread(s, 1, n, soap->recvfd); +#else +/* WR[ */ +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + r = httpBlockRead(soap->rpmreqid, s, n); + else + r = read(soap->recvfd, s, n); + if (r >= 0) + return r; + return 0; +#else +/* ]WR */ + r = read((SOAP_SOCKET)soap->recvfd, s, n); + if (r >= 0) + return (size_t)r; + soap->errnum = soap_errno; + return 0; +/* WR[ */ +#endif +/* ]WR */ +#endif +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar +soap_getchunkchar(struct soap *soap) +{ if (soap->bufidx < soap->buflen) + return soap->buf[soap->bufidx++]; + soap->bufidx = 0; + soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket)); + DBGMSG(RECV, soap->buf, soap->buflen); + if (soap->buflen) + return soap->buf[soap->bufidx++]; + return EOF; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +soap_isxdigit(int c) +{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_raw(struct soap *soap) +{ register size_t ret; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { if (soap->d_stream.next_out == Z_NULL) + return EOF; + if (soap->d_stream.avail_in || !soap->d_stream.avail_out) + { register int r; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n")); + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + if (soap->buflen) + { soap->count += soap->buflen; + return SOAP_OK; + } + } + else if (r != Z_BUF_ERROR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + return EOF; + } + } +zlib_again: + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize) + { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->buflen = soap->z_buflen; + } + } +#endif +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */ + { +chunk_again: + if (soap->chunksize) + { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + soap->chunksize -= ret; + } + else + { register soap_wchar c; + char *t, tmp[8]; + t = tmp; + if (!soap->chunkbuflen) + { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + if (!ret) + return EOF; + } + else + soap->bufidx = soap->buflen; + soap->buflen = soap->chunkbuflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (%u %u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen)); + while (!soap_isxdigit((int)(c = soap_getchunkchar(soap)))) + if ((int)c == EOF) + return EOF; + do + *t++ = (char)c; + while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + if ((int)c == EOF) + return EOF; + *t = '\0'; + soap->chunksize = soap_strtoul(tmp, &t, 16); + if (!soap->chunksize) + { soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n")); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + return EOF; + } + soap->buflen = soap->bufidx + soap->chunksize; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to %u (%u %s)\n", (unsigned int)soap->buflen, (unsigned int)soap->bufidx, tmp)); + if (soap->buflen > soap->chunkbuflen) + { soap->buflen = soap->chunkbuflen; + soap->chunksize -= soap->buflen - soap->bufidx; + soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%lu bytes left)\n", (unsigned long)(soap->buflen - soap->bufidx))); + } + else if (soap->chunkbuflen) + soap->chunksize = 0; + ret = soap->buflen - soap->bufidx; + if (!ret) + goto chunk_again; + } + } + else +#endif + { soap->bufidx = 0; + soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + } +#ifndef WITH_LEANER + if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret))) + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { register int r; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = (unsigned int)ret; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->z_buflen = soap->buflen; + soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret)); + if (!ret) + goto zlib_again; + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + return EOF; + } + } +#endif + soap->count += ret; + return !ret; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_DIME) + { if (soap->dime.buflen) + { char *s; + int i; + unsigned char tmp[12]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n")); + soap->count += soap->dime.buflen - soap->buflen; + soap->buflen = soap->dime.buflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3)); + for (i = -(long)soap->dime.size&3; i > 0; i--) + { soap->bufidx++; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n")); + s = (char*)tmp; + for (i = 12; i > 0; i--) + { *s++ = soap->buf[soap->bufidx++]; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + soap->dime.flags = tmp[0] & 0x7; + soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size)); + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.size) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n")); + soap->dime.buflen = 0; + soap->dime.chunksize = 0; + } + soap->count = soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count)); + return SOAP_OK; + } + if (soap->dime.chunksize) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize)); + if (soap_recv_raw(soap)) + return EOF; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count)); + return SOAP_OK; + } + } +#endif + return soap_recv_raw(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getchar(struct soap *soap) +{ register soap_wchar c; + if (soap->ahead) + { c = soap->ahead; + soap->ahead = 0; + return c; + } + return soap_get1(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const struct soap_code_map* +SOAP_FMAC2 +soap_code(const struct soap_code_map *map, const char *str) +{ while (map->string) + { if (!strcmp(str, map->string)) /* case sensitive */ + return map; + map++; + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_int_code(const struct soap_code_map *map, const char *str, long other) +{ while (map->string) + { if (!soap_tag_cmp(str, map->string)) /* case insensitive */ + return map->code; + map++; + } + return other; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_str_code(const struct soap_code_map *map, long code) +{ while (map->code != code && map->string) + map++; + return map->string; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_char(struct soap *soap) +{ char tmp[8]; + register int i; + register soap_wchar c; + register char *s = tmp; + for (i = 0; i < 7; i++) + { c = soap_get1(soap); + if (c == ';' || (int)c == EOF) + break; + *s++ = (char)c; + } + *s = '\0'; + if (*tmp == '#') + { if (tmp[1] == 'x' || tmp[1] == 'X') + return soap_strtol(tmp + 2, NULL, 16); + return atol(tmp + 1); + } + if (!strcmp(tmp, "lt")) + return '<'; + if (!strcmp(tmp, "gt")) + return '>'; + if (!strcmp(tmp, "amp")) + return '&'; + if (!strcmp(tmp, "quot")) + return '"'; + if (!strcmp(tmp, "apos")) + return '\''; +#ifndef WITH_LEAN + return (soap_wchar)soap_int_code(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR); +#else + return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */ +#endif +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +soap_wchar +soap_get0(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx]; +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +soap_wchar +soap_get1(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx++]; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_get(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + soap->ahead = 0; + else + c = soap_get1(soap); + for (;;) + { if (soap->cdata) + { if (c == ']') + { c = soap_get1(soap); + if (c == ']') + { soap->cdata = 0; + soap_get1(soap); /* skip > */ + c = soap_get1(soap); + } + else + { soap_revget1(soap); + return ']'; + } + } + else + return c; + } + switch (c) + { case '<': + do c = soap_get1(soap); + while (soap_blank(c)); + if (c == '!' || c == '?' || c == '%') + { if (c == '!') + { c = soap_get1(soap); + if (c == '[') + { do c = soap_get1(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + break; + soap->cdata = 1; + c = soap_get1(soap); + continue; + } + if (c == '-' && (c = soap_get1(soap)) == '-') + { do + { c = soap_get1(soap); + if (c == '-' && (c = soap_get1(soap)) == '-') + break; + } while ((int)c != EOF); + } + } + while ((int)c != EOF && c != '>') + c = soap_get1(soap); + if ((int)c == EOF) + break; + c = soap_get1(soap); + continue; + } + if (c == '/') + return SOAP_TT; + soap_revget1(soap); + return SOAP_LT; + case '>': + return SOAP_GT; + case '"': + return SOAP_QT; + case '\'': + return SOAP_AP; + case '&': + return soap_char(soap) | 0x80000000; + } + break; + } + return c; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_advance(struct soap *soap) +{ register soap_wchar c; + while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + return c; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_skip(struct soap *soap) +{ register soap_wchar c; + do c = soap_get(soap); + while (soap_blank(c)); + return c; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_move(struct soap *soap, long n) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n)); + for (; n > 0; n--) + if ((int)soap_getchar(soap) == EOF) + return SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_tell(struct soap *soap) +{ return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pututf8(struct soap *soap, register unsigned long c) +{ char tmp[16]; + if (c > 0 && c < 0x80) + { *tmp = (char)c; + return soap_send_raw(soap, tmp, 1); + } +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { register char *t = tmp; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + *t = '\0'; + } + else +#endif + sprintf(tmp, "&#%lu;", c); + return soap_send(soap, tmp); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getutf8(struct soap *soap) +{ register soap_wchar c, c1, c2, c3, c4; + c = soap_get(soap); + if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN)) + return c; + c1 = soap_get(soap); + if (c1 < 0x80) + { soap_unget(soap, c1); + return c; + } + c1 &= 0x3F; + if (c < 0xE0) + return ((soap_wchar)(c & 0x1F) << 6) | c1; + c2 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF0) + return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2; + c3 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF8) + return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3; + c4 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xFC) + return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; + return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthex(struct soap *soap, const unsigned char *s, int n) +{ /* TODO: serialize to DOM (as an option) using new soap_s2hex() */ + char d[2]; + register int i; + for (i = 0; i < n; i++) + { register int m = *s++; + d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0')); + m &= 0x0F; + d[1] = (char)(m + (m > 9 ? '7' : '0')); + if (soap_send_raw(soap, d, 2)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_gethex(struct soap *soap, int *n) +{ +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register char *s; + register int i, k; + if (soap_append_lab(soap, NULL, 0)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + for (i = 0; i < k; i++) + { register char d1, d2; + register soap_wchar c; + c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = (int)(soap->lablen - k + i); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN); + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register char d1, d2; + register soap_wchar c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap_end_block(soap); + soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putbase64(struct soap *soap, const unsigned char *s, int n) +{ register int i; + register unsigned long m; + char d[4]; + if (!s) + return SOAP_OK; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2base64(soap, s, soap->dom->data, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + d[i] = '='; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_getbase64(struct soap *soap, int *n, int malloc_flag) +{ +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register int i, k; + register char *s; + if (soap_append_lab(soap, NULL, 2)) + return NULL; + s = soap->labbuf + soap->labidx; + k = 3 * ((soap->lablen - soap->labidx) / 3); + soap->labidx = 3 * (soap->lablen / 3); + if (!s) + return NULL; + for (i = 0; i < k; i += 3) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)(soap->lablen - k + i); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + i *= 3; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_strdup(struct soap *soap, const char *s) +{ char *t = NULL; + if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1))) + strcpy(t, s); + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_new_block(struct soap *soap) +{ struct soap_blist *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist)); + if (!(p = (struct soap_blist*)SOAP_MALLOC(sizeof(struct soap_blist)))) + return SOAP_EOM; + p->next = soap->blist; + p->ptr = NULL; + p->size = 0; + soap->blist = p; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_push_block(struct soap *soap, size_t n) +{ char *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)soap->blist->size + (unsigned int)n)); + if (!(p = (char*)SOAP_MALLOC(n + sizeof(char*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + *(char**)p = soap->blist->ptr; + *(size_t*)(p + sizeof(char*)) = n; + soap->blist->ptr = p; + soap->blist->size += n; + return p + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_block(struct soap *soap) +{ char *p; + if (!soap->blist->ptr) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n")); + p = soap->blist->ptr; + soap->blist->size -= *(size_t*)(p + sizeof(char*)); + soap->blist->ptr = *(char**)p; + SOAP_FREE(p); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_update_ptrs(struct soap *soap, char *start, char *end, long offset) +{ int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + register void *p, **q; + for (i = 0; i < SOAP_IDHASH; i++) + for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + offset)); + ip->ptr = (char*)ip->ptr + offset; + } + for (q = &ip->link; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p)); + *q = (char*)p + offset; + } + } + for (q = &ip->copy; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p)); + *q = (char*)p + offset; + } + } + for (fp = ip->flist; fp; fp = fp->next) + { if ((char*)fp->ptr >= start && (char*)fp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp)); + fp->ptr = (char*)fp->ptr + offset; + } + } + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static int +soap_has_copies(struct soap *soap, register const char *start, register const char *end) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + register const char *p; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { for (p = (const char*)ip->copy; p; p = *(const char**)p) + if (p >= start && p < end) + return SOAP_ERR; + for (fp = ip->flist; fp; fp = fp->next) + if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_resolve(struct soap *soap) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + short flag; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr) + { register void *p, **q, *r; + q = (void**)ip->link; + ip->link = NULL; + r = ip->ptr; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id)); + while (q) + { p = *q; + *q = r; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r)); + q = (void**)p; + } + } + else if (*ip->id == '#') + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id)); + strcpy(soap->id, ip->id + 1); + return soap->error = SOAP_MISSING_ID; + } + } + } + do + { flag = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size)) + { if (ip->copy) + { register void *p, **q = (void**)ip->copy; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id)); + ip->copy = NULL; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size)); + p = *q; + memcpy(q, ip->ptr, ip->size); + q = (void**)p; + } while (q); + flag = 1; + } + for (fp = ip->flist; fp; fp = ip->flist) + { register unsigned int k = fp->level; + register void *p = ip->ptr; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); + while (ip->level < k) + { register void **q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return soap->error; + *q = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q)); + p = (void*)q; + k--; + } + if (fp->fcopy) + fp->fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size); + else + soap_fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size); + ip->flist = fp->next; + SOAP_FREE(fp); + flag = 1; + } + } + } + } + } while (flag); +#ifdef SOAP_DEBUG + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->copy || ip->flist) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->id)); + } + } + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n")); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_size_block(struct soap *soap, size_t n) +{ if (soap->blist->ptr) + { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n; + *(size_t*)(soap->blist->ptr + sizeof(char*)) = n; + } + return soap->blist->size; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_first_block(struct soap *soap) +{ char *p, *q, *r; + p = soap->blist->ptr; + if (!p) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n")); + r = NULL; + do + { q = *(char**)p; + *(char**)p = r; + r = p; + p = q; + } while (p); + soap->blist->ptr = r; + return r + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_next_block(struct soap *soap) +{ char *p; + p = soap->blist->ptr; + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n")); + soap->blist->ptr = *(char**)p; + SOAP_FREE(p); + if (soap->blist->ptr) + return soap->blist->ptr + sizeof(char*) + sizeof(size_t); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_block_size(struct soap *soap) +{ return *(size_t*)(soap->blist->ptr + sizeof(char*)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end_block(struct soap *soap) +{ struct soap_blist *bp; + char *p, *q; + bp = soap->blist; + if (bp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n")); + for (p = bp->ptr; p; p = q) + { q = *(char**)p; + SOAP_FREE(p); + } + soap->blist = bp->next; + SOAP_FREE(bp); + } + DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n")); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_save_block(struct soap *soap, char *p, int flag) +{ register size_t n; + register char *q, *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)soap->blist->size, soap->blist->ptr, p)); + if (soap->blist->size) + { if (!p) + p = (char*)soap_malloc(soap, soap->blist->size); + if (p) + { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap)) + { n = soap_block_size(soap); +#ifndef WITH_NOIDREF + if (flag) + soap_update_ptrs(soap, q, q + n, (long)s - (long)q); /* pointers s and q may or may not be related */ +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s)); + memcpy(s, q, n); + s += n; + } + } + else + soap->error = SOAP_EOM; + } + soap_end_block(soap); + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsize(struct soap *soap, const char *type, int size) +{ return soap_putsizes(soap, type, &size, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizes(struct soap *soap, const char *type, const int *size, int dim) +{ return soap_putsizesoffsets(soap, type, size, NULL, dim); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim) +{ int i; + if (!type) + return NULL; + if (soap->version == 2) + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), " %d", size[i]); + } + else + { if (offset) + { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]); + } + else + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i]); + } + strcat(soap->type, "]"); + } + return soap->type; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffset(struct soap *soap, int offset) +{ return soap_putoffsets(soap, &offset, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffsets(struct soap *soap, const int *offset, int dim) +{ register int i; + sprintf(soap->arrayOffset, "[%d", offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]); + strcat(soap->arrayOffset, "]"); + return soap->arrayOffset; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_size(const int *size, int dim) +{ register int i, n = size[0]; + for (i = 1; i < dim; i++) + n *= size[i]; + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getoffsets(const char *attr, const int *size, int *offset, int dim) +{ register int i, j = 0; + if (offset) + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += offset[i] = (int)atol(attr); + attr = strchr(attr, ','); + } + else + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += (int)atol(attr); + attr = strchr(attr, ','); + } + return j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsize(const char *attr1, const char *attr2, int *j) +{ register int n, k; + char *s; + *j = 0; + if (!*attr1) + return -1; + n = 1; + do + { attr1++; + k = (int)soap_strtol(attr1, &s, 10); + n *= k; + if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1) + return -1; + attr1 = strchr(s, ','); + if (!attr1) + attr1 = strchr(s, ' '); + if (attr2 && *attr2) + { attr2++; + *j *= k; + k = (int)soap_strtol(attr2, &s, 10); + *j += k; + if (k < 0) + return -1; + attr2 = s; + } + } while (attr1 && *attr1 != ']'); + return n - *j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsizes(const char *attr, int *size, int dim) +{ register int i, k, n; + if (!*attr) + return -1; + i = strlen(attr); + n = 1; + do + { for (i = i-1; i >= 0; i--) + if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ') + break; + k = (int)atol(attr + i + 1); + n *= size[--dim] = k; + if (k < 0 || n > SOAP_MAXARRAYSIZE) + return -1; + } while (i >= 0 && attr[i] != '['); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getposition(const char *attr, int *pos) +{ register int i, n; + if (!*attr) + return -1; + n = 0; + i = 1; + do + { pos[n++] = (int)atol(attr + i); + while (attr[i] && attr[i] != ',' && attr[i] != ']') + i++; + if (attr[i] == ',') + i++; + } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']'); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_push_namespace(struct soap *soap, const char *id, const char *ns) +{ register struct soap_nlist *np; + register struct Namespace *p; + np = (struct soap_nlist*)SOAP_MALLOC(sizeof(struct soap_nlist) + strlen(id)); + if (!np) + return soap->error = SOAP_EOM; + np->next = soap->nlist; + soap->nlist = np; + strcpy(np->id, id); + np->level = soap->level; + np->index = -1; + np->ns = NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns)); + p = soap->local_namespaces; + if (p) + { register short i = 0; + for (; p->id; p++, i++) + { if (p->ns && !strcmp(ns, p->ns)) + { if (p->out) + { SOAP_FREE(p->out); + p->out = NULL; + } + break; + } + if (p->out) + { if (!SOAP_STRCMP(ns, p->out)) + break; + } + else if (p->in) + { if (!soap_tag_cmp(ns, p->in)) + { if ((p->out = (char*)SOAP_MALLOC(strlen(ns) + 1))) + strcpy(p->out, ns); + break; + } + } + } + if (p && p->id) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id)); + np->index = i; + } + } + if (!p || !p->id) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns)); + np->ns = (char*)SOAP_MALLOC(strlen(ns) + 1); + if (!np->ns) + return soap->error = SOAP_EOM; + strcpy(np->ns, ns); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_namespace(struct soap *soap) +{ register struct soap_nlist *np; + while (soap->nlist && soap->nlist->level >= soap->level) + { np = soap->nlist->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id)); + if (soap->nlist->ns) + SOAP_FREE(soap->nlist->ns); + SOAP_FREE(soap->nlist); + soap->nlist = np; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2) +{ register struct soap_nlist *np = soap->nlist; + while (np && (strncmp(np->id, id1, n1) || np->id[n1])) + np = np->next; + if (np) + { if (np->index < 0 || (np->index >= 0 && soap->local_namespaces[np->index].id && (strncmp(soap->local_namespaces[np->index].id, id2, n2) || soap->local_namespaces[np->index].id[n2]))) + return SOAP_NAMESPACE; + return SOAP_OK; + } + if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2)) + return SOAP_OK; + return SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_tag_cmp(const char *s, const char *t) +{ for (;;) + { register int c1 = *s; + register int c2 = *t; + if (!c1 || c1 == '"') + break; + if (c2 != '-') + { if (c1 != c2) + { if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + } + if (c1 != c2) + { if (c2 != '*') + return 1; + c2 = *++t; + if (!c2) + return 0; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + for (;;) + { c1 = *s; + if (!c1 || c1 == '"') + break; + if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c1 == c2) + if (!soap_tag_cmp(s + 1, t + 1)) + return 0; + s++; + } + break; + } + } + s++; + t++; + } + if (*t == '*' && !t[1]) + return 0; + return *t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_tag(struct soap *soap, const char *tag1, const char *tag2) +{ register const char *s, *t; + if (!tag1 || !tag2 || !*tag2) + return SOAP_OK; + s = strchr(tag1, ':'); + t = strchr(tag2, ':'); + if (t) + { if (s) + { if (t[1] && SOAP_STRCMP(s + 1, t + 1)) + return SOAP_TAG_MISMATCH; + if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + } + else if (SOAP_STRCMP(tag1, t + 1)) + return SOAP_TAG_MISMATCH; + else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; + } + if (s) + { if (SOAP_STRCMP(s + 1, tag2)) + return SOAP_TAG_MISMATCH; + } + else if (SOAP_STRCMP(tag1, tag2)) + return SOAP_TAG_MISMATCH; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_array(struct soap *soap, const char *type) +{ if (*soap->arrayType) + if (soap_match_tag(soap, soap->arrayType, type) + && soap_match_tag(soap, soap->arrayType, "xsd:anyType") + && soap_match_tag(soap, soap->arrayType, "xsd:ur-type") + ) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type)); + return SOAP_TAG_MISMATCH; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ + +#ifdef WITH_OPENSSL +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_server_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *dhfile, const char *randfile, const char *sid) +{ int err; + soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + if (dhfile) + { soap->dhfile = dhfile; + soap->rsa = 0; + } + else + { soap->dhfile = NULL; + soap->rsa = 1; + } + soap->randfile = randfile; + soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION); + if (!(err = soap->fsslauth(soap))) + if (sid) + SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid)); + return err; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile) +{ soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->dhfile = NULL; + soap->rsa = 0; + soap->randfile = randfile; + soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION); + return soap->fsslauth(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static void +ssl_init() +{ static int done = 0; + if (!done) + { done = 1; + SSL_library_init(); +#ifndef WITH_LEAN + SSL_load_error_strings(); +#endif + if (!RAND_load_file("/dev/urandom", 1024)) + { int r; +#ifdef HAVE_RAND_R + unsigned int s = (unsigned int)time(NULL); +#endif + char buf[SOAP_BUFLEN]; + RAND_seed(buf, sizeof(buf)); + while (!RAND_status()) + { +#ifdef HAVE_RAND_R + r = rand_r(&s); +#else + r = rand(); +#endif + RAND_seed(&r, sizeof(int)); + } + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static const char * +ssl_error(struct soap *soap, int ret) +{ int err = SSL_get_error(soap->ssl, ret); + const char *msg = soap_str_code(h_ssl_error_codes, err); + if (msg) + strcpy(soap->msgbuf, msg); + else + return ERR_error_string(err, soap->msgbuf); + if (ERR_peek_error()) + { unsigned long r; + strcat(soap->msgbuf, "\n"); + while ((r = ERR_get_error())) + ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf)); + } + else + { switch (ret) + { case 0: + strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information."); + break; + case -1: + sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno)); + break; + } + } + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_password(char *buf, int num, int rwflag, void *userdata) +{ if (num < (int)strlen((char*)userdata) + 1) + return 0; + return strlen(strcpy(buf, (char*)userdata)); +} +#endif + +/******************************************************************************/ +/* This callback is included for future references. It should not be deleted +#ifndef PALM_2 +static DH * +ssl_tmp_dh(SSL *ssl, int is_export, int keylength) +{ static DH *dh512 = NULL; + static DH *dh1024 = NULL; + DH *dh; + switch (keylength) + { case 512: + if (!dh512) + { BIO *bio = BIO_new_file("dh512.pem", "r"); + if (bio) + { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + return dh512; + } + } + else + return dh512; + default: + if (!dh1024) + { BIO *bio = BIO_new_file("dh1024.pem", "r"); + if (bio) + { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } + dh = dh1024; + } + return dh; +} +#endif +*/ +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_auth_init(struct soap *soap) +{ ssl_init(); + if (!soap->ctx) + if (!(soap->ctx = SSL_CTX_new(SSLv23_method()))) + return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR); + if (soap->randfile) + { if (!RAND_load_file(soap->randfile, -1)) + return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR); + } + if (soap->cafile || soap->capath) + if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath)) + return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and/or directory", SOAP_SSL_ERROR); + if (!SSL_CTX_set_default_verify_paths(soap->ctx)) + return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR); + if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR); + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); + } + } + if (soap->rsa) + { RSA *rsa = RSA_generate_key(512, RSA_F4, NULL, NULL); + if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa)) + { if (rsa) + RSA_free(rsa); + return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR); + } + RSA_free(rsa); + } + else if (soap->dhfile) + { DH *dh = 0; + BIO *bio; + bio = BIO_new_file(soap->dhfile, "r"); + if (!bio) + return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR); + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0) + { if (dh) + DH_free(dh); + return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR); + } + DH_free(dh); + } + SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); + SSL_CTX_set_verify(soap->ctx, soap->require_client_auth ? (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : soap->require_server_auth ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, soap->fsslverify); +#if (OPENSSL_VERSION_NUMBER < 0x00905100L) + SSL_CTX_set_verify_depth(soap->ctx, 1); +#else + SSL_CTX_set_verify_depth(soap->ctx, 9); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_verify_callback(int ok, X509_STORE_CTX *store) +{ +#ifdef SOAP_DEBUG + if (!ok) + { char data[256]; + X509 *cert = X509_STORE_CTX_get_current_cert(store); + fprintf(stderr, "SSL Verify error with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); + X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate issuer %s\n", data); + X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate subject %s\n", data); + } +#endif + /* return 1 to always continue, but unsafe progress will be terminated by SSL */ + return ok; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_accept(struct soap *soap) +{ int i, r; + if (!soap_valid_socket(soap->socket)) + return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR); + if (!soap->ssl) + { soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + } + else + SSL_clear(soap->ssl); + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; +#ifdef WIN32 + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK); +#endif + soap->bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, soap->bio, soap->bio); + i = 100; /* 100 * 0.1 ms retries */ + while ((r = SSL_accept(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { struct timeval timeout; + fd_set fd; + if (i-- <= 0) + break; + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r < 0 && soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + } + else + { soap->errnum = err; + break; + } + } +#ifdef WIN32 + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + if (r <= 0) + { soap_set_receiver_error(soap, ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + soap_closesock(soap); + return SOAP_SSL_ERROR; + } + if (soap->require_client_auth) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_closesock(soap); + return soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in soap_ssl_accept()", SOAP_SSL_ERROR); + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_closesock(soap); + return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR); + } + X509_free(peer); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#endif /* WITH_OPENSSL */ + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_init(struct soap *soap) +{ soap->errmode = 1; +#ifdef WIN32 + if (tcp_done) + return 0; + else + { WSADATA w; + if (WSAStartup(MAKEWORD(1, 1), &w)) + return -1; + tcp_done = 1; + } +#endif + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_done(struct soap *soap) +{ +#ifdef SOAP_DEBUG + int i; +#endif + soap_free(soap); + while (soap->clist) + { struct soap_clist *p = soap->clist->next; + SOAP_FREE(soap->clist); + soap->clist = p; + } + soap->keep_alive = 0; /* to force close the socket */ + soap_closesock(soap); +#ifdef WITH_COOKIES + soap_free_cookies(soap); +#endif + while (soap->plugins) + { register struct soap_plugin *p = soap->plugins->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id)); + if (soap->plugins->fcopy || !soap->copy) + soap->plugins->fdelete(soap, soap->plugins); + SOAP_FREE(soap->plugins); + soap->plugins = p; + } + soap->fplugin = fplugin; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; +#endif + soap->fignore = NULL; + soap->fserveloop = NULL; +#ifdef WITH_OPENSSL + if (soap->session) + { SSL_SESSION_free(soap->session); + soap->session = NULL; + } +#endif + if (!soap->copy) + { if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } +#ifdef WITH_OPENSSL + if (soap->ctx) + { SSL_CTX_free(soap->ctx); + soap->ctx = NULL; + } +#endif + } +#ifdef SOAP_DEBUG + for (i = 0; i < SOAP_MAXLOGS; i++) + { soap_close_logfile(soap, i); + if (soap->logfile[i]) + { SOAP_FREE((void*)soap->logfile[i]); + soap->logfile[i] = NULL; + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_cleanup(struct soap *soap) +{ soap_done(soap); +#ifdef WIN32 + if (!tcp_done) + return; + tcp_done = 0; + WSACleanup(); +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +tcp_error(struct soap *soap) +{ register const char *msg = NULL; + switch (soap->errmode) + { case 0: + msg = soap_strerror(soap); + break; + case 1: + msg = "WSAStartup failed"; + break; + case 2: + { +#ifndef WITH_LEAN + msg = soap_str_code(h_error_codes, soap->errnum); + if (!msg) +#endif + { sprintf(soap->msgbuf, "TCP error %d", soap->errnum); + msg = soap->msgbuf; + } + } + } + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static const char* +http_error(struct soap *soap, int status) +{ register const char *msg = SOAP_STR_EOS; +#ifndef WITH_LEAN + msg = soap_str_code(h_http_error_codes, status); + if (!msg) + msg = SOAP_STR_EOS; +#endif + return msg; +} +#endif +#endif + +/******************************************************************************/ +/* WR[ */ +#ifndef WITH_IPV6 +/* ]WR */ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr) +{ unsigned long iadd; + struct hostent hostent, *host = &hostent; +/* WR[ */ +#ifdef VXWORKS + int hostint; + char *addrcopy = (char*)malloc(strlen(addr) + 1); /*copy of addr. */ + /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */ + strncpy(addrcopy, addr, strlen(addr)+1); + iadd = inet_addr(addrcopy); +#else +/* ]WR */ +#if defined(_AIXVERSION_431) || defined(TRU64) + struct hostent_data ht_data; +#endif + iadd = inet_addr(addr); +/* WR[ */ +#endif +/* ]WR */ + if ((int)iadd != -1) + { memcpy(inaddr, &iadd, sizeof(iadd)); +/* WR[ */ +#ifdef VXWORKS + free(addrcopy); +#endif +/* ]WR */ + return SOAP_OK; + } +#if defined(__GLIBC__) + if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0) + host = NULL; +#elif defined(_AIXVERSION_431) || defined(TRU64) + memset((void*)&ht_data, 0, sizeof(ht_data)); + if (gethostbyname_r(addr, &hostent, &ht_data) < 0) + { host = NULL; + soap->errnum = h_errno; + } +#elif defined(HAVE_GETHOSTBYNAME_R) + host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum); +/* WR[ */ +#elif defined(VXWORKS) + /* If the DNS resolver library resolvLib has been configured in the vxWorks + * image, a query for the host IP address is sent to the DNS server, if the + * name was not found in the local host table. */ + hostint = hostGetByName(addrcopy); + if (hostint == ERROR) + { host = NULL; + soap->errnum = soap_errno; + } + free(addrcopy); /*free() is placed after the error checking to assure that + * errno captured is that from hostGetByName() */ +/* ]WR */ +#else + if (!(host = gethostbyname(addr))) + soap->errnum = h_errno; +#endif + if (!host) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n")); + return SOAP_ERR; + } +/* WR[ */ +#ifdef VXWORKS + inaddr->s_addr = hostint; +#else +/* ]WR */ + memcpy(inaddr, host->h_addr, host->h_length); +/* WR[ */ +#endif +/* ]WR */ + return SOAP_OK; +} +#endif +#endif +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) +{ struct sockaddr_in sockaddr; +/* WR[ */ +#ifdef WITH_IPV6 + struct addrinfo *addrinfo; + struct addrinfo hints; + struct addrinfo resaddr; + struct sockaddr_storage addrstorage; + int err; +#endif /* WITH_IPV6 */ +/* ]WR */ + register int fd; +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->socket)) + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + if (tcp_init(soap)) + { soap_set_sender_error(soap, tcp_error(soap), "TCP initialization failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->errmode = 0; +/* WR[ */ +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + soap->errmode = 2; + if (soap->proxy_host) + err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &addrinfo); + else + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo); + if (addrinfo) + { resaddr = *addrinfo; + addrstorage = *((struct sockaddr_storage*)addrinfo->ai_addr); + resaddr.ai_addr = (struct sockaddr*)&addrstorage; + freeaddrinfo(addrinfo); + } + if (err) + { soap_set_sender_error(soap, gai_strerror(err), "TCP getaddrinfo on proxy host failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + fd = (int)socket(resaddr.ai_family, resaddr.ai_socktype, resaddr.ai_protocol); /* modified to use fd */ + soap->errmode = 0; +#else /* WITH_IPV6 */ +/* ]WR */ + fd = (int)socket(AF_INET, SOCK_STREAM, 0); +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ + if (fd < 0) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP socket failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl (fd, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->connect_flags & SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + if ((soap->connect_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags & ~SO_LINGER, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#endif +#endif +/* WR[ */ +#ifndef WITH_IPV6 +/* ]WR */ + memset((void*)&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Open socket %d to host='%s'\n", fd, host)); + soap->errmode = 2; + if (soap->proxy_host) + { if (soap->fresolve(soap, soap->proxy_host, &sockaddr.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "TCP get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + sockaddr.sin_port = htons((short)soap->proxy_port); + } + else + { if (soap->fresolve(soap, host, &sockaddr.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "TCP get host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + sockaddr.sin_port = htons((short)port); + } + soap->errmode = 0; +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +/* WR[ */ +#elif defined(VXWORKS) + { vx_nonblocking = TRUE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +/* ]WR */ +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +/* WR[ */ +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +/* ]WR */ +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + for (;;) + { +/* WR[ */ +#ifdef WITH_IPV6 + if (connect((SOAP_SOCKET)fd, resaddr.ai_addr, resaddr.ai_addrlen)) /* modified to use fd */ +#else /* WITH_IPV6 */ + if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr))) +#endif /* WITH_IPV6 */ +/* ]WR */ + { +#ifndef WITH_LEAN + if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS || soap_socket_errno == SOAP_EWOULDBLOCK)) + { struct timeval timeout; +#if defined(SOCKLEN_T) + SOCKLEN_T n = sizeof(struct sockaddr_in); +#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) + socklen_t n = sizeof(struct sockaddr_in); +#elif defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) + int n = sizeof(struct sockaddr_in); +#else + size_t n = sizeof(struct sockaddr_in); +#endif + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)fd, &fds); + for (;;) + { int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + n = sizeof(soap->errnum); + if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &n) && !soap->errnum) + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + else +#endif + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + else + break; + } +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +/* WR[ */ +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +/* ]WR */ +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = fd; +#ifdef WITH_OPENSSL + soap->imode &= ~SOAP_ENC_SSL; + soap->omode &= ~SOAP_ENC_SSL; + if (!strncmp(endpoint, "https:", 6)) + { int r; + if (soap->proxy_host) + { unsigned int k = soap->omode; /* make sure we only parse HTTP */ + size_t n = soap->count; /* save the content length */ + soap->omode &= ~SOAP_ENC; /* mask IO and ENC */ + soap->omode |= SOAP_IO_BUFFER; + soap_begin_send(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to proxy server\n")); + sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->http_version); + if ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return SOAP_INVALID_SOCKET; +#ifndef WITH_LEAN + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return soap->error; + } +#endif + if ((soap->error = soap->fposthdr(soap, NULL, NULL)) + || soap_flush(soap)) + return SOAP_INVALID_SOCKET; + soap->omode = k; + k = soap->imode; + soap->imode &= ~SOAP_ENC; /* mask IO and ENC */ + if (soap_begin_recv(soap)) + return SOAP_INVALID_SOCKET; + soap->imode = k; + soap->count = n; + soap_begin_send(soap); + } + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + { soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; + } + if (soap->session) + { if (!strcmp(soap->session_host, host) && soap->session_port == port) + SSL_set_session(soap->ssl, soap->session); + SSL_SESSION_free(soap->session); + soap->session = NULL; + } + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; + soap->bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, soap->bio, soap->bio); +#ifndef WITH_LEAN + if (soap->connect_timeout) +#ifdef WIN32 + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif +#endif + for (;;) + { if ((r = SSL_connect(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + { soap_set_sender_error(soap, ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap->connect_timeout) + { struct timeval timeout; + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)(soap->socket), &fds); + for (;;) + { int r = select((SOAP_SOCKET)(soap->socket + 1), &fds, NULL, &fds, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + continue; + } + } + break; + } +#ifndef WITH_LEAN + if (soap->connect_timeout) +#ifdef WIN32 + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + if (soap->require_server_auth) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, soap->msgbuf, sizeof(soap->msgbuf)); + X509_free(peer); + if (soap_tag_cmp(soap->msgbuf, host)) + { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + } + } +#endif + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_bind(struct soap *soap, const char *host, int port, int backlog) +{ struct sockaddr_in sockaddr; +/* WR[ */ +#ifdef WITH_IPV6 + struct addrinfo *addrinfo; + struct addrinfo hints; + struct addrinfo resaddr; + struct sockaddr_storage addrstorage; + int err; +#endif /* WITH_IPV6 */ +/* ]WR */ +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 1; + if (tcp_init(soap)) + { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +/* WR[ */ +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + soap->errmode = 2; + if (host) + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo); + else + err = getaddrinfo(NULL, soap_int2s(soap, port), &hints, &addrinfo); + if (NULL != addrinfo) + { + resaddr = *addrinfo; + addrstorage = *((struct sockaddr_storage *) addrinfo->ai_addr); + resaddr.ai_addr = (struct sockaddr *) &addrstorage; + freeaddrinfo(addrinfo); + } + if (err) + { soap_set_receiver_error(soap, gai_strerror(err), "TCP getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->errmode = 0; + if ((soap->master = socket(resaddr.ai_family, resaddr.ai_socktype, resaddr.ai_protocol)) < 0) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP socket failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#else /* WITH_IPV6 */ +/* ]WR */ + soap->errmode = 0; + if ((soap->master = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP socket failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl (soap->master, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap->keep_alive && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#endif +/* WR[ */ +#ifdef WITH_IPV6 + soap->errmode = 0; + if (bind(soap->master, resaddr.ai_addr, resaddr.ai_addrlen) || listen(soap->master, backlog)) + { + soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "TCP bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#else /* WITH_IPV6 */ +/* ]WR */ + memset((void*)&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + soap->errmode = 2; + if (host) + { if (soap->fresolve(soap, host, &sockaddr.sin_addr)) + { soap_set_receiver_error(soap, tcp_error(soap), "TCP get host by name failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + else + sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); + sockaddr.sin_port = htons((short)port); + soap->errmode = 0; + if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) || listen((SOAP_SOCKET)soap->master, backlog)) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "TCP bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ +#ifdef WITH_OPENSSL + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + return SOAP_INVALID_SOCKET; +#endif + return soap->master; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_poll(struct soap *soap) +{ +#ifndef WITH_LEAN + struct timeval timeout; + fd_set sfd, rfd, xfd; + int r; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&rfd); + FD_ZERO(&sfd); + FD_ZERO(&xfd); + if (soap_valid_socket(soap->socket)) + { FD_SET(soap->socket, &rfd); + FD_SET(soap->socket, &sfd); + FD_SET(soap->socket, &xfd); + r = select(soap->socket + 1, &rfd, &sfd, &xfd, &timeout); + if (r > 0 && FD_ISSET(soap->socket, &xfd)) + r = -1; + } + else if (soap_valid_socket(soap->master)) + { FD_SET(soap->master, &rfd); + r = select(soap->master + 1, &rfd, &sfd, NULL, &timeout); + } + else + return SOAP_OK; + if (r > 0) + { +#ifdef WITH_OPENSSL + if (soap->ssl) + { if (soap_valid_socket(soap->socket) && FD_ISSET(soap->socket, &rfd)) + { char buf = '\0'; + if (SSL_peek(soap->ssl, &buf, 1) <= 0) + return SOAP_EOF; + } + } +#endif + if (soap_valid_socket(soap->socket) && FD_ISSET(soap->socket, &rfd)) + return SOAP_EOF; + return SOAP_OK; + } + if (r < 0 && (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR); + return soap->error = SOAP_TCP_ERROR; + } + else + soap->errnum = soap_errno; + return SOAP_EOF; +#else + return SOAP_OK; +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n) +{ int fd; +#if defined(SOCKLEN_T) + fd = (int)accept((SOAP_SOCKET)s, a, (SOCKLEN_T*)n); +#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) + fd = (int)accept((SOAP_SOCKET)s, a, (socklen_t*)n); +#elif defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) + fd = (int)accept((SOAP_SOCKET)s, a, n); +#else + fd = (int)accept((SOAP_SOCKET)s, a, (size_t*)n); +#endif +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif +#endif + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_accept(struct soap *soap) +{ +/* WR[ */ +#ifdef WITH_IPV6 + struct sockaddr_storage sockaddr; +#else /* WITH_IPV6 */ +/* ]WR */ + struct sockaddr_in sockaddr; +/* WR[ */ +#endif +/* ]WR */ + int n = (int)sizeof(sockaddr); +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + soap->error = SOAP_OK; + memset((void*)&sockaddr, 0, sizeof(sockaddr)); + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 0; + if (soap_valid_socket(soap->master)) + { for (;;) + { +#ifndef WITH_LEAN + if (soap->accept_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->accept_timeout > 0) + { timeout.tv_sec = soap->accept_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->accept_timeout/1000000; + timeout.tv_usec = -soap->accept_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->master, &fd); + for (;;) + { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + soap_set_receiver_error(soap, "Timeout", "TCP accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + soap_closesock(soap); + soap_set_sender_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = TRUE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + } +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK); +#endif + } + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + } +/* WR[ */ +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + } +/* ]WR */ +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&sockaddr, &n); + if (soap_valid_socket(soap->socket)) + { +/* WR[ */ +#ifdef WITH_IPV6 +/* Use soap->host to store the numeric form of the remote host */ + getnameinfo((struct sockaddr*)&sockaddr, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host)); + soap->ip = 0; /* info stored in soap->host */ + soap->port = 0; /* info stored in soap->host */ +#else /* WITH_IPV6 */ +/* ]WR */ + soap->ip = ntohl(sockaddr.sin_addr.s_addr); + soap->port = (int)ntohs(sockaddr.sin_port); /* does not return port number on some systems */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF)); +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ + soap->keep_alive = ((soap->imode & SOAP_IO_KEEPALIVE) != 0); +#ifndef WITH_LEAN + if (soap->accept_flags & SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + if ((soap->accept_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags & ~SO_LINGER, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap->keep_alive && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + if (soap->accept_timeout) + { +#if defined(WIN32) + u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); +/* WR[ */ +#elif defined(VXWORKS) + vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&vx_nonblocking)); +/* ]WR */ +#elif defined(PALM) + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK); +#elif defined(SYMBIAN) + long blocking = 0; + ioctl((SOAP_SOCKET)soap->master, 0/*FIONBIO*/, &blocking); +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + } + return soap->socket; + } + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host)); + soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + } + else + { soap_set_receiver_error(soap, tcp_error(soap), "TCP no master socket in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_disconnect(struct soap *soap) +{ +#ifdef WITH_OPENSSL + if (soap->ssl) + { int r, s = 0; + if (soap->session) + SSL_SESSION_free(soap->session); + if (*soap->host) + { soap->session = SSL_get1_session(soap->ssl); + if (soap->session) + { strcpy(soap->session_host, soap->host); + soap->session_port = soap->port; + } + } + r = SSL_shutdown(soap->ssl); + if (r != 1) + { s = ERR_get_error(); + if (s) + { if (soap_valid_socket(soap->socket)) + { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); + soap->socket = SOAP_INVALID_SOCKET; + } + r = SSL_shutdown(soap->ssl); + } + } + DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r))); + SSL_free(soap->ssl); + soap->ssl = NULL; + if (s) + return SOAP_SSL_ERROR; + ERR_remove_state(0); + } +#endif + if (soap_valid_socket(soap->socket)) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Closing socket %d\n", soap->socket)); + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2); + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_closesocket(struct soap *soap, SOAP_SOCKET fd) +{ return closesocket(fd); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how) +{ return shutdown(fd, how); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_closesock(struct soap *soap) +{ register int status = soap->error; + if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive) + { if (soap->fclose && (soap->error = soap->fclose(soap))) + return soap->error; + soap->socket = SOAP_INVALID_SOCKET; + soap->keep_alive = 0; + } +#ifdef WITH_ZLIB + if (soap->zlib_state == SOAP_ZLIB_DEFLATE) + deflateEnd(&soap->d_stream); + else if (soap->zlib_state == SOAP_ZLIB_INFLATE) + inflateEnd(&soap->d_stream); + soap->zlib_state = SOAP_ZLIB_NONE; +#endif + return soap->error = status; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_hash(register const char *s) +{ register size_t h = 0; + while (*s) + h = 65599*h + *s++; + return h % SOAP_IDHASH; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_pht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n")); + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new1(soap_mode mode) +{ return soap_new2(mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new() +{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new2(soap_mode imode, soap_mode omode) +{ struct soap *soap = (struct soap*)SOAP_MALLOC(sizeof(struct soap)); + if (soap) + soap_init2(soap, imode, omode); + return soap; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_pht(struct soap *soap) +{ register struct soap_plist *pp, *next; + register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n")); + for (i = 0; i < (int)SOAP_PTRHASH; i++) + { for (pp = soap->pht[i]; pp; pp = next) + { next = pp->next; + SOAP_FREE(pp); + } + soap->pht[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type) +{ register int i; + struct soap_plist *pp; + if (soap->version != 1) + soap->encoding = 1; + if (a) + i = soap_array_pointer_lookup(soap, p, a, n, type, &pp); + else + i = soap_pointer_lookup(soap, p, type, &pp); + if (i) + { if (soap_is_embedded(soap, pp) + || soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + return i; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (p) + for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next) + if (pp->ptr == p && pp->type == type) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id)); + return pp->id; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register int h; + register struct soap_plist *pp = *ppp = (struct soap_plist*)SOAP_MALLOC(sizeof(struct soap_plist)); + if (!pp) + return 0; + if (a) + h = soap_hash_ptr(a->__ptr); + else + h = soap_hash_ptr(p); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%lu\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1)); + pp->next = soap->pht[h]; + pp->type = type; + pp->mark1 = 0; + pp->mark2 = 0; + pp->ptr = p; + pp->array = a; + soap->pht[h] = pp; + pp->id = ++soap->idnum; + return pp->id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (!p || !a->__ptr) + return 0; + for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next) + { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr) + { register int i; + for (i = 0; i < n; i++) + if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i]) + break; + if (i == n) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_begin_count(struct soap *soap) +{ soap_clr_attr(soap); + soap_set_local_namespaces(soap); +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME)) + soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME; + else +#endif + { soap->mode = soap->omode; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE + || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML)) +#ifndef WITH_LEANER + && !soap->fpreparesend +#endif + )) + soap->mode &= ~SOAP_IO_LENGTH; + else + soap->mode |= SOAP_IO_LENGTH; + } +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (!(soap->mode & SOAP_ENC_DIME)) + soap->mode &= ~SOAP_IO_LENGTH; + if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } + +#endif + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); + soap->dime.list = soap->dime.last; /* keep track of last DIME attachment */ +#endif + soap->count = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->part = SOAP_BEGIN; + soap->idnum = 0; +#ifndef WITH_LEANER + soap->dime.count = 0; /* count # of attachments */ + soap->dime.size = 0; /* accumulate total size of attachments */ + if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + soap->fprepareinit(soap); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_send(struct soap *soap) +{ soap->error = SOAP_OK; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); + soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME)); +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket)) + { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML)) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } + soap->mode &= ~SOAP_IO_LENGTH; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap_new_block(soap); + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */ +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->sendfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY); +#endif +#endif +#endif +#endif +#endif + if (soap->mode & SOAP_IO) + { soap->bufidx = 0; + soap->buflen = 0; + } + soap->chunksize = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->part = SOAP_BEGIN; + soap->idnum = 0; + soap->level = 0; +#ifdef WITH_ZLIB + soap->z_ratio_out = 1.0; + if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE) + { +#ifdef WITH_GZIP + memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10); + soap->d_stream.next_out = (Byte*)soap->z_buf + 10; + soap->d_stream.avail_out = SOAP_BUFLEN - 10; + soap->z_crc = crc32(0L, NULL, 0); + if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) +#else + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK) +#endif + return soap->error = SOAP_ZLIB_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n")); + soap->zlib_state = SOAP_ZLIB_DEFLATE; + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); +#ifndef WITH_LEANER + if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap->fprepareinit(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_embedded(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (soap_pointer_lookup(soap, p, t, &pp)) + { pp->mark1 = 1; + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t)); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_reference(struct soap *soap, const void *p, int t) +{ + struct soap_plist *pp; + if (!p || (soap->mode & SOAP_XML_TREE)) + return 1; + if (soap_pointer_lookup(soap, p, t, &pp)) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp)) + { pp->mark1 = 0; + pp->mark2 = 0; + } + else + return 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t) +{ register int i; + struct soap_plist *pp; + if (!p) + return 1; + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (i) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (!soap_pointer_enter(soap, p, a, n, t, &pp)) + return 1; + else + { pp->mark1 = 0; + pp->mark2 = 0; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p dim=%d type=%d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embedded_id(struct soap *soap, int id, const void *p, int t) +{ struct soap_plist *pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id)); + if (soap->mode & SOAP_XML_TREE) + return id; + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (id < 0) + { id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 2; + else + pp->mark2 = 2; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id multiref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return -1; + } + return id; + } + if (id < 0) + id = soap_pointer_lookup(soap, p, t, &pp); + else if (id && !soap_pointer_lookup(soap, p, t, &pp)) + return 0; + if (id && pp) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id embedded ref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 != 0; + return pp->mark2 != 0; + } + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 1; + return pp->mark2 == 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_single(struct soap *soap, struct soap_plist *pp) +{ if (soap->part == SOAP_IN_HEADER) + return 1; + if (!pp) + return 0; + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 0; + return pp->mark2 == 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return; + if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_dime(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t) +{ struct soap_plist *pp; + int i; + if (!p || !a->__ptr || (!aid && !atype)) + return soap_element_id(soap, tag, id, p, a, n, type, t); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:"")); + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (!i) + { i = soap_pointer_enter(soap, p, a, n, t, &pp); + if (!i) + { soap->error = SOAP_EOM; + return -1; + } + } + if (id < 0) + id = i; + if (!aid) + { sprintf(soap->tmpbuf, soap->dime_id_format, id); + aid = soap_strdup(soap, soap->tmpbuf); + } + if (soap_element_href(soap, tag, 0, "href", aid)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (pp->mark1 != 3) + { struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size); + if (!content) + { soap->error = SOAP_EOM; + return -1; + } + content->id = aid; + content->type = atype; + content->options = aoptions; + pp->mark1 = 3; + } + } + else + pp->mark2 = 3; + return -1; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_iht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + soap->iht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_iht(struct soap *soap) +{ register int i; + register struct soap_ilist *ip, *p; + register struct soap_flist *fp, *fq; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = p) + { for (fp = ip->flist; fp; fp = fq) + { fq = fp->next; + SOAP_FREE(fp); + } + p = ip->next; + SOAP_FREE(ip); + } + soap->iht[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +static struct soap_ilist * +soap_hlookup(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next) + if (!strcmp(ip->id, id)) + return ip; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_lookup(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + ip = soap_hlookup(soap, id); +#ifndef WITH_LEANER + if (!ip && *id != '#' && !strchr(id, ':')) /* try content id "cid:" with DIME attachments */ + { char cid[SOAP_TAGLEN]; + strcpy(cid, "cid:"); + strncat(cid + 4, id, sizeof(cid) - 5); + cid[sizeof(cid) - 1] = '\0'; + ip = soap_hlookup(soap, cid); + } +#endif + return ip; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_enter(struct soap *soap, const char *id) +{ register size_t h; + register struct soap_ilist *ip; + ip = (struct soap_ilist*)SOAP_MALLOC(sizeof(struct soap_ilist) + strlen(id)); + if (ip) + { h = soap_hash(id); + strcpy(ip->id, id); + ip->next = soap->iht[h]; + soap->iht[h] = ip; + return ip; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_malloc(struct soap *soap, size_t n) +{ register char *p; + if (!n) + return NULL; + if (!soap) + return SOAP_MALLOC(n); + n += (-(long)n) & 7; + if (!(p = (char*)SOAP_MALLOC(n + sizeof(void*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + /* keep chain of alloced cells for later destruction */ + soap->alloced = 1; + *(void**)(p + n) = soap->alist; + *(size_t*)(p + n + sizeof(void*)) = n; + soap->alist = p + n; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Malloc %u bytes at location %p\n", (unsigned int)n, p)); + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_dealloc(struct soap *soap, void *p) +{ if (!soap) + return; + if (p) + { register char **q; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p)); + SOAP_FREE(p); + return; + } + } + soap_delete(soap, p); + } + else + { register char *q; + while (soap->alist) + { q = (char*)soap->alist; + soap->alist = *(void**)q; + q -= *(size_t*)(q + sizeof(void*)); + SOAP_FREE(q); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Dealloc all data done\n")); + } + /* we must assume these were deallocated: */ + soap->action = NULL; + soap->fault = NULL; + soap->header = NULL; + soap->authrealm = NULL; +#ifndef WITH_LEANER + soap_clr_mime(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_delete(struct soap *soap, void *p) +{ register struct soap_clist **cp = &soap->clist; + if (p) + { while (*cp) + { if (p == (*cp)->ptr) + { register struct soap_clist *q = *cp; + *cp = q->next; + q->fdelete(q); + SOAP_FREE(q); + return; + } + cp = &(*cp)->next; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p)); + } + else + { while (*cp) + { register struct soap_clist *q = *cp; + *cp = q->next; + if (q->ptr == (void*)soap->fault) + soap->fault = NULL; /* this was deallocated */ + else if (q->ptr == (void*)soap->header) + soap->header = NULL; /* this was deallocated */ + q->fdelete(q); + SOAP_FREE(q); + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_clist * +SOAP_FMAC2 +soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*)) +{ register struct soap_clist *cp; + if ((cp = (struct soap_clist*)SOAP_MALLOC(sizeof(struct soap_clist)))) + { cp->next = soap->clist; + cp->type = t; + cp->size = n; + cp->ptr = p; + cp->fdelete = fdelete; + soap->clist = cp; + } + return cp; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_unlink(struct soap *soap, const void *p) +{ register char **q; + register struct soap_clist **cp; + if (!soap || !p) + return; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p)); + return; + } + } + for (cp = &soap->clist; *cp; cp = &(*cp)->next) + { if (p == (*cp)->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p)); + q = (char**)*cp; + *cp = (*cp)->next; + SOAP_FREE(q); + return; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_lookup_type(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + if (id && *id) + { ip = soap_lookup(soap, id); + if (ip) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type)); + return ip->type; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k) +{ struct soap_ilist *ip; + void **q; + if (!p || !id || !*id) + return p; + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n)); + ip->type = t; + ip->size = n; + ip->link = p; + ip->copy = NULL; + ip->flist = NULL; + ip->ptr = NULL; + ip->level = k; + *p = NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n)); + if (ip->type != t) + { strcpy(soap->id, id); + soap->error = SOAP_HREF; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t)); + return NULL; + } + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return NULL; + *p = (void*)q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + *p = ip->ptr; + } + else if (ip->level > k) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id)); + while (ip->level > k) + { void *s, **r = &ip->link; + q = (void**)ip->link; + while (q) + { *r = (void*)soap_malloc(soap, sizeof(void*)); + s = *q; + *q = *r; + r = (void**)*r; + q = (void**)s; + } + *r = NULL; + ip->size = n; + ip->copy = NULL; + ip->level = ip->level - 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n)); + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + *p = q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_forward(struct soap *soap, const char *href, void *p, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, const void*, size_t)) +{ struct soap_ilist *ip; + if (!p || !href || !*href) + return p; + ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, href); /* new hash table entry for string id */ + ip->type = st; + ip->size = n; + ip->link = NULL; + ip->copy = NULL; + ip->ptr = NULL; + ip->level = 0; + ip->flist = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry href='%s' type=%d size=%lu level=%d location=%p\n", href, st, (unsigned long)n, k, p)); + } + else if (ip->type != st || (ip->level == k && ip->size != n)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n)); + strcpy(soap->id, href); + soap->error = SOAP_HREF; + return NULL; + } + if (fcopy || n < sizeof(void*) || *href != '#') + { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(sizeof(struct soap_flist)); + if (!fp) + { soap->error = SOAP_EOM; + return NULL; + } + fp->next = ip->flist; + fp->type = tt; + fp->ptr = p; + fp->level = k; + if (fcopy) + fp->fcopy = fcopy; + else + fp->fcopy = soap_fcopy; + ip->flist = fp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u href='%s'\n", st, tt, (unsigned long)n, p, k, href)); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href)); + *(void**)p = ip->copy; + ip->copy = p; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)) +{ struct soap_ilist *ip; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + soap->alloced = 0; + if (!p) + { if (finstantiate) + p = finstantiate(soap, t, type, arrayType, &n); + else + p = soap_malloc(soap, n); + if (p) + soap->alloced = 1; + } +#ifndef WITH_NOIDREF + if (!id || !*id) +#endif + return p; +#ifndef WITH_NOIDREF + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p)); + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + ip->type = t; + ip->link = NULL; + ip->copy = NULL; + ip->flist = NULL; + ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%lu level=%u location=%p\n", id, t, (unsigned long)n, k, p)); + } + else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n)); + strcpy(soap->id, id); + soap->error = SOAP_HREF; + return NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id)); + strcpy(soap->id, id); + soap->error = SOAP_MULTI_ID; + return NULL; + } + else + { ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update entry id='%s' type=%d location=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + } + return ip->ptr; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n) +{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n)); + memcpy(p, q, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_send(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->dime.list) + { /* SOAP body referenced attachments must appear first */ + soap->dime.last->next = soap->dime.first; + soap->dime.first = soap->dime.list->next; + soap->dime.list->next = NULL; + soap->dime.last = soap->dime.list; + } + if (soap_putdime(soap) || soap_putmime(soap)) + return soap->error; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n")); + if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */ + { if (soap_flush(soap)) +#ifdef WITH_ZLIB + { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + } + return soap->error; + } +#else + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { int r; + soap->d_stream.avail_in = 0; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n")); + r = deflate(&soap->d_stream, Z_FINISH); + if (soap->d_stream.avail_out != SOAP_BUFLEN) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out)) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + return soap->error; + } + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (r == Z_OK); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in; + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_state = SOAP_ZLIB_NONE; + if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } +#ifdef WITH_GZIP + soap->z_buf[0] = soap->z_crc & 0xFF; + soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF; + soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF; + soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF; + soap->z_buf[4] = soap->d_stream.total_in & 0xFF; + soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF; + soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF; + soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF; + if (soap_flush_raw(soap, soap->z_buf, 8)) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc)); +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { char *p; +#ifndef WITH_NOHTTP + if (!(soap->mode & SOAP_ENC_XML)) + { soap->mode--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size)); + if (soap->status >= SOAP_POST) + soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size); + else if (soap->status != SOAP_STOP) + soap->error = soap->fresponse(soap, soap->status, soap->blist->size); + if (soap->error || soap_flush(soap)) + return soap->error; + soap->mode++; + } +#endif + for (p = soap_first_block(soap); p; p = soap_next_block(soap)) + { DBGMSG(SENT, p, soap_block_size(soap)); + if ((soap->error = soap->fsend(soap, p, soap_block_size(soap)))) + { soap_end_block(soap); + return soap->error; + } + } + soap_end_block(soap); + } +#ifndef WITH_LEANER + else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { DBGMSG(SENT, "\r\n0\r\n\r\n", 7); + if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7))) + return soap->error; + } +#endif + } +#ifdef WITH_OPENSSL + if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#else + if (soap_valid_socket(soap->socket) && !soap->keep_alive) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send message ok\n")); + soap->part = SOAP_END; + soap->count = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_recv(struct soap *soap) +{ soap->part = SOAP_END; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MIME) && soap_getmime(soap)) + return soap->error; + soap->mime.list = soap->mime.first; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.list = soap->dime.first; + soap->dime.first = NULL; + soap->dime.last = NULL; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n")); +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->mode &= ~SOAP_ENC_ZLIB; + memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf; + soap->buflen = soap->z_buflen; + soap->zlib_state = SOAP_ZLIB_NONE; + if (inflateEnd(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; +#ifdef WITH_GZIP + if (soap->zlib_in == SOAP_ZLIB_GZIP) + { soap_wchar c; + short i; + for (i = 0; i < 8; i++) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + soap->z_buf[i] = (char)c; + } + if (soap->z_crc != ((uLong)(unsigned char)soap->z_buf[0] | ((uLong)(unsigned char)soap->z_buf[1] << 8) | ((uLong)(unsigned char)soap->z_buf[2] << 16) | ((uLong)(unsigned char)soap->z_buf[3] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc)); + return soap->error = SOAP_ZLIB_ERROR; + } + if (soap->d_stream.total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n")); + return soap->error = SOAP_ZLIB_ERROR; + } + } +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */ + ; + if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap))) + return soap->error; +#ifndef WITH_NOIDREF + return soap_resolve(soap); +#else + return SOAP_OK; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free(struct soap *soap) +{ register struct soap_nlist *np; + register struct soap_attribute *tp; + register struct Namespace *ns; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n")); + while (soap->nlist) + { np = soap->nlist->next; + if (soap->nlist->ns) + SOAP_FREE(soap->nlist->ns); + SOAP_FREE(soap->nlist); + soap->nlist = np; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n")); + while (soap->blist) + soap_end_block(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attributes\n")); + while (soap->attributes) + { tp = soap->attributes->next; + if (soap->attributes->value) + SOAP_FREE(soap->attributes->value); + SOAP_FREE(soap->attributes); + soap->attributes = tp; + } +#ifdef WITH_FAST + if (soap->labbuf) + SOAP_FREE(soap->labbuf); + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif +#ifndef WITH_NOIDREF + soap_free_pht(soap); + soap_free_iht(soap); +#endif + ns = soap->local_namespaces; + if (ns) + { for (; ns->id; ns++) + { if (ns->out) + { SOAP_FREE(ns->out); + if (soap->encodingStyle == ns->out) + soap->encodingStyle = SOAP_STR_EOS; + ns->out = NULL; + } + if (soap->encodingStyle == ns->ns) + soap->encodingStyle = SOAP_STR_EOS; + } + SOAP_FREE(soap->local_namespaces); + soap->local_namespaces = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_init_logs(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + { soap->logfile[i] = NULL; + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_open_logfile(struct soap *soap, int i) +{ if (soap->logfile[i]) + soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a"); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_close_logfile(struct soap *soap, int i) +{ if (soap->fdebug[i]) + { fclose(soap->fdebug[i]); + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_close_logfiles(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + soap_close_logfile(soap, i); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_set_logfile(struct soap *soap, int i, const char *logfile) +{ char *s = NULL; + soap_close_logfile(soap, i); + if (soap->logfile[i]) + SOAP_FREE((void*)soap->logfile[i]); + if (logfile) + if ((s = (char*)SOAP_MALLOC(strlen(logfile) + 1))) + strcpy(s, logfile); + soap->logfile[i] = s; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_recv_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_sent_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_test_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_TEST, logfile); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy(struct soap *soap) +{ return soap_copy_context((struct soap*)SOAP_MALLOC(sizeof(struct soap)), soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy_context(struct soap *copy, struct soap *soap) +{ if (copy) + { register struct soap_plugin *p; + memcpy(copy, soap, sizeof(struct soap)); + copy->copy = 1; + copy->user = NULL; + copy->userid = NULL; + copy->passwd = NULL; + copy->nlist = NULL; + copy->blist = NULL; + copy->clist = NULL; + copy->alist = NULL; + copy->attributes = NULL; + copy->local_namespaces = NULL; + soap_set_local_namespaces(copy); +#ifndef WITH_NOIDREF + soap_init_iht(copy); + soap_init_pht(copy); +#endif + copy->header = NULL; + copy->fault = NULL; + copy->action = NULL; + *copy->host = '\0'; +#ifndef WITH_LEAN +#ifdef WITH_COOKIES + copy->cookies = soap_copy_cookies(soap); +#else + copy->cookies = NULL; +#endif +#endif +#ifdef SOAP_DEBUG + soap_init_logs(copy); + soap_set_recv_logfile(copy, "RECV.log"); + soap_set_sent_logfile(copy, "SENT.log"); + soap_set_test_logfile(copy, "TEST.log"); +#endif + copy->plugins = NULL; + for (p = soap->plugins; p; p = p->next) + { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(sizeof(struct soap_plugin)); + if (!q) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id)); + *q = *p; + if (p->fcopy && (soap->error = p->fcopy(soap, q, p))) + { SOAP_FREE(q); + return NULL; + } + q->next = copy->plugins; + copy->plugins = q; + } + } + else + soap->error = SOAP_EOM; + return copy; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init(struct soap *soap) +{ soap->version = 0; + soap_imode(soap, SOAP_IO_DEFAULT); + soap_omode(soap, SOAP_IO_DEFAULT); + soap->copy = 0; + soap->plugins = NULL; + soap->user = NULL; + soap->userid = NULL; + soap->passwd = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fconnect = NULL; + soap->fdisconnect = NULL; +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; +#endif + soap->fignore = NULL; + soap->fserveloop = NULL; + soap->fplugin = fplugin; +#ifndef WITH_LEANER + soap->fdimereadopen = NULL; + soap->fdimewriteopen = NULL; + soap->fdimereadclose = NULL; + soap->fdimewriteclose = NULL; + soap->fdimeread = NULL; + soap->fdimewrite = NULL; +#endif + soap->float_format = "%.8g"; /* .8 preserves single FP precision as much as possible, but might not be very efficient */ + soap->double_format = "%.17lg"; /* .17 preserves double FP precision as much as possible, but might not be very efficient */ + soap->dime_id_format = "cid:id%d"; /* default DIME id format */ + soap->http_version = "1.1"; + soap->actor = NULL; + soap->max_keep_alive = SOAP_MAXKEEPALIVE; + soap->keep_alive = 0; + soap->recv_timeout = 0; + soap->send_timeout = 0; + soap->connect_timeout = 0; + soap->accept_timeout = 0; + soap->socket_flags = 0; + soap->connect_flags = 0; + soap->bind_flags = 0; + soap->accept_flags = 0; + soap->ip = 0; +#ifdef WITH_FAST + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif + soap->encodingStyle = SOAP_STR_EOS; +#ifndef WITH_NONAMESPACES + soap->namespaces = namespaces; +#else + soap->namespaces = NULL; +#endif + soap->local_namespaces = NULL; + soap->nlist = NULL; + soap->blist = NULL; + soap->clist = NULL; + soap->alist = NULL; + soap->attributes = NULL; + soap->header = NULL; + soap->fault = NULL; + soap->master = SOAP_INVALID_SOCKET; + soap->socket = SOAP_INVALID_SOCKET; + soap->os = NULL; + soap->is = NULL; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +#endif +#ifndef UNDER_CE + soap->recvfd = 0; + soap->sendfd = 1; +#else + soap->recvfd = stdin; + soap->sendfd = stdout; +#endif + soap->host[0] = '\0'; + soap->port = 0; + soap->action = NULL; + soap->proxy_host = NULL; + soap->proxy_port = 8080; + soap->proxy_userid = NULL; + soap->proxy_passwd = NULL; + soap->authrealm = NULL; + soap->prolog = NULL; +#ifdef WITH_OPENSSL + soap->fsslauth = ssl_auth_init; + soap->fsslverify = ssl_verify_callback; + soap->bio = NULL; + soap->ssl = NULL; + soap->ctx = NULL; + soap->require_server_auth = 0; + soap->require_client_auth = 0; + soap->rsa = 0; + soap->keyfile = NULL; + soap->password = NULL; + soap->dhfile = NULL; + soap->cafile = NULL; + soap->capath = NULL; + soap->randfile = NULL; + soap->session = NULL; +#endif +#ifdef WITH_ZLIB + soap->zlib_state = SOAP_ZLIB_NONE; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.zalloc = NULL; + soap->d_stream.zfree = NULL; + soap->d_stream.opaque = NULL; + soap->z_level = 6; +#endif +#ifndef WITH_LEAN + soap->cookies = NULL; + soap->cookie_domain = NULL; + soap->cookie_path = NULL; + soap->cookie_max = 32; +#endif +#ifdef SOAP_DEBUG + soap_init_logs(soap); + soap_set_recv_logfile(soap, "RECV.log"); + soap_set_sent_logfile(soap, "SENT.log"); + soap_set_test_logfile(soap, NULL); +#endif +/* WR[ */ +#ifdef WMW_RPM_IO + soap->rpmreqid = NULL; +#endif /* WMW_RPM_IO */ +/* ]WR */ +#ifdef PALM + palmNetLibOpen(); +#endif +#ifndef WITH_NOIDREF + soap_init_iht(soap); + soap_init_pht(soap); +#endif + soap_begin(soap); +#ifdef SOAP_DEBUG + soap_set_test_logfile(soap, "TEST.log"); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init1(struct soap *soap, soap_mode mode) +{ soap_init2(soap, mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init2(struct soap *soap, soap_mode imode, soap_mode omode) +{ soap_init(soap); + soap_imode(soap, imode); + soap_omode(soap, omode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_begin(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing\n")); + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + soap->null = 0; + soap->position = 0; + soap->encoding = 0; + soap->mustUnderstand = 0; + soap->mode = 0; + soap->ns = 0; + soap->part = SOAP_BEGIN; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + soap->error = SOAP_OK; + soap->peeked = 0; + soap->ahead = 0; + soap->idnum = 0; + soap->level = 0; + soap->endpoint[0] = '\0'; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; +#endif + soap_free(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end(struct soap *soap) +{ register struct soap_clist *cp; + soap_free(soap); + soap_dealloc(soap, NULL); + while (soap->clist) + { cp = soap->clist->next; + SOAP_FREE(soap->clist); + soap->clist = cp; + } + soap_closesock(soap); +#ifdef SOAP_DEBUG + soap_close_logfiles(soap); +#endif +#ifdef PALM + palmNetLibClose(); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_namespaces(struct soap *soap, struct Namespace *p) +{ struct Namespace *ns = soap->local_namespaces; + struct soap_nlist *np, *nq, *nr; + unsigned int level = soap->level; + soap->namespaces = p; + soap->local_namespaces = NULL; + soap_set_local_namespaces(soap); + /* reverse the list */ + np = soap->nlist; + soap->nlist = NULL; + if (np) + { nq = np->next; + np->next = NULL; + while (nq) + { nr = nq->next; + nq->next = np; + np = nq; + nq = nr; + } + } + while (np) + { soap->level = np->level; /* preserve element nesting level */ + if (np->ns) + { if (soap_push_namespace(soap, np->id, np->ns)) + return soap->error; + } + else if (np->index >= 0 && ns) + { if (ns[np->index].out) + { if (soap_push_namespace(soap, np->id, ns[np->index].out)) + return soap->error; + } + else if (soap_push_namespace(soap, np->id, ns[np->index].ns)) + return soap->error; + } + if (np->ns) + SOAP_FREE(np->ns); + nq = np; + np = np->next; + SOAP_FREE(nq); + } + if (ns) + { int i; + for (i = 0; ns[i].id; i++) + { if (ns[i].out) + { SOAP_FREE(ns[i].out); + ns[i].out = NULL; + } + } + SOAP_FREE(ns); + } + soap->level = level; /* restore level */ + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void +soap_set_local_namespaces(struct soap *soap) +{ if (soap->namespaces && !soap->local_namespaces) + { register const struct Namespace *ns1; + register struct Namespace *ns2; + register size_t n = 1; + for (ns1 = soap->namespaces; ns1->id; ns1++) + n++; + n *= sizeof(struct Namespace); + ns2 = (struct Namespace*)SOAP_MALLOC(n); + if (ns2) + { memcpy(ns2, soap->namespaces, n); + if (ns2[0].ns) + { if (!strcmp(ns2[0].ns, soap_env1)) + soap->version = 1; + else + soap->version = 2; + } + soap->local_namespaces = ns2; + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element(struct soap *soap, const char *tag, int id, const char *type) +{ struct Namespace *ns = soap->local_namespaces; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:"")); +/**/ +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *p, *e = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + e->next = NULL; + e->prnt = soap->dom; + e->nstr = NULL; + e->name = soap_strdup(soap, tag); /* check EOM? */ + e->data = NULL; + e->type = 0; + e->node = NULL; + e->elts = NULL; + e->atts = NULL; + if (soap->dom) + { p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = e; + } + else + soap->dom->elts = e; + } + soap->dom = e; + } + else +#endif +{ + soap->level++; + if (!soap->ns && !(soap->mode & SOAP_XML_CANONICAL)) + if (soap_send(soap, soap->prolog ? soap->prolog : "")) + return soap->error; + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, tag)) + return soap->error; +} +/**/ + if (!soap->ns) + { for (ns = soap->local_namespaces; ns && ns->id; ns++) + { if (*ns->id && (ns->out || ns->ns)) + { sprintf(soap->tmpbuf, "xmlns:%s", ns->id); + if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns)) + return soap->error; + } + } + soap->ns = 1; + } + if (id > 0) + { sprintf(soap->tmpbuf, "_%d", id); + if (soap_attribute(soap, "id", soap->tmpbuf)) + return soap->error; + } + if (type && *type) + { if (soap_attribute(soap, "xsi:type", type)) + return soap->error; + } + if (soap->null && soap->position > 0) + { int i; + sprintf(soap->tmpbuf, "[%d", soap->positions[0]); + for (i = 1; i < soap->position; i++) + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]); + strcat(soap->tmpbuf, "]"); + if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf)) + return soap->error; + } + if (soap->mustUnderstand) + { if (soap->actor && *soap->actor) + { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor)) + return soap->error; + } + if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1")) + return soap->error; + soap->mustUnderstand = 0; + } + if (soap->encoding) + { if (soap->encodingStyle && soap->local_namespaces) + { if (!*soap->encodingStyle) + { if (soap->local_namespaces[1].out) + soap->encodingStyle = soap->local_namespaces[1].out; + else + soap->encodingStyle = soap->local_namespaces[1].ns; + } + if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle)) + return soap->error; + } + soap->encoding = 0; + } + soap->null = 0; + soap->position = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type) +{ if (*tag == '-') + return SOAP_OK; + if (soap_element(soap, tag, id, type)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRRCHR +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_strrchr(const char *s, int t) +{ register char *r = NULL; + while (*s) + if (*s++ == t) + r = (char*)s - 1; + return r; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOL +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_strtol(const char *s, char **t, int b) +{ register long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { short neg = 0; + if (*s == '-') + { s++; + neg = 1; + } + else if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n > 214748364) + break; + n *= 10; + n += c - '0'; + s++; + } + if (neg) + n = -n; + } + else /* b == 16 and value is always positive */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x07FFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOUL +SOAP_FMAC1 +unsigned long +SOAP_FMAC2 +soap_strtoul(const char *s, char **t, int b) +{ unsigned long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n > 429496729) + break; + n *= 10; + n += c - '0'; + s++; + } + } + else /* b == 16 */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x0FFFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset) +{ if (soap_element(soap, tag, id, "SOAP-ENC:Array")) + return soap->error; + if (soap->version == 2) + { const char *s; + s = soap_strrchr(type, '['); + if ((size_t)(s - type) < sizeof(soap->tmpbuf)) + { strncpy(soap->tmpbuf, type, s - type); + soap->tmpbuf[s - type] = '\0'; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf))) + return soap->error; + if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1))) + return soap->error; + } + } + else + { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset))) + return soap->error; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type))) + return soap->error; + } + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_start_end_out(struct soap *soap, const char *tag) +{ register struct soap_attribute *tp; +/**/ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + a->next = soap->dom->atts; + a->nstr = NULL; + a->name = soap_strdup(soap, tp->name); /* check EOM */ + a->data = soap_strdup(soap, tp->value); /* check EOM */ + a->wide = NULL; + soap->dom->atts = a; + tp->visible = 0; + } + } + return SOAP_OK; + } +#endif +/**/ + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { if (soap_send(soap, " ") || soap_send(soap, tp->name)) + return soap->error; + if (tp->visible == 2 && tp->value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, tp->value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + tp->visible = 0; + } + } + if (tag) + { soap->level--; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { if (soap_send_raw(soap, ">", 1) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; + } +#endif + return soap_send_raw(soap, "/>", 2); + } + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_out(struct soap *soap, const char *tag) +{ if (*tag == '-') + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag)); +/**/ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + return SOAP_OK; + } +#endif +/**/ + soap->level--; + if (soap_send_raw(soap, "error; + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_ref(struct soap *soap, const char *tag, int id, int href) +{ register int n = 0; + if (soap->version == 2) + n = 1; + sprintf(soap->href, "#_%d", href); + return soap_element_href(soap, tag, id, "href" + n, soap->href + n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val)); + if (soap_element(soap, tag, id, NULL) + || soap_attribute(soap, ref, val) + || soap_element_start_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_null(struct soap *soap, const char *tag, int id, const char *type) +{ struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + if (tp->visible) + break; + if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL)) + { if (soap_element(soap, tag, id, type)) + return soap->error; + if (soap->part != SOAP_IN_HEADER && soap->encodingStyle) + if (soap_attribute(soap, "xsi:nil", "true")) + return soap->error; + return soap_element_start_end_out(soap, tag); + } + soap->null = 1; + soap->position = 0; + soap->mustUnderstand = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_id(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, int n, const char *type, int t) +{ if (!p || (a && !a->__ptr)) + { soap_element_null(soap, tag, id, type); + return -1; + } +#ifndef WITH_NOIDREF + if (soap->mode & SOAP_XML_TREE) + return 0; + if (id < 0) + { struct soap_plist *pp; + if (a) + id = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + else + id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap_is_embedded(soap, pp)) + { soap_element_ref(soap, tag, 0, id); + return -1; + } + if (soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + } + return id; +#else + return 0; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + if (soap_element(soap, "SOAP-RPC:result", 0, NULL) + || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc) + || soap_element_start_end_out(soap, NULL) + || soap_string_out(soap, tag, 0) + || soap_element_end_out(soap, "SOAP-RPC:result")) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attribute(struct soap *soap, const char *name, const char *value) +{ +/**/ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + a->next = soap->dom->atts; + a->nstr = NULL; + a->name = soap_strdup(soap, name); /* check EOM */ + a->data = soap_strdup(soap, value); /* check EOM */ + a->wide = NULL; + soap->dom->atts = a; + return SOAP_OK; + } +#endif +/**/ +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { if (soap_set_attr(soap, name, value)) + return soap->error; + } + else +#endif + { if (soap_send(soap, " ") || soap_send(soap, name)) + return soap->error; + if (value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_in(struct soap *soap, const char *tag, int nillable) +{ if (!soap_peek_element(soap)) + { if (soap->other) + return soap->error = SOAP_TAG_MISMATCH; + if (tag && *tag == '-') + return SOAP_OK; + if (!(soap->error = soap_match_tag(soap, soap->tag, tag))) + { soap->peeked = 0; + if (soap->body) + soap->level++; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" )); + if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT)) + return soap->error = SOAP_NULL; + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_in(struct soap *soap, const char *tag) +{ register soap_wchar c; + register char *s; + register const char *t; + register int n = 0; + if (tag && *tag == '-') + return SOAP_OK; + soap->level--; + soap_pop_namespace(soap); + if (soap->error == SOAP_NO_TAG) + soap->error = SOAP_OK; + if (soap->peeked && *soap->tag) + n++; + soap->peeked = 0; + do + { while (((c = soap_get(soap)) != SOAP_TT)) + { if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c == SOAP_LT) + n++; + } + } while (n--); + s = soap->tag; + do c = soap_get(soap); + while (soap_blank(c)); + do + { *s++ = (char)c; + c = soap_get(soap); + } while (soap_notblank(c)); + *s = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + while (soap_blank(c)) + c = soap_get(soap); + if (c != SOAP_GT) + return soap->error = SOAP_SYNTAX_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"")); + if (!tag) + return SOAP_OK; + if ((s = strchr(soap->tag, ':'))) + s++; + else + s = soap->tag; + if ((t = strchr(tag, ':'))) + t++; + else + t = tag; + if (!SOAP_STRCMP(s, t)) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n")); + return soap->error = SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_attr_value(struct soap *soap, const char *name, int flag) +{ register struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + if (!soap_match_tag(soap, tp->name, name)) + break; + if (tp && tp->visible == 2) + { if (flag == 2 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_PROHIBITED; + else + return tp->value; + } + else if (flag == 1 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_REQUIRED; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_attr(struct soap *soap, const char *name, const char *value) +{ register struct soap_attribute *tp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:"")); + for (tp = soap->attributes; tp; tp = tp->next) + if (!strcmp(tp->name, name)) + break; + if (!tp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name)); + if (!(tp = (struct soap_attribute*)SOAP_MALLOC(sizeof(struct soap_attribute) + strlen(name)))) + return soap->error = SOAP_EOM; + tp->ns = NULL; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_attribute **tpp = &soap->attributes; + const char *s = strchr(name, ':'); + if (!strncmp(name, "xmlns", 5)) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0) + break; + } + else if (!s) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0)) + break; + } + else + { int k; + for (; *tpp; tpp = &(*tpp)->next) + { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name]) + { if (!tp->ns) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p(%s)\n", name, (*tpp)->ns, (*tpp)->ns)); + tp->ns = (*tpp)->ns; + } + } + else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0))) + break; + } + } + tp->next = *tpp; + *tpp = tp; + } + else +#endif + { tp->next = soap->attributes; + soap->attributes = tp; + } + strcpy(tp->name, name); + tp->value = NULL; + } + else if (value && tp->value && tp->size <= strlen(value)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value)); + SOAP_FREE(tp->value); + tp->value = NULL; + tp->ns = NULL; + } + if (value) + { if (!tp->value) + { tp->size = strlen(value) + 1; + if (!(tp->value = (char*)SOAP_MALLOC(tp->size))) + return soap->error = SOAP_EOM; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value of %s (%p)\n", tp->name, tp->value)); + } + strcpy(tp->value, value); + if (!strncmp(tp->name, "xmlns:", 6)) + tp->ns = tp->value; + tp->visible = 2; + } + else + tp->visible = 1; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_attr(struct soap *soap) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { while (soap->attributes) + { tp = soap->attributes->next; + SOAP_FREE(soap->attributes->value); + SOAP_FREE(soap->attributes); + soap->attributes = tp; + } + } + else +#endif + { for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d) +{ size_t i; + soap_wchar c; + for (i = 0; i < n; i++) + { c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + *s++ = '<'; + break; + case SOAP_GT: + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + *s++ = '>'; + break; + case SOAP_QT: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '"'; + break; + case SOAP_AP: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '\''; + break; + case '\t': + case '\n': + case '\r': + case ' ': + case '/': + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + default: + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + } + return soap->error = SOAP_EOM; +} +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +static int +soap_append_lab(struct soap *soap, const char *s, size_t n) +{ if (soap->labidx + n >= soap->lablen) + { register char *t = soap->labbuf; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen)); + if (soap->lablen == 0) + soap->lablen = SOAP_LABLEN; + while (soap->labidx + n >= soap->lablen) + soap->lablen <<= 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen)); + soap->labbuf = (char*)SOAP_MALLOC(soap->lablen); + if (!soap->labbuf) + { if (t) + free(t); + return soap->error = SOAP_EOM; + } + if (t && soap->labidx) + { memcpy(soap->labbuf, t, soap->labidx); + free(t); + } + } + if (s) + { memcpy(soap->labbuf + soap->labidx, s, n); + soap->labidx += n; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_peek_element(struct soap *soap) +{ register struct soap_attribute *tp; + const char *t; + register char *s; + register soap_wchar c; + register int i; + if (soap->peeked) + { if (!*soap->tag) + return soap->error = SOAP_NO_TAG; + return SOAP_OK; + } + soap->peeked = 1; + for (;;) + { c = soap_getutf8(soap); + if (c == SOAP_BOM) + c = soap_getutf8(soap); + while (soap_blank(c)) + c = soap_getutf8(soap); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c != SOAP_LT) + { *soap->tag = '\0'; + soap_unget(soap, c); + return soap->error = SOAP_NO_TAG; + } + s = soap->tag; + do c = soap_get(soap); + while (soap_blank(c)); + i = sizeof(soap->tag); + while (c != '/' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_get(soap); + } + while (soap_blank(c)) + c = soap_get(soap); + *s = '\0'; + if (*soap->tag != '?') + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <%s?>\n", soap->tag)); + while ((int)c != EOF && c != SOAP_GT && c != '?') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf) - 2; + while (c != '=' && c != SOAP_GT && c != '?' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_get(soap); + } + while (soap_blank(c)) + c = soap_get(soap); + if (c == '=') + { *s++ = '='; + do c = soap_get(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, s, i, c) == SOAP_EOM) + while (soap_getattrval(soap, soap->tmpbuf, sizeof(soap->tmpbuf), c) == SOAP_EOM) + ; + else if (!strcmp(soap->tag, "?xml") && (!soap_tag_cmp(soap->tmpbuf, "encoding=iso-8859-1") || !soap_tag_cmp(soap->tmpbuf, "encoding=latin1"))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML latin1 encoding\n")); + soap->mode |= SOAP_ENC_LATIN; + } + } + do c = soap_get(soap); + while (soap_blank(c)); + } + } + soap->id[0] = '\0'; + soap->href[0] = '\0'; + soap->type[0] = '\0'; + soap->arrayType[0] = '\0'; + soap->arraySize[0] = '\0'; + soap->arrayOffset[0] = '\0'; + soap->other = 0; + soap->root = -1; + soap->position = 0; + soap->null = 0; + soap->mustUnderstand = 0; + soap_clr_attr(soap); + while ((int)c != EOF && c != SOAP_GT && c != '/') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf); + while (c != '=' && c != '/' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_get(soap); + } + *s = '\0'; + if (i == sizeof(soap->tmpbuf)) + return soap->error = SOAP_SYNTAX_ERROR; + if (!strncmp(soap->tmpbuf, "xmlns:", 6)) + { soap->tmpbuf[5] = '\0'; + t = soap->tmpbuf + 6; + } + else if (!strcmp(soap->tmpbuf, "xmlns")) + t = SOAP_STR_EOS; + else + t = NULL; + for (tp = soap->attributes; tp; tp = tp->next) + if (!SOAP_STRCMP(tp->name, soap->tmpbuf)) + break; + if (!tp) + { tp = (struct soap_attribute*)SOAP_MALLOC(sizeof(struct soap_attribute) + strlen(soap->tmpbuf)); + if (!tp) + return soap->error = SOAP_EOM; + strcpy(tp->name, soap->tmpbuf); + tp->value = NULL; + tp->size = 0; + tp->next = soap->attributes; + soap->attributes = tp; + } + while (soap_blank(c)) + c = soap_get(soap); + if (c == '=') + { do c = soap_get(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, tp->value, tp->size, c)) + { +#ifdef WITH_FAST + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + soap->labidx = 0; + if (soap_append_lab(soap, tp->value, tp->size)) + return soap->error; + SOAP_FREE(tp->value); + for (;;) + { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + soap->labidx = soap->lablen; + if (soap_append_lab(soap, NULL, 0)) + return soap->error; + } + else + break; + } + tp->size = soap->lablen; + if (!(tp->value = (char*)SOAP_MALLOC(tp->size))) + return soap->error = SOAP_EOM; + memcpy(tp->value, soap->labbuf, soap->lablen); +#else + size_t n; + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_new_block(soap)) + return soap->error; + for (;;) + { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN))) + return soap->error; + if (soap_getattrval(soap, s, SOAP_BLKLEN, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + } + else + break; + } + n = tp->size + soap->blist->size; + if (!(s = (char*)SOAP_MALLOC(n))) + return soap->error = SOAP_EOM; + if (tp->value) + { memcpy(s, tp->value, tp->size); + SOAP_FREE(tp->value); + } + soap_save_block(soap, s + tp->size, 0); + tp->value = s; + tp->size = n; +#endif + } + do c = soap_get(soap); + while (soap_blank(c)); + tp->visible = 2; /* seen this attribute w/ value */ + } + else + tp->visible = 1; /* seen this attribute w/o value */ + if (t && tp->value) + { if (soap_push_namespace(soap, t, tp->value)) + return soap->error; + tp->visible = 0; + } + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->value) + { if (!strcmp(tp->name, "id")) + { *soap->id = '#'; + strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2); + soap->id[sizeof(soap->id)-1] = '\0'; + } + else if (!strcmp(tp->name, "href")) + { strncpy(soap->href, tp->value, sizeof(soap->href) - 1); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else if ((soap->version == 2 || (soap->mode & SOAP_XML_GRAPH)) && !strcmp(tp->name, "ref")) + { *soap->href = '#'; + strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else if (!soap_match_tag(soap, tp->name, "xsi:type")) + { strncpy(soap->type, tp->value, sizeof(soap->type) - 1); + soap->type[sizeof(soap->type)-1] = '\0'; + } + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType")) + { s = soap_strrchr(tp->value, '['); + if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType)) + { strncpy(soap->arrayType, tp->value, s - tp->value); + soap->arrayType[s - tp->value] = '\0'; + strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1); + } + else + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + soap->arraySize[sizeof(soap->arrayType)-1] = '\0'; + soap->arrayType[sizeof(soap->arrayType)-1] = '\0'; + } + else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:itemType")) + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize")) + strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:offset")) + strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset)); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:position")) + soap->position = soap_getposition(tp->value, soap->positions); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:root")) + soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor") + || !soap_match_tag(soap, tp->name, "SOAP-ENV:role")) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next") + && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next")) + soap->other = 1; + } + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if ((!soap_match_tag(soap, tp->name, "xsi:null") + || !soap_match_tag(soap, tp->name, "xsi:nil")) + && (!strcmp(tp->value, "1") + || !strcmp(tp->value, "true"))) + soap->null = 1; + } + } + if (!(soap->body = (c != '/'))) + do c = soap_get(soap); + while (soap_blank(c)); + return soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_retry(struct soap *soap) +{ soap->peeked = 1; + soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_revert(struct soap *soap) +{ if (!soap->peeked) + { soap->peeked = 1; + if (soap->body) + soap->level--; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_string_out(struct soap *soap, const char *s, int flag) +{ register const char *t; + register soap_wchar c; + register soap_wchar mask = 0xFFFFFF80UL; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_strdup(soap, s); /* check EOM */ + return SOAP_OK; + } +#endif + if (soap->mode & SOAP_C_UTFSTRING) + mask = 0; + t = s; + while ((c = *t++)) + { switch (c) + { + case 9: + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 10: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 13: + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + break; + case '&': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&", 5)) + return soap->error; + s = t; + break; + case '<': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "<", 4)) + return soap->error; + s = t; + break; + case '>': + if (!flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, ">", 4)) + return soap->error; + s = t; + } + break; + case '"': + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, """, 6)) + return soap->error; + s = t; + } + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_MBTOWC + if (soap->mode & SOAP_C_MBSTRING) + { wchar_t wc; + register int m = mbtowc(&wc, t - 1, MB_CUR_MAX); + if (m > 0 && wc != c) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc)) + return soap->error; + s = t + m - 1; + continue; + } + } +#endif +#endif + if (c & mask) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c)) + return soap->error; + s = t; + } + } + } + return soap_send_raw(soap, s, t - s - 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) +{ register char *s; + char *t = NULL; + register size_t i; + register long l = 0; + register int n = 0; + register size_t m = 0; + register soap_wchar c; +#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB) + char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8]; +#else + char buf[8]; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n")); +#ifdef WITH_CDATA + if (!flag) + { register int state = 0; +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + c = soap_getchar(soap); + if ((int)c == EOF) + goto end; + if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN)) + { soap_unget(soap, c); + c = soap_getutf8(soap); + if (soap->mode & SOAP_C_UTFSTRING) + { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + } + switch (state) + { case 1: + if (c == ']') + state = 4; + *s++ = c; + continue; + case 2: + if (c == '-') + state = 6; + *s++ = c; + continue; + case 3: + if (c == '?') + state = 8; + *s++ = c; + continue; + /* CDATA */ + case 4: + if (c == ']') + state = 5; + else + state = 1; + *s++ = c; + continue; + case 5: + if (c == '>') + state = 0; + else + state = 1; + *s++ = c; + continue; + /* comment */ + case 6: + if (c == '-') + state = 7; + else + state = 2; + *s++ = c; + continue; + case 7: + if (c == '>') + state = 0; + else + state = 2; + *s++ = c; + continue; + /* PI */ + case 8: + if (c == '>') + state = 0; + else + state = 3; + *s++ = c; + continue; + } + switch (c) + { + case '/': + if (n > 0) + { c = soap_getchar(soap); + if (c == '>') + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + c = soap_getchar(soap); + if (c == '/') + { if (n == 0) + { c = SOAP_TT; + goto end; + } + n--; + } + else if (c == '!') + { c = soap_getchar(soap); + if (c == '[') + { do c = soap_getchar(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + goto end; + t = (char*)"![CDATA["; + m = 8; + state = 1; + } + else if (c == '-') + { if ((c = soap_getchar(soap)) == '-') + state = 2; + t = (char*)"!-"; + m = 2; + soap_unget(soap, c); + } + else + { t = (char*)"!"; + m = 1; + soap_unget(soap, c); + } + *s++ = '<'; + break; + } + else if (c == '?') + state = 3; + else + n++; + soap_unget(soap, c); + *s++ = '<'; + break; + case '>': + *s++ = '>'; + break; + case '"': + *s++ = '"'; + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1) + { t = buf; + *s++ = *t++; + m--; + } + else + *s++ = SOAP_UNKNOWN_CHAR; + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + if (soap->mode & SOAP_C_UTFSTRING) + { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + else + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + t = (char*)"/"; + m = 1; + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<' | 0x80000000: + if (flag) + *s++ = '<'; + else + { *s++ = '&'; + t = (char*)"lt;"; + m = 3; + } + break; + case '>' | 0x80000000: + if (flag) + *s++ = '>'; + else + { *s++ = '&'; + t = (char*)"gt;"; + m = 3; + } + break; + case '&' | 0x80000000: + if (flag) + *s++ = '&'; + else + { *s++ = '&'; + t = (char*)"amp;"; + m = 4; + } + break; + case '"' | 0x80000000: + if (flag) + *s++ = '"'; + else + { *s++ = '&'; + t = (char*)"quot;"; + m = 5; + } + break; + case '\'' | 0x80000000: + if (flag) + *s++ = '\''; + else + { *s++ = '&'; + t = (char*)"apos;"; + m = 5; + } + break; + default: + if ((int)c == EOF) + goto end; +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1) + { t = buf; + *s++ = *t++; + m--; + } + else + *s++ = SOAP_UNKNOWN_CHAR; + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; +#ifdef WITH_FAST + t = soap_strdup(soap, soap->labbuf); +#else + soap_size_block(soap, i+1); + t = soap_save_block(soap, NULL, 0); +#endif + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + if (flag == 2) + if (soap_s2QName(soap, t, &t)) + return NULL; + if (soap->peeked && *soap->tag) + { soap->peeked = 0; + if (soap_element_end_in(soap, NULL)) + return NULL; + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) +{ const char *t; + char tmp; + register soap_wchar c; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->wide = NULL; /* soap_malloc() ??? */ + return SOAP_OK; + } +#endif + while ((c = *s++)) + { switch (c) + { + case 9: + if (flag) + t = " "; + else + t = "\t"; + break; + case 10: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + t = " "; + else + t = "\n"; + break; + case 13: + t = " "; + break; + case '&': + t = "&"; + break; + case '<': + t = "<"; + break; + case '>': + if (flag) + t = ">"; + else + t = ">"; + break; + case '"': + if (flag) + t = """; + else + t = "\""; + break; + default: + if (c > 0 && c < 0x80) + { tmp = (char)c; + if (soap_send_raw(soap, &tmp, 1)) + return soap->error; + } + else if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + continue; + } + if (soap_send(soap, t)) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t * +SOAP_FMAC2 +soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) +{ wchar_t *s; + register int i, n = 0; + register long l = 0; + register soap_wchar c; + const char *t = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n")); + if (soap->peeked && *soap->tag) + { n = 1; + soap->peeked = 0; + } + if (soap_new_block(soap)) + return NULL; + for (;;) + { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN))) + return NULL; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (t) + { *s++ = (wchar_t)*t++; + if (!*t) + t = NULL; + continue; + } + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_getutf8(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + if (flag) + *s++ = (soap_wchar)'<'; + else + { *s++ = (soap_wchar)'&'; + t = "lt;"; + } + break; + case '>': + if (flag) + *s++ = (soap_wchar)'>'; + else + { *s++ = (soap_wchar)'&'; + t = "gt;"; + } + break; + case '"': + if (flag) + *s++ = (soap_wchar)'"'; + else + { *s++ = (soap_wchar)'&'; + t = "quot;"; + } + break; + default: + if ((int)c == EOF) + goto end; + *s++ = (wchar_t)c & 0x7FFFFFFF; + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; + soap_size_block(soap, sizeof(wchar_t) * (i + 1)); + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + if (soap->peeked && *soap->tag) + { soap->peeked = 0; + if (soap_element_end_in(soap, NULL)) + return NULL; + } + return (wchar_t*)soap_save_block(soap, NULL, 0); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_int2s(struct soap *soap, int n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2int(struct soap *soap, const char *s, int *p) +{ if (s) + { char *r; + *p = (int)soap_strtol(s, &r, 10); + if (*r) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int * +SOAP_FMAC2 +soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2int(soap, soap_value(soap), p)) + return NULL; + } + p = (int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(int), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_long2s(struct soap *soap, long n) +{ sprintf(soap->tmpbuf, "%ld", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2long(struct soap *soap, const char *s, long *p) +{ if (s) + { char *r; + *p = soap_strtol(s, &r, 10); + if (*r) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +long * +SOAP_FMAC2 +soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2long(soap, soap_value(soap), p)) + return NULL; + } + p = (long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(long), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_LONG642s(struct soap *soap, LONG64 n) +{ sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_LONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p) +{ if (s && sscanf(s, SOAP_LONG_FORMAT, p) != 1) + soap->error = SOAP_TYPE; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +LONG64 * +SOAP_FMAC2 +soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2LONG64(soap, soap_value(soap), p)) + return NULL; + } + p = (LONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(LONG64), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_byte2s(struct soap *soap, char n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2byte(struct soap *soap, const char *s, char *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (*r || n < -128 || n > 127) + soap->error = SOAP_TYPE; + *p = (char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2byte(soap, soap_value(soap), p)) + return NULL; + } + p = (char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(char), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_short2s(struct soap *soap, short n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2short(struct soap *soap, const char *s, short *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (*r || n < -32768 || n > 32767) + soap->error = SOAP_TYPE; + *p = (short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +short * +SOAP_FMAC2 +soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2short(soap, soap_value(soap), p)) + return NULL; + } + p = (short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(short), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_float2s(struct soap *soap, float n) +{ const char *s; + if (soap_isnan((double)n)) + s = "NaN"; + else if (soap_ispinff(n)) + s = "INF"; + else if (soap_isninff(n)) + s = "-INF"; + else + { sprintf(soap->tmpbuf, soap->float_format, n); + s = soap->tmpbuf; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_float2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2float(struct soap *soap, const char *s, float *p) +{ if (s) + { if (!soap_tag_cmp(s, "INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = FLT_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = FLT_NAN; + else + { +#if defined(HAVE_STRTOF) + char *r; + *p = strtof(s, &r); + if (*r) +#elif defined(HAVE_STRTOD) + char *r; + *p = (float)strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, soap->float_format, p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static int soap_isnumeric(struct soap *soap, const char *type) +{ if (soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":float") + && soap_match_tag(soap, soap->type, ":double") + && soap_match_tag(soap, soap->type, ":decimal") + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return SOAP_ERR; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +float * +SOAP_FMAC2 +soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2float(soap, soap_value(soap), p)) + return NULL; + } + p = (float*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(float), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_double2s(struct soap *soap, double n) +{ const char *s; + if (soap_isnan(n)) + s = "NaN"; + else if (soap_ispinfd(n)) + s = "INF"; + else if (soap_isninfd(n)) + s = "-INF"; + else + { sprintf(soap->tmpbuf, soap->double_format, n); + s = soap->tmpbuf; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_double2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2double(struct soap *soap, const char *s, double *p) +{ if (s) + { if (!soap_tag_cmp(s, "INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = DBL_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = DBL_NAN; + else + { +#ifdef HAVE_STRTOD + char *r; + *p = strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, soap->double_format, p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +double * +SOAP_FMAC2 +soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2double(soap, soap_value(soap), p)) + return NULL; + } + p = (double*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(double), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedByte2s(struct soap *soap, unsigned char n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (*r || n > 255) + soap->error = SOAP_TYPE; + *p = (unsigned char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned char * +SOAP_FMAC2 +soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2unsignedByte(soap, soap_value(soap), p)) + return NULL; + } + p = (unsigned char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned char), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedShort2s(struct soap *soap, unsigned short n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (*r || n > 65535) + soap->error = SOAP_TYPE; + *p = (unsigned short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned short * +SOAP_FMAC2 +soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2unsignedShort(soap, soap_value(soap), p)) + return NULL; + } + p = (unsigned short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned short), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedInt2s(struct soap *soap, unsigned int n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p) +{ if (s) + { char *r; + *p = (unsigned int)soap_strtoul(s, &r, 10); + if (*r) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned int * +SOAP_FMAC2 +soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2unsignedInt(soap, soap_value(soap), p)) + return NULL; + } + p = (unsigned int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned int), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedLong2s(struct soap *soap, unsigned long n) +{ sprintf(soap->tmpbuf, "%lu", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p) +{ if (s) + { char *r; + *p = soap_strtoul(s, &r, 10); + if (*r) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned long * +SOAP_FMAC2 +soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2unsignedLong(soap, soap_value(soap), p)) + return NULL; + } + p = (unsigned long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned long), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_ULONG642s(struct soap *soap, ULONG64 n) +{ sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_ULONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p) +{ if (s && sscanf(s, SOAP_ULONG_FORMAT, p) != 1) + soap->error = SOAP_TYPE; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +ULONG64 * +SOAP_FMAC2 +soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2ULONG64(soap, soap_value(soap), p)) + return NULL; + } + p = (ULONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(ULONG64), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2string(struct soap *soap, const char *s, char **t) +{ *t = NULL; + if (s && !(*t = soap_strdup(soap, s))) + soap->error = SOAP_EOM; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2QName(struct soap *soap, const char *s, char **t) +{ if (s) + { struct soap_nlist *np; + const char *p; + if (!strncmp(s, "xml:", 4)) + { *t = soap_strdup(soap, s); + return SOAP_OK; + } + np = soap->nlist; + p = strchr(s, ':'); + if (p) + { register int n = p - s; + while (np && (strncmp(np->id, s, n) || np->id[n])) + np = np->next; + p++; + } + else + { while (np && *np->id) + np = np->next; + p = s; + } + if (np) + { if (np->index >= 0 && soap->local_namespaces) + { register const char *q = soap->local_namespaces[np->index].id; + if (q) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2))) + sprintf(*t, "%s:%s", q, p); + return SOAP_OK; + } + } + if (np->ns) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4))) + sprintf(*t, "\"%s\":%s", np->ns, p); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:"")); + return soap->error = SOAP_NAMESPACE; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s)); + if ((*t = (char*)soap_malloc(soap, strlen(p) + 4))) + sprintf(*t, "\"\":%s", p); + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_QName2s(struct soap *soap, const char *s) +{ struct Namespace *p; + char *t; + int n; + if (!s || *s != '"') + return s; + s++; + if ((p = soap->local_namespaces)) + { for (; p->id; p++) + { if (p->ns) + if (!soap_tag_cmp(s, p->ns)) + break; + if (p->in) + if (!soap_tag_cmp(s, p->in)) + break; + } + if (p && p->id) + { s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s)); + strcpy(t, p->id); + strcat(t, s + 1); + return t; + } + } + } + t = (char*)strchr(s, '"'); + if (t) + n = t - s; + else + n = 0; + t = soap_strdup(soap, s); + t[n] = '\0'; + sprintf(soap->tmpbuf, "xmlns:_%lu", soap->idnum++); + soap_set_attr(soap, soap->tmpbuf, t); + s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6); + strcpy(t, soap->tmpbuf + 6); + strcat(t, s + 1); + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0 + || soap_element_begin_out(soap, tag, id, type) + || soap_string_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->body) + { *p = soap_string_in(soap, flag, minlen, maxlen); + if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL)) + return NULL; + } + else + *p = NULL; + p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0 + || soap_element_begin_out(soap, tag, id, type) + || soap_wstring_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->body) + { *p = soap_wstring_in(soap, 1, minlen, maxlen); + if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL)) + return NULL; + } + else + *p = NULL; + p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static time_t +soap_timegm(struct tm *T) +{ +#if defined(HAVE_TIMEGM) + return timegm(T); +#elif defined(HAVE_GETTIMEOFDAY) + struct timezone t; + struct timeval tv; + memset((void*)&t, 0, sizeof(t)); + gettimeofday(&tv, &t); + T->tm_min -= t.tz_minuteswest - (t.tz_dsttime != 0)*60; + T->tm_isdst = 0; + return mktime(T); +/* WR[ */ + /* The following define was added for VxWorks*/ +#elif defined(HAVE_MKTIME) + /* FOR VXWORKS: + vxWorks does not seem to have any variable representation of time zones, but + timezone information can be set in INSTALL_DIR/target/h/private/timeP.h header + file, by setting the ZONEBUFFER define. The ZONEBUFFER define follows this + format: + name_of_zone:<(unused)>:time_in_minutes_from_UTC:daylight_start:daylight_end + To calculate local time, the value of time_in_minutes_from_UTC is subtracted + from UTC; time_in_minutes_from_UTC must be positive. Daylight information is + expressed as mmddhh (month-day-hour), for example: + UTC::0:040102:100102 + */ + return mktime(T); +/* ]WR */ +#elif defined(HAVE_FTIME) + struct timeb t; + memset((void*)&t, 0, sizeof(t)); + t.timezone = 0; + t.dstflag = -1; + ftime(&t); + T->tm_min -= t.timezone - (t.dstflag != 0)*60; + T->tm_isdst = 0; + return mktime(T); +#else +#warning "time_t (de)serialization is not MT safe on this platform" + time_t t; + char *tz = getenv("TZ"); + putenv("TZ=UTC"); + tzset(); + t = mktime(T); + if (tz) + { char tmp[16]; + strcpy(tmp, "TZ="); + strncat(tmp, tz, 12); + tmp[15] = '\0'; + putenv(tmp); + } + else + putenv("TZ="); + tzset(); + return t; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_dateTime2s(struct soap *soap, time_t n) +{ struct tm T; + struct tm *pT = &T; +#if defined(HAVE_GMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +/* WR[ */ + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PGMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_PGMTIME) + if (gmtime(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +/* ]WR */ +#elif defined(HAVE_GMTIME) + if ((pT = gmtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GETTIMEOFDAY) + struct timezone tz; + memset((void*)&tz, 0, sizeof(tz)); +#if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(tz.tz_dsttime!=0), abs(tz.tz_minuteswest)%60); + } +#else + if ((pT = localtime(&n))) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(tz.tz_dsttime!=0), abs(tz.tz_minuteswest)%60); + } +#endif +#elif defined(HAVE_FTIME) + struct timeb t; + memset((void*)&t, 0, sizeof(t)); +#if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { ftime(&t); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(t.dstflag!=0), abs(t.timezone)%60); + } +/* WR[ */ + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60); + } +/* ]WR */ +#else + if ((pT = localtime(&n))) + { ftime(&t); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(t.dstflag!=0), abs(t.timezone)%60); + } +#endif +#elif defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +/* WR[ */ + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +/* ]WR */ +#else + if ((pT = localtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#endif + else + strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z"); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_dateTime2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2dateTime(struct soap *soap, const char *s, time_t *p) +{ if (s) + { struct tm T; + char zone[16]; + memset((void*)&T, 0, sizeof(T)); + zone[sizeof(zone)-1] = '\0'; + sscanf(s, "%d-%d-%dT%d:%d:%d%15s", &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone); + if (T.tm_year == 1) + T.tm_year = 70; + else + T.tm_year -= 1900; + T.tm_mon--; + if (*zone) + { if (*zone == '.') + { for (s = zone + 1; *s; s++) + if (*s < '0' || *s > '9') + break; + } + else + s = zone; + if (*s != 'Z') + { int h = 0, m = 0; + sscanf(s, "%d:%d", &h, &m); + T.tm_hour -= h; + if (h >= 0) + T.tm_min -= m; + else + T.tm_min += m; + } + *p = soap_timegm(&T); + } + else + *p = mktime(&T); /* no time zone: suppose it is localtime? */ + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +time_t * +SOAP_FMAC2 +soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char * type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":dateTime")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL); + if (p) + { if (soap_s2dateTime(soap, soap_value(soap), p)) + return NULL; + } + p = (time_t*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(time_t), 0, NULL); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outliteral(struct soap *soap, const char *tag, char *const*p) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if ((t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS); + } + else + { t = tag; + sprintf(soap->tmpbuf, "<%s>", tag); + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p && *p) + { if (soap_send(soap, *p)) + return soap->error; + } + if (t) + { sprintf(soap->tmpbuf, "", t); + return soap_send(soap, soap->tmpbuf); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_inliteral(struct soap *soap, const char *tag, char **p) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->null) + *p = NULL; + else + *p = soap_string_in(soap, 0, -1, -1); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p) +{ int i; + const char *t = NULL; + wchar_t c; + const wchar_t *s; + if (tag && *tag != '-') + { if (tag && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS); + } + else + { t = tag; + sprintf(soap->tmpbuf, "<%s>", tag); + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p) + { s = *p; + while ((c = *s++)) + if (soap_pututf8(soap, (unsigned char)c)) + return soap->error; + } + if (t) + { sprintf(soap->tmpbuf, "", t); + return soap_send(soap, soap->tmpbuf); + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->null) + *p = NULL; + else + *p = soap_wstring_in(soap, 0, -1, -1); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_value(struct soap *soap) +{ size_t i; + soap_wchar c = 0; + char *s = soap->tmpbuf; + if (!soap->body) + return SOAP_STR_EOS; + for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++) + { c = soap_get(soap); + if (c == SOAP_TT || (int)c == EOF || soap_blank(c)) + break; + *s++ = (char)c; + } + if ((int)c == EOF || c == SOAP_TT) + soap_unget(soap, c); + *s = '\0'; + return soap->tmpbuf; /* return non-null pointer */ +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getline(struct soap *soap, char *s, int len) +{ int i = len; + soap_wchar c = 0; + for (;;) + { while (--i > 0) + { c = soap_getchar(soap); + if (c == '\r' || c == '\n') + break; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (c != '\n') + c = soap_getchar(soap); /* got \r, now get \n */ + if (c == '\n') + { *s = '\0'; + if (i+1 == len) /* empty line: end of HTTP/MIME header */ + break; + c = soap_unget(soap, soap_getchar(soap)); + if (c != ' ' && c != '\t') /* HTTP line continuation? */ + break; + } + else if ((int)c == EOF) + return soap->error = SOAP_EOF; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static size_t +soap_count_attachments(struct soap *soap) +{ +#ifndef WITH_LEANER + register struct soap_multipart *content; + register size_t count = soap->count; + if (soap->mode & SOAP_ENC_DIME) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n")); + for (content = soap->dime.first; content; content = content->next) + { count += 12 + ((content->size+3)&(~3)); + if (content->id) + count += ((strlen(content->id)+3)&(~3)); + if (content->type) + count += ((strlen(content->type)+3)&(~3)); + if (content->options) + count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment %lu bytes\n", (unsigned long)content->size)); + } + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary) + { register size_t n = strlen(soap->mime.boundary); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { register const char *s; + /* count \r\n--boundary\r\n */ + count += 6 + n; + /* count Content-Type: ...\r\n */ + if (content->type) + count += 16 + strlen(content->type); + s = soap_str_code(mime_codes, content->encoding); + /* count Content-Transfer-Encoding: ...\r\n */ + if (s) + count += 29 + strlen(s); + /* count Content-ID: ...\r\n */ + if (content->id) + count += 14 + strlen(content->id); + /* count Content-Location: ...\r\n */ + if (content->location) + count += 20 + strlen(content->location); + /* count Content-Description: ...\r\n */ + if (content->description) + count += 23 + strlen(content->location); + /* count \r\n...content */ + count += 2 + content->size; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment %lu bytes\n", (unsigned long)content->size)); + } + /* count \r\n--boundary--\r\n */ + count += 8 + n; + } + return count; +#else + return soap->count; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_putdimefield(struct soap *soap, const char *s, size_t n) +{ if (soap_send_raw(soap, s, n)) + return soap->error; + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_dime_option(struct soap *soap, unsigned short optype, const char *option) +{ size_t n; + char *s = NULL; + if (option) + { n = strlen(option); + s = (char*)soap_malloc(soap, n + 5); + if (s) + { s[0] = optype >> 8; + s[1] = optype & 0xFF; + s[2] = n >> 8; + s[3] = n & 0xFF; + strcpy(s + 4, option); + } + } + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdimehdr(struct soap *soap) +{ unsigned char tmp[12]; + size_t optlen = 0, idlen = 0, typelen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:"")); + if (soap->dime.options) + optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4; + if (soap->dime.id) + idlen = strlen(soap->dime.id); + if (soap->dime.type) + typelen = strlen(soap->dime.type); + tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7); + tmp[1] = soap->dime.flags & 0xF0; + tmp[2] = optlen >> 8; + tmp[3] = optlen & 0xFF; + tmp[4] = idlen >> 8; + tmp[5] = idlen & 0xFF; + tmp[6] = typelen >> 8; + tmp[7] = typelen & 0xFF; + tmp[8] = soap->dime.size >> 24; + tmp[9] = (soap->dime.size >> 16) & 0xFF; + tmp[10] = (soap->dime.size >> 8) & 0xFF; + tmp[11] = soap->dime.size & 0xFF; + if (soap_send_raw(soap, (char*)tmp, 12) + || soap_putdimefield(soap, soap->dime.options, optlen) + || soap_putdimefield(soap, soap->dime.id, idlen) + || soap_putdimefield(soap, soap->dime.type, typelen)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_DIME)) + return SOAP_OK; + for (content = soap->dime.first; content; content = content->next) + { void *handle; + soap->dime.size = content->size; + soap->dime.id = content->id; + soap->dime.type = content->type; + soap->dime.options = content->options; + soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA; + if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n")); + return soap->error; + } + if (!content->size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)) + { size_t chunksize = sizeof(soap->tmpbuf); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n")); + do + { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size)); + if (size < chunksize) + { soap->dime.flags &= ~SOAP_DIME_CF; + if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + } + else + soap->dime.flags |= SOAP_DIME_CF; + soap->dime.size = size; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, soap->tmpbuf, size)) + break; + if (soap->dime.id) + { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA); + soap->dime.id = NULL; + soap->dime.type = NULL; + soap->dime.options = NULL; + } + } while (size >= chunksize); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap)) + return soap->error; + do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)soap->dime.size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + if (soap->fdimereadclose) + soap->fdimereadclose(soap, handle); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, (char*)content->ptr, content->size)) + return soap->error; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static char * +soap_getdimefield(struct soap *soap, size_t n) +{ register soap_wchar c; + register int i; + register char *s; + char *p = NULL; + if (n) + { p = (char*)soap_malloc(soap, n + 1); + if (p) + { s = p; + for (i = n; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + *s++ = (char)c; + } + *s = '\0'; + if ((soap->error = soap_move(soap, -(long)n&3))) + return NULL; + } + else + soap->error = SOAP_EOM; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdimehdr(struct soap *soap) +{ register soap_wchar c; + register char *s; + register int i; + unsigned char tmp[12]; + size_t optlen, idlen, typelen; + if (!(soap->mode & SOAP_ENC_DIME)) + return soap->error = SOAP_DIME_END; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n")); + if (soap->dime.buflen || soap->dime.chunksize) + { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap)))) + return soap->error = SOAP_EOF; + soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n")); + return SOAP_OK; + } + s = (char*)tmp; + for (i = 12; i > 0; i--) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION) + return soap->error = SOAP_DIME_MISMATCH; + soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0); + optlen = (tmp[2] << 8) | tmp[3]; + idlen = (tmp[4] << 8) | tmp[5]; + typelen = (tmp[6] << 8) | tmp[7]; + soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags)); + if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error) + return soap->error; + if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error) + return soap->error; + if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:"", soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:"")); + if (soap->dime.flags & SOAP_DIME_ME) + soap->mode &= ~SOAP_ENC_DIME; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdime(struct soap *soap) +{ struct soap_multipart *content; + if (soap_getdimehdr(soap)) + return soap->error; + if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error)) + { const char *id, *type, *options; + size_t size, n; + if (!soap->dime.ptr) + return soap->error; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + for (;;) + { size = soap->dime.size; + for (;;) + { n = soap->buflen - soap->bufidx; + if (size < n) + n = size; + if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n))) + break; + size -= n; + if (!size) + { soap->bufidx += n; + break; + } + if (soap_recv(soap)) + { soap->error = SOAP_EOF; + goto end; + } + } + if (soap_move(soap, -(long)soap->dime.size&3)) + { soap->error = SOAP_EOF; + break; + } + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + break; + } +end: + if (soap->fdimewriteclose) + soap->fdimewriteclose(soap, (void*)soap->dime.ptr); + soap->dime.size = 0; + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else if (soap->dime.flags & SOAP_DIME_CF) + { const char *id, *type, *options; + register soap_wchar c; + register char *s; + register int i; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + if (soap_new_block(soap)) + return SOAP_EOM; + for (;;) + { s = (char*)soap_push_block(soap, soap->dime.size); + if (!s) + return soap->error = SOAP_EOM; + for (i = soap->dime.size; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (soap_move(soap, -(long)soap->dime.size&3)) + return soap->error = SOAP_EOF; + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + return soap->error; + } + soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */ + if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0))) + return soap->error; + soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */ + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else + soap->dime.ptr = soap_getdimefield(soap, soap->dime.size); + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size); + if (!content) + return soap->error = SOAP_EOM; + content->id = soap->dime.id; + content->type = soap->dime.type; + content->options = soap->dime.options; + return soap->error; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmimehdr(struct soap *soap) +{ struct soap_multipart *content; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + while (!*soap->msgbuf); + if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-') + { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1; + /* remove white space */ + while (soap_blank(*s)) + s--; + s[1] = '\0'; + if (soap->mime.boundary) + { if (strcmp(soap->msgbuf + 2, soap->mime.boundary)) + return soap->error = SOAP_MIME_ERROR; + } + else + soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2); + if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL)) + return soap->error = SOAP_EOM; + content = soap->mime.last; + for (;;) + { register char *key = soap->msgbuf; + register char *val; + if (!*key) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key)); + val = strchr(soap->msgbuf, ':'); + if (val) + { *val = '\0'; + do val++; + while (*val && *val <= 32); + if (!soap_tag_cmp(key, "Content-ID")) + content->id = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Location")) + content->location = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Type")) + content->type = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Description")) + content->description = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Transfer-Encoding")) + content->encoding = (enum soap_mime_encoding)soap_int_code(mime_codes, val, (long)SOAP_MIME_NONE); + } + if (soap_getline(soap, key, sizeof(soap->msgbuf))) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmime(struct soap *soap) +{ register soap_wchar c; + if (!soap->mime.last) + return SOAP_OK; + for (;;) + { register size_t i, m = 0; + register char *s, *t = NULL; + struct soap_multipart *content = soap->mime.last; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:"")); + if (soap_new_block(soap)) + return soap->error = SOAP_EOM; + for (;;) + { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN))) + return soap->error = SOAP_EOM; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (m > 0) + { *s++ = *t++; + m--; + } + else + { c = soap_get1(soap); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c == '\r') + { t = soap->tmpbuf; + memset(t, 0, sizeof(soap->tmpbuf)); + strcpy(t, "\n--"); + strncat(t, soap->mime.boundary, sizeof(soap->tmpbuf)-4); + do c = soap_getchar(soap); + while (c == *t++); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (!*--t) + goto end; + *t = (char)c; + m = t - soap->tmpbuf + 1; + t = soap->tmpbuf; + c = '\r'; + } + *s++ = (char)c; + } + } + } +end: + *s = '\0'; /* force 0-terminated */ + content->size = soap_size_block(soap, i+1)-1; + content->ptr = soap_save_block(soap, NULL, 0); + if (c == '-' && soap_getchar(soap) == '-') + break; + while (c != '\r' && (int)c != EOF && soap_blank(c)) + c = soap_getchar(soap); + if (c != '\r' || soap_getchar(soap) != '\n') + return soap->error = SOAP_MIME_ERROR; + if (soap_getmimehdr(soap)) + return soap->error; + } + do c = soap_getchar(soap); + while ((int)c != EOF && c != '\r'); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (soap_getchar(soap) != '\n') + return soap->error = SOAP_MIME_ERROR; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmimehdr(struct soap *soap, struct soap_multipart *content) +{ const char *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:"")); + if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n")) + return soap->error; + if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n")) + return soap->error; + s = soap_str_code(mime_codes, content->encoding); + if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n")) + return soap->error; + if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n")) + return soap->error; + if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n")) + return soap->error; + if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n")) + return soap->error; + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + if (soap_putmimehdr(soap, content) + || soap_send_raw(soap, content->ptr, content->size)) + return soap->error; + return soap_send3(soap, "\r\n--", soap->mime.boundary, "--\r\n"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_dime(struct soap *soap) +{ soap->omode |= SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_mime(struct soap *soap, const char *boundary, const char *start) +{ soap->omode |= SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = soap_strdup(soap, boundary); + soap->mime.start = soap_strdup(soap, start); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_dime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_mime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart* +soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size) +{ struct soap_multipart *content; + content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart)); + if (content) + { content->next = NULL; + content->ptr = ptr; + content->size = size; + content->id = NULL; + content->type = NULL; + content->options = NULL; + content->encoding = SOAP_MIME_NONE; + content->location = NULL; + content->description = NULL; + if (!*first) + *first = content; + if (*last) + (*last)->next = content; + *last = content; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->options = soap_dime_option(soap, optype, option); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->encoding = encoding; + content->location = soap_strdup(soap, location); + content->description = soap_strdup(soap, description); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart* +SOAP_FMAC2 +soap_next_multipart(struct soap_multipart *content) +{ if (content) + return content->next; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_select_mime_boundary(struct soap *soap) +{ while (!soap->mime.boundary || soap_valid_mime_boundary(soap)) + { register char *s = soap->mime.boundary; + register size_t n = 0; + if (s) + n = strlen(s); + if (n < 16) + { n = 72; + s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1); + if (!s) + return; + } + strcpy(s, "<>"); + s += 2; + n -= 4; + while (n) + { *s++ = soap_base64o[rand()&0x3F]; + n--; + } + strcpy(s, "<>"); + } + if (!soap->mime.start) + soap->mime.start = ""; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_valid_mime_boundary(struct soap *soap) +{ register struct soap_multipart *content; + register size_t k = strlen(soap->mime.boundary); + for (content = soap->mime.first; content; content = content->next) + { if (content->ptr && content->size >= k) + { register const char *p = (const char*)content->ptr; + register size_t i; + for (i = 0; i < content->size - k; i++, p++) + if (!strncmp(p, soap->mime.boundary, k)) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ + +#ifdef WITH_COOKIES +/******************************************************************************/ +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_encode_cookie(const char *s, char *t, size_t len) +{ register int c; + register size_t n = len; + while ((c = *s++) && --n > 0) + { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c)) + *t++ = c; + else if (n > 2) + { *t++ = '%'; + *t++ = (c >> 4) + (c > 159 ? '7' : '0'); + c &= 0xF; + *t++ = c + (c > 9 ? '7' : '0'); + n -= 2; + } + else + break; + } + *t = '\0'; + return len - n; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + size_t n; + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (*path == '/') + path++; + n = strlen(path); + for (p = soap->cookies; p; p = p->next) + if (!strcmp(p->name, name) + && domain + && p->domain + && !strcmp(p->domain, domain) + && !strncmp(p->path, path, n)) + break; + return p; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + int n; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie: %s=%s domain=%s path=%s\n", name, value?value:"", domain?domain:"", path?path:"")); + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR); + return NULL; + } + if (*path == '/') + path++; + q = soap_cookie(soap, name, domain, path); + if (!q) + { if ((q = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie)))) + { if ((q->name = (char*)SOAP_MALLOC(strlen(name)+1))) + strcpy(q->name, name); + q->value = NULL; + q->domain = NULL; + q->path = NULL; + q->expire = -1; + q->version = 0; + q->secure = 0; + q->env = 0; + q->modified = 0; + for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--) + if (!strcmp((*p)->name, name) && (*p)->path && strcmp((*p)->path, path) < 0) + break; + if (n) + { q->next = *p; + *p = q; + } + else + { SOAP_FREE(q->name); + SOAP_FREE(q); + q = NULL; + } + } + } + else + q->modified = 1; + if (q) + { if (q->value) + { SOAP_FREE(q->value); + q->value = NULL; + } + if (q->domain) + { SOAP_FREE(q->domain); + q->domain = NULL; + } + if (q->path) + { SOAP_FREE(q->path); + q->path = NULL; + } + if (value && *value && (q->value = (char*)SOAP_MALLOC(strlen(value)+1))) + strcpy(q->value, value); + if (domain && *domain && (q->domain = (char*)SOAP_MALLOC(strlen(domain)+1))) + strcpy(q->domain, domain); + if (path && *path && (q->path = (char*)SOAP_MALLOC(strlen(path)+1))) + strcpy(q->path, path); + q->session = 1; + } + return q; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + if (!domain) + domain = soap->cookie_domain; + if (!domain) + { soap_set_receiver_error(soap, "Cookie domain not set", SOAP_STR_EOS, SOAP_HTTP_ERROR); + return; + } + if (!path) + path = soap->cookie_path; + if (!path) + { soap_set_receiver_error(soap, "Cookie path not set", SOAP_STR_EOS, SOAP_HTTP_ERROR); + return; + } + if (*path == '/') + path++; + for (p = &soap->cookies, q = *p; q; q = *p) + if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path))) + { if (q->value) + SOAP_FREE(q->value); + if (q->domain) + SOAP_FREE(q->domain); + if (q->path) + SOAP_FREE(q->path); + *p = q->next; + SOAP_FREE(q); + } + else + p = &q->next; +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->expire; + return -1; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->expire = expire; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 1; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 0; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putsetcookies(struct soap *soap) +{ struct soap_cookie *p; + char *s, tmp[4096]; + const char *t; + for (p = soap->cookies; p; p = p->next) + { if (p->modified || !p->env) + { s = tmp; + if (p->name) + s += soap_encode_cookie(p->name, s, tmp-s+4064); + if (p->value && *p->value) + { *s++ = '='; + s += soap_encode_cookie(p->value, s, tmp-s+4064); + } + if (p->domain && (int)strlen(p->domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", p->domain); + else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", soap->cookie_domain); + strcat(s, ";Path=\"/"); + if (p->path) + t = p->path; + else + t = soap->cookie_path; + if (t) + { if (*t == '/') + t++; + if ((int)strlen(t) < tmp-s+4064) + strcat(s, t); + } + s += strlen(s); + *s++ = '"'; + if (p->version > 0) + sprintf(s, ";Version=%u", p->version); + if (p->expire >= 0) + sprintf(s, ";Max-Age=%ld", p->expire); + if (p->secure) + strcat(s, ";Secure"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp)); + if (soap->fposthdr(soap, "Set-Cookie", tmp)) + return soap->error; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure) +{ struct soap_cookie **p, *q; + unsigned int version = 0; + time_t now = time(NULL); + char *s, tmp[4096]; + p = &soap->cookies; + while ((q = *p)) + { if (q->expire && now > q->expire) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name)); + SOAP_FREE(q->name); + if (q->value) + SOAP_FREE(q->value); + if (q->domain) + SOAP_FREE(q->domain); + if (q->path) + SOAP_FREE(q->path); + *p = q->next; + SOAP_FREE(q); + } + else if ((!q->domain || !strcmp(q->domain, domain)) + && (!q->path || !strncmp(q->path, path, strlen(q->path))) + && (!q->secure || secure)) + { s = tmp; + if (q->version != version) + { sprintf(s, "$Version=%u;", q->version); + version = q->version; + } + if (q->name) + s += soap_encode_cookie(q->name, s, tmp-s+4080); + if (q->value && *q->value) + { *s++ = '='; + s += soap_encode_cookie(q->value, s, tmp-s+4080); + } + if (q->path && (int)strlen(q->path) < tmp-s+4080) + { sprintf(s, ";$Path=\"/%s\"", q->path); + s += strlen(s); + } + if (q->domain && (int)strlen(q->domain) < tmp-s+4080) + sprintf(s, ";$Domain=\"%s\"", q->domain); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp)); + if (soap->fposthdr(soap, "Cookie", tmp)) + return soap->error; + p = &q->next; + } + else + p = &q->next; + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_getcookies(struct soap *soap, const char *val) +{ struct soap_cookie *p = NULL, *q; + const char *s; + char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + char *domain = NULL; + char *path = NULL; + unsigned int version = 0; + time_t now = time(NULL); + if (!val) + return; + s = val; + while (*s) + { s = soap_decode_key(tmp, sizeof(tmp), s); + if (!soap_tag_cmp(tmp, "$Version")) + { if ((s = soap_decode_val(tmp, sizeof(tmp), s))) + { if (p) + p->version = (int)atol(tmp); + else + version = (int)atol(tmp); + } + } + else if (!soap_tag_cmp(tmp, "$Path")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->path) + SOAP_FREE(p->path); + p->path = t; + } + else + { if (path) + SOAP_FREE(path); + path = t; + } + } + else if (!soap_tag_cmp(tmp, "$Domain")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->domain) + SOAP_FREE(p->domain); + p->domain = t; + } + else + { if (domain) + SOAP_FREE(domain); + domain = t; + } + } + else if (p && !soap_tag_cmp(tmp, "Path")) + { if (p->path) + SOAP_FREE(p->path); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->path = (char*)SOAP_MALLOC(strlen(tmp)+1))) + strcpy(p->path, tmp); + } + else + p->path = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Domain")) + { if (p->domain) + SOAP_FREE(p->domain); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->domain = (char*)SOAP_MALLOC(strlen(tmp)+1))) + strcpy(p->domain, tmp); + } + else + p->domain = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Version")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->version = (unsigned int)atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Max-Age")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->expire = now + atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Expires")) + { struct tm T; + char a[3]; + static const char mns[] = "anebarprayunulugepctovec"; + s = soap_decode_val(tmp, sizeof(tmp), s); + if (strlen(tmp) > 20) + { memset((void*)&T, 0, sizeof(T)); + a[0] = tmp[4]; + a[1] = tmp[5]; + a[2] = '\0'; + T.tm_mday = (int)atol(a); + a[0] = tmp[8]; + a[1] = tmp[9]; + T.tm_mon = (strstr(mns, a) - mns) / 2; + a[0] = tmp[11]; + a[1] = tmp[12]; + T.tm_year = 100 + (int)atol(a); + a[0] = tmp[13]; + a[1] = tmp[14]; + T.tm_hour = (int)atol(a); + a[0] = tmp[16]; + a[1] = tmp[17]; + T.tm_min = (int)atol(a); + a[0] = tmp[19]; + a[1] = tmp[20]; + T.tm_sec = (int)atol(a); + p->expire = soap_timegm(&T); + } + } + else if (p && !soap_tag_cmp(tmp, "Secure")) + p->secure = 1; + else + { if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(p->name); + if (p->value) + SOAP_FREE(p->value); + if (p->domain) + SOAP_FREE(p->domain); + if (p->path) + SOAP_FREE(p->path); + SOAP_FREE(p); + } + if ((p = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie)))) + { p->name = (char*)SOAP_MALLOC(strlen(tmp)+1); + strcpy(p->name, tmp); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { p->value = (char*)SOAP_MALLOC(strlen(tmp)+1); + strcpy(p->value, tmp); + } + else + p->value = NULL; + p->domain = domain; + p->path = path; + p->expire = 0; + p->secure = 0; + p->version = version; + } + } + } + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + } + if (p->name) + SOAP_FREE(p->name); + if (p->value) + SOAP_FREE(p->value); + if (p->domain) + SOAP_FREE(p->domain); + if (p->path) + SOAP_FREE(p->path); + SOAP_FREE(p); + } + if (domain) + SOAP_FREE(domain); + if (path) + SOAP_FREE(path); +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getenv_cookies(struct soap *soap) +{ struct soap_cookie *p; + const char *s; + char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + if (!(s = getenv("HTTP_COOKIE"))) + return SOAP_ERR; + do + { s = soap_decode_key(key, sizeof(key), s); + s = soap_decode_val(val, sizeof(val), s); + p = soap_set_cookie(soap, key, val, NULL, NULL); + if (p) + p->env = 1; + } while (*s); + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_copy_cookies(struct soap *soap) +{ struct soap_cookie *p, **q, *r; + q = &r; + for (p = soap->cookies; p; p = p->next) + { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie)))) + return r; + **q = *p; + if (p->name) + { if (((*q)->name = (char*)SOAP_MALLOC(strlen(p->name)+1))) + strcpy((*q)->name, p->name); + } + if (p->value) + { if (((*q)->value = (char*)SOAP_MALLOC(strlen(p->value)+1))) + strcpy((*q)->value, p->value); + } + if (p->domain) + { if (((*q)->domain = (char*)SOAP_MALLOC(strlen(p->domain)+1))) + strcpy((*q)->domain, p->domain); + } + if (p->path) + { if (((*q)->path = (char*)SOAP_MALLOC(strlen(p->path)+1))) + strcpy((*q)->path, p->path); + } + q = &(*q)->next; + } + *q = NULL; + return r; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_cookies(struct soap *soap) +{ struct soap_cookie *p; + for (p = soap->cookies; p; p = soap->cookies) + { soap->cookies = p->next; + SOAP_FREE(p->name); + if (p->value) + SOAP_FREE(p->value); + if (p->domain) + SOAP_FREE(p->domain); + if (p->path) + SOAP_FREE(p->path); + SOAP_FREE(p); + } +} + +/******************************************************************************/ +#endif /* WITH_COOKIES */ + +/******************************************************************************/ +#ifdef WITH_GZIP +#ifndef PALM_1 +static int +soap_getgziphdr(struct soap *soap) +{ int i; + soap_wchar c, f = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n")); + for (i = 0; i < 9; i++) + { if ((int)(c = soap_get1(soap) == EOF)) + return soap->error = SOAP_EOF; + if (i == 2) + f = c; + } + if (f & 0x04) /* FEXTRA */ + { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--) + if ((int)soap_get1(soap) == EOF) + return soap->error = SOAP_EOF; + } + if (f & 0x08) /* FNAME */ + do + c = soap_get1(soap); + while (c && (int)c != EOF); + if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */ + do + c = soap_get1(soap); + while (c && (int)f != EOF); + if ((int)c != EOF && (f & 0x01)) /* FHCRC */ + { if ((int)(c = soap_get1(soap)) != EOF) + c = soap_get1(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_recv(struct soap *soap) +{ soap_wchar c; + soap->error = SOAP_OK; + soap_free(soap); + soap_set_local_namespaces(soap); + soap->version = 0; /* don't assume we're parsing SOAP content by default */ +#ifndef WITH_NOIDREF + soap_free_iht(soap); +#endif + if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK) + soap->omode |= SOAP_IO_CHUNK; + soap->imode &= ~SOAP_IO; + soap->mode = soap->imode; + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + soap->ahead = 0; + soap->peeked = 0; + soap->level = 0; + soap->part = SOAP_BEGIN; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + *soap->endpoint = '\0'; + soap->userid = NULL; + soap->passwd = NULL; + soap->action = NULL; + soap->authrealm = NULL; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +#endif +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->recvfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->recvfd, _O_BINARY); +#endif +#endif +#endif +#endif +#ifdef WITH_ZLIB + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.next_in = Z_NULL; + soap->d_stream.avail_in = 0; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + soap->z_ratio_in = 1.0; +#endif +#ifndef WITH_LEANER + if (soap->fprepareinit) + soap->fprepareinit(soap); +#endif + c = soap_getchar(soap); +#ifdef WITH_GZIP + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->mode |= SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_GZIP; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + /* should not chunk over plain transport, so why bother to check? */ + /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */ + /* soap->z_buflen = soap->bufidx; */ + /* else */ + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + c = soap_getchar(soap); + } +#endif +#ifndef WITH_LEANER + if (c == '-' && soap_get0(soap) == '-') + soap->mode |= SOAP_ENC_MIME; + else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20) + soap->mode |= SOAP_ENC_DIME; + else +#endif + { while (soap_blank(c)) + c = soap_getchar(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifndef WITH_NOHTTP + if (c != '<' && !(soap->mode & (SOAP_ENC_DIME | SOAP_ENC_ZLIB))) + { soap->mode &= ~SOAP_IO; + if ((soap->error = soap->fparse(soap))) + { soap->keep_alive = 0; /* force close later */ + return soap->error; + } + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { soap->chunkbuflen = soap->buflen; + soap->buflen = soap->bufidx; + soap->chunksize = 0; + } +#ifndef WITH_LEANER + else if (soap->fpreparerecv && soap->buflen != soap->bufidx) + soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx); +#endif +#ifdef WITH_ZLIB + if (soap->zlib_in) + { /* fparse should not use soap_unget to push back last char */ +#ifdef WITH_GZIP + c = soap_get1(soap); + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + } + else + { soap_revget1(soap); +#else + { +#endif + if (inflateInit(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n")); + } + soap->mode |= SOAP_ENC_ZLIB; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + } +#endif + } +#endif +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + { if (soap_getmimehdr(soap)) + return soap->error; + if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + } + if (soap->mode & SOAP_ENC_DIME) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + soap->count = soap->buflen - soap->bufidx; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse(struct soap *soap) +{ char header[SOAP_HDRLEN], *s; + unsigned short g = 0, k; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for response...\n")); + *soap->endpoint = '\0'; + soap->length = 0; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf)); + for (;;) + { if (soap_getline(soap, header, SOAP_HDRLEN)) + { if (soap->error == SOAP_EOF) + { soap->error = SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n")); + break; + } + return soap->error; + } + if (!*header) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header)); + s = strchr(header, ':'); + if (s) + { *s = '\0'; + do s++; + while (*s && *s <= 32); + if ((soap->error = soap->fparsehdr(soap, header, s))) + return soap->error; + } + } + if ((s = strchr(soap->msgbuf, ' '))) + k = (unsigned short)soap_strtoul(s, NULL, 10); + else + k = 0; + } while (k == 100); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing\n")); + s = strstr(soap->msgbuf, "HTTP/"); + if (s && s[7] != '1') + { if (soap->keep_alive == 1) + soap->keep_alive = 0; + if (k == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* k == 0 for HTTP request */ + { soap->imode |= SOAP_IO_CHUNK; + soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; + } + } + if (soap->keep_alive < 0) + soap->keep_alive = 1; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive)); + if (s && (((g = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5))) + { size_t m = strlen(soap->endpoint); + size_t n = m + (s - soap->msgbuf) - 5 - (!g); + if (n >= sizeof(soap->endpoint)) + n = sizeof(soap->endpoint) - 1; + strncpy(soap->path, soap->msgbuf + 4 + (!g), n - m); + soap->path[n - m] = '\0'; + strcat(soap->endpoint, soap->path); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint)); + if (g) + { soap->error = soap->fget(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + return soap->error; + } + return SOAP_OK; + } + if (k == 0 || (k >= 200 && k <= 299) || k == 400 || k == 500) + return SOAP_OK; + return soap_set_receiver_error(soap, "HTTP error", soap->msgbuf, k); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse_header(struct soap *soap, const char *key, const char *val) +{ if (!soap_tag_cmp(key, "Host")) + { +#ifdef WITH_OPENSSL + if (soap->imode & SOAP_ENC_SSL) + strcpy(soap->endpoint, "https://"); + else +#endif + strcpy(soap->endpoint, "http://"); + strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifndef WITH_LEANER + else if (!soap_tag_cmp(key, "Content-Type")) + { if (soap_get_header_attribute(soap, val, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + else if (soap_get_header_attribute(soap, val, "multipart/related")) + { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary")); + soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start")); + soap->mode |= SOAP_ENC_MIME; + } + } +#endif + else if (!soap_tag_cmp(key, "Content-Length")) + soap->length = soap_strtoul(val, NULL, 10); + else if (!soap_tag_cmp(key, "Content-Encoding")) + { if (!soap_tag_cmp(val, "deflate")) +#ifdef WITH_ZLIB + soap->zlib_in = SOAP_ZLIB_DEFLATE; +#else + return SOAP_ZLIB_ERROR; +#endif + else if (!soap_tag_cmp(val, "gzip")) +#ifdef WITH_GZIP + soap->zlib_in = SOAP_ZLIB_GZIP; +#else + return SOAP_ZLIB_ERROR; +#endif + } +#ifdef WITH_ZLIB + else if (!soap_tag_cmp(key, "Accept-Encoding")) + { +#ifdef WITH_GZIP + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip")) + soap->zlib_out = SOAP_ZLIB_GZIP; + else +#endif + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate")) + soap->zlib_out = SOAP_ZLIB_DEFLATE; + else + soap->zlib_out = SOAP_ZLIB_NONE; + } +#endif + else if (!soap_tag_cmp(key, "Transfer-Encoding")) + { soap->mode &= ~SOAP_IO; + if (!soap_tag_cmp(val, "chunked")) + soap->mode |= SOAP_IO_CHUNK; + } + else if (!soap_tag_cmp(key, "Connection")) + { if (!soap_tag_cmp(val, "keep-alive")) + soap->keep_alive = -soap->keep_alive; + else if (!soap_tag_cmp(val, "close")) + soap->keep_alive = 0; + } +#ifndef WITH_LEAN + else if (!soap_tag_cmp(key, "Authorization")) + { if (!soap_tag_cmp(val, "Basic *")) + { size_t n; + char *s; + soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n); + soap->tmpbuf[n] = '\0'; + if ((s = strchr(soap->tmpbuf, ':'))) + { *s = '\0'; + soap->userid = soap_strdup(soap, soap->tmpbuf); + soap->passwd = soap_strdup(soap, s + 1); + } + } + } + else if (!soap_tag_cmp(key, "WWW-Authenticate")) + soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val+6, "realm")); + else if (!soap_tag_cmp(key, "Expect")) + { if (!soap_tag_cmp(val, "100-continue")) + { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL)) + || (soap->error = soap->fposthdr(soap, NULL, NULL))) + return soap->error; + } + } +#endif + else if (!soap_tag_cmp(key, "SOAPAction")) + { if (val[0] && val[1]) + { soap->action = soap_strdup(soap, val + 1); + soap->action[strlen(soap->action) - 1] = '\0'; + } + } + else if (!soap_tag_cmp(key, "Location")) + { strncpy(soap->endpoint, val, sizeof(soap->endpoint)); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifdef WITH_COOKIES + else if (!soap_tag_cmp(key, "Cookie") || !soap_tag_cmp(key, "Set-Cookie")) + soap_getcookies(soap, val); +#endif + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_get_header_attribute(struct soap *soap, const char *line, const char *key) +{ register const char *s = line; + if (s) + { while (*s) + { register short flag; + s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s); + flag = soap_tag_cmp(soap->tmpbuf, key); + s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s); + if (!flag) + return soap->tmpbuf; + } + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_key(char *buf, size_t len, const char *val) +{ return soap_decode(buf, len, val, "=,;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_val(char *buf, size_t len, const char *val) +{ if (*val != '=') + { *buf = '\0'; + return val; + } + return soap_decode(buf, len, val + 1, ",;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char* +soap_decode(char *buf, size_t len, const char *val, const char *sep) +{ const char *s; + char *t = buf; + for (s = val; *s; s++) + if (*s != ' ' && *s != '\t' && !strchr(sep, *s)) + break; + if (*s == '"') + { s++; + while (*s && *s != '"' && --len) + *t++ = *s++; + } + else + { while (soap_notblank(*s) && !strchr(sep, *s) && --len) + { if (*s == '%') + { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4) + + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0'); + s += 3; + } + else + *t++ = *s++; + } + } + *t = '\0'; + while (*s && !strchr(sep, *s)) + s++; + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_out(struct soap *soap) +{ +#ifndef WITH_LEANER + size_t n = 0; + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start) + { const char *s; + if (soap->mode & SOAP_ENC_DIME) + s = "application/dime"; + else if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + else + s = "text/xml; charset=utf-8"; + sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start); + n = strlen(soap->tmpbuf); + if (soap_send_raw(soap, soap->tmpbuf, n)) + return soap->error; + } + if (soap->mode & SOAP_IO_LENGTH) + soap->dime.size = soap->count; /* DIME in MIME correction */ + if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME)) + { if (soap_putdimehdr(soap)) + return soap->error; + } +#endif + soap->part = SOAP_IN_ENVELOPE; + return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope")) + return soap->error; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME)) + { soap->dime.size = soap->count - soap->dime.size; /* DIME in MIME correction */ + sprintf(soap->id, soap->dime_id_format, 0); + soap->dime.id = soap->id; + if (soap->local_namespaces) + { if (soap->local_namespaces[0].out) + soap->dime.type = (char*)soap->local_namespaces[0].out; + else + soap->dime.type = (char*)soap->local_namespaces[0].ns; + } + soap->dime.options = NULL; + soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI; + if (!soap->dime.first) + soap->dime.flags |= SOAP_DIME_ME; + soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + ((strlen(soap->dime.type)+3)&(~3)); + } + if (soap->mode & SOAP_ENC_DIME) + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); +#endif + soap->part = SOAP_END_ENVELOPE; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_in(struct soap *soap) +{ register struct Namespace *p; + soap->part = SOAP_IN_ENVELOPE; + if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0)) + return soap->error = SOAP_VERSIONMISMATCH; + p = soap->local_namespaces; + if (p) + { const char *ns = p[0].out; + if (!ns) + ns = p[0].ns; + if (!strcmp(ns, soap_env1)) + { soap->version = 1; /* make sure we use SOAP 1.1 */ + if (p[1].out) + SOAP_FREE(p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc1)))) + strcpy(p[1].out, soap_enc1); + } + else if (!strcmp(ns, soap_env2)) + { soap->version = 2; /* make sure we use SOAP 1.2 */ + if (p[1].out) + SOAP_FREE(p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc2)))) + strcpy(p[1].out, soap_enc2); + } + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_in(struct soap *soap) +{ if (soap_element_end_in(soap, "SOAP-ENV:Envelope")) + return soap->error; + soap->part = SOAP_END_ENVELOPE; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_out(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap->version == 1) + soap->encoding = 1; + if (soap_element(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + if ((soap->mode & SOAP_XML_SEC) && soap_attribute(soap, "id", "_0")) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Body")) + return soap->error; + soap->part = SOAP_IN_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_in(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + return soap_element_begin_in(soap, "SOAP-ENV:Body", 0); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_in(struct soap *soap) +{ if (soap_element_end_in(soap, "SOAP-ENV:Body")) + return soap->error; + soap->part = SOAP_END_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_header(struct soap *soap) +{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH) + soap->error = SOAP_OK; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_endpoint(struct soap *soap, const char *endpoint) +{ register const char *s; + register size_t i, n; + *soap->endpoint = '\0'; + *soap->host = '\0'; + *soap->path = '\0'; + soap->port = 80; + if (!endpoint || !*endpoint) + return; +#ifdef WITH_OPENSSL + if (!strncmp(endpoint, "https:", 6)) + soap->port = 443; +#endif + strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1); + s = strchr(endpoint, ':'); + if (s && s[1] == '/' && s[2] == '/') + s += 3; + else + s = endpoint; + n = strlen(s); + if (n >= sizeof(soap->host)) + n = sizeof(soap->host) - 1; +/* WR[ */ +#ifdef WITH_IPV6 + if ('[' == s[0]) + { s++; + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (']' == s[i]) + { + s++; + break; + } + } + } + else + { for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } + } +#else /* WITH_IPV6 */ +/* ]WR */ + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } +/* WR[ */ +#endif /* WITH_IPV6 */ +/* ]WR */ + soap->host[i] = '\0'; + if (s[i] == ':') + { soap->port = (int)atol(s + i + 1); + for (i++; i < n; i++) + if (s[i] == '/') + break; + } + if (s[i]) + { strncpy(soap->path, s + i + 1, sizeof(soap->path)); + soap->path[sizeof(soap->path) - 1] = '\0'; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect(struct soap *soap, const char *endpoint, const char *action) +{ return soap_connect_command(soap, SOAP_POST, endpoint, action); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action) +{ char host[sizeof(soap->host)]; + int port; + size_t count; + soap->error = SOAP_OK; + strcpy(host, soap->host); /* save to compare */ + port = soap->port; /* save to compare */ + soap_set_endpoint(soap, endpoint); + if (action) + soap->action = soap_strdup(soap, action); +#ifndef WITH_LEANER + if (soap->fconnect) + { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port))) + return soap->error; + } + else +#endif + if (soap->fopen && *soap->host) + { soap->status = http_command; + if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap)) + { soap->keep_alive = 0; /* force close */ + soap_closesock(soap); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port)); + soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port); + if (soap->error) + return soap->error; + soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0); + } + } + if (soap_begin_send(soap)) + return soap->error; + count = soap_count_attachments(soap); +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint) + { unsigned int k = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((k & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count))) + return soap->error; +#ifndef WITH_LEANER + if ((k & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = k; + } + if (http_command != SOAP_POST) + return soap_end_send(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2base64(struct soap *soap, const unsigned char *s, char *t, size_t n) +{ register size_t i; + register unsigned long m; + register char *p; + if (!t) + t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1); + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + t[0] = '\0'; + if (!s) + return p; + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + t += 4; + } + t[0] = '\0'; + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + t[i] = '='; + t[4] = '\0'; + } + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_base642s(struct soap *soap, const char *s, char *t, size_t l, size_t *n) +{ register int i, j, c; + register unsigned long m; + char *p = t; + if (n) + *n = 0; + for (;;) + { for (i = 0; i < SOAP_BLKLEN; i++) + { m = 0; + j = 0; + while (j < 4) + { c = *s++; + if (c == '=' || !c) + { i *= 3; + switch (j) + { case 2: + *t++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *t++ = (char)((m >> 10) & 0xFF); + *t++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n += i; + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } + *t++ = (char)((m >> 16) & 0xFF); + *t++ = (char)((m >> 8) & 0xFF); + *t++ = (char)(m & 0xFF); + if (l < 3) + { if (n) + *n += i; + return p; + } + l -= 3; + } + if (n) + *n += 3 * SOAP_BLKLEN; + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthttphdr(struct soap *soap, int status, size_t count) +{ register const char *s; + register int err; + if (status == SOAP_FILE && soap->http_content) + s = soap->http_content; + else if (status == SOAP_HTML) + s = "text/html; charset=utf-8"; +#ifndef WITH_LEANER + else if (soap->mode & SOAP_ENC_DIME) + s = "application/dime"; +#endif + else if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + else + s = "text/xml; charset=utf-8"; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->status != SOAP_GET) + { register const char *t = strchr(s, ';'); + sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary); + if (t) + strncat(soap->tmpbuf, s, t - s); + else + strcat(soap->tmpbuf, s); + if (soap->mime.start) + { strcat(soap->tmpbuf, "\"; start=\""); + strcat(soap->tmpbuf, soap->mime.start); + } + strcat(soap->tmpbuf, "\""); + s = soap->tmpbuf; + } +#endif + if ((err = soap->fposthdr(soap, "Content-Type", s))) + return err; +#ifdef WITH_ZLIB + if (soap->omode & SOAP_ENC_ZLIB) + { +#ifdef WITH_GZIP + err = soap->fposthdr(soap, "Content-Encoding", "gzip"); +#else + err = soap->fposthdr(soap, "Content-Encoding", "deflate"); +#endif + if (err) + return err; + } +#endif +#ifndef WITH_LEANER + if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK) + err = soap->fposthdr(soap, "Transfer-Encoding", "chunked"); + else +#endif + if (count > 0) + { sprintf(soap->tmpbuf, "%lu", (unsigned long)count); + err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf); + } + if (err) + return err; + return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_get(struct soap *soap) +{ return SOAP_GET_METHOD; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count) +{ register const char *s; + register int err; + if (soap->status == SOAP_GET) + { s = "GET"; + count = 0; + } + else + s = "POST"; +#ifdef PALM + if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8)) +#else + if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6))) +#endif + return SOAP_OK; + if (soap->proxy_host && strncmp(endpoint, "https:", 6)) + sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version); + else + sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, path, soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + if (port != 80) + sprintf(soap->tmpbuf, "%s:%d", host, port); + else + strcpy(soap->tmpbuf, host); + if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf)) + || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, SOAP_OK, count))) + return err; +#ifdef WITH_ZLIB +#ifdef WITH_GZIP + if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate"))) +#else + if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate"))) +#endif + return err; +#endif +#ifndef WITH_LEAN + if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf))) + return err; + } + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return err; + } +#endif +#ifdef WITH_COOKIES +#ifdef WITH_OPENSSL + if (soap_putcookies(soap, host, path, soap->ssl != NULL)) + return soap->error; +#else + if (soap_putcookies(soap, host, path, 0)) + return soap->error; +#endif +#endif + if (action && soap->version == 1) + { sprintf(soap->tmpbuf, "\"%s\"", action); + if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf))) + return err; + } + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_send_header(struct soap *soap, const char *s) +{ register const char *t; + do + { t = strchr(s, '\n'); /* disallow \n in HTTP headers */ + if (!t) + t = s + strlen(s); + if (soap_send_raw(soap, s, t - s)) + return soap->error; + s = t + 1; + } while (*t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post_header(struct soap *soap, const char *key, const char *val) +{ if (key) + { if (http_send_header(soap, key)) + return soap->error; + if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val))) + return soap->error; + } + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_response(struct soap *soap, int status, size_t count) +{ register int err; +/* WR[ */ +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + httpOutputEnable(soap->rpmreqid); +#endif /* WMW_RPM_IO */ +/* ]WR */ + if (!status || status == SOAP_HTML || status == SOAP_FILE) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "OK 200\n")); +/* WR[ */ +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else +/* ]WR */ + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +/* WR[ */ +#endif /* WMW_RPM_IO */ +/* ]WR */ + { sprintf(soap->tmpbuf, "HTTP/%s 200 OK", soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", "200 OK"))) + return err; + } + else if (status > 200 && status < 600) + { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status)); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; +#ifndef WITH_LEAN + if (status == 401) + { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", soap->authrealm ? soap->authrealm : "gSOAP Web Service"); + if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf))) + return err; + } + else if ((status >= 301 && status <= 303) || status == 307) + { if ((err = soap->fposthdr(soap, "Location", soap->endpoint))) + return err; + } +#endif + } + else + { const char *s = *soap_faultcode(soap); + if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender")) + s = "400 Bad Request"; + else + s = "500 Internal Server Error"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status)); +/* WR[ */ +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else +/* ]WR */ + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +/* WR[ */ +#endif /* WMW_RPM_IO */ +/* ]WR */ + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) + return err; + } + if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, status, count))) + return err; +#ifdef WITH_COOKIES + if (soap_putsetcookies(soap)) + return soap->error; +#endif + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_response(struct soap *soap, int status) +{ register size_t count; + if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */)) + && (status == SOAP_HTML || status == SOAP_FILE)) + { soap->omode &= ~SOAP_IO; + soap->omode |= SOAP_IO_STORE; + } + soap->status = status; + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML)) + { register int n = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((n & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fresponse(soap, status, count))) + return soap->error; +#ifndef WITH_LEANER + if ((n & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = n; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static const char* +soap_set_validation_fault(struct soap *soap, const char *s, const char *t) +{ sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag); + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_fault(struct soap *soap) +{ const char **c = soap_faultcode(soap); + const char **s = soap_faultstring(soap); + if (!*c) + { if (soap->version == 2) + *c = "SOAP-ENV:Sender"; + else + *c = "SOAP-ENV:Client"; + } + if (*s) + return; + switch (soap->error) + { +#ifndef WITH_LEAN + case SOAP_CLI_FAULT: + *s = "Client fault"; + break; + case SOAP_SVR_FAULT: + *s = "Server fault"; + break; + case SOAP_TAG_MISMATCH: + *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL); + break; + case SOAP_TYPE: + *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type); + break; + case SOAP_SYNTAX_ERROR: + *s = "Well-formedness constraint violation"; + break; + case SOAP_NO_TAG: + *s = "No XML element tag found"; + break; + case SOAP_MUSTUNDERSTAND: + *c = "SOAP-ENV:MustUnderstand"; + sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_VERSIONMISMATCH: + *c = "SOAP-ENV:VersionMismatch"; + *s = "SOAP version mismatch or invalid SOAP message"; + break; + case SOAP_DATAENCODINGUNKNOWN: + *c = "SOAP-ENV:DataEncodingUnknown"; + *s = "Unsupported SOAP data encoding"; + break; + case SOAP_NAMESPACE: + *s = soap_set_validation_fault(soap, "namespace mismatch", NULL); + break; + case SOAP_FATAL_ERROR: + *s = "Fatal error"; + break; + case SOAP_NO_METHOD: + sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_GET_METHOD: + *s = "HTTP GET method not implemented"; + break; + case SOAP_EOM: + *s = "Out of memory"; + break; + case SOAP_IOB: + *s = "Array index out of bounds"; + break; + case SOAP_NULL: + *s = soap_set_validation_fault(soap, "nil not allowed", NULL); + break; + case SOAP_MULTI_ID: + *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id); + break; + case SOAP_MISSING_ID: + *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id); + break; + case SOAP_HREF: + *s = soap_set_validation_fault(soap, "incompatible object ref ", soap->id); + break; + case SOAP_FAULT: + break; +#ifndef WITH_NOIO + case SOAP_TCP_ERROR: + *s = tcp_error(soap); + break; +#endif + case SOAP_HTTP_ERROR: + *s = "HTTP error"; + break; + case SOAP_SSL_ERROR: + *s = "SSL error"; + break; + case SOAP_PLUGIN_ERROR: + *s = "Plugin registry error"; + break; + case SOAP_DIME_MISMATCH: + *s = "DIME version/transmission error"; + break; + case SOAP_DIME_END: + *s = "End of DIME error"; + break; + case SOAP_DIME_ERROR: + *s = "DIME format error"; + break; + case SOAP_MIME_ERROR: + *s = "MIME format error"; + break; + case SOAP_ZLIB_ERROR: +#ifdef WITH_ZLIB + sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:""); + *s = soap->msgbuf; +#else + *s = "Zlib not installed for required message (de)compression"; +#endif + break; + case SOAP_REQUIRED: + *s = soap_set_validation_fault(soap, "missing required attribute", NULL); + break; + case SOAP_PROHIBITED: + *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL); + break; + case SOAP_OCCURS: + *s = soap_set_validation_fault(soap, "a min/maxOccurs violation was detected", NULL); + break; + case SOAP_LENGTH: + *s = soap_set_validation_fault(soap, "content length violation", NULL); + break; +#endif + case SOAP_EOF: +#ifndef WITH_NOIO + sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap)); + *s = soap->msgbuf; + break; +#else + *s = "End of file or no input"; + break; +#endif + default: +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN + if (soap->error > 200 && soap->error < 600) + { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error)); + *s = soap->msgbuf; + } + else +#endif +#endif + { sprintf(soap->msgbuf, "Error code %d", soap->error); + *s = soap->msgbuf; + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_fault(struct soap *soap) +{ register int status = soap->error; + if (status == SOAP_STOP) + return status; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error)); + soap->keep_alive = 0; /* to terminate connection */ + soap_set_fault(soap); + if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && (!soap->fpoll || soap->fpoll(soap) == SOAP_OK)) + { soap->error = SOAP_OK; + soap_serializeheader(soap); + soap_serializefault(soap); + soap_begin_count(soap); + if (soap->mode & SOAP_IO_LENGTH) + { soap_envelope_begin_out(soap); + soap_putheader(soap); + soap_body_begin_out(soap); + soap_putfault(soap); + soap_body_end_out(soap); + soap_envelope_end_out(soap); + } + if (soap_response(soap, status) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_putfault(soap) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap_closesock(soap); + soap_end_send(soap); + } + soap->error = status; + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_fault(struct soap *soap) +{ register int status = soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Receiving SOAP Fault\n")); + soap->error = SOAP_OK; + if (soap_getfault(soap)) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n")); + *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client"); + soap->error = status; + soap_set_fault(soap); + } + else + { register const char *s = *soap_faultcode(soap); + if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver")) + status = SOAP_SVR_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender")) + status = SOAP_CLI_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand")) + status = SOAP_MUSTUNDERSTAND; + else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch")) + status = SOAP_VERSIONMISMATCH; + else + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Fault code %s\n", s)); + status = SOAP_FAULT; + } + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + soap->error = status; + } + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_empty_response(struct soap *soap) +{ soap->count = 0; + if (soap_response(soap, SOAP_OK) || soap_end_send(soap)) + return soap_closesock(soap); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_empty_response(struct soap *soap) +{ if (soap_begin_recv(soap) || soap_end_recv(soap)) + return soap_closesock(soap); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +soap_strerror(struct soap *soap) +{ + int err = soap->errnum; + if (!err) + err = soap_errno; + if (err) + { +#ifndef WIN32 + return strerror(err); +#else + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&soap->errorstr, sizeof(soap->errorstr), NULL); + return soap->errorstr; +#endif + } + return "Operation interrupted or timed out"; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_set_error(struct soap *soap, const char *faultcode, const char *faultstring, const char *faultdetail, int soaperror) +{ *soap_faultcode(soap) = faultcode; + *soap_faultstring(soap) = faultstring; + if (faultdetail && *faultdetail) + { register const char **s = soap_faultdetail(soap); + if (s) + *s = faultdetail; + } + return soap->error = soaperror; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultstring, const char *faultdetail) +{ char *s = NULL, *t = NULL; + if (faultstring) + s = soap_strdup(soap, faultstring); + if (faultdetail) + t = soap_strdup(soap, faultdetail); + return soap_set_error(soap, faultcode, s, t, SOAP_FAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef WITH_NOIO +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault(struct soap *soap, FILE *fd) +{ if (soap->error) + { const char **s; + if (!*soap_faultcode(soap)) + soap_set_fault(soap); + fprintf(fd, "SOAP FAULT: %s\n\"%s\"\n", *soap_faultcode(soap), *soap_faultstring(soap)); + s = soap_faultdetail(soap); + if (s && *s) + fprintf(fd, "Detail: %s\n", *s); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +#ifndef WITH_NOIO +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault_location(struct soap *soap, FILE *fd) +{ +#ifndef WITH_LEAN + int c; + if (soap->error && soap->buflen > 0) + { if (soap->bufidx == 0) + soap->bufidx = 1; + c = soap->buf[soap->bufidx - 1]; + soap->buf[soap->bufidx - 1] = '\0'; + if (soap->buflen - soap->bufidx > 1024) + soap->buf[soap->bufidx + 1024] = '\0'; + else + soap->buf[soap->buflen - 1] = '\0'; + fprintf(fd, "%s%c\n** HERE **\n", soap->buf, c); + if (soap->bufidx < soap->buflen) + fprintf(fd, "%s\n", soap->buf + soap->bufidx); + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg) +{ register struct soap_plugin *p; + register int r; + if (!(p = (struct soap_plugin*)SOAP_MALLOC(sizeof(struct soap_plugin)))) + return soap->error = SOAP_EOM; + p->id = NULL; + p->data = NULL; + p->fcopy = NULL; + p->fdelete = NULL; + r = fcreate(soap, p, arg); + if (!r && p->fdelete) + { p->next = soap->plugins; + soap->plugins = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id)); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r)); + SOAP_FREE(p); + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void * +fplugin(struct soap *soap, const char *id) +{ register struct soap_plugin *p; + for (p = soap->plugins; p; p = p->next) + if (p->id == id || !strcmp(p->id, id)) + return p->data; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void * +SOAP_FMAC2 +soap_lookup_plugin(struct soap *soap, const char *id) +{ return soap->fplugin(soap, id); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif + diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h new file mode 100644 index 0000000..097b551 --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h @@ -0,0 +1,1885 @@ +/* + +stdsoap2.h 2.7.0f + +gSOAP runtime environment. + +gSOAP XML Web services tools +Copyright (C) 2000-2005, Robert van Engelen, Genivia, Inc., All Rights Reserved. + +Contributors: + +Wind River Systems, Inc., for the following additions (marked WR[...]) : + - vxWorks compatible + - Support for IPv6. + +-------------------------------------------------------------------------------- + + This software is released under one of the following three licenses: + GPL, the gSOAP public license, or Genivia's license for commercial use. + +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2005, Robert van Engelen, Genivia, Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- +*/ + +#ifdef WITH_SOAPDEFS_H +# include "soapdefs.h" /* include user-defined stuff */ +#endif + +#ifndef _THREAD_SAFE +# define _THREAD_SAFE +#endif + +#ifndef OPENSERVER +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +#ifndef SOAP_BEGIN_NAMESPACE +# define SOAP_BEGIN_NAMESPACE(name) +#endif + +#ifndef SOAP_END_NAMESPACE +# define SOAP_END_NAMESPACE(name) +#endif + +#ifndef SOAP_FMAC1 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC1 +#endif + +#ifndef SOAP_FMAC2 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC2 +#endif + +#ifndef SOAP_FMAC3 /* (de)serializer declaration macro */ +# define SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC3S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC3S SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC4 /* (de)serializer declaration macro */ +# define SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC4S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC4S SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC5 /* stub/skeleton declaration macro */ +# define SOAP_FMAC5 +#endif + +#ifndef SOAP_FMAC6 /* stub/skeleton declaration macro */ +# define SOAP_FMAC6 +#endif + +#ifndef SOAP_CMAC /* class declaration macro */ +# define SOAP_CMAC +#endif + +#ifndef SOAP_NMAC /* namespace table declaration macro */ +# define SOAP_NMAC +#endif + +#ifndef SOAP_SOURCE_STAMP +# define SOAP_SOURCE_STAMP(str) +#endif + +#ifdef WITH_LEANER +# ifndef WITH_LEAN +# define WITH_LEAN +# endif +#endif + +#ifdef WITH_LEAN +# ifdef WITH_COOKIES +# error "Cannot build WITH_LEAN code WITH_COOKIES enabled" +# endif +#endif + +#ifndef STDSOAP_H +#define STDSOAP_H + +#if defined(__vxworks) || defined(__VXWORKS__) +# define VXWORKS +#endif + +#ifdef _WIN32 +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef UNDER_CE +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef __BORLANDC__ +# ifdef __WIN32__ +# ifndef WIN32 +# define WIN32 +# endif +# endif +#endif + +#ifdef __CYGWIN__ +# ifndef CYGWIN +# define CYGWIN +# endif +#endif + +#ifdef __SYMBIAN32__ +# define SYMBIAN +# undef WIN32 +#endif + +#if defined(__palmos__) || defined(PALM_GCC) || defined(__PALMOS_TRAPS__) +# ifndef PALM +# define PALM +# endif +#endif + +#if defined(__hpux) +# ifndef HP_UX +# define HP_UX +# endif +#endif + +#ifdef __alpha +# ifndef TRU64 +# define TRU64 +# endif +#endif + +#ifdef __MVS__ +# ifndef OS390 +# define OS390 +# endif +#endif + +#ifdef _AIX +# define __socklen_t_defined +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# if defined(UNDER_CE) +# define WITH_LEAN +# define HAVE_SSCANF +# elif defined(WIN32) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(CYGWIN) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__APPLE__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(_AIXVERSION_431) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(HP_UX) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(FREEBSD) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_GETTIMEOFDAY +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__VMS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__GLIBC__) || defined(__GNU__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define HAVE_ISNAN +# elif defined(TRU64) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_GETTIMEOFDAY +# define HAVE_SYS_TIMEB_H +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define __USE_STD_IOSTREAM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(MAC_CARBON) +# define WITH_NOIO +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(PALM) +# define WITH_LEAN +# define HAVE_STRTOD /* strtod() is defined in palmFunctions.h */ +# include /* Needs to be included before unix headers */ +# include +# define IGNORE_STDIO_STUBS +# include +# define O_NONBLOCK FNONBIO +# include +# include +# include "palmFunctions.h" +# elif defined(SYMBIAN) +# define WITH_LEAN +# define WITH_NONAMESPACES +# define HAVE_STRTOD /* use STRTOD since sscanf doesn't seem to work */ +# include +# include +# elif defined(VXWORKS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_RAND_R +# define HAVE_PGMTIME_R +# define HAVE_PLOCALTIME_R +# define HAVE_MKTIME +# elif defined(OS390) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MB +# else +/* Default asumptions on supported functions */ +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# endif +#endif + +#if defined(TRU64) +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +#elif defined(WIN32) +# define SOAP_LONG_FORMAT "%I64d" +# define SOAP_ULONG_FORMAT "%I64u" +#endif + +#ifndef SOAP_LONG_FORMAT +# define SOAP_LONG_FORMAT "%lld" /* printf format for 64 bit ints */ +#endif + +#ifndef SOAP_ULONG_FORMAT +# define SOAP_ULONG_FORMAT "%llu" /* printf format for unsigned 64 bit ints */ +#endif + +#ifndef SOAP_MALLOC /* use libc malloc */ +# define SOAP_MALLOC(n) malloc(n) +#endif + +#ifndef SOAP_FREE /* use libc free */ +# define SOAP_FREE(p) free(p) +#endif + +#include + +#ifndef PALM +# include +# include +#endif + +#include +#include + +#if defined(__cplusplus) && !defined(WITH_LEAN) +# include +# include + using namespace std; +#endif + +#ifdef WITH_NOHTTP +# ifndef WITH_NOIO +# define WITH_NOIO +# undef WITH_COOKIES +# endif +#endif + +#ifndef UNDER_CE +# ifndef PALM +# ifndef WITH_NOIO +# include +# include +# endif +# ifndef WITH_LEAN +# ifdef HAVE_SYS_TIMEB_H +# include /* for ftime() */ +# endif +# include +# endif +# endif +#endif + +#ifdef OPENSERVER +# include +# include +# include + extern int h_errno; +#endif + +#ifndef WITH_NOIO +# ifndef WIN32 +# ifndef PALM +# include +# ifdef VXWORKS +# include +# endif +# ifndef VXWORKS +# ifndef SYMBIAN +# include +# endif +# endif +# ifdef SUN_OS +# include /* SUN */ +# include /* SUN < 2.8 (?) */ +# endif +# ifdef VXWORKS +# include +# else +# include +# endif +# include +# ifdef OS390 +# include +# else +# include /* TCP_NODELAY */ +# endif +# include +# endif +# endif +#endif + +#ifdef WITH_FASTCGI +# include +#endif + +#ifdef WITH_OPENSSL +# define OPENSSL_NO_KRB5 +# include +# include +# include +# ifndef ALLOW_OLD_VERSIONS +# if (OPENSSL_VERSION_NUMBER < 0x00905100L) +# error "Must use OpenSSL 0.9.6 or later" +# endif +# endif +#endif + +#ifdef WITH_GZIP +# ifndef WITH_ZLIB +# define WITH_ZLIB +# endif +#endif + +#ifdef WITH_CASEINSENSITIVETAGS +# define SOAP_STRCMP soap_tag_cmp /* case insensitve XML element/attribute names */ +#else +# define SOAP_STRCMP strcmp /* case sensitive XML element/attribute names */ +#endif + +#ifdef WITH_ZLIB +# include +#endif + +#ifndef PALM +# include /* for isnan() */ +#endif + +/* #define DEBUG */ /* Uncomment to debug sending (in file SENT.log) receiving (in file RECV.log) and messages (in file TEST.log) */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +# ifndef UNDER_CE +# include +# include +# endif +# include +/* # include */ /* Alternative: use winsock2 (not available with eVC) */ +/* WR[ */ +# ifdef WITH_IPV6 +# include +# include +# endif +#else +# ifdef VXWORKS +# include +# include +# include +# endif +/* ]WR */ +# ifndef WITH_NOIO +# ifndef PALM +# include +# include +# include +# include +# endif +# endif +#endif + +#ifdef WIN32 +# define SOAP_SOCKET SOCKET +#else +# define SOAP_SOCKET int +# define closesocket(n) close(n) +#endif + +#define SOAP_INVALID_SOCKET (-1) +#define soap_valid_socket(n) ((n) != SOAP_INVALID_SOCKET) + +#if defined(SYMBIAN) +# define LONG64 long +# define ULONG64 unsigned LONG64 +#elif !defined(WIN32) || defined(__GLIBC__) || defined(__GNU__) +# ifndef LONG64 +# define LONG64 long long +# define ULONG64 unsigned LONG64 +# endif +#elif defined(UNDER_CE) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#elif defined(__BORLANDC__) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#endif + +#if defined(WIN32) +# define soap_int32 __int32 +#elif defined(SYMBIAN) +# define soap_int32 long +#elif defined(PALM) +# define soap_int32 Int32 +#else +# define soap_int32 int32_t +#endif + +#ifdef WIN32 +# define SOAP_EINTR WSAEINTR +# define SOAP_EAGAIN WSAEWOULDBLOCK +# define SOAP_EWOULDBLOCK WSAEWOULDBLOCK +# define SOAP_EINPROGRESS WSAEINPROGRESS +#else +# define SOAP_EINTR EINTR +# define SOAP_EAGAIN EAGAIN +# ifdef SYMBIAN +# define SOAP_EWOULDBLOCK 9898 +# define SOAP_EINPROGRESS 9899 +# else +# define SOAP_EWOULDBLOCK EWOULDBLOCK +# define SOAP_EINPROGRESS EINPROGRESS +# endif +#endif + +#ifdef WIN32 +# ifdef UNDER_CE +# define soap_errno GetLastError() +# define soap_socket_errno GetLastError() +# else +# define soap_errno GetLastError() +# define soap_socket_errno WSAGetLastError() +# endif +#else +# ifndef WITH_NOIO +# define soap_errno errno +# define soap_socket_errno errno +# else +# define soap_errno 0 +# define soap_socket_errno 0 +# endif +#endif + +#ifndef SOAP_BUFLEN +# ifndef WITH_LEAN +# define SOAP_BUFLEN (32768) /* buffer length for socket packets, also used by gethostbyname_r so don't make this too small */ +# else +# define SOAP_BUFLEN (2048) +# endif +#endif +#ifndef SOAP_LABLEN +# ifndef WITH_LEAN +# define SOAP_LABLEN (256) /* initial look-aside buffer length */ +# else +# define SOAP_LABLEN (32) +# endif +#endif +#ifndef SOAP_PTRHASH +# ifndef WITH_LEAN +# define SOAP_PTRHASH (1024) /* size of pointer analysis hash table (must be power of 2) */ +# else +# define SOAP_PTRHASH (16) +# endif +#endif +#ifndef SOAP_IDHASH +# ifndef WITH_LEAN +# define SOAP_IDHASH (1999) /* prime size of hash table for parsed id/ref */ +# else +# define SOAP_IDHASH (19) /* 19, 199 */ +# endif +#endif +#ifndef SOAP_BLKLEN +# ifndef WITH_LEAN +# define SOAP_BLKLEN (256) /* size of blocks to collect long strings and XML attributes */ +# else +# define SOAP_BLKLEN (32) +# endif +#endif +#ifndef SOAP_TAGLEN +# ifndef WITH_LEAN +# define SOAP_TAGLEN (256) /* maximum length of XML element tag/attribute name or host/path name + 1 */ +# else +# define SOAP_TAGLEN (64) +# endif +#endif +#ifndef SOAP_HDRLEN +# ifndef WITH_LEAN +# define SOAP_HDRLEN (8192) /* maximum length of HTTP header line (must be >4096 to read cookies) */ +# else +# define SOAP_HDRLEN (1024) +# endif +#endif +#ifndef SOAP_MAXDIMS +# ifndef WITH_LEAN +# define SOAP_MAXDIMS (16) /* maximum array dimensions (array nestings) must be less than 64 to protect soap->tmpbuf */ +# else +# define SOAP_MAXDIMS (4) +# endif +#endif + +#ifndef SOAP_MAXLOGS +# define SOAP_MAXLOGS (3) /* max number of debug logs per struct soap environment */ +# define SOAP_INDEX_RECV (0) +# define SOAP_INDEX_SENT (1) +# define SOAP_INDEX_TEST (2) +#endif + +#ifndef SOAP_MAXKEEPALIVE +# define SOAP_MAXKEEPALIVE (100) /* max iterations to keep server connection alive */ +#endif + +#ifndef SOAP_MAXARRAYSIZE +# define SOAP_MAXARRAYSIZE (100000) /* "trusted" max size of inbound SOAP array for compound array allocation */ +#endif + +#ifdef VXWORKS +# ifdef __INCmathh +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) isNan(num) +# endif +#endif + +#ifdef WIN32 +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) _isnan(num) +#endif + +#ifdef SUN_OS +# define soap_isnan(n) isnan(n) +#endif + +#if !defined(HAVE_ISNAN) && (defined(_MATH_H) || defined(_MATH_INCLUDED)) +# define HAVE_ISNAN +#endif + +#ifndef soap_isnan +# ifdef HAVE_ISNAN +# define soap_isnan(n) isnan(n) +# else +# define soap_isnan(_) (0) +# endif +#endif + +extern const struct soap_double_nan { unsigned int n1, n2; } soap_double_nan; + +#ifdef VXWORKS +# ifndef FLT_MAX +# define FLT_MAX _ARCH_FLT_MAX +# endif +# ifndef DBL_MAX +# define DBL_MAX _ARCH_DBL_MAX +# endif +#endif + +#ifndef FLT_NAN +# ifdef HAVE_ISNAN +# define FLT_NAN (*(float*)&soap_double_nan) +# else +# define FLT_NAN (0.0) +# endif +#endif + +#ifndef FLT_PINFTY +# ifdef FLT_MAX +# define FLT_PINFTY FLT_MAX +# else +# ifdef HUGE_VAL +# define FLT_PINFTY (float)HUGE_VAL +# else +# ifdef FLOAT_MAX +# define FLT_PINFTY FLOAT_MAX +# else +# define FLT_PINFTY (3.40282347e+38F) +# endif +# endif +# endif +#endif + +#ifndef FLT_NINFTY +# define FLT_NINFTY (-FLT_PINFTY) +#endif + +#ifndef DBL_NAN +# ifdef HAVE_ISNAN +# define DBL_NAN (*(double*)&soap_double_nan) +# else +# define DBL_NAN (0.0) +# endif +#endif + +#ifndef DBL_PINFTY +# ifdef DBL_MAX +# define DBL_PINFTY DBL_MAX +# else +# ifdef HUGE_VAL +# define DBL_PINFTY (double)HUGE_VAL +# else +# ifdef DOUBLE_MAX +# define DBL_PINFTY DOUBLE_MAX +# else +# define DBL_PINFTY (1.7976931348623157e+308) +# endif +# endif +# endif +#endif + +#ifndef DBL_NINFTY +# define DBL_NINFTY (-DBL_PINFTY) +#endif + +#define soap_ispinfd(n) ((n) >= DBL_PINFTY) +#define soap_ispinff(n) ((n) >= FLT_PINFTY) +#define soap_isninfd(n) ((n) <= DBL_NINFTY) +#define soap_isninff(n) ((n) <= FLT_NINFTY) + +/* gSOAP error codes */ + +#define SOAP_EOF EOF +#define SOAP_ERR EOF +#define SOAP_OK 0 +#define SOAP_CLI_FAULT 1 +#define SOAP_SVR_FAULT 2 +#define SOAP_TAG_MISMATCH 3 +#define SOAP_TYPE 4 +#define SOAP_SYNTAX_ERROR 5 +#define SOAP_NO_TAG 6 +#define SOAP_IOB 7 +#define SOAP_MUSTUNDERSTAND 8 +#define SOAP_NAMESPACE 9 +/* #define SOAP_OBJ_MISMATCH 10 obsolete */ +#define SOAP_FATAL_ERROR 11 +#define SOAP_FAULT 12 +#define SOAP_NO_METHOD 13 +#define SOAP_GET_METHOD 14 +#define SOAP_EOM 15 +#define SOAP_NULL 16 +#define SOAP_MULTI_ID 17 +#define SOAP_MISSING_ID 18 +#define SOAP_HREF 19 +#define SOAP_TCP_ERROR 20 +#define SOAP_HTTP_ERROR 21 +#define SOAP_SSL_ERROR 22 +#define SOAP_ZLIB_ERROR 23 +#define SOAP_DIME_ERROR 24 +#define SOAP_DIME_HREF 25 +#define SOAP_DIME_MISMATCH 26 +#define SOAP_DIME_END 27 +#define SOAP_MIME_ERROR 28 +#define SOAP_VERSIONMISMATCH 29 +#define SOAP_PLUGIN_ERROR 30 +#define SOAP_DATAENCODINGUNKNOWN 31 +#define SOAP_REQUIRED 32 +#define SOAP_PROHIBITED 33 +#define SOAP_OCCURS 34 +#define SOAP_LENGTH 35 + +#define soap_xml_error_check(e) ((e) == SOAP_TAG_MISMATCH || (e) == SOAP_TAG_END || (e) == SOAP_SYNTAX_ERROR || (e) == SOAP_NAMESPACE || (e) == SOAP_MULTI_ID || (e) == SOAP_MISSING_ID || (e) == SOAP_REQUIRED || (e) == SOAP_PROHIBITED || (e) == SOAP_OCCURS || (e) == SOAP_LENGTH || (e) == SOAP_NULL || (e) == SOAP_HREF) +#define soap_soap_error_check(e) ((e) == SOAP_CLI_FAULT || (e) == SOAP_SVR_FAULT || (e) == SOAP_VERSIONMISMATCH || (e) == SOAP_MUSTUNDERSTAND || (e) == SOAP_FAULT || (e) == SOAP_NO_METHOD) +#define soap_tcp_error_check(e) ((e) == SOAP_EOF || (e) == SOAP_TCP_ERROR) +#define soap_ssl_error_check(e) ((e) == SOAP_SSL_ERROR) +#define soap_zlib_error_check(e) ((e) == SOAP_ZLIB_ERROR) +#define soap_mime_error_check(e) ((e) == SOAP_MIME_ERROR) +#define soap_dime_error_check(e) ((e) == SOAP_DIME_ERROR || (e) == SOAP_DIME_MISMATCH) +#define soap_http_error_check(e) ((e) == SOAP_HTTP_ERROR || (e) == SOAP_GET_METHOD || ((e) >= 100 && (e) < 600)) + +/* gSOAP HTTP response status codes 100 to 600 are reserved */ + +/* Special gSOAP HTTP response status codes */ + +#define SOAP_STOP 1000 /* No HTTP response */ +#define SOAP_HTML 1001 /* Custom HTML response */ +#define SOAP_FILE 1002 /* Custom file-based response */ + +/* gSOAP HTTP request status codes */ + +#define SOAP_POST 1003 +#define SOAP_GET 1104 + +/* gSOAP DIME */ + +#define SOAP_DIME_CF 0x01 +#define SOAP_DIME_ME 0x02 +#define SOAP_DIME_MB 0x04 +#define SOAP_DIME_VERSION 0x08 /* DIME version 1 */ +#define SOAP_DIME_MEDIA 0x10 +#define SOAP_DIME_ABSURI 0x20 + +/* gSOAP ZLIB */ + +#define SOAP_ZLIB_NONE 0x00 +#define SOAP_ZLIB_DEFLATE 0x01 +#define SOAP_ZLIB_INFLATE 0x02 +#define SOAP_ZLIB_GZIP 0x02 + +/* gSOAP transport, connection, and content encoding modes */ + +typedef soap_int32 soap_mode; + +#define SOAP_IO 0x00000003 /* IO mask */ +#define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */ +#define SOAP_IO_BUFFER 0x00000001 /* buffer output in packets of size SOAP_BUFLEN */ +#define SOAP_IO_STORE 0x00000002 /* store entire output to determine length for transport */ +#define SOAP_IO_CHUNK 0x00000003 /* use HTTP chunked transfer AND buffer packets */ + +#define SOAP_IO_LENGTH 0x00000004 +#define SOAP_IO_KEEPALIVE 0x00000008 + +#define SOAP_ENC_LATIN 0x00800010 /* iso-8859-1 encoding */ +#define SOAP_ENC_XML 0x00000020 /* plain XML encoding, no HTTP header */ +#define SOAP_ENC_DIME 0x00000040 +#define SOAP_ENC_MIME 0x00000080 +#define SOAP_ENC_ZLIB 0x00000100 +#define SOAP_ENC_SSL 0x00000200 + +#define SOAP_ENC 0x00000FFF /* IO and ENC mask */ + +#define SOAP_XML_STRICT 0x00001000 /* strict validation */ +#define SOAP_XML_CANONICAL 0x00002000 /* C14N canonical XML */ +#define SOAP_XML_TREE 0x00004000 +#define SOAP_XML_GRAPH 0x00008000 +#define SOAP_XML_NIL 0x00010000 +#define SOAP_XML_DOM 0x00020000 +#define SOAP_XML_SEC 0x00040000 /* reserved for WS security */ + +#define SOAP_C_NOIOB 0x00100000 +#define SOAP_C_UTFSTRING 0x00200000 +#define SOAP_C_MBSTRING 0x00400000 + +#define SOAP_DOM_TREE 0x01000000 +#define SOAP_DOM_NODE 0x02000000 + +#define SOAP_IO_DEFAULT SOAP_IO_FLUSH + +/* SSL client/server authentication settings */ + +#define SOAP_SSL_NO_AUTHENTICATION 0x00 /* for testing purposes */ +#define SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION 0x01 /* client requires server to authenticate */ +#define SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION 0x02 /* server requires client to authenticate */ + +#define SOAP_SSL_DEFAULT SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION + +/* */ + +#define SOAP_BEGIN 0 +#define SOAP_IN_ENVELOPE 2 +#define SOAP_IN_HEADER 3 +#define SOAP_END_HEADER 4 +#define SOAP_IN_BODY 5 +#define SOAP_END_BODY 6 +#define SOAP_END_ENVELOPE 7 +#define SOAP_END 8 + +/* DEBUG macros */ + +#ifndef WITH_LEAN +# ifdef DEBUG +# ifndef SOAP_DEBUG +# define SOAP_DEBUG +# endif +# endif +#endif + +#ifdef SOAP_DEBUG +# ifndef SOAP_MESSAGE +# define SOAP_MESSAGE fprintf +# endif +# ifndef DBGLOG +# define DBGLOG(DBGFILE, CMD) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { FILE *fdebug = soap->fdebug[SOAP_INDEX_##DBGFILE];\ + CMD;\ + fflush(fdebug);\ + }\ + }\ +} +# endif +# ifndef DBGMSG +# define DBGMSG(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { fwrite((MSG), 1, (LEN), soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +#else +# define DBGLOG(DBGFILE, CMD) +# define DBGMSG(DBGFILE, MSG, LEN) +#endif + +/* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to distinguish XML entities) */ +typedef soap_int32 soap_wchar; + +struct Namespace +{ const char *id; + const char *ns; + const char *in; + char *out; +}; + +struct soap_nlist +{ struct soap_nlist *next; + unsigned int level; + short index; /* corresponding entry in ns mapping table */ + char *ns; /* only set when parsed ns URI is not in the ns mapping table */ + char id[1]; /* the actual string value flows into the allocated region below this struct */ +}; + +struct soap_blist +{ struct soap_blist *next; + char *ptr; + size_t size; +}; + +struct soap_array +{ void *__ptr; + int __size; +}; + +/* pointer serialization management */ +struct soap_plist +{ struct soap_plist *next; + const void *ptr; + const struct soap_array *array; + int type; + int id; + char mark1; + char mark2; +}; + +/* class allocation list */ +struct soap_clist +{ struct soap_clist *next; + void *ptr; + int type; + int size; + void (*fdelete)(struct soap_clist*); +}; + +struct soap_attribute +{ struct soap_attribute *next; + char *value; + size_t size; + char *ns; + short visible; + char name[1]; /* the actual name string flows into the allocated region below this struct */ +}; + +struct soap_cookie +{ struct soap_cookie *next; + char *name; + char *value; + char *domain; + char *path; + long expire; /* client-side: local time to expire; server-side: seconds to expire */ + unsigned int version; + short secure; + short session; /* server-side */ + short env; /* server-side: got cookie from client */ + short modified; /* server-side: client cookie was modified */ +}; + +#ifdef __cplusplus +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); + +class soap_multipart_iterator +{ public: + struct soap_multipart *content; + bool operator==(const soap_multipart_iterator& iter) const + { return content == iter.content; } + bool operator!=(const soap_multipart_iterator& iter) const + { return content != iter.content; } + struct soap_multipart &operator*() const + { return *content; } + soap_multipart_iterator &operator++() + { content = soap_next_multipart(content); return *this; } + soap_multipart_iterator() : content(NULL) + { } + soap_multipart_iterator(struct soap_multipart *p) : content(p) + { } +}; +#endif + +#ifndef WITH_LEANER +struct soap_dime +{ size_t count; + size_t size; + size_t chunksize; + size_t buflen; + char flags; + char *ptr; + const char *id; + const char *type; + const char *options; + struct soap_multipart *list; /* list of DIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +struct soap_mime +{ char *boundary; /* MIME boundary */ + const char *start; /* MIME start ID */ + struct soap_multipart *list; /* list of DIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* RFC2045 MIME content transfer encodings */ +enum soap_mime_encoding +{ SOAP_MIME_NONE, + SOAP_MIME_7BIT, + SOAP_MIME_8BIT, + SOAP_MIME_BINARY, + SOAP_MIME_QUOTED_PRINTABLE, + SOAP_MIME_BASE64, + SOAP_MIME_IETF_TOKEN, + SOAP_MIME_X_TOKEN +}; +#endif + +#ifndef WITH_LEANER +/* DIME/MIME multipart list */ +struct soap_multipart +{ struct soap_multipart *next; + char *ptr; /* points to raw data content */ + size_t size; /* size of data content */ + const char *id; /* DIME/MIME content ID */ + const char *type; /* DIME/MIME type (MIME type format) */ + const char *options; /* DIME options */ + enum soap_mime_encoding encoding; /* MIME Content-Transfer-Encoding */ + const char *location; /* MIME Content-Location (optional) */ + const char *description; /* MIME Content-Description (optional) */ +#ifdef __cplusplus + typedef soap_multipart_iterator iterator; +#endif +}; +#endif + +#ifndef WITH_LEANER +struct soap_dom_attribute +{ struct soap_dom_attribute *next; + const char *nstr; + char *name; + char *data; + wchar_t *wide; + struct soap *soap; +#ifdef __cplusplus + struct soap_dom_attribute &set(const char *nstr, const char *name); /* set namespace and name */ + struct soap_dom_attribute &set(const char *data); /* set data */ + void unlink(); + soap_dom_attribute(); + soap_dom_attribute(struct soap *soap); + soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data); + ~soap_dom_attribute(); +#endif +}; +#endif + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_iterator +{ public: + struct soap_dom_element *elt; + const char *nstr; + const char *name; + int type; + bool operator==(const soap_dom_iterator&) const; + bool operator!=(const soap_dom_iterator&) const; + struct soap_dom_element &operator*() const; + soap_dom_iterator &operator++(); + soap_dom_iterator(); + soap_dom_iterator(struct soap_dom_element*); + ~soap_dom_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_element +{ struct soap_dom_element *next; /* next sibling */ + struct soap_dom_element *prnt; /* parent */ + struct soap_dom_element *elts; /* first child element */ + struct soap_dom_attribute *atts; /* first child attribute */ + const char *nstr; /* namespace string */ + char *name; /* element tag name */ + char *data; /* element content data (with SOAP_C_UTFSTRING flag set) */ + wchar_t *wide; /* element content data */ + int type; /* optional: serialized C/C++ data type */ + void *node; /* optional: pointer to serialized C/C++ data */ + struct soap *soap; +#ifdef __cplusplus + typedef soap_dom_iterator iterator; + struct soap_dom_element &set(const char *nstr, const char *name); + struct soap_dom_element &set(const char *data); + struct soap_dom_element &set(void *node, int type); + struct soap_dom_element &add(struct soap_dom_element*); + struct soap_dom_element &add(struct soap_dom_element&); + struct soap_dom_element &add(struct soap_dom_attribute*); + struct soap_dom_element &add(struct soap_dom_attribute&); + soap_dom_iterator begin(); + soap_dom_iterator end(); + soap_dom_iterator find(const char *nstr, const char *name); + soap_dom_iterator find(int type); + void unlink(); + soap_dom_element(); + soap_dom_element(struct soap *soap); + soap_dom_element(struct soap *soap, const char *nstr, const char *name); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type); + ~soap_dom_element(); +#endif +}; +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) +} +extern ostream &operator<<(ostream&, const struct soap_dom_element&); +extern istream &operator>>(istream&, struct soap_dom_element&); +extern "C" { +#endif + +struct soap +{ short version; /* 1 = SOAP1.1 and 2 = SOAP1.2 (set automatically from namespace URI in nsmap table) */ + short copy; /* 1 = copy of another soap struct */ + soap_mode mode; + soap_mode imode; + soap_mode omode; + const char *float_format; /* points to user-definable format string for floats (<1024 chars) */ + const char *double_format; /* points to user-definable format string for doubles (<1024 chars) */ + const char *dime_id_format; /* points to user-definable format string for integer DIME id ( 0, gives socket recv timeout in seconds, < 0 in usec */ + int send_timeout; /* when > 0, gives socket send timeout in seconds, < 0 in usec */ + int connect_timeout; /* when > 0, gives socket connect() timeout in seconds, < 0 in usec */ + int accept_timeout; /* when > 0, gives socket accept() timeout in seconds, < 0 in usec */ + int socket_flags; /* socket recv() and send() flags, e.g. set to MSG_NOSIGNAL to disable sigpipe */ + int connect_flags; /* connect() SOL_SOCKET sockopt flags, e.g. set to SO_DEBUG to debug socket */ + int bind_flags; /* bind() SOL_SOCKET sockopt flags, e.g. set to SO_REUSEADDR to enable reuse */ + int accept_flags; /* accept() SOL_SOCKET sockopt flags */ + const struct Namespace *namespaces; /* Pointer to global namespace mapping table */ + struct Namespace *local_namespaces; /* Local namespace mapping table */ + struct soap_nlist *nlist; /* namespace stack */ + struct soap_blist *blist; /* block allocation stack */ + struct soap_clist *clist; /* class instance allocation list */ + void *alist; /* memory allocation list */ + struct soap_ilist *iht[SOAP_IDHASH]; + struct soap_plist *pht[SOAP_PTRHASH]; + struct SOAP_ENV__Header *header; + struct SOAP_ENV__Fault *fault; + void *user; /* to pass user-defined data */ + struct soap_plugin *plugins; /* linked list of plug-in data */ + char *userid; /* HTTP Basic authorization userid */ + char *passwd; /* HTTP Basic authorization passwd */ + int (*fpost)(struct soap*, const char*, const char*, int, const char*, const char*, size_t); + int (*fget)(struct soap*); + int (*fposthdr)(struct soap*, const char*, const char*); + int (*fresponse)(struct soap*, int, size_t); + int (*fparse)(struct soap*); + int (*fparsehdr)(struct soap*, const char*, const char*); + int (*fresolve)(struct soap*, const char*, struct in_addr* inaddr); + int (*fconnect)(struct soap*, const char*, const char*, int); + int (*fdisconnect)(struct soap*); + int (*fclosesocket)(struct soap*, SOAP_SOCKET); + int (*fshutdownsocket)(struct soap*, SOAP_SOCKET, int); + int (*fopen)(struct soap*, const char*, const char*, int); + int (*faccept)(struct soap*, int, struct sockaddr*, int *n); + int (*fclose)(struct soap*); + int (*fsend)(struct soap*, const char*, size_t); + size_t (*frecv)(struct soap*, char*, size_t); + int (*fpoll)(struct soap*); + int (*fignore)(struct soap*, const char*); + int (*fserveloop)(struct soap*); + void *(*fplugin)(struct soap*, const char*); +#ifndef WITH_LEANER + int (*fprepareinit)(struct soap*); + int (*fpreparesend)(struct soap*, const char*, size_t); + int (*fpreparerecv)(struct soap*, const char*, size_t); + void *(*fdimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fdimewriteopen)(struct soap*, const char*, const char*, const char*); + void (*fdimereadclose)(struct soap*, void*); + void (*fdimewriteclose)(struct soap*, void*); + size_t (*fdimeread)(struct soap*, void*, char*, size_t); + int (*fdimewrite)(struct soap*, void*, const char*, size_t); +#endif + int master; + int socket; +#if defined(__cplusplus) && !defined(WITH_LEAN) + ostream *os; + istream *is; +#else + void *os; /* preserve alignment */ + void *is; /* preserve alignment */ +#endif +#ifndef UNDER_CE + int sendfd; + int recvfd; +#else + FILE *sendfd; + FILE *recvfd; +#endif +#ifdef WIN32 + char errorstr[256]; /* buf for FormatMessage() */ +#endif + size_t bufidx; /* index in soap.buf[] */ + size_t buflen; /* length of soap.buf[] content */ + soap_wchar ahead; /* parser lookahead */ + short cdata; /* CDATA parser state */ + short body; + unsigned int level; /* XML nesting level */ + size_t count; /* message length counter */ + size_t length; /* message length as set by HTTP header */ +#ifdef WITH_FAST + char *labbuf; /* look-aside buffer */ + size_t lablen; /* look-aside buffer allocated length */ + size_t labidx; /* look-aside buffer index to available part */ +#endif + char buf[SOAP_BUFLEN];/* send and receive buffer */ + char tmpbuf[1024]; /* in/output buffer for HTTP headers, simpleType values, attribute names, and DIME >=1024 bytes */ + char msgbuf[1024]; /* output buffer for (error) messages <=1024 bytes */ + char tag[SOAP_TAGLEN]; + char id[SOAP_TAGLEN]; + char href[SOAP_TAGLEN]; + char type[SOAP_TAGLEN]; + char arrayType[SOAP_TAGLEN]; + char arraySize[SOAP_TAGLEN]; + char arrayOffset[SOAP_TAGLEN]; + short other; + short root; + short position; + int positions[SOAP_MAXDIMS]; + struct soap_attribute *attributes; /* attribute list */ + short encoding; + short mustUnderstand; + short null; + short ns; + short part; + short alloced; + short peeked; + short keep_alive; + size_t chunksize; + size_t chunkbuflen; + char endpoint[SOAP_TAGLEN]; + char path[SOAP_TAGLEN]; + char host[SOAP_TAGLEN]; + char *action; + char *authrealm; /* HTTP authentication realm */ + char *prolog; /* XML declaration prolog */ + int port; + unsigned int max_keep_alive; + const char *proxy_host; /* Proxy Server host name */ + int proxy_port; /* Proxy Server port (default = 8080) */ + const char *proxy_userid; /* Proxy Authorization user name */ + const char *proxy_passwd; /* Proxy Authorization password */ + int status; /* -1 when request, else error code to be returned by server */ + int error; + int errmode; + int errnum; + unsigned long idnum; + unsigned long ip; +#ifndef WITH_LEANER + struct soap_dom_element *dom; + struct soap_dime dime; + struct soap_mime mime; +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + const char *logfile[SOAP_MAXLOGS]; + FILE *fdebug[SOAP_MAXLOGS]; +#endif +#ifndef WITH_LEAN + struct soap_cookie *cookies; + const char *cookie_domain; + const char *cookie_path; + int cookie_max; +#endif +#ifdef WITH_OPENSSL + int (*fsslauth)(struct soap*); + int (*fsslverify)(int, X509_STORE_CTX*); + BIO *bio; + SSL *ssl; + SSL_CTX *ctx; + short require_server_auth; + short require_client_auth; + short rsa; /* when set, use RSA instead of DH */ + const char *keyfile; + const char *password; + const char *dhfile; + const char *cafile; + const char *capath; + const char *randfile; + SSL_SESSION *session; + char session_host[SOAP_TAGLEN]; + int session_port; +#endif +#ifdef WITH_ZLIB + short zlib_state; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_INFLATE */ + short zlib_in; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + short zlib_out; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + z_stream d_stream; /* decompression stream */ + char z_buf[SOAP_BUFLEN]; /* buffer */ + size_t z_buflen; + unsigned short z_level; /* compression level to be used (0=none, 1=fast to 9=best) */ + uLong z_crc; /* internal gzip crc */ + float z_ratio_in; /* detected compression ratio compressed_length/length of inbound message */ + float z_ratio_out; /* detected compression ratio compressed_length/length of outbound message */ +#endif +/* WR[ */ +#ifdef WMW_RPM_IO + void *rpmreqid; +#endif /* WMW_RPM_IO */ +/* ]WR */ +}; + +struct soap_code_map +{ long code; + const char *string; +}; + +/* forwarding list */ +struct soap_flist +{ struct soap_flist *next; + int type; + void *ptr; + unsigned int level; + void (*fcopy)(struct soap*, int, int, void*, const void*, size_t); +}; + +/* id-ref forwarding list */ +struct soap_ilist +{ struct soap_ilist *next; + int type; + size_t size; + void *link; + void *copy; + struct soap_flist *flist; + void *ptr; + unsigned int level; + char id[1]; /* the actual id string value flows into the allocated region below this struct */ +}; + +struct soap_plugin +{ struct soap_plugin *next; + const char *id; + void *data; + int (*fcopy)(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src); + void (*fdelete)(struct soap *soap, struct soap_plugin *p); /* should delete fields of plugin only and not free(p) */ +}; + +#ifndef WITH_NONAMESPACES +extern SOAP_NMAC struct Namespace namespaces[]; +#endif + +#ifndef WITH_LEAN +# define soap_get0(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx]) +# define soap_get1(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx++]) +#else +soap_wchar soap_get0(struct soap*); +soap_wchar soap_get1(struct soap*); +#endif + +#define soap_revget1(soap) ((soap)->bufidx--) +#define soap_unget(soap, c) ((soap)->ahead = c) +#define soap_register_plugin(soap, plugin) soap_register_plugin_arg(soap, plugin, NULL) +#define soap_imode(soap, n) ((soap)->mode = (soap)->imode = (n)) +#define soap_set_imode(soap, n) ((soap)->mode = (soap)->imode |= (n)) +#define soap_clr_imode(soap, n) ((soap)->mode = (soap)->imode &= ~(n)) +#define soap_omode(soap, n) ((soap)->mode = (soap)->omode = (n)) +#define soap_set_omode(soap, n) ((soap)->mode = (soap)->omode |= (n)) +#define soap_clr_omode(soap, n) ((soap)->mode = (soap)->omode &= ~(n)) +#define soap_destroy(soap) soap_delete((soap), NULL) + +#ifdef HAVE_STRRCHR +# define soap_strrchr(s, t) strrchr(s, t) +#else + SOAP_FMAC1 char* SOAP_FMAC2 soap_strrchr(const char *s, int t); +#endif + +#ifdef HAVE_STRTOL +# define soap_strtol(s, t, b) strtol(s, t, b) +#else + SOAP_FMAC1 long SOAP_FMAC2 soap_strtol(const char *s, char **t, int b); +#endif + +#ifdef HAVE_STRTOUL +# define soap_strtoul(s, t, b) strtoul(s, t, b) +#else + SOAP_FMAC1 unsigned long SOAP_FMAC2 soap_strtoul(const char *s, char **t, int b); +#endif + +#ifdef WITH_NOIDREF +# define soap_embedded(s, p, t) (0) +# define soap_id_lookup(s, i, p, t, n, k) (p) +# define soap_id_forward(s, h, p, st, tt, n, k, fc) (p) +# define soap_reference(s, a, t) (1) +# define soap_array_reference(s, p, a, n, t) (1) +# define soap_embed(s, p, a, n, t, pp) (0) +# define soap_embedded_id(s, i, p, t) (i) +# define soap_is_embedded(s, p) (0) +# define soap_is_single(s, p) (1) +# define soap_lookup_type(s, i) (0) +# define soap_getindependent(s) (0) +# define soap_putindependent(s) (0) +# define soap_getelement(s, n) (0) +# define soap_putelement(s, p, t, i, n) (0) +# define soap_markelement(s, p, n) (0) +#endif + +SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultstring(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultdetail(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializeheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getheader(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializefault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putfault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getfault(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_poll(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect_command(struct soap*, int, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_bind(struct soap*, const char*, int, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_accept(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_accept(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_server_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_client_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_puthttphdr(struct soap*, int status, size_t count); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_get_header_attribute(struct soap*, const char*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_key(char*, size_t, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_val(char*, size_t, const char*); + +SOAP_FMAC1 size_t SOAP_FMAC2 soap_hash(const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_endpoint(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_get(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getchar(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_tag_cmp(const char*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_sender_error(struct soap*, const char*, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_receiver_error(struct soap*, const char*, const char*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_raw(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send2(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send3(struct soap*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_pututf8(struct soap*, unsigned long); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getutf8(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_putbase64(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_getbase64(struct soap*, int*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_puthex(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_gethex(struct soap*, int*); + + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup_id(struct soap*, void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup(struct soap*, const void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_enter(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_pointer_lookup(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_lookup(struct soap*, const char*); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_enter(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_resolve(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_embedded(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_reference(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_reference(struct soap*, const void *p, const struct soap_array *a, int n, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_embedded_id(struct soap*, int id, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_embedded(struct soap*, struct soap_plist*); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_single(struct soap*, struct soap_plist*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_embedded(struct soap*, struct soap_plist*); +#endif + +SOAP_FMAC1 void SOAP_FMAC2 soap_begin_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_send(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_send(struct soap*); + +SOAP_FMAC1 const struct soap_code_map* SOAP_FMAC2 soap_code(const struct soap_code_map*, const char *str); +SOAP_FMAC1 long SOAP_FMAC2 soap_int_code(const struct soap_code_map*, const char *str, long other); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_str_code(const struct soap_code_map*, long code); + +SOAP_FMAC1 int SOAP_FMAC2 soap_getline(struct soap*, char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_recv(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_malloc(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_dealloc(struct soap*, void*); +SOAP_FMAC1 struct soap_clist * SOAP_FMAC2 soap_link(struct soap*, void*, int, int, void (*fdelete)(struct soap_clist*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_unlink(struct soap*, const void*); +SOAP_FMAC1 void SOAP_FMAC2 soap_free(struct soap*); + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_lookup_type(struct soap*, const char *id); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_lookup(struct soap*, const char *id, void **p, int t, size_t n, unsigned int k); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_forward(struct soap*, const char *id, void *p, int st, int tt, size_t n, unsigned int k, void(*fcopy)(struct soap*, int, int, void*, const void*, size_t)); +#endif +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_enter(struct soap*, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_size(const int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getoffsets(const char *, const int *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsize(const char *, const char *, int *); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsizes(const char *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getposition(const char *, int *); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsize(struct soap*, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizesoffsets(struct soap*, const char *, const int *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizes(struct soap*, const char *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffset(struct soap*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffsets(struct soap*, const int *, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_closesock(struct soap*); + +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new(void); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new1(soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new2(soap_mode, soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy(struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy_context(struct soap*,struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init1(struct soap*, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_init2(struct soap*, soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_done(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_cleanup(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_begin(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_end(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_delete(struct soap*, void*); + +#ifdef SOAP_DEBUG +SOAP_FMAC1 void SOAP_FMAC2 soap_set_recv_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_sent_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_test_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_close_logfiles(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_open_logfile(struct soap*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_value(struct soap*); + +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_advance(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_skip(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_tag(struct soap*, const char*, const char *); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_array(struct soap*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element(struct soap*, const char*, int, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_out(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_begin_out(struct soap*, const char *tag, int id, const char *type, const char *offset); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_ref(struct soap*, const char *tag, int id, int href); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_href(struct soap*, const char *tag, int id, const char *ref, const char *val); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_null(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_id(struct soap*, const char *tag, int id, const void *p, const struct soap_array *a, int d, const char *type, int n); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_result(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_out(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_start_end_out(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_attribute(struct soap*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_in(struct soap*, const char *tag, int nillable); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_in(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_peek_element(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_retry(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_revert(struct soap*); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_strdup(struct soap*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_string_out(struct soap*, const char *s, int flag); +SOAP_FMAC1 char* SOAP_FMAC2 soap_string_in(struct soap*, int, long, long); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_wstring_out(struct soap*, const wchar_t *s, int flag); +SOAP_FMAC1 wchar_t* SOAP_FMAC2 soap_wstring_in(struct soap*, int, long, long); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_namespace(struct soap*, const char *, const char*, int n1, int n2); + +SOAP_FMAC1 int SOAP_FMAC2 soap_set_namespaces(struct soap*, struct Namespace*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_namespace(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_push_namespace(struct soap*, const char *,const char *); + +SOAP_FMAC1 int SOAP_FMAC2 soap_new_block(struct soap*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_push_block(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_size_block(struct soap*, size_t); +SOAP_FMAC1 char* SOAP_FMAC2 soap_first_block(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_next_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_block_size(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_save_block(struct soap*, char*, int); +SOAP_FMAC1 void SOAP_FMAC2 soap_end_block(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_out(struct soap*); +SOAP_FMAC1 int soap_envelope_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_out(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_header(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_response(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_empty_response(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_empty_response(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault(struct soap*, FILE*); +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault_location(struct soap*, FILE*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_s2byte(struct soap*, const char*, char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2short(struct soap*, const char*, short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2int(struct soap*, const char*, int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2long(struct soap*, const char*, long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2LONG64(struct soap*, const char*, LONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2float(struct soap*, const char*, float*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2double(struct soap*, const char*, double*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedByte(struct soap*, const char*, unsigned char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedShort(struct soap*, const char*, unsigned short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedInt(struct soap*, const char*, unsigned int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedLong(struct soap*, const char*, unsigned long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2ULONG64(struct soap*, const char*, ULONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2string(struct soap*, const char*, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2QName(struct soap*, const char*, char**); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_s2dateTime(struct soap*, const char*, time_t*); +#endif + +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2base64(struct soap*, const unsigned char*, char*, size_t); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_byte2s(struct soap*, char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_short2s(struct soap*, short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_int2s(struct soap*, int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_long2s(struct soap*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_LONG642s(struct soap*, LONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_float2s(struct soap*, float); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_double2s(struct soap*, double); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedByte2s(struct soap*, unsigned char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedShort2s(struct soap*, unsigned short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedInt2s(struct soap*, unsigned int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedLong2s(struct soap*, unsigned long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_ULONG642s(struct soap*, ULONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_QName2s(struct soap*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_base642s(struct soap*, const char*, char*, size_t, size_t*); + +#ifndef WITH_LEAN +SOAP_FMAC1 const char* SOAP_FMAC2 soap_dateTime2s(struct soap*, time_t); +#endif + + +SOAP_FMAC1 int* SOAP_FMAC2 soap_inint(struct soap*, const char *tag, int *p, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_inbyte(struct soap*, const char *tag, char *p, const char *, int); +SOAP_FMAC1 long* SOAP_FMAC2 soap_inlong(struct soap*, const char *tag, long *p, const char *, int); +SOAP_FMAC1 LONG64* SOAP_FMAC2 soap_inLONG64(struct soap*, const char *tag, LONG64 *p, const char *, int); +SOAP_FMAC1 short* SOAP_FMAC2 soap_inshort(struct soap*, const char *tag, short *p, const char *, int); +SOAP_FMAC1 float* SOAP_FMAC2 soap_infloat(struct soap*, const char *tag, float *p, const char *, int); +SOAP_FMAC1 double* SOAP_FMAC2 soap_indouble(struct soap*, const char *tag, double *p, const char *, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_inunsignedByte(struct soap*, const char *tag, unsigned char *p, const char *, int); +SOAP_FMAC1 unsigned short* SOAP_FMAC2 soap_inunsignedShort(struct soap*, const char *tag, unsigned short *p, const char *, int); +SOAP_FMAC1 unsigned int* SOAP_FMAC2 soap_inunsignedInt(struct soap*, const char *tag, unsigned int *p, const char *, int); +SOAP_FMAC1 unsigned long* SOAP_FMAC2 soap_inunsignedLong(struct soap*, const char *tag, unsigned long *p, const char *, int); +SOAP_FMAC1 ULONG64* SOAP_FMAC2 soap_inULONG64(struct soap*, const char *tag, ULONG64 *p, const char *, int); +SOAP_FMAC1 char** SOAP_FMAC2 soap_instring(struct soap*, const char *tag, char **p, const char *, int, int, long, long); +SOAP_FMAC1 char** SOAP_FMAC2 soap_inliteral(struct soap*, const char *tag, char **p); + +#ifndef WITH_LEAN +SOAP_FMAC1 time_t* SOAP_FMAC2 soap_indateTime(struct soap*, const char *tag, time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwstring(struct soap*, const char *tag, wchar_t **p, const char *, int, long, long); +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwliteral(struct soap*, const char *tag, wchar_t **p); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_outbyte(struct soap*, const char *tag, int id, const char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outshort(struct soap*, const char *tag, int id, const short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outint(struct soap*, const char *tag, int id, const int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outlong(struct soap*, const char *tag, int id, const long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outLONG64(struct soap*, const char *tag, int id, const LONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outfloat(struct soap*, const char *tag, int id, const float *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outdouble(struct soap*, const char *tag, int id, const double *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedByte(struct soap*, const char *tag, int id, const unsigned char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedShort(struct soap*, const char *tag, int id, const unsigned short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedInt(struct soap*, const char *tag, int id, const unsigned int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedLong(struct soap*, const char *tag, int id, const unsigned long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outULONG64(struct soap*, const char *tag, int id, const ULONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outstring(struct soap*, const char *tag, int id, char *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outliteral(struct soap*, const char *tag, char *const*p); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_outdateTime(struct soap*, const char *tag, int id, const time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_outwstring(struct soap*, const char *tag, int id, wchar_t *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outwliteral(struct soap*, const char *tag, wchar_t *const*p); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_element_dime(struct soap *, const char*, int, const void*, const struct soap_array*, const char*, const char*, const char*, int, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_move(struct soap*, long); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_tell(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_dime_option(struct soap*, unsigned short, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmimehdr(struct soap*, struct soap_multipart*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_mime(struct soap*, const char *boundary, const char *start); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_mime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_dime_attachment(struct soap*, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_mime_attachment(struct soap*, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description); +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_register_plugin_arg(struct soap*, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_lookup_plugin(struct soap*, const char*); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_attr_value(struct soap *soap, const char *name, int flag); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_attr(struct soap *soap, const char *name, const char *value); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_attr(struct soap *soap); + +#ifdef WITH_COOKIES +SOAP_FMAC1 size_t SOAP_FMAC2 soap_encode_cookie(const char*, char*, size_t); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_set_cookie(struct soap*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern long SOAP_FMAC2 soap_cookie_expire(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_expire(struct soap*, const char*, long, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_clr_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_clr_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_getenv_cookies(struct soap*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_copy_cookies(struct soap*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_free_cookies(struct soap*); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c new file mode 100644 index 0000000..6b7160b --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c @@ -0,0 +1,13101 @@ +/* + +stdsoap2.c[pp] 2.7.6b + +gSOAP runtime + +gSOAP XML Web services tools +Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under one of the following licenses: +GPL, the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems, Inc., for the following additions: + - vxWorks compatible +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- + +Installation note: + +Win32 build needs winsock.dll (Visual C++ "wsock32.lib") +To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link" +tab (the project file needs to be selected in the file view) and add +"wsock32.lib" to the "Object/library modules" entry + +On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with +-fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack +when locally allocated data exceeds 64K. + +*/ + +#include "stdsoap2.h" + +#ifdef __cplusplus +SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.6b 2005-08-26 12:00:00 GMT") +extern "C" { +#else +SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.6b 2005-08-26 12:00:00 GMT") +#endif + +/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */ +#ifndef SOAP_UNKNOWN_CHAR +#define SOAP_UNKNOWN_CHAR (127) +#endif + +/* EOF=-1 */ +#define SOAP_LT (soap_wchar)(-2) /* XML character '<' */ +#define SOAP_TT (soap_wchar)(-3) /* XML character '' */ +#define SOAP_QT (soap_wchar)(-5) /* XML character '"' */ +#define SOAP_AP (soap_wchar)(-6) /* XML character ''' */ + +#define SOAP_BOM (soap_wchar)(0xFEFF) /* UTF BOM is Unicode FEFF */ + +#define soap_blank(c) ((c) >= 0 && (c) <= 32) +#define soap_notblank(c) ((c) > 32) +#define soap_hash_ptr(p) (((unsigned long)(p) >> 3) & (SOAP_PTRHASH - 1)) + +static int soap_isxdigit(int); +static soap_wchar soap_char(struct soap*); + +#ifndef WITH_NOIDREF +static void soap_update_ptrs(struct soap*, char*, char*, long); +static int soap_has_copies(struct soap*, const char*, const char*); +static void soap_init_iht(struct soap*); +static void soap_free_iht(struct soap*); +static void soap_init_pht(struct soap*); +static void soap_free_pht(struct soap*); +#endif + +#ifdef SOAP_DEBUG +static void soap_init_logs(struct soap*); +static void soap_close_logfile(struct soap*, int); +static void soap_set_logfile(struct soap*, int, const char*); +static void soap_free_mht(struct soap*); +static void soap_track_unlink(struct soap*, const void*); +#endif + +static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int); +static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*); +static int soap_getattrval(struct soap*, char*, size_t, soap_wchar); +static void *fplugin(struct soap*, const char*); + +#ifndef WITH_LEAN +static const char *soap_set_validation_fault(struct soap*, const char*, const char*); +static int soap_isnumeric(struct soap*, const char*); +static time_t soap_timegm(struct tm*); +static struct soap_nlist *soap_lookup_ns(struct soap *soap, const char *tag, size_t n); +static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized); +static void soap_pop_ns(struct soap *soap); +static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n); +#endif + +#ifndef WITH_LEANER +static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t); +static int soap_putdimefield(struct soap*, const char*, size_t); +static char *soap_getdimefield(struct soap*, size_t); +static void soap_select_mime_boundary(struct soap*); +static int soap_valid_mime_boundary(struct soap*); +static int soap_match_cid(const char*, const char*); +static void soap_resolve_attachment(struct soap*, struct soap_multipart*); +#endif + +#ifdef WITH_GZIP +static int soap_getgziphdr(struct soap*); +#endif + +#ifdef WITH_OPENSSL +static void ssl_init(); +static int ssl_auth_init(struct soap*); +static int ssl_verify_callback(int, X509_STORE_CTX*); +static int ssl_password(char*, int, int, void *); +static const char *ssl_error(struct soap*, int); +/* This callback is included for future references. It should not be deleted +static DH *ssl_tmp_dh(SSL*, int, int); +*/ +#endif + +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +static const char *soap_decode(char*, size_t, const char*, const char*); +#endif + +#ifndef WITH_NOHTTP +static soap_wchar soap_getchunkchar(struct soap*); +static const char *http_error(struct soap*, int); +static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t); +static int http_get(struct soap*); +static int http_send_header(struct soap*, const char*); +static int http_post_header(struct soap*, const char*, const char*); +static int http_response(struct soap*, int, size_t); +static int http_parse(struct soap*); +static int http_parse_header(struct soap*, const char*, const char*); +#endif + +#ifndef WITH_NOIO +static int fsend(struct soap*, const char*, size_t); +static size_t frecv(struct soap*, char*, size_t); +static int tcp_init(struct soap*); +static const char *tcp_error(struct soap*); +#ifndef WITH_IPV6 +static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr); +#endif +static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port); +static int tcp_accept(struct soap*, int, struct sockaddr*, int*); +static int tcp_disconnect(struct soap*); +static int tcp_closesocket(struct soap*, SOAP_SOCKET); +static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int); +static const char *soap_strerror(struct soap*); +#endif + +#ifdef VXWORKS +static int vx_nonblocking = TRUE; /* ioctl argument */ +#endif + +#if defined(PALM) && !defined(PALM_2) +unsigned short errno; +#endif + +#ifndef PALM_1 +static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/"; +static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/"; +static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope"; +static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding"; +static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc"; +#endif + +#ifndef PALM_1 +const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF}; +static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63"; +#endif + +#ifndef WITH_LEAN +static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t"; +/* Alternative indentation form for SOAP_XML_INDENT: +static const char soap_indent[21] = "\n "; +*/ +#endif + +static const char soap_padding[3] = "\0\0"; +#define SOAP_STR_PADDING (soap_padding) +#define SOAP_STR_EOS (soap_padding) +#define SOAP_NON_NULL (soap_padding) + +#ifndef WITH_LEAN +static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */ +{ { 160, "nbsp" }, + { 161, "iexcl" }, + { 162, "cent" }, + { 163, "pound" }, + { 164, "curren" }, + { 165, "yen" }, + { 166, "brvbar" }, + { 167, "sect" }, + { 168, "uml" }, + { 169, "copy" }, + { 170, "ordf" }, + { 171, "laquo" }, + { 172, "not" }, + { 173, "shy" }, + { 174, "reg" }, + { 175, "macr" }, + { 176, "deg" }, + { 177, "plusmn" }, + { 178, "sup2" }, + { 179, "sup3" }, + { 180, "acute" }, + { 181, "micro" }, + { 182, "para" }, + { 183, "middot" }, + { 184, "cedil" }, + { 185, "sup1" }, + { 186, "ordm" }, + { 187, "raquo" }, + { 188, "frac14" }, + { 189, "frac12" }, + { 190, "frac34" }, + { 191, "iquest" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acirc" }, + { 195, "Atilde" }, + { 196, "Auml" }, + { 197, "Aring" }, + { 198, "AElig" }, + { 199, "Ccedil" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecirc" }, + { 203, "Euml" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icirc" }, + { 207, "Iuml" }, + { 208, "ETH" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocirc" }, + { 213, "Otilde" }, + { 214, "Ouml" }, + { 215, "times" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucirc" }, + { 220, "Uuml" }, + { 221, "Yacute" }, + { 222, "THORN" }, + { 223, "szlig" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acirc" }, + { 227, "atilde" }, + { 228, "auml" }, + { 229, "aring" }, + { 230, "aelig" }, + { 231, "ccedil" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecirc" }, + { 235, "euml" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icirc" }, + { 239, "iuml" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocirc" }, + { 245, "otilde" }, + { 246, "ouml" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucirc" }, + { 252, "uuml" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "yuml" }, + { 0, NULL } +}; +#endif + +#ifndef WITH_NOIO +#ifndef WITH_LEAN +static const struct soap_code_map h_error_codes[] = +{ +#ifdef HOST_NOT_FOUND + { HOST_NOT_FOUND, "Host not found" }, +#endif +#ifdef TRY_AGAIN + { TRY_AGAIN, "Try Again" }, +#endif +#ifdef NO_RECOVERY + { NO_RECOVERY, "No Recovery" }, +#endif +#ifdef NO_DATA + { NO_DATA, "No Data" }, +#endif +#ifdef NO_ADDRESS + { NO_ADDRESS, "No Address" }, +#endif + { 0, NULL } +}; +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN +static const struct soap_code_map h_http_error_codes[] = +{ { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Time-out" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Large" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested range not satisfiable" }, + { 417, "Expectation Failed" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Time-out" }, + { 505, "HTTP Version not supported" }, + { 0, NULL } +}; +#endif +#endif + +#ifdef WITH_OPENSSL +static const struct soap_code_map h_ssl_error_codes[] = +{ +#define _SSL_ERROR(e) { e, #e } + _SSL_ERROR(SSL_ERROR_SSL), + _SSL_ERROR(SSL_ERROR_ZERO_RETURN), + _SSL_ERROR(SSL_ERROR_WANT_READ), + _SSL_ERROR(SSL_ERROR_WANT_WRITE), + _SSL_ERROR(SSL_ERROR_WANT_CONNECT), + _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP), + _SSL_ERROR(SSL_ERROR_SYSCALL), + { 0, NULL } +}; +#endif + +#ifndef WITH_LEANER +static const struct soap_code_map mime_codes[] = +{ { SOAP_MIME_7BIT, "7bit" }, + { SOAP_MIME_8BIT, "8bit" }, + { SOAP_MIME_BINARY, "binary" }, + { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" }, + { SOAP_MIME_BASE64, "base64" }, + { SOAP_MIME_IETF_TOKEN, "ietf-token" }, + { SOAP_MIME_X_TOKEN, "x-token" }, + { 0, NULL } +}; +#endif + +#ifdef WIN32 +static int tcp_done = 0; +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +fsend(struct soap *soap, const char *s, size_t n) +{ register int nwritten; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->os) + { soap->os->write(s, n); + if (soap->os->good()) + return SOAP_OK; + return SOAP_EOF; + } +#endif + while (n) + { if (soap_valid_socket(soap->socket)) + { +#ifndef WITH_LEAN + if (soap->send_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->send_timeout > 0) + { timeout.tv_sec = soap->send_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->send_timeout/1000000; + timeout.tv_usec = -soap->send_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + return SOAP_EOF; + } + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + nwritten = SSL_write(soap->ssl, s, n); + else if (soap->bio) + nwritten = BIO_write(soap->bio, s, n); + else +#endif +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + { if (soap->peerlen) + nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); + else + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + /* retry and back-off algorithm */ + /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */ + if (nwritten < 0) + { struct timeval timeout; + fd_set fd; + int udp_repeat; + int udp_delay; + if ((soap->connect_flags & SO_BROADCAST)) + udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */ + else + udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */ + udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */ + do + { timeout.tv_sec = 0; + timeout.tv_usec = 1000 * udp_delay; /* ms */ + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + select((SOAP_SOCKET)(soap->socket + 1), NULL, NULL, &fd, &timeout); + if (soap->peerlen) + nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); + else + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + udp_delay <<= 1; + if (udp_delay > 500) /* UDP_UPPER_DELAY */ + udp_delay = 500; + } + while (nwritten < 0 && --udp_repeat > 0); + } + } + else +#endif +#ifndef PALM + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); +#else + nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags); +#endif + if (nwritten <= 0) + { +#ifdef WITH_OPENSSL + int err; + if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return SOAP_EOF; +#endif + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EWOULDBLOCK && soap_socket_errno != SOAP_EAGAIN) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + else + { +#ifdef WITH_FASTCGI + nwritten = fwrite((void*)s, 1, n, stdout); + fflush(stdout); +#else +#ifdef UNDER_CE + nwritten = fwrite(s, 1, n, soap->sendfd); +#else +#ifdef VXWORKS +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1; + else + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#else + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#endif /* WMW_RPM_IO */ +#else + nwritten = write((SOAP_SOCKET)soap->sendfd, s, n); +#endif +#endif +#endif + if (nwritten <= 0) + { if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK && soap_errno != SOAP_EAGAIN) + { soap->errnum = soap_errno; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + n -= nwritten; + s += nwritten; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_raw(struct soap *soap, const char *s, size_t n) +{ if (!n) + return SOAP_OK; + if (soap->mode & SOAP_IO_LENGTH) + { soap->count += n; +#ifndef WITH_LEANER + if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } + if (soap->mode & SOAP_IO) + { register size_t i = SOAP_BUFLEN - soap->bufidx; + while (n >= i) + { memcpy(soap->buf + soap->bufidx, s, i); + soap->bufidx = SOAP_BUFLEN; + if (soap_flush(soap)) + return soap->error; + s += i; + n -= i; + i = SOAP_BUFLEN; + } + memcpy(soap->buf + soap->bufidx, s, n); + soap->bufidx += n; + return SOAP_OK; + } + return soap_flush_raw(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush(struct soap *soap) +{ register int n = soap->bufidx; + if (n) + { soap->bufidx = 0; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->d_stream.next_in = (Byte*)soap->buf; + soap->d_stream.avail_in = (unsigned int)n; +#ifdef WITH_GZIP + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n); +#endif + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in)); + if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } + if (!soap->d_stream.avail_out) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN)) + return soap->error; + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (soap->d_stream.avail_in); + } + else +#endif + return soap_flush_raw(soap, soap->buf, n); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush_raw(struct soap *soap, const char *s, size_t n) +{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { register char *t; + if (!(t = (char*)soap_push_block(soap, n))) + return soap->error = SOAP_EOM; + memcpy(t, s, n); +#ifndef WITH_LEANER + if (soap->fpreparesend) + return soap->error = soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { char t[16]; + sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n); + DBGMSG(SENT, t, strlen(t)); + if ((soap->error = soap->fsend(soap, t, strlen(t)))) + return soap->error; + soap->chunksize += n; + } + DBGMSG(SENT, s, n); +#endif + return soap->error = soap->fsend(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send(struct soap *soap, const char *s) +{ if (s) + return soap_send_raw(soap, s, strlen(s)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send2(struct soap *soap, const char *s1, const char *s2) +{ if (soap_send(soap, s1)) + return soap->error; + return soap_send(soap, s2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3) +{ if (soap_send(soap, s1) + || soap_send(soap, s2)) + return soap->error; + return soap_send(soap, s3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static size_t +frecv(struct soap *soap, char *s, size_t n) +{ register int r; + soap->errnum = 0; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->is) + { if (soap->is->good()) + return soap->is->read(s, n).gcount(); + return 0; + } +#endif + if (soap_valid_socket(soap->socket)) + { for (;;) + { +#ifndef WITH_LEAN + if (soap->recv_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->recv_timeout > 0) + { timeout.tv_sec = soap->recv_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->recv_timeout/1000000; + timeout.tv_usec = -soap->recv_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + return 0; + } + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN) + { soap->errnum = soap_socket_errno; + return 0; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + { int err; + r = SSL_read(soap->ssl, s, n); + if (r > 0) + return (size_t)r; + err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return 0; + } + else if (soap->bio) + { r = BIO_read(soap->bio, s, n); + if (r > 0) + return (size_t)r; + return 0; + } + else +#endif + { +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + r = recvfrom((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + soap->peerlen = (size_t)k; +#ifndef WITH_IPV6 + soap->ip = ntohl(soap->peer.sin_addr.s_addr); + soap->port = (int)ntohs(soap->peer.sin_port); +#endif + } + else +#endif + r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + if (r >= 0) + return (size_t)r; + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN && soap_socket_errno != SOAP_EWOULDBLOCK) + { soap->errnum = soap_socket_errno; + return 0; + } + } +#ifndef WITH_LEAN + { struct timeval timeout; + fd_set fd; + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); +#ifdef WITH_OPENSSL + if (soap->ssl && SSL_get_error(soap->ssl, r) == SSL_ERROR_WANT_WRITE) + r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#endif + if (r < 0 && soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return 0; + } + } +#endif + } + } +#ifdef WITH_FASTCGI + return fread(s, 1, n, stdin); +#else +#ifdef UNDER_CE + return fread(s, 1, n, soap->recvfd); +#else +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + r = httpBlockRead(soap->rpmreqid, s, n); +#endif + r = read((SOAP_SOCKET)soap->recvfd, s, n); + if (r >= 0) + return (size_t)r; + soap->errnum = soap_errno; + return 0; +#endif +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar +soap_getchunkchar(struct soap *soap) +{ if (soap->bufidx < soap->buflen) + return soap->buf[soap->bufidx++]; + soap->bufidx = 0; + soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket)); + DBGMSG(RECV, soap->buf, soap->buflen); + if (soap->buflen) + return soap->buf[soap->bufidx++]; + return EOF; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +soap_isxdigit(int c) +{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_raw(struct soap *soap) +{ register size_t ret; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { if (soap->d_stream.next_out == Z_NULL) + return EOF; + if (soap->d_stream.avail_in || !soap->d_stream.avail_out) + { register int r; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n")); + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + if (soap->buflen) + { soap->count += soap->buflen; + return SOAP_OK; + } + } + else if (r != Z_BUF_ERROR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +zlib_again: + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize) + { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->buflen = soap->z_buflen; + } + } +#endif +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */ + { +chunk_again: + if (soap->chunksize) + { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + soap->chunksize -= ret; + } + else + { register soap_wchar c; + char *t, tmp[8]; + t = tmp; + if (!soap->chunkbuflen) + { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + if (!ret) + return soap->ahead = EOF; + } + else + soap->bufidx = soap->buflen; + soap->buflen = soap->chunkbuflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen)); + while (!soap_isxdigit((int)(c = soap_getchunkchar(soap)))) + if ((int)c == EOF) + return soap->ahead = EOF; + do + *t++ = (char)c; + while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + if ((int)c == EOF) + return soap->ahead = EOF; + *t = '\0'; + soap->chunksize = soap_strtoul(tmp, &t, 16); + if (!soap->chunksize) + { soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n")); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + return soap->ahead = EOF; + } + soap->buflen = soap->bufidx + soap->chunksize; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp)); + if (soap->buflen > soap->chunkbuflen) + { soap->buflen = soap->chunkbuflen; + soap->chunksize -= soap->buflen - soap->bufidx; + soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx))); + } + else if (soap->chunkbuflen) + soap->chunksize = 0; + ret = soap->buflen - soap->bufidx; + if (!ret) + goto chunk_again; + } + } + else +#endif + { soap->bufidx = 0; + soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + } +#ifndef WITH_LEANER + if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret))) + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { register int r; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = (unsigned int)ret; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->z_buflen = soap->buflen; + soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret)); + if (!ret) + goto zlib_again; + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +#endif + soap->count += ret; + return !ret; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_DIME) + { if (soap->dime.buflen) + { char *s; + int i; + unsigned char tmp[12]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n")); + soap->count += soap->dime.buflen - soap->buflen; + soap->buflen = soap->dime.buflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3)); + for (i = -(long)soap->dime.size&3; i > 0; i--) + { soap->bufidx++; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n")); + s = (char*)tmp; + for (i = 12; i > 0; i--) + { *s++ = soap->buf[soap->bufidx++]; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + soap->dime.flags = tmp[0] & 0x7; + soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size)); + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.size) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n")); + soap->dime.buflen = 0; + soap->dime.chunksize = 0; + } + soap->count = soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count)); + return SOAP_OK; + } + if (soap->dime.chunksize) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize)); + if (soap_recv_raw(soap)) + return EOF; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count)); + return SOAP_OK; + } + } +#endif + return soap_recv_raw(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getchar(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if (c != EOF) + soap->ahead = 0; + return c; + } + return soap_get1(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const struct soap_code_map* +SOAP_FMAC2 +soap_code(const struct soap_code_map *map, const char *str) +{ if (str) + { while (map->string) + { if (!strcmp(str, map->string)) /* case sensitive */ + return map; + map++; + } + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_int_code(const struct soap_code_map *map, const char *str, long other) +{ while (map->string) + { if (!soap_tag_cmp(str, map->string)) /* case insensitive */ + return map->code; + map++; + } + return other; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_str_code(const struct soap_code_map *map, long code) +{ while (map->code != code && map->string) + map++; + return map->string; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_char(struct soap *soap) +{ char tmp[8]; + register int i; + register soap_wchar c; + register char *s = tmp; + for (i = 0; i < 7; i++) + { c = soap_get1(soap); + if (c == ';' || (int)c == EOF) + break; + *s++ = (char)c; + } + *s = '\0'; + if (*tmp == '#') + { if (tmp[1] == 'x' || tmp[1] == 'X') + return soap_strtol(tmp + 2, NULL, 16); + return atol(tmp + 1); + } + if (!strcmp(tmp, "lt")) + return '<'; + if (!strcmp(tmp, "gt")) + return '>'; + if (!strcmp(tmp, "amp")) + return '&'; + if (!strcmp(tmp, "quot")) + return '"'; + if (!strcmp(tmp, "apos")) + return '\''; +#ifndef WITH_LEAN + return (soap_wchar)soap_int_code(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR); +#else + return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */ +#endif +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +soap_wchar +soap_get0(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx]; +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +soap_wchar +soap_get1(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx++]; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_get(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if (c != EOF) + soap->ahead = 0; + } + else + c = soap_get1(soap); + for (;;) + { if (soap->cdata) + { if (c == ']') + { c = soap_get1(soap); + if (c == ']') + { soap->cdata = 0; + soap_get1(soap); /* skip > */ + c = soap_get1(soap); + } + else + { soap_revget1(soap); + return ']'; + } + } + else + return c; + } + switch (c) + { case '<': + do c = soap_get1(soap); + while (soap_blank(c)); + if (c == '!' || c == '?' || c == '%') + { register int k = 1; + if (c == '!') + { c = soap_get1(soap); + if (c == '[') + { do c = soap_get1(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + break; + soap->cdata = 1; + c = soap_get1(soap); + continue; + } + if (c == '-' && (c = soap_get1(soap)) == '-') + { do + { c = soap_get1(soap); + if (c == '-' && (c = soap_get1(soap)) == '-') + break; + } while ((int)c != EOF); + } + } + while ((int)c != EOF) + { if (c == '<') + k++; + else if (c == '>') + { if (--k <= 0) + break; + } + c = soap_get1(soap); + } + if ((int)c == EOF) + break; + c = soap_get1(soap); + continue; + } + if (c == '/') + return SOAP_TT; + soap_revget1(soap); + return SOAP_LT; + case '>': + return SOAP_GT; + case '"': + return SOAP_QT; + case '\'': + return SOAP_AP; + case '&': + return soap_char(soap) | 0x80000000; + } + break; + } + return c; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_move(struct soap *soap, long n) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n)); + for (; n > 0; n--) + if ((int)soap_getchar(soap) == EOF) + return SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_tell(struct soap *soap) +{ return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pututf8(struct soap *soap, register unsigned long c) +{ char tmp[16]; + if (c > 0 && c < 0x80) + { *tmp = (char)c; + return soap_send_raw(soap, tmp, 1); + } +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { register char *t = tmp; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + *t = '\0'; + } + else +#endif + sprintf(tmp, "&#%lu;", c); + return soap_send(soap, tmp); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getutf8(struct soap *soap) +{ register soap_wchar c, c1, c2, c3, c4; + c = soap_get(soap); + if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN)) + return c; + c1 = soap_get(soap); + if (c1 < 0x80) + { soap_unget(soap, c1); + return c; + } + c1 &= 0x3F; + if (c < 0xE0) + return ((soap_wchar)(c & 0x1F) << 6) | c1; + c2 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF0) + return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2; + c3 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF8) + return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3; + c4 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xFC) + return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; + return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthex(struct soap *soap, const unsigned char *s, int n) +{ char d[2]; + register int i; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (i = 0; i < n; i++) + { register int m = *s++; + d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0')); + m &= 0x0F; + d[1] = (char)(m + (m > 9 ? '7' : '0')); + if (soap_send_raw(soap, d, 2)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_gethex(struct soap *soap, int *n) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register char *s; + register int i, k; + if (soap_append_lab(soap, NULL, 0)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + for (i = 0; i < k; i++) + { register char d1, d2; + register soap_wchar c; + c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = (int)(soap->lablen - k + i); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN); + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register char d1, d2; + register soap_wchar c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap_end_block(soap); + soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putbase64(struct soap *soap, const unsigned char *s, int n) +{ register int i; + register unsigned long m; + char d[4]; + if (!s) + return SOAP_OK; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + d[i] = '='; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_getbase64(struct soap *soap, int *n, int malloc_flag) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register int i, k; + register char *s; + if (soap_append_lab(soap, NULL, 2)) + return NULL; + s = soap->labbuf + soap->labidx; + k = 3 * ((soap->lablen - soap->labidx) / 3); + soap->labidx = 3 * (soap->lablen / 3); + if (!s) + return NULL; + for (i = 0; i < k; i += 3) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)(soap->lablen - k + i - 1); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i - 1); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i - 1); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + i *= 3; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ /* Check MTOM xop:Include element (within hex/base64Binary) */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + int body = soap->body; /* should save type too? */ + if (!soap_peek_element(soap)) + { if (!soap_element_begin_in(soap, "xop:Include", 0) && *soap->href) + { if (soap_dime_forward(soap, ptr, size, id, type, options)) + return soap->error; + } + if (soap->body && soap_element_end_in(soap, NULL)) + return soap->error; + } + soap->body = body; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ struct soap_xlist *xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist)); + *ptr = NULL; + *size = 0; + *id = soap_strdup(soap, soap->href); + *type = NULL; + *options = NULL; + if (!xp) + return soap->error = SOAP_EOM; + xp->next = soap->xlist; + xp->ptr = ptr; + xp->size = size; + xp->id = *id; + xp->type = type; + xp->options = options; + soap->xlist = xp; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_strdup(struct soap *soap, const char *s) +{ char *t = NULL; + if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1))) + strcpy(t, s); + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_new_block(struct soap *soap) +{ struct soap_blist *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist)); + if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist)))) + return SOAP_EOM; + p->next = soap->blist; + p->ptr = NULL; + p->size = 0; + soap->blist = p; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_push_block(struct soap *soap, size_t n) +{ char *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)soap->blist->size + (unsigned int)n)); + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + *(char**)p = soap->blist->ptr; + *(size_t*)(p + sizeof(char*)) = n; + soap->blist->ptr = p; + soap->blist->size += n; + return p + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_block(struct soap *soap) +{ char *p; + if (!soap->blist->ptr) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n")); + p = soap->blist->ptr; + soap->blist->size -= *(size_t*)(p + sizeof(char*)); + soap->blist->ptr = *(char**)p; + SOAP_FREE(soap, p); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_update_ptrs(struct soap *soap, char *start, char *end, long offset) +{ int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; +#ifndef WITH_LEANER + register struct soap_xlist *xp; +#endif + register void *p, **q; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + offset)); + ip->ptr = (char*)ip->ptr + offset; + } + for (q = &ip->link; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p)); + *q = (char*)p + offset; + } + } + for (q = &ip->copy; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p)); + *q = (char*)p + offset; + } + } + for (fp = ip->flist; fp; fp = fp->next) + { if ((char*)fp->ptr >= start && (char*)fp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp)); + fp->ptr = (char*)fp->ptr + offset; + } + } + } + } +#ifndef WITH_LEANER + for (xp = soap->xlist; xp; xp = xp->next) + { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:"", xp->ptr, (char*)xp->ptr + offset)); + xp->ptr = (unsigned char**)((char*)xp->ptr + offset); + xp->size = (int*)((char*)xp->size + offset); + xp->type = (char**)((char*)xp->type + offset); + xp->options = (char**)((char*)xp->options + offset); + } + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static int +soap_has_copies(struct soap *soap, register const char *start, register const char *end) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + register const char *p; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { for (p = (const char*)ip->copy; p; p = *(const char**)p) + if (p >= start && p < end) + return SOAP_ERR; + for (fp = ip->flist; fp; fp = fp->next) + if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_resolve(struct soap *soap) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + short flag; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr) + { register void *p, **q, *r; + q = (void**)ip->link; + ip->link = NULL; + r = ip->ptr; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id)); + while (q) + { p = *q; + *q = r; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r)); + q = (void**)p; + } + } + else if (*ip->id == '#') + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id)); + strcpy(soap->id, ip->id + 1); + return soap->error = SOAP_MISSING_ID; + } + } + } + do + { flag = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size)) + { if (ip->copy) + { register void *p, **q = (void**)ip->copy; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id)); + ip->copy = NULL; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size)); + p = *q; + memcpy(q, ip->ptr, ip->size); + q = (void**)p; + } while (q); + flag = 1; + } + for (fp = ip->flist; fp; fp = ip->flist) + { register unsigned int k = fp->level; + register void *p = ip->ptr; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); + while (ip->level < k) + { register void **q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return soap->error; + *q = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q)); + p = (void*)q; + k--; + } + if (fp->fcopy) + fp->fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size); + else + soap_fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size); + ip->flist = fp->next; + SOAP_FREE(soap, fp); + flag = 1; + } + } + } + } + } while (flag); +#ifdef SOAP_DEBUG + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->copy || ip->flist) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->id)); + } + } + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n")); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_size_block(struct soap *soap, size_t n) +{ if (soap->blist->ptr) + { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n; + *(size_t*)(soap->blist->ptr + sizeof(char*)) = n; + } + return soap->blist->size; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_first_block(struct soap *soap) +{ char *p, *q, *r; + p = soap->blist->ptr; + if (!p) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n")); + r = NULL; + do + { q = *(char**)p; + *(char**)p = r; + r = p; + p = q; + } while (p); + soap->blist->ptr = r; + return r + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_next_block(struct soap *soap) +{ char *p; + p = soap->blist->ptr; + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n")); + soap->blist->ptr = *(char**)p; + SOAP_FREE(soap, p); + if (soap->blist->ptr) + return soap->blist->ptr + sizeof(char*) + sizeof(size_t); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_block_size(struct soap *soap) +{ return *(size_t*)(soap->blist->ptr + sizeof(char*)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end_block(struct soap *soap) +{ struct soap_blist *bp; + char *p, *q; + bp = soap->blist; + if (bp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n")); + for (p = bp->ptr; p; p = q) + { q = *(char**)p; + SOAP_FREE(soap, p); + } + soap->blist = bp->next; + SOAP_FREE(soap, bp); + } + DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n")); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_save_block(struct soap *soap, char *p, int flag) +{ register size_t n; + register char *q, *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)soap->blist->size, soap->blist->ptr, p)); + if (soap->blist->size) + { if (!p) + p = (char*)soap_malloc(soap, soap->blist->size); + if (p) + { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap)) + { n = soap_block_size(soap); +#ifndef WITH_NOIDREF + if (flag) + soap_update_ptrs(soap, q, q + n, (long)s - (long)q); /* pointers s and q may or may not be related */ +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s)); + memcpy(s, q, n); + s += n; + } + } + else + soap->error = SOAP_EOM; + } + soap_end_block(soap); + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsize(struct soap *soap, const char *type, int size) +{ return soap_putsizes(soap, type, &size, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizes(struct soap *soap, const char *type, const int *size, int dim) +{ return soap_putsizesoffsets(soap, type, size, NULL, dim); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim) +{ int i; + if (!type) + return NULL; + if (soap->version == 2) + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), " %d", size[i]); + } + else + { if (offset) + { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]); + } + else + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i]); + } + strcat(soap->type, "]"); + } + return soap->type; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffset(struct soap *soap, int offset) +{ return soap_putoffsets(soap, &offset, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffsets(struct soap *soap, const int *offset, int dim) +{ register int i; + sprintf(soap->arrayOffset, "[%d", offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]); + strcat(soap->arrayOffset, "]"); + return soap->arrayOffset; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_size(const int *size, int dim) +{ register int i, n = size[0]; + for (i = 1; i < dim; i++) + n *= size[i]; + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getoffsets(const char *attr, const int *size, int *offset, int dim) +{ register int i, j = 0; + if (offset) + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += offset[i] = (int)atol(attr); + attr = strchr(attr, ','); + } + else + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += (int)atol(attr); + attr = strchr(attr, ','); + } + return j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsize(const char *attr1, const char *attr2, int *j) +{ register int n, k; + char *s; + *j = 0; + if (!*attr1) + return -1; + if (*attr1 == '[') + attr1++; + n = 1; + for (;;) + { k = (int)soap_strtol(attr1, &s, 10); + n *= k; + if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1) + return -1; + attr1 = strchr(s, ','); + if (!attr1) + attr1 = strchr(s, ' '); + if (attr2 && *attr2) + { attr2++; + *j *= k; + k = (int)soap_strtol(attr2, &s, 10); + *j += k; + if (k < 0) + return -1; + attr2 = s; + } + if (!attr1) + break; + attr1++; + } + return n - *j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsizes(const char *attr, int *size, int dim) +{ register int i, k, n; + if (!*attr) + return -1; + i = strlen(attr); + n = 1; + do + { for (i = i-1; i >= 0; i--) + if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ') + break; + k = (int)atol(attr + i + 1); + n *= size[--dim] = k; + if (k < 0 || n > SOAP_MAXARRAYSIZE) + return -1; + } while (i >= 0 && attr[i] != '['); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getposition(const char *attr, int *pos) +{ register int i, n; + if (!*attr) + return -1; + n = 0; + i = 1; + do + { pos[n++] = (int)atol(attr + i); + while (attr[i] && attr[i] != ',' && attr[i] != ']') + i++; + if (attr[i] == ',') + i++; + } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']'); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_push_namespace(struct soap *soap, const char *id, const char *ns) +{ register struct soap_nlist *np; + register struct Namespace *p; + register short i = -1; + register size_t n, k; + n = strlen(id); + k = strlen(ns) + 1; + p = soap->local_namespaces; + if (p) + { for (i = 0; p->id; p++, i++) + { if (p->ns && !strcmp(ns, p->ns)) + { if (p->out) + { SOAP_FREE(soap, p->out); + p->out = NULL; + } + break; + } + if (p->out) + { if (!strcmp(ns, p->out)) + break; + } + else if (p->in) + { if (!soap_tag_cmp(ns, p->in)) + { if ((p->out = (char*)SOAP_MALLOC(soap, k))) + strcpy(p->out, ns); + break; + } + } + } + if (!p || !p->id) + i = -1; + } + if (i >= 0) + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k); + if (!np) + return soap->error = SOAP_EOM; + np->next = soap->nlist; + soap->nlist = np; + np->level = soap->level; + np->index = i; + strcpy(np->id, id); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns)); + if (i < 0) + { np->ns = np->id + n + 1; + strcpy(np->ns, ns); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns)); + } + else + { np->ns = NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id)); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_namespace(struct soap *soap) +{ register struct soap_nlist *np; + while (soap->nlist && soap->nlist->level >= soap->level) + { np = soap->nlist->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id)); + SOAP_FREE(soap, soap->nlist); + soap->nlist = np; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2) +{ register struct soap_nlist *np = soap->nlist; + while (np && (strncmp(np->id, id1, n1) || np->id[n1])) + np = np->next; + if (np) + { if (np->index < 0 + || (soap->local_namespaces[np->index].id + && (strncmp(soap->local_namespaces[np->index].id, id2, n2) + || soap->local_namespaces[np->index].id[n2]))) + return SOAP_NAMESPACE; + return SOAP_OK; + } + if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2)) + return SOAP_OK; + return SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_tag_cmp(const char *s, const char *t) +{ for (;;) + { register int c1 = *s; + register int c2 = *t; + if (!c1 || c1 == '"') + break; + if (c2 != '-') + { if (c1 != c2) + { if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + } + if (c1 != c2) + { if (c2 != '*') + return 1; + c2 = *++t; + if (!c2) + return 0; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + for (;;) + { c1 = *s; + if (!c1 || c1 == '"') + break; + if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1)) + return 0; + s++; + } + break; + } + } + s++; + t++; + } + if (*t == '*' && !t[1]) + return 0; + return *t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_tag(struct soap *soap, const char *tag1, const char *tag2) +{ register const char *s, *t; + if (!tag1 || !tag2 || !*tag2) + return SOAP_OK; + s = strchr(tag1, ':'); + t = strchr(tag2, ':'); + if (t) + { if (s) + { if (t[1] && SOAP_STRCMP(s + 1, t + 1)) + return SOAP_TAG_MISMATCH; + if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + } + else if (SOAP_STRCMP(tag1, t + 1)) + return SOAP_TAG_MISMATCH; + else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; + } + if (s) + { if (SOAP_STRCMP(s + 1, tag2)) + return SOAP_TAG_MISMATCH; + } + else if (SOAP_STRCMP(tag1, tag2)) + return SOAP_TAG_MISMATCH; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_array(struct soap *soap, const char *type) +{ if (*soap->arrayType) + if (soap_match_tag(soap, soap->arrayType, type) + && soap_match_tag(soap, soap->arrayType, "xsd:anyType") + && soap_match_tag(soap, soap->arrayType, "xsd:ur-type") + ) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type)); + return SOAP_TAG_MISMATCH; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ + +#ifdef WITH_OPENSSL +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_rand() +{ unsigned char buf[4]; + ssl_init(); + RAND_pseudo_bytes(buf, 4); + return *(int*)buf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_server_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *dhfile, const char *randfile, const char *sid) +{ int err; + soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + if (dhfile) + { soap->dhfile = dhfile; + soap->rsa = 0; + } + else + { soap->dhfile = NULL; + soap->rsa = 1; + } + soap->randfile = randfile; + soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION); + if (!(err = soap->fsslauth(soap))) + if (sid) + SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid)); + return err; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile) +{ soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->dhfile = NULL; + soap->rsa = 0; + soap->randfile = randfile; + soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION); + return soap->fsslauth(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static void +ssl_init() +{ static int done = 0; + if (!done) + { done = 1; + SSL_library_init(); +#ifndef WITH_LEAN + SSL_load_error_strings(); +#endif + if (!RAND_load_file("/dev/urandom", 1024)) + { char buf[1024]; + RAND_seed(buf, sizeof(buf)); + while (!RAND_status()) + { int r = rand(); + RAND_seed(&r, sizeof(int)); + } + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static const char * +ssl_error(struct soap *soap, int ret) +{ int err = SSL_get_error(soap->ssl, ret); + const char *msg = soap_str_code(h_ssl_error_codes, err); + if (msg) + strcpy(soap->msgbuf, msg); + else + return ERR_error_string(err, soap->msgbuf); + if (ERR_peek_error()) + { unsigned long r; + strcat(soap->msgbuf, "\n"); + while ((r = ERR_get_error())) + ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf)); + } + else + { switch (ret) + { case 0: + strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information."); + break; + case -1: + sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno)); + break; + } + } + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_password(char *buf, int num, int rwflag, void *userdata) +{ if (num < (int)strlen((char*)userdata) + 1) + return 0; + return strlen(strcpy(buf, (char*)userdata)); +} +#endif + +/******************************************************************************/ +/* This callback is included for future references. It should not be deleted +#ifndef PALM_2 +static DH * +ssl_tmp_dh(SSL *ssl, int is_export, int keylength) +{ static DH *dh512 = NULL; + static DH *dh1024 = NULL; + DH *dh; + switch (keylength) + { case 512: + if (!dh512) + { BIO *bio = BIO_new_file("dh512.pem", "r"); + if (bio) + { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + return dh512; + } + } + else + return dh512; + default: + if (!dh1024) + { BIO *bio = BIO_new_file("dh1024.pem", "r"); + if (bio) + { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } + dh = dh1024; + } + return dh; +} +#endif +*/ + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_auth_init(struct soap *soap) +{ ssl_init(); + if (!soap->ctx) + { if (!(soap->ctx = SSL_CTX_new(SSLv23_method()))) + return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR); + } + if (soap->randfile) + { if (!RAND_load_file(soap->randfile, -1)) + return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR); + } + if (soap->cafile || soap->capath) + { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath)) + return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR); + } + if (!SSL_CTX_set_default_verify_paths(soap->ctx)) + return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR); +/* See below */ + if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR); + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); + } +/* Suggested alternative approach to check cafile first before the key file: + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile)) + { if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL error", "Can't read certificate or key file", SOAP_SSL_ERROR); + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); + } + } +*/ + if (soap->rsa) + { RSA *rsa = RSA_generate_key(512, RSA_F4, NULL, NULL); + if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa)) + { if (rsa) + RSA_free(rsa); + return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR); + } + RSA_free(rsa); + } + else if (soap->dhfile) + { DH *dh = 0; + BIO *bio; + bio = BIO_new_file(soap->dhfile, "r"); + if (!bio) + return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR); + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0) + { if (dh) + DH_free(dh); + return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR); + } + DH_free(dh); + } + SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); + SSL_CTX_set_verify(soap->ctx, soap->require_client_auth ? (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : soap->require_server_auth ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, soap->fsslverify); +#if (OPENSSL_VERSION_NUMBER < 0x00905100L) + SSL_CTX_set_verify_depth(soap->ctx, 1); +#else + SSL_CTX_set_verify_depth(soap->ctx, 9); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_verify_callback(int ok, X509_STORE_CTX *store) +{ +#ifdef SOAP_DEBUG + if (!ok) + { char data[256]; + X509 *cert = X509_STORE_CTX_get_current_cert(store); + fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); + X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate issuer %s\n", data); + X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate subject %s\n", data); + } +#endif + /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */ + return ok; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_accept(struct soap *soap) +{ BIO *bio; + int i, r; + if (!soap_valid_socket(soap->socket)) + return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR); + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + return SOAP_INVALID_SOCKET; + if (!soap->ssl) + { soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + } + else + SSL_clear(soap->ssl); + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; +#ifdef WIN32 + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK); +#endif + bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); + i = 100; /* 100 * 0.1 ms retries */ + while ((r = SSL_accept(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { struct timeval timeout; + fd_set fd; + if (i-- <= 0) + break; + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r < 0 && soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + return SOAP_EOF; + } + } + else + { soap->errnum = err; + break; + } + } +#ifdef WIN32 + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + if (r <= 0) + { soap_set_receiver_error(soap, ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + soap_closesock(soap); + return SOAP_SSL_ERROR; + } + if (soap->require_client_auth) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_closesock(soap); + return soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in soap_ssl_accept()", SOAP_SSL_ERROR); + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_closesock(soap); + return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR); + } + X509_free(peer); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#endif /* WITH_OPENSSL */ + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_init(struct soap *soap) +{ soap->errmode = 1; +#ifdef WIN32 + if (tcp_done) + return 0; + else + { WSADATA w; + if (WSAStartup(MAKEWORD(1, 1), &w)) + return -1; + tcp_done = 1; + } +#endif + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_done(struct soap *soap) +{ +#ifdef SOAP_DEBUG + int i; +#endif + soap_free(soap); + while (soap->clist) + { struct soap_clist *p = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = p; + } + soap->keep_alive = 0; /* to force close the socket */ + soap_closesock(soap); +#ifdef WITH_COOKIES + soap_free_cookies(soap); +#endif + while (soap->plugins) + { register struct soap_plugin *p = soap->plugins->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id)); + if (soap->plugins->fcopy || !soap->copy) + soap->plugins->fdelete(soap, soap->plugins); + SOAP_FREE(soap, soap->plugins); + soap->plugins = p; + } + soap->fplugin = fplugin; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinal = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; +#ifdef WITH_OPENSSL + if (soap->session) + { SSL_SESSION_free(soap->session); + soap->session = NULL; + } +#endif + if (!soap->copy) + { if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } +#ifdef WITH_OPENSSL + if (soap->ctx) + { SSL_CTX_free(soap->ctx); + soap->ctx = NULL; + } +#endif + } +#ifdef SOAP_DEBUG + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n")); + for (i = 0; i < SOAP_MAXLOGS; i++) + { if (soap->logfile[i]) + { SOAP_FREE(soap, (void*)soap->logfile[i]); + soap->logfile[i] = NULL; + } + soap_close_logfile(soap, i); + } + soap_free_mht(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_cleanup(struct soap *soap) +{ soap_done(soap); +#ifdef WIN32 + if (!tcp_done) + return; + tcp_done = 0; + WSACleanup(); +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +tcp_error(struct soap *soap) +{ register const char *msg = NULL; + switch (soap->errmode) + { case 0: + msg = soap_strerror(soap); + break; + case 1: + msg = "WSAStartup failed"; + break; + case 2: + { +#ifndef WITH_LEAN + msg = soap_str_code(h_error_codes, soap->errnum); + if (!msg) +#endif + { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum); + msg = soap->msgbuf; + } + } + } + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static const char* +http_error(struct soap *soap, int status) +{ register const char *msg = SOAP_STR_EOS; +#ifndef WITH_LEAN + msg = soap_str_code(h_http_error_codes, status); + if (!msg) + msg = SOAP_STR_EOS; +#endif + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_IPV6 +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr) +{ soap_int32 iadd = -1; + struct hostent hostent, *host = &hostent; +#ifdef VXWORKS + int hostint; + char *addrcopy = (char*)SOAP_MALLOC(soap, strlen(addr) + 1); /*copy of addr. */ + /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */ + strncpy(addrcopy, addr, strlen(addr)+1); + iadd = inet_addr(addrcopy); +#else +#if defined(_AIXVERSION_431) || defined(TRU64) + struct hostent_data ht_data; +#endif + iadd = inet_addr(addr); +#endif + if (iadd != -1) + { memcpy(inaddr, &iadd, sizeof(iadd)); +#ifdef VXWORKS + SOAP_FREE(soap, addrcopy); +#endif + return SOAP_OK; + } +#if defined(__GLIBC__) + if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0) + host = NULL; +#elif defined(_AIXVERSION_431) || defined(TRU64) + memset((void*)&ht_data, 0, sizeof(ht_data)); + if (gethostbyname_r(addr, &hostent, &ht_data) < 0) + { host = NULL; + soap->errnum = h_errno; + } +#elif defined(HAVE_GETHOSTBYNAME_R) + host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum); +#elif defined(VXWORKS) + /* If the DNS resolver library resolvLib has been configured in the vxWorks + * image, a query for the host IP address is sent to the DNS server, if the + * name was not found in the local host table. */ + hostint = hostGetByName(addrcopy); + if (hostint == ERROR) + { host = NULL; + soap->errnum = soap_errno; + } + SOAP_FREE(soap, addrcopy); /*free() is placed after the error checking to assure that + * errno captured is that from hostGetByName() */ +#else + if (!(host = gethostbyname(addr))) + soap->errnum = h_errno; +#endif + if (!host) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n")); + return SOAP_ERR; + } +#ifdef VXWORKS + inaddr->s_addr = hostint; +#else + memcpy(inaddr, host->h_addr, host->h_length); +#endif + return SOAP_OK; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) +{ +#ifdef WITH_IPV6 + struct addrinfo hints, *res, *ressave; + int err; +#endif + register int fd; +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->socket)) + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + if (tcp_init(soap)) + { soap->errnum = 0; + soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->errmode = 0; +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + soap->errmode = 2; + if (soap->proxy_host) + err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res); + else + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res); + if (err) + { soap_set_sender_error(soap, gai_strerror(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + ressave = res; +again: + fd = (int)socket(res->ai_family, res->ai_socktype, res->ai_protocol); + soap->errmode = 0; +#else +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + fd = (int)socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + fd = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + if (fd < 0) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->connect_flags & SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + if ((soap->connect_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags & ~SO_LINGER, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port)); +#ifndef WITH_IPV6 + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (soap->proxy_host) + { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)soap->proxy_port); + } + else + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)port); + } + soap->errmode = 0; + if ((soap->omode & SOAP_IO_UDP)) + return fd; +#endif +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = TRUE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + for (;;) + { +#ifdef WITH_IPV6 + if (connect((SOAP_SOCKET)fd, res->ai_addr, res->ai_addrlen)) +#else + if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer))) +#endif + { +#ifndef WITH_LEAN + if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS || soap_socket_errno == SOAP_EWOULDBLOCK)) + { struct timeval timeout; + SOAP_SOCKLEN_T k; + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)fd, &fds); + for (;;) + { int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + k = (SOAP_SOCKLEN_T)sizeof(soap->errnum); + if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum) /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap->errnum = soap_socket_errno; + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + else +#endif +#ifdef WITH_IPV6 + if (res->ai_next) + { res = res->ai_next; + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + goto again; + } + else +#endif + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + else + break; + } +#ifdef WITH_IPV6 + soap->peerlen = 0; /* IPv6: already connected so use send() */ + freeaddrinfo(ressave); +#endif +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */ + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = fd; + soap->imode &= ~SOAP_ENC_SSL; + soap->omode &= ~SOAP_ENC_SSL; + if (!strncmp(endpoint, "https:", 6)) + { +#ifdef WITH_OPENSSL + BIO *bio; + int r; + if (soap->proxy_host) + { short v; + unsigned int k = soap->omode; /* make sure we only parse HTTP */ + size_t n = soap->count; /* save the content length */ + soap->omode &= ~SOAP_ENC; /* mask IO and ENC */ + soap->omode |= SOAP_IO_BUFFER; + soap_begin_send(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to proxy server\n")); + sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->http_version); + if ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return SOAP_INVALID_SOCKET; +#ifndef WITH_LEAN + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return soap->error; + } +#endif + if ((soap->error = soap->fposthdr(soap, NULL, NULL)) + || soap_flush(soap)) + return SOAP_INVALID_SOCKET; + soap->omode = k; + k = soap->imode; + soap->imode &= ~SOAP_ENC; /* mask IO and ENC */ + v = soap->version; /* preserve */ + if (soap_begin_recv(soap)) + return SOAP_INVALID_SOCKET; + soap->version = v; /* restore */ + soap->imode = k; /* restore */ + soap->count = n; /* restore */ + soap_begin_send(soap); + } + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + { soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; + } + if (soap->session) + { if (!strcmp(soap->session_host, host) && soap->session_port == port) + SSL_set_session(soap->ssl, soap->session); + SSL_SESSION_free(soap->session); + soap->session = NULL; + } + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; + bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); +#ifndef WITH_LEAN + if (soap->connect_timeout) +#ifdef WIN32 + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif +#endif + for (;;) + { if ((r = SSL_connect(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + { soap_set_sender_error(soap, ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap->connect_timeout) + { struct timeval timeout; + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)soap->socket, &fds); + for (;;) + { int r = select((SOAP_SOCKET)(soap->socket + 1), &fds, NULL, &fds, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + continue; + } + } + break; + } +#ifndef WITH_LEAN + if (soap->connect_timeout) +#ifdef WIN32 + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + if (soap->require_server_auth) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, soap->msgbuf, sizeof(soap->msgbuf)); + X509_free(peer); + if (soap_tag_cmp(soap->msgbuf, host)) + { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR); + return SOAP_INVALID_SOCKET; + } + } +#else + soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; +#endif + } + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_bind(struct soap *soap, const char *host, int port, int backlog) +{ +#ifdef WITH_IPV6 + struct addrinfo *addrinfo; + struct addrinfo hints; + struct addrinfo res; + int err; +#endif +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 1; + if (tcp_init(soap)) + { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + soap->errmode = 2; + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo); + if (addrinfo) + { res = *addrinfo; + soap->peer = *((struct sockaddr_storage*)addrinfo->ai_addr); + soap->peerlen = addrinfo->ai_addrlen; + res.ai_addr = (struct sockaddr*)&soap->peer; + res.ai_addrlen = soap->peerlen; + freeaddrinfo(addrinfo); + } + if (err) + { soap_set_receiver_error(soap, gai_strerror(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->master = socket(res.ai_family, res.ai_socktype, res.ai_protocol); +#else +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + soap->master = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + soap->errmode = 0; + if (!soap_valid_socket(soap->master)) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + soap->socket = soap->master; +#endif +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(soap->master, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#endif +#ifdef WITH_IPV6 + soap->errmode = 0; + if (bind((SOAP_SOCKET)soap->master, res.ai_addr, res.ai_addrlen)) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#else + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (host) + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + else + soap->peer.sin_addr.s_addr = htonl(INADDR_ANY); + soap->peer.sin_port = htons((short)port); + soap->errmode = 0; + if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&soap->peer, soap->peerlen)) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif + if (!(soap->omode & SOAP_IO_UDP) && listen((SOAP_SOCKET)soap->master, backlog)) + { soap->errnum = soap_socket_errno; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + return soap->master; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_poll(struct soap *soap) +{ +#ifndef WITH_LEAN + struct timeval timeout; + fd_set rfd, sfd, xfd; + int r; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&rfd); + FD_ZERO(&sfd); + FD_ZERO(&xfd); + if (soap_valid_socket(soap->socket)) + { FD_SET((SOAP_SOCKET)soap->socket, &rfd); + FD_SET((SOAP_SOCKET)soap->socket, &sfd); + FD_SET((SOAP_SOCKET)soap->socket, &xfd); + r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, &xfd, &timeout); + if (r > 0 && FD_ISSET((SOAP_SOCKET)soap->socket, &xfd)) + r = -1; + } + else if (soap_valid_socket(soap->master)) + { FD_SET((SOAP_SOCKET)soap->master, &sfd); + r = select((SOAP_SOCKET)(soap->master + 1), NULL, &sfd, NULL, &timeout); + } + else + return SOAP_OK; + if (r > 0) + { if (soap_valid_socket(soap->socket) + && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd) + && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd) + || recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0)) + return SOAP_OK; + } + else if (r < 0) + { soap->errnum = soap_socket_errno; + if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno != SOAP_EINTR) + { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR); + return soap->error = SOAP_TCP_ERROR; + } + } + else + soap->errnum = 0; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r)); + return SOAP_EOF; +#else + return SOAP_OK; +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n) +{ int fd; + fd = (int)accept((SOAP_SOCKET)s, a, (SOAP_SOCKLEN_T*)n); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif +#endif + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_accept(struct soap *soap) +{ int n = (int)sizeof(soap->peer); +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + soap->error = SOAP_OK; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + return soap->socket = soap->master; +#endif + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 0; + soap->keep_alive = 0; + if (soap_valid_socket(soap->master)) + { for (;;) + { +#ifndef WITH_LEAN + if (soap->accept_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->accept_timeout > 0) + { timeout.tv_sec = soap->accept_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->accept_timeout/1000000; + timeout.tv_usec = -soap->accept_timeout%1000000; + } + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->master, &fd); + for (;;) + { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (soap_socket_errno != SOAP_EINTR) + { soap->errnum = soap_socket_errno; + soap_closesock(soap); + soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = TRUE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + } +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK); +#endif + } + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + } +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n); + soap->peerlen = (size_t)n; + if (soap_valid_socket(soap->socket)) + { +#ifdef WITH_IPV6 +/* Use soap->host to store the numeric form of the remote host */ + getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host)); + soap->ip = 0; /* info stored in soap->peer and soap->host */ + soap->port = 0; /* info stored in soap->peer and soap->host */ +#else + soap->ip = ntohl(soap->peer.sin_addr.s_addr); + soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF)); +#endif +#ifndef WITH_LEAN + if (soap->accept_flags & SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + if ((soap->accept_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags & ~SO_LINGER, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + if (soap->accept_timeout) + { +#if defined(WIN32) + u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); +#elif defined(VXWORKS) + vx_nonblocking = FALSE; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking)); + ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&vx_nonblocking)); +#elif defined(PALM) + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK); +#elif defined(SYMBIAN) + long blocking = 0; + ioctl((SOAP_SOCKET)soap->master, 0/*FIONBIO*/, &blocking); +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + return soap->socket; + } + if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host)); + soap->errnum = soap_socket_errno; + soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + } + else + { soap->errnum = 0; + soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_disconnect(struct soap *soap) +{ +#ifdef WITH_OPENSSL + if (soap->ssl) + { int r, s = 0; + if (soap->session) + SSL_SESSION_free(soap->session); + if (*soap->host) + { soap->session = SSL_get1_session(soap->ssl); + if (soap->session) + { strcpy(soap->session_host, soap->host); + soap->session_port = soap->port; + } + } + r = SSL_shutdown(soap->ssl); + if (r != 1) + { s = ERR_get_error(); + if (s) + { if (soap_valid_socket(soap->socket)) + { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); + soap->socket = SOAP_INVALID_SOCKET; + } + r = SSL_shutdown(soap->ssl); + } + } + DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r))); + SSL_free(soap->ssl); + soap->ssl = NULL; + if (s) + return SOAP_SSL_ERROR; + ERR_remove_state(0); + } +#endif + if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP)) + { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2); + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_closesocket(struct soap *soap, SOAP_SOCKET fd) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd)); + return closesocket(fd); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how)); + return shutdown(fd, how); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_closesock(struct soap *soap) +{ register int status = soap->error; + if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive) + { if (soap->fclose && (soap->error = soap->fclose(soap))) + return soap->error; + soap->keep_alive = 0; + } +#ifdef WITH_ZLIB + if (soap->zlib_state == SOAP_ZLIB_DEFLATE) + deflateEnd(&soap->d_stream); + else if (soap->zlib_state == SOAP_ZLIB_INFLATE) + inflateEnd(&soap->d_stream); + soap->zlib_state = SOAP_ZLIB_NONE; +#endif + return soap->error = status; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_hash(register const char *s) +{ register size_t h = 0; + while (*s) + h = 65599*h + *s++; + return h % SOAP_IDHASH; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_pht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n")); + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new1(soap_mode mode) +{ return soap_new2(mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new() +{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new2(soap_mode imode, soap_mode omode) +{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap)); + if (soap) + soap_init2(soap, imode, omode); + return soap; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_pht(struct soap *soap) +{ register struct soap_pblk *pb, *next; + register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n")); + for (pb = soap->pblk; pb; pb = next) + { next = pb->next; + SOAP_FREE(soap, pb); + } + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type) +{ register int i; + struct soap_plist *pp; + if (soap->version != 1) + soap->encoding = 1; + if (a) + i = soap_array_pointer_lookup(soap, p, a, n, type, &pp); + else + i = soap_pointer_lookup(soap, p, type, &pp); + if (i) + { if (soap_is_embedded(soap, pp) + || soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + return i; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (p) + { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next) + { if (pp->ptr == p && pp->type == type) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register int h; + register struct soap_plist *pp; + if (!soap->pblk || soap->pidx >= SOAP_PTRBLK) + { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk)); + if (!pb) + { soap->error = SOAP_EOM; + return 0; + } + pb->next = soap->pblk; + soap->pblk = pb; + soap->pidx = 0; + } + *ppp = pp = &soap->pblk->plist[soap->pidx++]; + if (a) + h = soap_hash_ptr(a->__ptr); + else + h = soap_hash_ptr(p); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1)); + pp->next = soap->pht[h]; + pp->type = type; + pp->mark1 = 0; + pp->mark2 = 0; + pp->ptr = p; + pp->array = a; + soap->pht[h] = pp; + pp->id = ++soap->idnum; + return pp->id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (!p || !a->__ptr) + return 0; + for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next) + { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr) + { register int i; + for (i = 0; i < n; i++) + if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i]) + break; + if (i == n) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_count(struct soap *soap) +{ soap_clr_attr(soap); + soap_set_local_namespaces(soap); +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME)) + soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME; + else +#endif + { soap->mode = soap->omode; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE + || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML)) +#ifndef WITH_LEANER + && !soap->fpreparesend +#endif + )) + soap->mode &= ~SOAP_IO_LENGTH; + else + soap->mode |= SOAP_IO_LENGTH; + } +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (!(soap->mode & SOAP_ENC_DIME)) + soap->mode &= ~SOAP_IO_LENGTH; + if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + soap->mode |= SOAP_ENC_MIME; + else + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); + soap->dime.list = soap->dime.last; /* keep track of last DIME attachment */ +#endif + soap->count = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->part = SOAP_BEGIN; + soap->idnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); +#ifndef WITH_LEANER + soap->dime.count = 0; /* count # of attachments */ + soap->dime.size = 0; /* accumulate total size of attachments */ + if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fprepareinit(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_count(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->fpreparefinal) + return soap->error = soap->fpreparefinal(soap); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n")); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_send(struct soap *soap) +{ soap->error = SOAP_OK; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); + soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME)); +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif +#ifdef WITH_UDP + if ((soap->mode & SOAP_IO_UDP)) + { soap->mode |= SOAP_ENC_XML; + if (soap->count > SOAP_BUFLEN) + return soap->error = SOAP_UDP_ERROR; + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket)) + { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML)) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } + soap->mode &= ~SOAP_IO_LENGTH; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap_new_block(soap); + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + { soap->mode |= SOAP_ENC_MIME; + soap->mode &= ~SOAP_ENC_DIME; + } + else + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */ +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->sendfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY); +#endif +#endif +#endif +#endif +#endif + if (soap->mode & SOAP_IO) + { soap->bufidx = 0; + soap->buflen = 0; + } + soap->chunksize = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->idnum = 0; + soap->level = 0; +#ifdef WITH_ZLIB + soap->z_ratio_out = 1.0; + if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE) + { +#ifdef WITH_GZIP + memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10); + soap->d_stream.next_out = (Byte*)soap->z_buf + 10; + soap->d_stream.avail_out = SOAP_BUFLEN - 10; + soap->z_crc = crc32(0L, NULL, 0); + if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) +#else + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK) +#endif + return soap->error = SOAP_ZLIB_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n")); + soap->zlib_state = SOAP_ZLIB_DEFLATE; + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); + soap->part = SOAP_BEGIN; +#ifndef WITH_LEANER + if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap->fprepareinit(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_embedded(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (soap_pointer_lookup(soap, p, t, &pp)) + { pp->mark1 = 1; + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t)); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_reference(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (!p || (soap->mode & SOAP_XML_TREE)) + return 1; + if (soap_pointer_lookup(soap, p, t, &pp)) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp)) + { pp->mark1 = 0; + pp->mark2 = 0; + } + else + return 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t) +{ register int i; + struct soap_plist *pp; + if (!p || !a->__ptr) + return 1; + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (i) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (!soap_pointer_enter(soap, p, a, n, t, &pp)) + return 1; + else + { pp->mark1 = 0; + pp->mark2 = 0; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p dim=%d type=%d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embedded_id(struct soap *soap, int id, const void *p, int t) +{ struct soap_plist *pp; + if (soap->mode & SOAP_XML_TREE) + return id; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (id < 0) + { id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 2; + else + pp->mark2 = 2; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id multiref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return -1; + } + return id; + } + if (id < 0) + id = soap_pointer_lookup(soap, p, t, &pp); + else if (id && !soap_pointer_lookup(soap, p, t, &pp)) + return 0; + if (id && pp) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id embedded ref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 != 0; + return pp->mark2 != 0; + } + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 1; + return pp->mark2 == 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_single(struct soap *soap, struct soap_plist *pp) +{ if (soap->part == SOAP_IN_HEADER) + return 1; + if (!pp) + return 0; + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 0; + return pp->mark2 == 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return; + if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t) +{ struct soap_plist *pp; + int i; + if (!p || !a->__ptr || (!aid && !atype)) + return soap_element_id(soap, tag, id, p, a, n, type, t); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:"")); + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (!i) + { i = soap_pointer_enter(soap, p, a, n, t, &pp); + if (!i) + { soap->error = SOAP_EOM; + return -1; + } + } + if (id < 0) + id = i; + if (!aid) + { sprintf(soap->tmpbuf, soap->dime_id_format, id); + aid = soap_strdup(soap, soap->tmpbuf); + } + /* Add MTOM xop:Include element when necessary */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include")) + { if (soap_element_begin_out(soap, tag, 0, type) + || soap_element_href(soap, "xop:Include", 0, "href", aid) + || soap_element_end_out(soap, tag)) + return soap->error; + } + else if (soap_element_href(soap, tag, 0, "href", aid)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (pp->mark1 != 3) + { struct soap_multipart *content; + if (soap->mode & SOAP_ENC_MTOM) + content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size); + else + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size); + if (!content) + { soap->error = SOAP_EOM; + return -1; + } + if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */ + { if (soap->mode & SOAP_ENC_MTOM) + { char *s = (char*)soap_malloc(soap, strlen(aid) - 1); + if (s) + { *s = '<'; + strcpy(s + 1, aid + 4); + strcat(s, ">"); + content->id = s; + } + } + else + content->id = aid + 4; + } + else + content->id = aid; + content->type = atype; + content->options = aoptions; + content->encoding = SOAP_MIME_BINARY; + pp->mark1 = 3; + } + } + else + pp->mark2 = 3; + return -1; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_iht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + soap->iht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_iht(struct soap *soap) +{ register int i; + register struct soap_ilist *ip, *p; + register struct soap_flist *fp, *fq; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = p) + { for (fp = ip->flist; fp; fp = fq) + { fq = fp->next; + SOAP_FREE(soap, fp); + } + p = ip->next; + SOAP_FREE(soap, ip); + } + soap->iht[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_lookup(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next) + if (!strcmp(ip->id, id)) + return ip; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_enter(struct soap *soap, const char *id) +{ register size_t h; + register struct soap_ilist *ip; + ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id)); + if (ip) + { h = soap_hash(id); + strcpy(ip->id, id); + ip->next = soap->iht[h]; + soap->iht[h] = ip; + return ip; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_malloc(struct soap *soap, size_t n) +{ register char *p; + if (!n) + return (void*)SOAP_NON_NULL; + if (!soap) + return SOAP_MALLOC(soap, n); + n += (-(long)n) & 7; + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + /* keep chain of alloced cells for later destruction */ + soap->alloced = 1; + *(void**)(p + n) = soap->alist; + *(size_t*)(p + n + sizeof(void*)) = n; + soap->alist = p + n; + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_init_mht(struct soap *soap) +{ register int i; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->mht[i] = NULL; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_free_mht(struct soap *soap) +{ register int i; + register struct soap_mlist *mp, *mq; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + { for (mp = soap->mht[i]; mp; mp = mq) + { mq = mp->next; + if (mp->live) + fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr); + free(mp); + } + soap->mht[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_track_malloc(struct soap *soap, const char *file, int line, size_t size) +{ register void *p = malloc(size); + if (soap) + { register int h = soap_hash_ptr(p); + register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist)); + if (soap->fdebug[SOAP_INDEX_TEST]) + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p)); + mp->next = soap->mht[h]; + mp->ptr = p; + mp->file = file; + mp->line = line; + mp->live = 1; + soap->mht[h] = mp; + } + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_track_free(struct soap *soap, const char *file, int line, void *p) +{ register int h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + { if (mp->live) + { free(p); + if (soap->fdebug[SOAP_INDEX_TEST]) + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p)); + mp->live = 0; + } + else + fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line); + } + else + fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_track_unlink(struct soap *soap, const void *p) +{ register int h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + mp->live = 0; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_dealloc(struct soap *soap, void *p) +{ if (!soap) + return; + if (p) + { register char **q; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p)); + SOAP_FREE(soap, p); + return; + } + } + soap_delete(soap, p); + } + else + { register char *q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n")); + while (soap->alist) + { q = (char*)soap->alist; + soap->alist = *(void**)q; + q -= *(size_t*)(q + sizeof(void*)); + SOAP_FREE(soap, q); + } + } + /* we must assume these were deallocated: */ + soap->action = NULL; + soap->fault = NULL; + soap->header = NULL; + soap->userid = NULL; + soap->passwd = NULL; + soap->authrealm = NULL; +#ifndef WITH_LEANER + soap_clr_mime(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_delete(struct soap *soap, void *p) +{ register struct soap_clist **cp = &soap->clist; + if (p) + { while (*cp) + { if (p == (*cp)->ptr) + { register struct soap_clist *q = *cp; + *cp = q->next; + q->fdelete(q); + SOAP_FREE(soap, q); + return; + } + cp = &(*cp)->next; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p)); + } + else + { while (*cp) + { register struct soap_clist *q = *cp; + *cp = q->next; + if (q->ptr == (void*)soap->fault) + soap->fault = NULL; /* this was deallocated */ + else if (q->ptr == (void*)soap->header) + soap->header = NULL; /* this was deallocated */ + q->fdelete(q); + SOAP_FREE(soap, q); + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_clist * +SOAP_FMAC2 +soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*)) +{ register struct soap_clist *cp; + if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist)))) + { cp->next = soap->clist; + cp->type = t; + cp->size = n; + cp->ptr = p; + cp->fdelete = fdelete; + soap->clist = cp; + } + return cp; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_unlink(struct soap *soap, const void *p) +{ register char **q; + register struct soap_clist **cp; + if (!soap || !p) + return; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p)); +#ifdef SOAP_DEBUG + soap_track_unlink(soap, p); +#endif + return; + } + } + for (cp = &soap->clist; *cp; cp = &(*cp)->next) + { if (p == (*cp)->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p)); + q = (char**)*cp; + *cp = (*cp)->next; + SOAP_FREE(soap, q); + return; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_lookup_type(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + if (id && *id) + { ip = soap_lookup(soap, id); + if (ip) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type)); + return ip->type; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k) +{ struct soap_ilist *ip; + void **q; + if (!p || !id || !*id) + return p; + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n)); + ip->type = t; + ip->size = n; + ip->link = p; + ip->copy = NULL; + ip->flist = NULL; + ip->ptr = NULL; + ip->level = k; + *p = NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n)); + if (ip->type != t) + { strcpy(soap->id, id); + soap->error = SOAP_HREF; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t)); + return NULL; + } + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return NULL; + *p = (void*)q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + *p = ip->ptr; + } + else if (ip->level > k) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id)); + while (ip->level > k) + { void *s, **r = &ip->link; + q = (void**)ip->link; + while (q) + { *r = (void*)soap_malloc(soap, sizeof(void*)); + s = *q; + *q = *r; + r = (void**)*r; + q = (void**)s; + } + *r = NULL; + ip->size = n; + ip->copy = NULL; + ip->level = ip->level - 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n)); + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + *p = q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_forward(struct soap *soap, const char *href, void *p, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, const void*, size_t)) +{ struct soap_ilist *ip; + if (!p || !href || !*href) + return p; + ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, href); /* new hash table entry for string id */ + ip->type = st; + ip->size = n; + ip->link = NULL; + ip->copy = NULL; + ip->ptr = NULL; + ip->level = 0; + ip->flist = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry href='%s' type=%d size=%lu level=%d location=%p\n", href, st, (unsigned long)n, k, p)); + } + else if (ip->type != st || (ip->level == k && ip->size != n)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n)); + strcpy(soap->id, href); + soap->error = SOAP_HREF; + return NULL; + } + if (fcopy || n < sizeof(void*) || *href != '#') + { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist)); + if (!fp) + { soap->error = SOAP_EOM; + return NULL; + } + fp->next = ip->flist; + fp->type = tt; + fp->ptr = p; + fp->level = k; + if (fcopy) + fp->fcopy = fcopy; + else + fp->fcopy = soap_fcopy; + ip->flist = fp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u href='%s'\n", st, tt, (unsigned long)n, p, k, href)); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href)); + *(void**)p = ip->copy; + ip->copy = p; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)) +{ +#ifndef WITH_NOIDREF + struct soap_ilist *ip; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + soap->alloced = 0; + if (!p) + { if (finstantiate) + p = finstantiate(soap, t, type, arrayType, &n); + else + p = soap_malloc(soap, n); + if (p) + soap->alloced = 1; + } +#ifndef WITH_NOIDREF + if (!id || !*id) +#endif + return p; +#ifndef WITH_NOIDREF + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p)); + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + ip->type = t; + ip->link = NULL; + ip->copy = NULL; + ip->flist = NULL; + ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%lu level=%u location=%p\n", id, t, (unsigned long)n, k, p)); + } + else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n)); + strcpy(soap->id, id); + soap->error = SOAP_HREF; + return NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id)); + strcpy(soap->id, id); + soap->error = SOAP_DUPLICATE_ID; + return NULL; + } + else + { ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update entry id='%s' type=%d location=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + } + return ip->ptr; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n) +{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n)); + memcpy(p, q, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_send(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->dime.list) + { /* SOAP body referenced attachments must appear first */ + soap->dime.last->next = soap->dime.first; + soap->dime.first = soap->dime.list->next; + soap->dime.list->next = NULL; + soap->dime.last = soap->dime.list; + } + if (soap_putdime(soap) || soap_putmime(soap)) + return soap->error; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n")); + if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */ + { if (soap_flush(soap)) +#ifdef WITH_ZLIB + { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + } + return soap->error; + } +#else + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { int r; + soap->d_stream.avail_in = 0; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n")); + r = deflate(&soap->d_stream, Z_FINISH); + if (soap->d_stream.avail_out != SOAP_BUFLEN) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out)) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + return soap->error; + } + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (r == Z_OK); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in; + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_state = SOAP_ZLIB_NONE; + if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } +#ifdef WITH_GZIP + soap->z_buf[0] = soap->z_crc & 0xFF; + soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF; + soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF; + soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF; + soap->z_buf[4] = soap->d_stream.total_in & 0xFF; + soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF; + soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF; + soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF; + if (soap_flush_raw(soap, soap->z_buf, 8)) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc)); +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { char *p; +#ifndef WITH_NOHTTP + if (!(soap->mode & SOAP_ENC_XML)) + { soap->mode--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size)); + if (soap->status >= SOAP_POST) + soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size); + else if (soap->status != SOAP_STOP) + soap->error = soap->fresponse(soap, soap->status, soap->blist->size); + if (soap->error || soap_flush(soap)) + return soap->error; + soap->mode++; + } +#endif + for (p = soap_first_block(soap); p; p = soap_next_block(soap)) + { DBGMSG(SENT, p, soap_block_size(soap)); + if ((soap->error = soap->fsend(soap, p, soap_block_size(soap)))) + { soap_end_block(soap); + return soap->error; + } + } + soap_end_block(soap); + } +#ifndef WITH_LEANER + else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { DBGMSG(SENT, "\r\n0\r\n\r\n", 7); + if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7))) + return soap->error; + } +#endif + } +#ifdef WITH_OPENSSL + if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#else + if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n")); + soap->omode &= ~SOAP_XML_SEC; + soap->count = 0; + soap->part = SOAP_END; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_recv(struct soap *soap) +{ soap->part = SOAP_END; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap)) + return soap->error; + soap->dime.list = soap->dime.first; + soap->dime.first = NULL; + soap->dime.last = NULL; + if ((soap->mode & SOAP_ENC_MIME) && soap_getmime(soap)) + return soap->error; + soap->mime.list = soap->mime.first; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n")); +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->mode &= ~SOAP_ENC_ZLIB; + memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf; + soap->buflen = soap->z_buflen; + soap->zlib_state = SOAP_ZLIB_NONE; + if (inflateEnd(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; +#ifdef WITH_GZIP + if (soap->zlib_in == SOAP_ZLIB_GZIP) + { soap_wchar c; + short i; + for (i = 0; i < 8; i++) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + soap->z_buf[i] = (char)c; + } + if (soap->z_crc != ((uLong)(unsigned char)soap->z_buf[0] | ((uLong)(unsigned char)soap->z_buf[1] << 8) | ((uLong)(unsigned char)soap->z_buf[2] << 16) | ((uLong)(unsigned char)soap->z_buf[3] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc)); + return soap->error = SOAP_ZLIB_ERROR; + } + if (soap->d_stream.total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n")); + return soap->error = SOAP_ZLIB_ERROR; + } + } +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */ + ; + if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap))) + return soap->error; +#ifndef WITH_NOIDREF + return soap_resolve(soap); +#else +#ifndef WITH_LEANER + if (soap->xlist) + { if (soap->mode & SOAP_ENC_MTOM) + return soap->error = SOAP_MIME_HREF; + return soap->error = SOAP_DIME_HREF; + } +#endif + return SOAP_OK; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free(struct soap *soap) +{ register struct Namespace *ns; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n")); + while (soap->nlist) + { register struct soap_nlist *np = soap->nlist->next; + SOAP_FREE(soap, soap->nlist); + soap->nlist = np; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n")); + while (soap->blist) + soap_end_block(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n")); + while (soap->attributes) + { register struct soap_attribute *tp = soap->attributes->next; + if (soap->attributes->value) + SOAP_FREE(soap, soap->attributes->value); + SOAP_FREE(soap, soap->attributes); + soap->attributes = tp; + } +#ifdef WITH_FAST + if (soap->labbuf) + SOAP_FREE(soap, soap->labbuf); + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif + ns = soap->local_namespaces; + if (ns) + { for (; ns->id; ns++) + { if (ns->out) + { if (soap->encodingStyle == ns->out) + soap->encodingStyle = SOAP_STR_EOS; + SOAP_FREE(soap, ns->out); + ns->out = NULL; + } + if (soap->encodingStyle == ns->ns) + soap->encodingStyle = SOAP_STR_EOS; + } + SOAP_FREE(soap, soap->local_namespaces); + soap->local_namespaces = NULL; + } +#ifndef WITH_LEANER + while (soap->xlist) + { struct soap_xlist *xp = soap->xlist->next; + SOAP_FREE(soap, soap->xlist); + soap->xlist = xp; + } +#endif +#ifndef WITH_NOIDREF + soap_free_pht(soap); + soap_free_iht(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_init_logs(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + { soap->logfile[i] = NULL; + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_open_logfile(struct soap *soap, int i) +{ if (soap->logfile[i]) + soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a"); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_close_logfile(struct soap *soap, int i) +{ if (soap->fdebug[i]) + { fclose(soap->fdebug[i]); + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_close_logfiles(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + soap_close_logfile(soap, i); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_set_logfile(struct soap *soap, int i, const char *logfile) +{ char *s = NULL; + soap_close_logfile(soap, i); + if (soap->logfile[i]) + SOAP_FREE(soap, (void*)soap->logfile[i]); + if (logfile) + if ((s = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1))) + strcpy(s, logfile); + soap->logfile[i] = s; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_recv_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_sent_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_test_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_TEST, logfile); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy(struct soap *soap) +{ return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy_context(struct soap *copy, struct soap *soap) +{ if (copy) + { register struct soap_plugin *p; + memcpy(copy, soap, sizeof(struct soap)); + copy->copy = 1; + copy->user = NULL; + copy->error = SOAP_OK; + copy->userid = NULL; + copy->passwd = NULL; + copy->nlist = NULL; + copy->blist = NULL; + copy->clist = NULL; + copy->alist = NULL; + copy->attributes = NULL; +#ifdef WITH_FAST + copy->labbuf = NULL; + copy->lablen = 0; + copy->labidx = 0; +#endif +#ifdef SOAP_DEBUG + soap_init_mht(copy); +#endif + copy->local_namespaces = NULL; +#ifndef WITH_NOIDREF + soap_init_iht(copy); + soap_init_pht(copy); +#endif + copy->header = NULL; + copy->fault = NULL; + copy->action = NULL; + *copy->host = '\0'; +#ifndef WITH_LEAN +#ifdef WITH_COOKIES + copy->cookies = soap_copy_cookies(copy); +#else + copy->cookies = NULL; +#endif +#endif +#ifdef SOAP_DEBUG + soap_init_logs(copy); + soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]); + soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]); + soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]); +#endif + copy->plugins = NULL; + for (p = soap->plugins; p; p = p->next) + { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin)); + if (!q) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id)); + *q = *p; + if (p->fcopy && (soap->error = p->fcopy(copy, q, p))) + { SOAP_FREE(copy, q); + return NULL; + } + q->next = copy->plugins; + copy->plugins = q; + } + } + else + soap->error = SOAP_EOM; + return copy; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init(struct soap *soap) +{ soap->version = 0; + soap_imode(soap, SOAP_IO_DEFAULT); + soap_omode(soap, SOAP_IO_DEFAULT); + soap->copy = 0; + soap->plugins = NULL; + soap->user = NULL; + soap->userid = NULL; + soap->passwd = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fconnect = NULL; + soap->fdisconnect = NULL; +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinal = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; + soap->fplugin = fplugin; +#ifndef WITH_LEANER + soap->fdimereadopen = NULL; + soap->fdimewriteopen = NULL; + soap->fdimereadclose = NULL; + soap->fdimewriteclose = NULL; + soap->fdimeread = NULL; + soap->fdimewrite = NULL; +#endif + soap->float_format = "%.8g"; /* .8 preserves single FP precision as much as possible, but might not be very efficient */ + soap->double_format = "%.17lg"; /* .17 preserves double FP precision as much as possible, but might not be very efficient */ + soap->dime_id_format = "cid:id%d"; /* default DIME id format */ + soap->http_version = "1.1"; + soap->actor = NULL; + soap->max_keep_alive = SOAP_MAXKEEPALIVE; + soap->keep_alive = 0; + soap->recv_timeout = 0; + soap->send_timeout = 0; + soap->connect_timeout = 0; + soap->accept_timeout = 0; + soap->socket_flags = 0; + soap->connect_flags = 0; + soap->bind_flags = 0; + soap->accept_flags = 0; + soap->ip = 0; +#ifdef WITH_FAST + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif + soap->encodingStyle = SOAP_STR_EOS; +#ifndef WITH_NONAMESPACES + soap->namespaces = namespaces; +#else + soap->namespaces = NULL; +#endif + soap->local_namespaces = NULL; + soap->nlist = NULL; + soap->blist = NULL; + soap->clist = NULL; + soap->alist = NULL; + soap->attributes = NULL; + soap->header = NULL; + soap->fault = NULL; + soap->master = SOAP_INVALID_SOCKET; + soap->socket = SOAP_INVALID_SOCKET; + soap->os = NULL; + soap->is = NULL; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; + soap->xlist = NULL; +#endif +#ifndef UNDER_CE + soap->recvfd = 0; + soap->sendfd = 1; +#else + soap->recvfd = stdin; + soap->sendfd = stdout; +#endif + soap->host[0] = '\0'; + soap->port = 0; + soap->action = NULL; + soap->proxy_host = NULL; + soap->proxy_port = 8080; + soap->proxy_userid = NULL; + soap->proxy_passwd = NULL; + soap->authrealm = NULL; + soap->prolog = NULL; +#ifdef WITH_OPENSSL + soap->fsslauth = ssl_auth_init; + soap->fsslverify = ssl_verify_callback; + soap->bio = NULL; + soap->ssl = NULL; + soap->ctx = NULL; + soap->require_server_auth = 0; + soap->require_client_auth = 0; + soap->rsa = 0; + soap->keyfile = NULL; + soap->password = NULL; + soap->dhfile = NULL; + soap->cafile = NULL; + soap->capath = NULL; + soap->crlfile = NULL; + soap->randfile = NULL; + soap->session = NULL; +#endif +#ifdef WITH_ZLIB + soap->zlib_state = SOAP_ZLIB_NONE; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.zalloc = NULL; + soap->d_stream.zfree = NULL; + soap->d_stream.opaque = NULL; + soap->z_level = 6; +#endif +#ifndef WITH_LEAN + soap->c14ninclude = NULL; + soap->c14nexclude = NULL; + soap->cookies = NULL; + soap->cookie_domain = NULL; + soap->cookie_path = NULL; + soap->cookie_max = 32; +#endif +#ifdef SOAP_DEBUG + soap_init_mht(soap); + soap_init_logs(soap); + soap_set_recv_logfile(soap, "RECV.log"); + soap_set_sent_logfile(soap, "SENT.log"); + soap_set_test_logfile(soap, NULL); +#endif +#ifdef WMW_RPM_IO + soap->rpmreqid = NULL; +#endif /* WMW_RPM_IO */ +#ifdef PALM + palmNetLibOpen(); +#endif +#ifndef WITH_NOIDREF + soap_init_iht(soap); + soap_init_pht(soap); +#endif + soap_begin(soap); +#ifdef SOAP_DEBUG + soap_set_test_logfile(soap, "TEST.log"); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init1(struct soap *soap, soap_mode mode) +{ soap_init2(soap, mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init2(struct soap *soap, soap_mode imode, soap_mode omode) +{ soap_init(soap); + soap_imode(soap, imode); + soap_omode(soap, omode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_begin(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing\n")); + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + soap->null = 0; + soap->position = 0; + soap->encoding = 0; + soap->mustUnderstand = 0; + soap->mode = 0; + soap->ns = 0; + soap->part = SOAP_END; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + soap->error = SOAP_OK; + soap->peeked = 0; + soap->ahead = 0; + soap->idnum = 0; + soap->level = 0; + soap->endpoint[0] = '\0'; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; +#endif + soap_free(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end(struct soap *soap) +{ register struct soap_clist *cp; + soap_free(soap); + soap_dealloc(soap, NULL); + while (soap->clist) + { cp = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = cp; + } + soap_closesock(soap); +#ifdef SOAP_DEBUG + soap_close_logfiles(soap); +#endif +#ifdef PALM + palmNetLibClose(); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_namespaces(struct soap *soap, struct Namespace *p) +{ register struct Namespace *ns = soap->local_namespaces; + register struct soap_nlist *np, *nq, *nr; + register unsigned int level = soap->level; + soap->namespaces = p; + soap->local_namespaces = NULL; + soap_set_local_namespaces(soap); + /* reverse the namespace list */ + np = soap->nlist; + soap->nlist = NULL; + if (np) + { nq = np->next; + np->next = NULL; + while (nq) + { nr = nq->next; + nq->next = np; + np = nq; + nq = nr; + } + } + /* then push on new stack */ + while (np) + { register const char *s; + soap->level = np->level; /* preserve element nesting level */ + s = np->ns; + if (!s && np->index >= 0 && ns) + { s = ns[np->index].out; + if (!s) + s = ns[np->index].ns; + } + if (s && soap_push_namespace(soap, np->id, s)) + return soap->error; + nq = np; + np = np->next; + SOAP_FREE(soap, nq); + } + if (ns) + { register int i; + for (i = 0; ns[i].id; i++) + { if (ns[i].out) + { SOAP_FREE(soap, ns[i].out); + ns[i].out = NULL; + } + } + SOAP_FREE(soap, ns); + } + soap->level = level; /* restore level */ + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_local_namespaces(struct soap *soap) +{ if (soap->namespaces && !soap->local_namespaces) + { register const struct Namespace *ns1; + register struct Namespace *ns2; + register size_t n = 1; + for (ns1 = soap->namespaces; ns1->id; ns1++) + n++; + n *= sizeof(struct Namespace); + ns2 = (struct Namespace*)SOAP_MALLOC(soap, n); + if (ns2) + { memcpy(ns2, soap->namespaces, n); + if (ns2[0].ns) + { if (!strcmp(ns2[0].ns, soap_env1)) + soap->version = 1; + else + soap->version = 2; + } + soap->local_namespaces = ns2; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_strsearch(const char *big, const char *little) +{ size_t n = strlen(little); + const char *s = big; + while (s) + { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' ')) + return s; + s = strchr(s, ' '); + if (s) + s++; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static struct soap_nlist * +soap_lookup_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np; + for (np = soap->nlist; np; np = np->next) + { if (!strncmp(np->id, tag, n) && !np->id[n]) + return np; + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static struct soap_nlist * +soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized) +{ register struct soap_nlist *np; + size_t n, k; + if (soap_strsearch(soap->c14nexclude, id)) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns?ns:"")); + if (!utilized) + { for (np = soap->nlist; np; np = np->next) + { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns))) + break; + } + if (np) + { if (np->index == 1) + utilized = np->index; + else + return NULL; + } + } + n = strlen(id); + if (ns) + k = strlen(ns); + else + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1); + if (!np) + { soap->error = SOAP_EOM; + return NULL; + } + np->next = soap->nlist; + soap->nlist = np; + strcpy(np->id, id); + if (ns) + { np->ns = np->id + n + 1; + strcpy(np->ns, ns); + } + else + np->ns = NULL; + np->level = soap->level; + np->index = utilized; + return np; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static void +soap_utilize_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n); + if (np) + { if (np->index == 0) + soap_push_ns(soap, np->id, np->ns, 1); + } + else + { strncpy(soap->tmpbuf, tag, n); + soap->tmpbuf[n] = '\0'; + soap_push_ns(soap, soap->tmpbuf, NULL, 1); + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static void +soap_pop_ns(struct soap *soap) +{ soap_pop_namespace(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element(struct soap *soap, const char *tag, int id, const char *type) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:"")); +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error = SOAP_EOM; + elt->soap = soap; + elt->next = NULL; + elt->prnt = soap->dom; + elt->name = soap_strdup(soap, tag); + elt->elts = NULL; + elt->atts = NULL; + elt->nstr = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->node = NULL; + elt->type = 0; + elt->head = NULL; + elt->tail = NULL; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + } + else + { +#endif + soap->level++; +#ifndef WITH_LEAN + if (!soap->ns) + { if (!(soap->mode & SOAP_XML_CANONICAL) + && soap_send(soap, soap->prolog ? soap->prolog : "\n")) + return soap->error; + } + else if (soap->mode & SOAP_XML_INDENT) + { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + soap->body = 1; + } +#endif + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, tag)) + return soap->error; +#ifdef WITH_DOM + } +#endif + if (!soap->ns) + { struct Namespace *ns; + for (ns = soap->local_namespaces; ns && ns->id; ns++) + { if (*ns->id && (ns->out || ns->ns)) + { sprintf(soap->tmpbuf, "xmlns:%s", ns->id); + if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns)) + return soap->error; + } + } + } + soap->ns = 1; /* start with 0 or 2, but should be one to continue */ +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *s = strchr(tag, ':'); + if (s) + soap_utilize_ns(soap, tag, s - tag); + } +#endif + if (id > 0) + { sprintf(soap->tmpbuf, "_%d", id); + if (soap_attribute(soap, "id", soap->tmpbuf)) + return soap->error; + } + if (type && *type) + { if (soap_attribute(soap, "xsi:type", type)) + return soap->error; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *s = strchr(type, ':'); + if (s) + soap_utilize_ns(soap, type, s - type); + } +#endif + } + if (soap->null && soap->position > 0) + { int i; + sprintf(soap->tmpbuf, "[%d", soap->positions[0]); + for (i = 1; i < soap->position; i++) + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]); + strcat(soap->tmpbuf, "]"); + if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf)) + return soap->error; + } + if (soap->mustUnderstand) + { if (soap->actor && *soap->actor) + { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor)) + return soap->error; + } + if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1")) + return soap->error; + soap->mustUnderstand = 0; + } + if (soap->encoding) + { if (soap->encodingStyle && soap->local_namespaces) + { if (!*soap->encodingStyle) + { if (soap->local_namespaces[1].out) + soap->encodingStyle = soap->local_namespaces[1].out; + else + soap->encodingStyle = soap->local_namespaces[1].ns; + } + if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle)) + return soap->error; + } + soap->encoding = 0; + } + soap->null = 0; + soap->position = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type) +{ if (*tag == '-') + return SOAP_OK; + if (soap_element(soap, tag, id, type)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRRCHR +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_strrchr(const char *s, int t) +{ register char *r = NULL; + while (*s) + if (*s++ == t) + r = (char*)s - 1; + return r; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOL +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_strtol(const char *s, char **t, int b) +{ register long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { short neg = 0; + if (*s == '-') + { s++; + neg = 1; + } + else if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 214748364 && (n > 214748364 || c >= '8')) + break; + n *= 10; + n += c - '0'; + s++; + } + if (neg) + n = -n; + } + else /* b == 16 and value is always positive */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x07FFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOUL +SOAP_FMAC1 +unsigned long +SOAP_FMAC2 +soap_strtoul(const char *s, char **t, int b) +{ unsigned long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 429496729 && (n > 429496729 || c >= '6')) + break; + n *= 10; + n += c - '0'; + s++; + } + } + else /* b == 16 */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x0FFFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset) +{ if (soap_element(soap, tag, id, "SOAP-ENC:Array")) + return soap->error; + if (soap->version == 2) + { const char *s; + s = soap_strrchr(type, '['); + if ((size_t)(s - type) < sizeof(soap->tmpbuf)) + { strncpy(soap->tmpbuf, type, s - type); + soap->tmpbuf[s - type] = '\0'; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf))) + return soap->error; + if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1))) + return soap->error; + } + } + else + { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset))) + return soap->error; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type))) + return soap->error; + } +#ifndef WITH_LEAN + if (type && *type && (soap->mode & SOAP_XML_CANONICAL)) + { const char *s = strchr(type, ':'); + if (s) + soap_utilize_ns(soap, type, s - type); + } +#endif + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_start_end_out(struct soap *soap, const char *tag) +{ register struct soap_attribute *tp; +#ifdef WITH_DOM + register struct soap_dom_attribute **att; + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { att = &soap->dom->atts; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error = SOAP_EOM; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, tp->name); + (*att)->data = soap_strdup(soap, tp->value); + (*att)->wide = NULL; + (*att)->soap = soap; + tp->visible = 0; + } + } + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_nlist *np; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->name) + { const char *s = strchr(tp->name, ':'); + if (s) + soap_utilize_ns(soap, tp->name, s - tp->name); + } + } + for (np = soap->nlist; np; np = np->next) + { if (np->index == 1 && np->ns) + { sprintf(soap->tmpbuf, "xmlns:%s", np->id); + soap_set_attr(soap, soap->tmpbuf, np->ns); + np->index = 2; + } + } + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { if (soap_send(soap, " ") || soap_send(soap, tp->name)) + return soap->error; + if (tp->visible == 2 && tp->value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, tp->value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + tp->visible = 0; + } + } + if (tag) + { +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { if (soap_send_raw(soap, ">", 1) + || soap_element_end_out(soap, tag)) + return soap->error; + } + else +#endif + soap->level--; /* decrement level just before /> */ + if (soap_send_raw(soap, "/>", 2)) + return soap->error; + return SOAP_OK; + } + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_out(struct soap *soap, const char *tag) +{ if (*tag == '-') + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + soap_pop_ns(soap); + if (soap->mode & SOAP_XML_INDENT) + { if (!soap->body) + { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + } + soap->body = 0; + } +#endif + if (soap_send_raw(soap, "error; + soap->level--; /* decrement level just before > */ + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_ref(struct soap *soap, const char *tag, int id, int href) +{ register int n = 0; + if (soap->version == 2) + n = 1; + sprintf(soap->href, "#_%d", href); + return soap_element_href(soap, tag, id, "href" + n, soap->href + n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val)); + if (soap_element(soap, tag, id, NULL) + || soap_attribute(soap, ref, val) + || soap_element_start_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_null(struct soap *soap, const char *tag, int id, const char *type) +{ struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + if (tp->visible) + break; + if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL)) + { if (soap_element(soap, tag, id, type)) + return soap->error; + if (soap->part != SOAP_IN_HEADER && soap->encodingStyle) + if (soap_attribute(soap, "xsi:nil", "true")) + return soap->error; + return soap_element_start_end_out(soap, tag); + } + soap->null = 1; + soap->position = 0; + soap->mustUnderstand = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_id(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, int n, const char *type, int t) +{ if (!p || (a && !a->__ptr)) + { soap_element_null(soap, tag, id, type); + return -1; + } +#ifndef WITH_NOIDREF + if (soap->mode & SOAP_XML_TREE) + return 0; + if (id < 0) + { struct soap_plist *pp; + if (a) + id = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + else + id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap_is_embedded(soap, pp)) + { soap_element_ref(soap, tag, 0, id); + return -1; + } + if (soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + } + return id; +#else + return 0; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + if (soap_element(soap, "SOAP-RPC:result", 0, NULL) + || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc) + || soap_element_start_end_out(soap, NULL) + || soap_string_out(soap, tag, 0) + || soap_element_end_out(soap, "SOAP-RPC:result")) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attribute(struct soap *soap, const char *name, const char *value) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + a->next = soap->dom->atts; + a->nstr = NULL; + a->name = soap_strdup(soap, name); + a->data = soap_strdup(soap, value); + a->wide = NULL; + a->soap = soap; + soap->dom->atts = a; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { /* TODO: consider using this code to handle default namespace + if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0')) + { if (name[5] == ':') + soap_push_ns(soap, name + 6, value, 0); + else + soap_push_ns(soap, "", value, 0); + } + */ + if (!strncmp(name, "xmlns:", 6)) + soap_push_ns(soap, name + 6, value, 0); + else if (soap_set_attr(soap, name, value)) + return soap->error; + } + else +#endif + { if (soap_send(soap, " ") || soap_send(soap, name)) + return soap->error; + if (value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_in(struct soap *soap, const char *tag, int nillable) +{ if (!soap_peek_element(soap)) + { if (soap->other) + return soap->error = SOAP_TAG_MISMATCH; + if (tag && *tag == '-') + return SOAP_OK; + if (!(soap->error = soap_match_tag(soap, soap->tag, tag))) + { soap->peeked = 0; + if (soap->body) + soap->level++; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" )); + if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT)) + return soap->error = SOAP_NULL; + } + } + else if (soap->error == SOAP_NO_TAG && tag && *tag == '-') + soap->error = SOAP_OK; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_in(struct soap *soap, const char *tag) +{ register soap_wchar c; + register char *s; + register const char *t; + register int n = 0; + if (tag && *tag == '-') + return SOAP_OK; + soap->level--; + soap_pop_namespace(soap); +#ifdef WITH_DOM + /* this whitespace or mixed content is not insignificant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1)) + return soap->error; + if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + if (soap->peeked) + { if (soap->error == SOAP_NO_TAG) + soap->error = SOAP_OK; + if (*soap->tag) + n++; + soap->peeked = 0; + } + do + { while (((c = soap_get(soap)) != SOAP_TT)) + { if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c == SOAP_LT) + n++; + else if (c == '/') + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + else + soap_unget(soap, c); + } + } + } while (n--); + s = soap->tag; + while (soap_notblank(c = soap_getutf8(soap))) + *s++ = (char)c; + *s = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + while (soap_blank(c)) + c = soap_get(soap); + if (c != SOAP_GT) + return soap->error = SOAP_SYNTAX_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"")); + if (!tag || !*tag) + return SOAP_OK; + if ((s = strchr(soap->tag, ':'))) + s++; + else + s = soap->tag; + if ((t = strchr(tag, ':'))) + t++; + else + t = tag; + if (!SOAP_STRCMP(s, t)) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n")); + return soap->error = SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_attr_value(struct soap *soap, const char *name, int flag) +{ register struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + if (!soap_match_tag(soap, tp->name, name)) + break; + if (tp && tp->visible == 2) + { if (flag == 2 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_PROHIBITED; + else + return tp->value; + } + else if (flag == 1 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_REQUIRED; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_attr(struct soap *soap, const char *name, const char *value) +{ register struct soap_attribute *tp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:"")); + for (tp = soap->attributes; tp; tp = tp->next) + { if (!strcmp(tp->name, name)) + break; + } + if (!tp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name)); + if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name)))) + return soap->error = SOAP_EOM; + tp->ns = NULL; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_attribute **tpp = &soap->attributes; + const char *s = strchr(name, ':'); + if (!strncmp(name, "xmlns", 5)) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0) + break; + } + else if (!s) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0)) + break; + } + else + { int k; + for (; *tpp; tpp = &(*tpp)->next) + { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name]) + { if (!tp->ns) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p(%s)\n", name, (*tpp)->ns, (*tpp)->ns)); + tp->ns = (*tpp)->ns; + } + } + else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0))) + break; + } + } + tp->next = *tpp; + *tpp = tp; + } + else +#endif + { tp->next = soap->attributes; + soap->attributes = tp; + } + strcpy(tp->name, name); + tp->value = NULL; + } + else if (value && tp->value && tp->size <= strlen(value)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value)); + SOAP_FREE(soap, tp->value); + tp->value = NULL; + tp->ns = NULL; + } + if (value) + { if (!tp->value) + { tp->size = strlen(value) + 1; + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value of %s (%p)\n", tp->name, tp->value)); + } + strcpy(tp->value, value); + if (!strncmp(tp->name, "xmlns:", 6)) + tp->ns = tp->value; + tp->visible = 2; +#ifndef WITH_LEAN + if (!strcmp(name, "wsu:Id")) + { soap->part = SOAP_BEGIN_SECURITY; + strncpy(soap->id, value, sizeof(soap->id)); + soap->id[sizeof(soap->id)-1] = '\0'; + } +#endif + } + else + tp->visible = 1; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_attr(struct soap *soap) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { while (soap->attributes) + { tp = soap->attributes->next; + SOAP_FREE(soap, soap->attributes->value); + SOAP_FREE(soap, soap->attributes); + soap->attributes = tp; + } + } + else +#endif + { for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d) +{ size_t i; + soap_wchar c; + for (i = 0; i < n; i++) + { c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + *s++ = '<'; + break; + case SOAP_GT: + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + *s++ = '>'; + break; + case SOAP_QT: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '"'; + break; + case SOAP_AP: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '\''; + break; + case '\t': + case '\n': + case '\r': + case ' ': + case '/': + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + default: + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + } + return soap->error = SOAP_EOM; +} +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_store_lab(struct soap *soap, const char *s, size_t n) +{ soap->labidx = 0; + return soap_append_lab(soap, s, n); +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_append_lab(struct soap *soap, const char *s, size_t n) +{ if (soap->labidx + n >= soap->lablen) + { register char *t = soap->labbuf; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen)); + if (soap->lablen == 0) + soap->lablen = SOAP_LABLEN; + while (soap->labidx + n >= soap->lablen) + soap->lablen <<= 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen)); + soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen); + if (!soap->labbuf) + { if (t) + SOAP_FREE(soap, t); + return soap->error = SOAP_EOM; + } + if (t) + { memcpy(soap->labbuf, t, soap->labidx); + SOAP_FREE(soap, t); + } + } + if (s) + { memcpy(soap->labbuf + soap->labidx, s, n); + soap->labidx += n; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_peek_element(struct soap *soap) +{ +#ifdef WITH_DOM + register struct soap_dom_attribute **att = NULL; + register char *lead = NULL; +#endif + register struct soap_attribute *tp; + const char *t; + register char *s; + register soap_wchar c; + register int i; + if (soap->peeked) + { if (!*soap->tag) + return soap->error = SOAP_NO_TAG; + return SOAP_OK; + } + soap->peeked = 1; + for (;;) + { c = soap_getutf8(soap); + if (c == SOAP_BOM) + c = soap_get(soap); +#ifdef WITH_DOM + /* whitespace leading to start tag is not insignificant for DOM */ + if (soap_blank(c)) + { soap->labidx = 0; + do + { if (soap_append_lab(soap, NULL, 0)) + return SOAP_EOM; + s = soap->labbuf + soap->labidx; + i = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + while (soap_blank(c) && i--) + { *s++ = c; + c = soap_get(soap); + } + } + while (soap_blank(c)); + *s = '\0'; + lead = soap_strdup(soap, soap->labbuf); + } +#else + while (soap_blank(c)) + c = soap_get(soap); +#endif + if (c != SOAP_LT) + { *soap->tag = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifdef WITH_DOM + /* whitespace leading to end tag is not insignificant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->tail = soap_strdup(soap, lead); +#endif + return soap->error = SOAP_NO_TAG; + } + s = soap->tag; + do c = soap_getutf8(soap); + while (soap_blank(c)); + i = sizeof(soap->tag); + while (c != '/' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_getutf8(soap); + } + while (soap_blank(c)) + c = soap_get(soap); + *s = '\0'; + if (*soap->tag != '?') + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <%s?>\n", soap->tag)); + while ((int)c != EOF && c != SOAP_GT && c != '?') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf) - 2; + while (c != '=' && c != SOAP_GT && c != '?' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_get(soap); + } + while (soap_blank(c)) + c = soap_get(soap); + if (c == '=') + { *s++ = '='; + do c = soap_get(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, s, i, c) == SOAP_EOM) + { while (soap_getattrval(soap, soap->tmpbuf, sizeof(soap->tmpbuf), c) == SOAP_EOM) + ; + } + else if (!strcmp(soap->tag, "?xml") + && (!soap_tag_cmp(soap->tmpbuf, "encoding=iso-8859-1") + || !soap_tag_cmp(soap->tmpbuf, "encoding=latin1"))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML latin1 encoding\n")); + soap->mode |= SOAP_ENC_LATIN; + } + } + do c = soap_get(soap); + while (soap_blank(c)); + } + } + soap->id[0] = '\0'; + soap->href[0] = '\0'; + soap->type[0] = '\0'; + soap->arrayType[0] = '\0'; + soap->arraySize[0] = '\0'; + soap->arrayOffset[0] = '\0'; + soap->other = 0; + soap->root = -1; + soap->position = 0; + soap->null = 0; + soap->mustUnderstand = 0; +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt; + elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error = SOAP_EOM; + elt->next = NULL; + elt->nstr = NULL; + elt->name = soap_strdup(soap, soap->tag); + elt->prnt = soap->dom; + elt->elts = NULL; + elt->atts = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->type = 0; + elt->node = NULL; + elt->head = lead; + elt->tail = NULL; + elt->soap = soap; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + att = &elt->atts; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + while ((int)c != EOF && c != SOAP_GT && c != '/') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf); + while (c != '=' && c != '/' && soap_notblank(c)) + { if (--i > 0) + *s++ = (char)c; + c = soap_get(soap); + } + *s = '\0'; + if (i == sizeof(soap->tmpbuf)) + return soap->error = SOAP_SYNTAX_ERROR; +#ifdef WITH_DOM + /* add attribute name to dom */ + if (att) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error = SOAP_EOM; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, soap->tmpbuf); + (*att)->data = NULL; + (*att)->wide = NULL; + (*att)->soap = soap; + } +#endif + if (!strncmp(soap->tmpbuf, "xmlns", 5)) + { if (soap->tmpbuf[5] == ':') + { soap->tmpbuf[5] = '\0'; + t = soap->tmpbuf + 6; + } + else if (soap->tmpbuf[5]) + t = NULL; + else + t = SOAP_STR_EOS; + } + else + t = NULL; + for (tp = soap->attributes; tp; tp = tp->next) + { if (!SOAP_STRCMP(tp->name, soap->tmpbuf)) + break; + } + if (!tp) + { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf)); + if (!tp) + return soap->error = SOAP_EOM; + strcpy(tp->name, soap->tmpbuf); + tp->value = NULL; + tp->size = 0; + tp->next = soap->attributes; + soap->attributes = tp; + } + while (soap_blank(c)) + c = soap_get(soap); + if (c == '=') + { do c = soap_get(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, tp->value, tp->size, c)) + { +#ifdef WITH_FAST + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_store_lab(soap, tp->value, tp->size)) + return soap->error; + if (tp->value) + SOAP_FREE(soap, tp->value); + for (;;) + { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + soap->labidx = soap->lablen; + if (soap_append_lab(soap, NULL, 0)) + return soap->error; + } + else + break; + } + if (soap->labidx) + tp->size = soap->lablen; + else + { tp->size = strlen(soap->labbuf) + 1; + if (tp->size < SOAP_LABLEN) + tp->size = SOAP_LABLEN; + } + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + strcpy(tp->value, soap->labbuf); +#else + size_t n; + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_new_block(soap)) + return soap->error; + for (;;) + { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN))) + return soap->error; + if (soap_getattrval(soap, s, SOAP_BLKLEN, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + } + else + break; + } + n = tp->size + soap->blist->size; + if (!(s = (char*)SOAP_MALLOC(soap, n))) + return soap->error = SOAP_EOM; + if (tp->value) + { memcpy(s, tp->value, tp->size); + SOAP_FREE(soap, tp->value); + } + soap_save_block(soap, s + tp->size, 0); + tp->value = s; + tp->size = n; +#endif + } + do c = soap_get(soap); + while (soap_blank(c)); + tp->visible = 2; /* seen this attribute w/ value */ +#ifdef WITH_DOM + if (att) + (*att)->data = soap_strdup(soap, tp->value); +#endif + } + else + tp->visible = 1; /* seen this attribute w/o value */ +#ifdef WITH_DOM + if (att) + att = &(*att)->next; +#endif + if (t && tp->value) + { if (soap_push_namespace(soap, t, tp->value)) + return soap->error; + tp->visible = 0; + } + } +#ifdef WITH_DOM + if (att) + { soap->dom->nstr = soap_dom_current_nstr(soap, soap->tag); + for (att = &soap->dom->atts; *att; att = &(*att)->next) + (*att)->nstr = soap_dom_current_nstr(soap, (*att)->name); + } +#endif + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (!(soap->body = (c != '/'))) + do c = soap_get(soap); + while (soap_blank(c)); +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { if (!soap->body && soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->value) + { if (!strcmp(tp->name, "id")) + { *soap->id = '#'; + strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2); + soap->id[sizeof(soap->id)-1] = '\0'; + } + else if (!strcmp(tp->name, "href")) + { strncpy(soap->href, tp->value, sizeof(soap->href) - 1); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else if ((soap->version == 2 || (soap->mode & SOAP_XML_GRAPH)) && !strcmp(tp->name, "ref")) + { *soap->href = '#'; + strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else if (!soap_match_tag(soap, tp->name, "xsi:type")) + { strncpy(soap->type, tp->value, sizeof(soap->type) - 1); + soap->type[sizeof(soap->type)-1] = '\0'; + } + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType")) + { s = soap_strrchr(tp->value, '['); + if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType)) + { strncpy(soap->arrayType, tp->value, s - tp->value); + soap->arrayType[s - tp->value] = '\0'; + strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1); + } + else + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + soap->arraySize[sizeof(soap->arrayType)-1] = '\0'; + soap->arrayType[sizeof(soap->arrayType)-1] = '\0'; + } + else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:itemType")) + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize")) + strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:offset")) + strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset)); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:position")) + soap->position = soap_getposition(tp->value, soap->positions); + else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:root")) + soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))); + else if ((soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENV:actor")) + || (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENV:role"))) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next") + && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next")) + soap->other = 1; + } + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if ((!soap_match_tag(soap, tp->name, "xsi:null") + || !soap_match_tag(soap, tp->name, "xsi:nil")) + && (!strcmp(tp->value, "1") + || !strcmp(tp->value, "true"))) + soap->null = 1; + } + } + return soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_retry(struct soap *soap) +{ soap->error = SOAP_OK; + soap_revert(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_revert(struct soap *soap) +{ if (!soap->peeked) + { soap->peeked = 1; + if (soap->body) + soap->level--; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_string_out(struct soap *soap, const char *s, int flag) +{ register const char *t; + register soap_wchar c; + register soap_wchar mask = 0xFFFFFF80UL; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_strdup(soap, s); + return SOAP_OK; + } +#endif + if (soap->mode & SOAP_C_UTFSTRING) + mask = 0; + t = s; + while ((c = *t++)) + { switch (c) + { + case 9: + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 10: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 13: + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + break; + case '&': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&", 5)) + return soap->error; + s = t; + break; + case '<': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "<", 4)) + return soap->error; + s = t; + break; + case '>': + if (!flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, ">", 4)) + return soap->error; + s = t; + } + break; + case '"': + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, """, 6)) + return soap->error; + s = t; + } + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_MBTOWC + if (soap->mode & SOAP_C_MBSTRING) + { wchar_t wc; + register int m = mbtowc(&wc, t - 1, MB_CUR_MAX); + if (m > 0 && wc != c) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc)) + return soap->error; + s = t += m - 1; + continue; + } + } +#endif +#endif + if (c & mask) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c)) + return soap->error; + s = t; + } + } + } + return soap_send_raw(soap, s, t - s - 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) +{ register char *s; + char *t = NULL; + register size_t i; + register long l = 0; + register int n = 0; + register int m = 0; + register soap_wchar c; +#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB) + char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8]; +#else + char buf[8]; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n")); + if (soap->peeked) + { if (!soap->body) + return NULL; + if (*soap->tag) + { n = 1; + soap->peeked = 0; +#ifndef WITH_LEAN + t = soap->tmpbuf; + t[0] = '<'; + strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 1); + strncat(t, ">", sizeof(soap->tmpbuf)); + m = strlen(soap->tag) + 2; +#endif + } + } +#ifdef WITH_CDATA + if (!flag) + { register int state = 0; +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + c = soap_getchar(soap); + if ((int)c == EOF) + goto end; + if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN)) + { soap_unget(soap, c); + c = soap_getutf8(soap); + if (soap->mode & SOAP_C_UTFSTRING) + { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + } + switch (state) + { case 1: + if (c == ']') + state = 4; + *s++ = c; + continue; + case 2: + if (c == '-') + state = 6; + *s++ = c; + continue; + case 3: + if (c == '?') + state = 8; + *s++ = c; + continue; + /* CDATA */ + case 4: + if (c == ']') + state = 5; + else + state = 1; + *s++ = c; + continue; + case 5: + if (c == '>') + state = 0; + else + state = 1; + *s++ = c; + continue; + /* comment */ + case 6: + if (c == '-') + state = 7; + else + state = 2; + *s++ = c; + continue; + case 7: + if (c == '>') + state = 0; + else + state = 2; + *s++ = c; + continue; + /* PI */ + case 8: + if (c == '>') + state = 0; + else + state = 3; + *s++ = c; + continue; + } + switch (c) + { + case '/': + if (n > 0) + { c = soap_getchar(soap); + if (c == '>') + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + c = soap_getchar(soap); + if (c == '/') + { if (n == 0) + { c = SOAP_TT; + goto end; + } + n--; + } + else if (c == '!') + { c = soap_getchar(soap); + if (c == '[') + { do c = soap_getchar(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + goto end; + t = (char*)"![CDATA["; + m = 8; + state = 1; + } + else if (c == '-') + { if ((c = soap_getchar(soap)) == '-') + state = 2; + t = (char*)"!-"; + m = 2; + soap_unget(soap, c); + } + else + { t = (char*)"!"; + m = 1; + soap_unget(soap, c); + } + *s++ = '<'; + break; + } + else if (c == '?') + state = 3; + else + n++; + soap_unget(soap, c); + *s++ = '<'; + break; + case '>': + *s++ = '>'; + break; + case '"': + *s++ = '"'; + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + if (soap->mode & SOAP_C_UTFSTRING) + { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + else + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + t = (char*)"/"; + m = 1; + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<' | 0x80000000: + if (flag) + *s++ = '<'; + else + { *s++ = '&'; + t = (char*)"lt;"; + m = 3; + } + break; + case '>' | 0x80000000: + if (flag) + *s++ = '>'; + else + { *s++ = '&'; + t = (char*)"gt;"; + m = 3; + } + break; + case '&' | 0x80000000: + if (flag) + *s++ = '&'; + else + { *s++ = '&'; + t = (char*)"amp;"; + m = 4; + } + break; + case '"' | 0x80000000: + if (flag) + *s++ = '"'; + else + { *s++ = '&'; + t = (char*)"quot;"; + m = 5; + } + break; + case '\'' | 0x80000000: + if (flag) + *s++ = '\''; + else + { *s++ = '&'; + t = (char*)"apos;"; + m = 5; + } + break; + default: + if ((int)c == EOF) + goto end; +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; +#ifdef WITH_FAST + t = soap_strdup(soap, soap->labbuf); +#else + soap_size_block(soap, i+1); + t = soap_save_block(soap, NULL, 0); +#endif + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (flag == 3) + soap->dom->tail = t; + else + soap->dom->data = t; + } +#endif + if (flag == 2) + if (soap_s2QName(soap, t, &t)) + return NULL; + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) +{ const char *t; + char tmp; + register soap_wchar c; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { wchar_t *r = (wchar_t*)s; + int n = 1; + while (*r++) + n++; + soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t)); + while (n--) + *r++ = *s++; + return SOAP_OK; + } +#endif + while ((c = *s++)) + { switch (c) + { + case 9: + if (flag) + t = " "; + else + t = "\t"; + break; + case 10: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + t = " "; + else + t = "\n"; + break; + case 13: + t = " "; + break; + case '&': + t = "&"; + break; + case '<': + t = "<"; + break; + case '>': + if (flag) + t = ">"; + else + t = ">"; + break; + case '"': + if (flag) + t = """; + else + t = "\""; + break; + default: + if (c > 0 && c < 0x80) + { tmp = (char)c; + if (soap_send_raw(soap, &tmp, 1)) + return soap->error; + } + else if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + continue; + } + if (soap_send(soap, t)) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t * +SOAP_FMAC2 +soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) +{ wchar_t *s; + register int i, n = 0; + register long l = 0; + register soap_wchar c; + const char *t = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n")); + if (soap->peeked) + { if (!soap->body) + return NULL; + if (*soap->tag) + { n = 1; + soap->peeked = 0; + } + } + if (soap_new_block(soap)) + return NULL; + for (;;) + { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN))) + return NULL; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (t) + { *s++ = (wchar_t)*t++; + if (!*t) + t = NULL; + continue; + } + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_getutf8(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + if (flag) + *s++ = (soap_wchar)'<'; + else + { *s++ = (soap_wchar)'&'; + t = "lt;"; + } + break; + case '>': + if (flag) + *s++ = (soap_wchar)'>'; + else + { *s++ = (soap_wchar)'&'; + t = "gt;"; + } + break; + case '"': + if (flag) + *s++ = (soap_wchar)'"'; + else + { *s++ = (soap_wchar)'&'; + t = "quot;"; + } + break; + default: + if ((int)c == EOF) + goto end; + *s++ = (wchar_t)c & 0x7FFFFFFF; + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; + soap_size_block(soap, sizeof(wchar_t) * (i + 1)); + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + s = (wchar_t*)soap_save_block(soap, NULL, 0); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->wide = s; +#endif + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_int2s(struct soap *soap, int n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2int(struct soap *soap, const char *s, int *p) +{ if (s) + { char *r; + *p = (int)soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int * +SOAP_FMAC2 +soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(int), 0, NULL); + else if (p) + { if (soap_s2int(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_long2s(struct soap *soap, long n) +{ sprintf(soap->tmpbuf, "%ld", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2long(struct soap *soap, const char *s, long *p) +{ if (s) + { char *r; + *p = soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +long * +SOAP_FMAC2 +soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(long), 0, NULL); + else if (p) + { if (soap_s2long(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_LONG642s(struct soap *soap, LONG64 n) +{ sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_LONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOLL + char *r; + *p = strtoll(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +# ifdef HAVE_SSCANF + if (sscanf(s, SOAP_LONG_FORMAT, p) != 1) +# endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +LONG64 * +SOAP_FMAC2 +soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (LONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(LONG64), 0, NULL); + else if (p) + { if (soap_s2LONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_byte2s(struct soap *soap, char n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2byte(struct soap *soap, const char *s, char *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -128 || n > 127) + soap->error = SOAP_TYPE; + *p = (char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(char), 0, NULL); + else if (p) + { if (soap_s2byte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_short2s(struct soap *soap, short n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2short(struct soap *soap, const char *s, short *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -32768 || n > 32767) + soap->error = SOAP_TYPE; + *p = (short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +short * +SOAP_FMAC2 +soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(short), 0, NULL); + else if (p) + { if (soap_s2short(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_float2s(struct soap *soap, float n) +{ const char *s; + if (soap_isnan((double)n)) + s = "NaN"; + else if (soap_ispinff(n)) + s = "INF"; + else if (soap_isninff(n)) + s = "-INF"; + else + { sprintf(soap->tmpbuf, soap->float_format, n); + s = soap->tmpbuf; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_float2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2float(struct soap *soap, const char *s, float *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = FLT_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = FLT_NAN; + else + { +/* On some systems, strtof appears to be broken or doesn't link: use with caution */ +#if defined(HAVE_STRTOF) + char *r; + *p = strtof((char*)s, &r); + if (*r) +#elif defined(HAVE_STRTOD) + char *r; + *p = (float)strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, "%g", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static int soap_isnumeric(struct soap *soap, const char *type) +{ if (soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":float") + && soap_match_tag(soap, soap->type, ":double") + && soap_match_tag(soap, soap->type, ":decimal") + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return SOAP_ERR; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +float * +SOAP_FMAC2 +soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL); + if (*soap->href) + p = (float*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(float), 0, NULL); + else if (p) + { if (soap_s2float(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_double2s(struct soap *soap, double n) +{ const char *s; + if (soap_isnan(n)) + s = "NaN"; + else if (soap_ispinfd(n)) + s = "INF"; + else if (soap_isninfd(n)) + s = "-INF"; + else + { sprintf(soap->tmpbuf, soap->double_format, n); + s = soap->tmpbuf; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_double2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2double(struct soap *soap, const char *s, double *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = DBL_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = DBL_NAN; + else + { +#ifdef HAVE_STRTOD + char *r; + *p = strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, "%lg", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +double * +SOAP_FMAC2 +soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL); + if (*soap->href) + p = (double*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(double), 0, NULL); + else if (p) + { if (soap_s2double(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedByte2s(struct soap *soap, unsigned char n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 255) + soap->error = SOAP_TYPE; + *p = (unsigned char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned char * +SOAP_FMAC2 +soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned char), 0, NULL); + else if (p) + { if (soap_s2unsignedByte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedShort2s(struct soap *soap, unsigned short n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 65535) + soap->error = SOAP_TYPE; + *p = (unsigned short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned short * +SOAP_FMAC2 +soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned short), 0, NULL); + else if (p) + { if (soap_s2unsignedShort(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedInt2s(struct soap *soap, unsigned int n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p) +{ if (s) + { char *r; + *p = (unsigned int)soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned int * +SOAP_FMAC2 +soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned int), 0, NULL); + else if (p) + { if (soap_s2unsignedInt(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedLong2s(struct soap *soap, unsigned long n) +{ sprintf(soap->tmpbuf, "%lu", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p) +{ if (s) + { char *r; + *p = soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned long * +SOAP_FMAC2 +soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned long), 0, NULL); + else if (p) + { if (soap_s2unsignedLong(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_ULONG642s(struct soap *soap, ULONG64 n) +{ sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_ULONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOULL + char *r; + *p = strtoull(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +# ifdef HAVE_SSCANF + if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1) +# endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +ULONG64 * +SOAP_FMAC2 +soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (ULONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(ULONG64), 0, NULL); + else if (p) + { if (soap_s2ULONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2string(struct soap *soap, const char *s, char **t) +{ *t = NULL; + if (s && !(*t = soap_strdup(soap, s))) + soap->error = SOAP_EOM; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2QName(struct soap *soap, const char *s, char **t) +{ if (s) + { struct soap_nlist *np; + const char *p; + if (!strncmp(s, "xml:", 4)) + { *t = soap_strdup(soap, s); + return SOAP_OK; + } + np = soap->nlist; + p = strchr(s, ':'); + if (p) + { register int n = p - s; + while (np && (strncmp(np->id, s, n) || np->id[n])) + np = np->next; + p++; + } + else + { while (np && *np->id) + np = np->next; + p = s; + } + if (np) + { if (np->index >= 0 && soap->local_namespaces) + { register const char *q = soap->local_namespaces[np->index].id; + if (q) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2))) + sprintf(*t, "%s:%s", q, p); + return SOAP_OK; + } + } + if (np->ns) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4))) + sprintf(*t, "\"%s\":%s", np->ns, p); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:"")); + return soap->error = SOAP_NAMESPACE; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s)); + if ((*t = (char*)soap_malloc(soap, strlen(p) + 4))) + sprintf(*t, "\"\":%s", p); + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_QName2s(struct soap *soap, const char *s) +{ struct Namespace *p; + char *t; + int n; + if (!s || *s != '"') + { +#ifndef WITH_LEAN + if (s && (soap->mode & SOAP_XML_CANONICAL)) + { t = strchr(s, ':'); + if (t) + soap_utilize_ns(soap, s, t - s); + } +#endif + return s; + } + s++; + if ((p = soap->local_namespaces)) + { for (; p->id; p++) + { if (p->ns) + if (!soap_tag_cmp(s, p->ns)) + break; + if (p->in) + if (!soap_tag_cmp(s, p->in)) + break; + } + if (p && p->id) + { s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s)); + strcpy(t, p->id); + strcat(t, s + 1); + return t; + } + } + } + t = (char*)strchr(s, '"'); + if (t) + n = t - s; + else + n = 0; + t = soap_strdup(soap, s); + t[n] = '\0'; + sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++); + soap_set_attr(soap, soap->tmpbuf, t); + s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6); + strcpy(t, soap->tmpbuf + 6); + strcat(t, s + 1); + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0 + || soap_element_begin_out(soap, tag, id, type) + || soap_string_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->body) + { *p = soap_string_in(soap, flag, minlen, maxlen); + if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL)) + return NULL; + } + else + *p = NULL; + if (*soap->href) + p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0 + || soap_element_begin_out(soap, tag, id, type) + || soap_wstring_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->body) + { *p = soap_wstring_in(soap, 1, minlen, maxlen); + if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL)) + return NULL; + } + else + *p = NULL; + if (*soap->href) + p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static time_t +soap_timegm(struct tm *T) +{ +#if defined(HAVE_TIMEGM) + return timegm(T); +#else + time_t t, g, z; +#ifdef HAVE_GMTIME_R + struct tm tm, *tmp = &tm; +#else + struct tm *tmp; +#endif + t = mktime(T); + if (t == -1) + return -1; +#ifdef HAVE_GMTIME_R + gmtime_r(&t, tmp); +#else + tmp = gmtime(&t); +#endif + tmp->tm_isdst = 0; + g = mktime(tmp); + if (g == -1) + return -1; + z = g - t; + return t - z; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_dateTime2s(struct soap *soap, time_t n) +{ struct tm T, *pT = &T; +#if defined(HAVE_GMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PGMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_PGMTIME) + if (gmtime(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GMTIME) + if ((pT = gmtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GETTIMEOFDAY) + struct timezone tz; + memset((void*)&tz, 0, sizeof(tz)); +# if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +# else + if ((pT = localtime(&n))) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +#endif +#elif defined(HAVE_FTIME) + struct timeb t; + memset((void*)&t, 0, sizeof(t)); +# if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { ftime(&t); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } + /* The following defines were added for VxWorks*/ +# elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60); + } +# else + if ((pT = localtime(&n))) + { ftime(&t); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } +# endif +#elif defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#else + if ((pT = localtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#endif + else + strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z"); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_dateTime2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2dateTime(struct soap *soap, const char *s, time_t *p) +{ if (s) + { struct tm T; + char zone[16]; + const char *t; + memset((void*)&T, 0, sizeof(T)); + zone[sizeof(zone)-1] = '\0'; + if (strchr(s, '-')) + t = "%d-%d-%dT%d:%d:%d%15s"; + else if (strchr(s, ':')) + t = "%4d%2d%2dT%d:%d:%d%15s"; + else /* parse non-XSD-standard alternative ISO 8601 format */ + t = "%4d%2d%2dT%2d%2d%2d%15s"; + sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone); + if (T.tm_year == 1) + T.tm_year = 70; + else + T.tm_year -= 1900; + T.tm_mon--; + if (*zone) + { if (*zone == '.') + { for (s = zone + 1; *s; s++) + if (*s < '0' || *s > '9') + break; + } + else + s = zone; + if (*s == '+' || *s == '-') + { int h = 0, m = 0; + if (s[3] == ':') + { sscanf(s, "%d:%d", &h, &m); + if (h < 0) + m = -m; + } + else + { m = (int)atol(s); + h = m / 100; + m = m % 100; + } + T.tm_hour -= h; + T.tm_min -= m; + } + *p = soap_timegm(&T); + } + else + *p = mktime(&T); /* no time zone: suppose it is localtime? */ + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +time_t * +SOAP_FMAC2 +soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char * type, int t) +{ if (soap_element_begin_in(soap, tag, 0)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":dateTime")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL); + if (*soap->href) + p = (time_t*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(time_t), 0, NULL); + else if (p) + { if (soap_s2dateTime(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outliteral(struct soap *soap, const char *tag, char *const*p) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS); + } + else + { t = tag; + sprintf(soap->tmpbuf, "<%s>", tag); + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p && *p) + { if (soap_send(soap, *p)) + return soap->error; + } + if (t) + { sprintf(soap->tmpbuf, "", t); + return soap_send(soap, soap->tmpbuf); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_inliteral(struct soap *soap, const char *tag, char **p) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->null) + *p = NULL; + else + *p = soap_string_in(soap, 0, -1, -1); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p) +{ int i; + const char *t = NULL; + wchar_t c; + const wchar_t *s; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS); + } + else + { t = tag; + sprintf(soap->tmpbuf, "<%s>", tag); + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p) + { s = *p; + while ((c = *s++)) + if (soap_pututf8(soap, (unsigned char)c)) + return soap->error; + } + if (t) + { sprintf(soap->tmpbuf, "", t); + return soap_send(soap, soap->tmpbuf); + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p) +{ if (soap_element_begin_in(soap, tag, 1)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->null) + *p = NULL; + else + *p = soap_wstring_in(soap, 0, -1, -1); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_token(struct soap *soap) +{ register size_t i; + register soap_wchar c = 0; + register char *s = soap->tmpbuf; + if (!soap->body) + return SOAP_STR_EOS; + do c = soap_get(soap); + while (soap_blank(c)); + for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++) + { if (c == SOAP_TT || (int)c == EOF || soap_blank(c)) + break; + *s++ = (char)c; + c = soap_get(soap); + } + if ((int)c == EOF || c == SOAP_TT) + soap_unget(soap, c); + *s = '\0'; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf)); + return soap->tmpbuf; /* return non-null pointer */ +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_value(struct soap *soap) +{ register size_t i; + register soap_wchar c = 0; + register char *s = soap->tmpbuf; + if (!soap->body) + return SOAP_STR_EOS; + do c = soap_get(soap); + while (soap_blank(c)); + for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++) + { if (c == SOAP_TT || (int)c == EOF) + break; + *s++ = (char)c; + c = soap_get(soap); + } + for (s--; i > 0; i--, s--) + if (!soap_blank(*s)) + break; + s[1] = '\0'; + if ((int)c == EOF || c == SOAP_TT) + soap_unget(soap, c); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->data = soap_strdup(soap, soap->tmpbuf); +#endif + return soap->tmpbuf; /* return non-null pointer */ +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getline(struct soap *soap, char *s, int len) +{ int i = len; + soap_wchar c = 0; + for (;;) + { while (--i > 0) + { c = soap_getchar(soap); + if (c == '\r' || c == '\n') + break; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (c != '\n') + c = soap_getchar(soap); /* got \r, now get \n */ + if (c == '\n') + { *s = '\0'; + if (i+1 == len) /* empty line: end of HTTP/MIME header */ + break; + c = soap_unget(soap, soap_getchar(soap)); + if (c != ' ' && c != '\t') /* HTTP line continuation? */ + break; + } + else if ((int)c == EOF) + return soap->error = SOAP_EOF; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static size_t +soap_count_attachments(struct soap *soap) +{ +#ifndef WITH_LEANER + register struct soap_multipart *content; + register size_t count = soap->count; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count)); + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n")); + for (content = soap->dime.first; content; content = content->next) + { count += 12 + ((content->size+3)&(~3)); + if (content->id) + count += ((strlen(content->id)+3)&(~3)); + if (content->type) + count += ((strlen(content->type)+3)&(~3)); + if (content->options) + count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary) + { register size_t n = strlen(soap->mime.boundary); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { register const char *s; + /* count \r\n--boundary\r\n */ + count += 6 + n; + /* count Content-Type: ...\r\n */ + if (content->type) + count += 16 + strlen(content->type); + /* count Content-Transfer-Encoding: ...\r\n */ + s = soap_str_code(mime_codes, content->encoding); + if (s) + count += 29 + strlen(s); + /* count Content-ID: ...\r\n */ + if (content->id) + count += 14 + strlen(content->id); + /* count Content-Location: ...\r\n */ + if (content->location) + count += 20 + strlen(content->location); + /* count Content-Description: ...\r\n */ + if (content->description) + count += 23 + strlen(content->location); + /* count \r\n...content */ + count += 2 + content->size; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + /* count \r\n--boundary-- */ + count += 6 + n; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count)); + return count; +#else + return soap->count; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_putdimefield(struct soap *soap, const char *s, size_t n) +{ if (soap_send_raw(soap, s, n)) + return soap->error; + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_dime_option(struct soap *soap, unsigned short optype, const char *option) +{ size_t n; + char *s = NULL; + if (option) + { n = strlen(option); + s = (char*)soap_malloc(soap, n + 5); + if (s) + { s[0] = optype >> 8; + s[1] = optype & 0xFF; + s[2] = n >> 8; + s[3] = n & 0xFF; + strcpy(s + 4, option); + } + } + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdimehdr(struct soap *soap) +{ unsigned char tmp[12]; + size_t optlen = 0, idlen = 0, typelen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:"")); + if (soap->dime.options) + optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4; + if (soap->dime.id) + idlen = strlen(soap->dime.id); + if (soap->dime.type) + typelen = strlen(soap->dime.type); + tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7); + tmp[1] = soap->dime.flags & 0xF0; + tmp[2] = optlen >> 8; + tmp[3] = optlen & 0xFF; + tmp[4] = idlen >> 8; + tmp[5] = idlen & 0xFF; + tmp[6] = typelen >> 8; + tmp[7] = typelen & 0xFF; + tmp[8] = soap->dime.size >> 24; + tmp[9] = (soap->dime.size >> 16) & 0xFF; + tmp[10] = (soap->dime.size >> 8) & 0xFF; + tmp[11] = soap->dime.size & 0xFF; + if (soap_send_raw(soap, (char*)tmp, 12) + || soap_putdimefield(soap, soap->dime.options, optlen) + || soap_putdimefield(soap, soap->dime.id, idlen) + || soap_putdimefield(soap, soap->dime.type, typelen)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_DIME)) + return SOAP_OK; + for (content = soap->dime.first; content; content = content->next) + { void *handle; + soap->dime.size = content->size; + soap->dime.id = content->id; + soap->dime.type = content->type; + soap->dime.options = content->options; + soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA; + if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n")); + return soap->error; + } + if (!content->size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)) + { size_t chunksize = sizeof(soap->tmpbuf); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n")); + do + { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size)); + if (size < chunksize) + { soap->dime.flags &= ~SOAP_DIME_CF; + if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + } + else + soap->dime.flags |= SOAP_DIME_CF; + soap->dime.size = size; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, soap->tmpbuf, size)) + break; + if (soap->dime.id) + { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA); + soap->dime.id = NULL; + soap->dime.type = NULL; + soap->dime.options = NULL; + } + } while (size >= chunksize); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap)) + return soap->error; + do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)soap->dime.size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + if (soap->fdimereadclose) + soap->fdimereadclose(soap, handle); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, (char*)content->ptr, content->size)) + return soap->error; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static char * +soap_getdimefield(struct soap *soap, size_t n) +{ register soap_wchar c; + register int i; + register char *s; + char *p = NULL; + if (n) + { p = (char*)soap_malloc(soap, n + 1); + if (p) + { s = p; + for (i = n; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + *s++ = (char)c; + } + *s = '\0'; + if ((soap->error = soap_move(soap, -(long)n&3))) + return NULL; + } + else + soap->error = SOAP_EOM; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdimehdr(struct soap *soap) +{ register soap_wchar c; + register char *s; + register int i; + unsigned char tmp[12]; + size_t optlen, idlen, typelen; + if (!(soap->mode & SOAP_ENC_DIME)) + return soap->error = SOAP_DIME_END; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n")); + if (soap->dime.buflen || soap->dime.chunksize) + { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap)))) + return soap->error = SOAP_EOF; + soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n")); + return SOAP_OK; + } + s = (char*)tmp; + for (i = 12; i > 0; i--) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION) + return soap->error = SOAP_DIME_MISMATCH; + soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0); + optlen = (tmp[2] << 8) | tmp[3]; + idlen = (tmp[4] << 8) | tmp[5]; + typelen = (tmp[6] << 8) | tmp[7]; + soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags)); + if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error) + return soap->error; + if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error) + return soap->error; + if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:"", soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:"")); + if (soap->dime.flags & SOAP_DIME_ME) + soap->mode &= ~SOAP_ENC_DIME; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdime(struct soap *soap) +{ while (soap->dime.flags & SOAP_DIME_CF) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap_move(soap, soap->dime.size)) + return soap->error = SOAP_EOF; + } + if (soap_move(soap, ((soap->dime.size+3)&(~3))-soap_tell(soap))) + return soap->error = SOAP_EOF; + for (;;) + { register struct soap_multipart *content; + if (soap_getdimehdr(soap)) + break; + if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error)) + { const char *id, *type, *options; + size_t size, n; + if (!soap->dime.ptr) + return soap->error; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + for (;;) + { size = soap->dime.size; + for (;;) + { n = soap->buflen - soap->bufidx; + if (size < n) + n = size; + if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n))) + break; + size -= n; + if (!size) + { soap->bufidx += n; + break; + } + if (soap_recv(soap)) + { soap->error = SOAP_EOF; + goto end; + } + } + if (soap_move(soap, -(long)soap->dime.size&3)) + { soap->error = SOAP_EOF; + break; + } + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + break; + } +end: + if (soap->fdimewriteclose) + soap->fdimewriteclose(soap, (void*)soap->dime.ptr); + soap->dime.size = 0; + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else if (soap->dime.flags & SOAP_DIME_CF) + { const char *id, *type, *options; + register soap_wchar c; + register char *s; + register int i; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + if (soap_new_block(soap)) + return SOAP_EOM; + for (;;) + { s = (char*)soap_push_block(soap, soap->dime.size); + if (!s) + return soap->error = SOAP_EOM; + for (i = soap->dime.size; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (soap_move(soap, -(long)soap->dime.size&3)) + return soap->error = SOAP_EOF; + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + return soap->error; + } + soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */ + if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0))) + return soap->error; + soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */ + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else + soap->dime.ptr = soap_getdimefield(soap, soap->dime.size); + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size); + if (!content) + return soap->error = SOAP_EOM; + content->id = soap->dime.id; + content->type = soap->dime.type; + content->options = soap->dime.options; + soap_resolve_attachment(soap, content); + if (soap->error) + return soap->error; + } + if (soap->error != SOAP_DIME_END) + return soap->error; + return soap->error = SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmimehdr(struct soap *soap) +{ struct soap_multipart *content; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + while (!*soap->msgbuf); + if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-') + { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1; + /* remove white space */ + while (soap_blank(*s)) + s--; + s[1] = '\0'; + if (soap->mime.boundary) + { if (strcmp(soap->msgbuf + 2, soap->mime.boundary)) + return soap->error = SOAP_MIME_ERROR; + } + else + soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2); + if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL)) + return soap->error = SOAP_EOM; + content = soap->mime.last; + for (;;) + { register char *key = soap->msgbuf; + register char *val; + if (!*key) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key)); + val = strchr(soap->msgbuf, ':'); + if (val) + { *val = '\0'; + do val++; + while (*val && *val <= 32); + if (!soap_tag_cmp(key, "Content-ID")) + content->id = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Location")) + content->location = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Disposition")) + content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name")); + else if (!soap_tag_cmp(key, "Content-Type")) + content->type = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Description")) + content->description = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Transfer-Encoding")) + content->encoding = (enum soap_mime_encoding)soap_int_code(mime_codes, val, (long)SOAP_MIME_NONE); + } + if (soap_getline(soap, key, sizeof(soap->msgbuf))) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmime(struct soap *soap) +{ register soap_wchar c = 0; + if (!soap->mime.last) + return SOAP_OK; + for (;;) + { register size_t i, m = 0; + register char *s, *t = NULL; + struct soap_multipart *content = soap->mime.last; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:"")); + if (soap_new_block(soap)) + return soap->error = SOAP_EOM; + for (;;) + { register short flag = 0; + if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN))) + return soap->error = SOAP_EOM; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (m > 0) + { flag = (*t == '\r'); + *s++ = *t++; + m--; + } + else + { if (!flag) + { c = soap_get1(soap); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + } + if (flag || c == '\r') + { t = soap->tmpbuf; + memset(t, 0, sizeof(soap->tmpbuf)); + strcpy(t, "\n--"); + if (soap->mime.boundary) + strncat(t, soap->mime.boundary, sizeof(soap->tmpbuf)-4); + do c = soap_getchar(soap); + while (c == *t++); + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (!*--t) + goto end; + *t = (char)c; + m = t - soap->tmpbuf + 1; + t = soap->tmpbuf; + c = '\r'; + } + *s++ = (char)c; + } + } + } +end: + *s = '\0'; /* force 0-terminated */ + content->size = soap_size_block(soap, i+1)-1; + content->ptr = soap_save_block(soap, NULL, 0); + soap_resolve_attachment(soap, content); + if (c == '-' && soap_getchar(soap) == '-') + break; + while (c != '\r' && (int)c != EOF && soap_blank(c)) + c = soap_getchar(soap); + if (c != '\r' || soap_getchar(soap) != '\n') + return soap->error = SOAP_MIME_ERROR; + if (soap_getmimehdr(soap)) + return soap->error; + } + /* + do c = soap_getchar(soap); + while ((int)c != EOF && c != '\r' && c != '\n'); + if ((int)c != '\r' || soap_getchar(soap) != '\n') + return soap->error = SOAP_MIME_ERROR; + */ + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_match_cid(const char *s, const char *t) +{ register size_t n; + if (!s) + return 1; + if (!strcmp(s, t)) + return 0; + if (!strncmp(s, "cid:", 4)) + s += 4; + n = strlen(t); + if (*t == '<') + { t++; + n -= 2; + } + if (!strncmp(s, t, n) && !s[n]) + return 0; + return 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_resolve_attachment(struct soap *soap, struct soap_multipart *content) +{ if (content->id) + { register struct soap_xlist **xp = &soap->xlist; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id)); + while (*xp) + { register struct soap_xlist *xq = *xp; + if (!soap_match_cid(xq->id, content->id)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id)); + *xp = xq->next; + *xq->ptr = (unsigned char*)content->ptr; + *xq->size = (int)content->size; + *xq->type = (char*)content->type; + if (content->options) + *xq->options = (char*)content->options; + else + *xq->options = (char*)content->description; + SOAP_FREE(soap, xq); + } + else + xp = &(*xp)->next; + } + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmimehdr(struct soap *soap, struct soap_multipart *content) +{ const char *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:"")); + if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n")) + return soap->error; + if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n")) + return soap->error; + s = soap_str_code(mime_codes, content->encoding); + if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n")) + return soap->error; + if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n")) + return soap->error; + if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n")) + return soap->error; + if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n")) + return soap->error; + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + if (soap_putmimehdr(soap, content) + || soap_send_raw(soap, content->ptr, content->size)) + return soap->error; + return soap_send3(soap, "\r\n--", soap->mime.boundary, "--"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_dime(struct soap *soap) +{ soap->omode |= SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_mime(struct soap *soap, const char *boundary, const char *start) +{ soap->omode |= SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = soap_strdup(soap, boundary); + soap->mime.start = soap_strdup(soap, start); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_dime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_mime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart* +soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size) +{ struct soap_multipart *content; + content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart)); + if (content) + { content->next = NULL; + content->ptr = ptr; + content->size = size; + content->id = NULL; + content->type = NULL; + content->options = NULL; + content->encoding = SOAP_MIME_NONE; + content->location = NULL; + content->description = NULL; + if (!*first) + *first = content; + if (*last) + (*last)->next = content; + *last = content; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->options = soap_dime_option(soap, optype, option); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->encoding = encoding; + content->location = soap_strdup(soap, location); + content->description = soap_strdup(soap, description); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart* +SOAP_FMAC2 +soap_next_multipart(struct soap_multipart *content) +{ if (content) + return content->next; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_select_mime_boundary(struct soap *soap) +{ while (!soap->mime.boundary || soap_valid_mime_boundary(soap)) + { register char *s = soap->mime.boundary; + register size_t n = 0; + if (s) + n = strlen(s); + if (n < 16) + { n = 72; + s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1); + if (!s) + return; + } + strcpy(s, "<>"); + s += 2; + n -= 4; + while (n) + { *s++ = soap_base64o[soap_random & 0x3F]; + n--; + } + strcpy(s, "<>"); + } + if (!soap->mime.start) + soap->mime.start = ""; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_valid_mime_boundary(struct soap *soap) +{ register struct soap_multipart *content; + register size_t k = strlen(soap->mime.boundary); + for (content = soap->mime.first; content; content = content->next) + { if (content->ptr && content->size >= k) + { register const char *p = (const char*)content->ptr; + register size_t i; + for (i = 0; i < content->size - k; i++, p++) + if (!strncmp(p, soap->mime.boundary, k)) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ + +#ifdef WITH_COOKIES +/******************************************************************************/ +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_encode_cookie(const char *s, char *t, size_t len) +{ register int c; + register size_t n = len; + while ((c = *s++) && --n > 0) + { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c)) + *t++ = c; + else if (n > 2) + { *t++ = '%'; + *t++ = (c >> 4) + (c > 159 ? '7' : '0'); + c &= 0xF; + *t++ = c + (c > 9 ? '7' : '0'); + n -= 2; + } + else + break; + } + *t = '\0'; + return len - n; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + size_t n; + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (*path == '/') + path++; + n = strlen(path); + for (p = soap->cookies; p; p = p->next) + if (!strcmp(p->name, name) + && domain + && p->domain + && !strcmp(p->domain, domain) + && !strncmp(p->path, path, n)) + break; + return p; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + int n; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie: %s=%s domain=%s path=%s\n", name, value?value:"", domain?domain:"", path?path:"")); + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR); + return NULL; + } + if (*path == '/') + path++; + q = soap_cookie(soap, name, domain, path); + if (!q) + { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1))) + strcpy(q->name, name); + q->value = NULL; + q->domain = NULL; + q->path = NULL; + q->expire = -1; + q->version = 0; + q->secure = 0; + q->modified = 0; + for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--) + if (!strcmp((*p)->name, name) && (*p)->path && strcmp((*p)->path, path) < 0) + break; + if (n) + { q->next = *p; + *p = q; + } + else + { SOAP_FREE(soap, q->name); + SOAP_FREE(soap, q); + q = NULL; + } + } + } + else + q->modified = 1; + if (q) + { if (q->value) + { SOAP_FREE(soap, q->value); + q->value = NULL; + } + if (q->domain) + { SOAP_FREE(soap, q->domain); + q->domain = NULL; + } + if (q->path) + { SOAP_FREE(soap, q->path); + q->path = NULL; + } + if (value && *value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1))) + strcpy(q->value, value); + if (domain && *domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1))) + strcpy(q->domain, domain); + if (path && *path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1))) + strcpy(q->path, path); + q->session = 1; + q->env = 0; + } + return q; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + if (!domain) + domain = soap->cookie_domain; + if (!domain) + { soap_set_receiver_error(soap, "Cookie domain not set", NULL, SOAP_HTTP_ERROR); + return; + } + if (!path) + path = soap->cookie_path; + if (!path) + { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR); + return; + } + if (*path == '/') + path++; + for (p = &soap->cookies, q = *p; q; q = *p) + if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path))) + { if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + p = &q->next; +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path)) && p->env) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->expire; + return -1; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->expire = expire; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 1; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 0; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putsetcookies(struct soap *soap) +{ struct soap_cookie *p; + char *s, tmp[4096]; + const char *t; + for (p = soap->cookies; p; p = p->next) + { if (p->modified || !p->env) + { s = tmp; + if (p->name) + s += soap_encode_cookie(p->name, s, tmp-s+4064); + if (p->value && *p->value) + { *s++ = '='; + s += soap_encode_cookie(p->value, s, tmp-s+4064); + } + if (p->domain && (int)strlen(p->domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", p->domain); + else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", soap->cookie_domain); + strcat(s, ";Path=\"/"); + if (p->path) + t = p->path; + else + t = soap->cookie_path; + if (t) + { if (*t == '/') + t++; + if ((int)strlen(t) < tmp-s+4064) + strcat(s, t); + } + s += strlen(s); + *s++ = '"'; + if (p->version > 0) + sprintf(s, ";Version=%u", p->version); + if (p->expire >= 0) + sprintf(s, ";Max-Age=%ld", p->expire); + if (p->secure) + strcat(s, ";Secure"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp))) + return soap->error; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure) +{ struct soap_cookie **p, *q; + unsigned int version = 0; + time_t now = time(NULL); + char *s, tmp[4096]; + p = &soap->cookies; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path)); + if (*path == '/') + path++; + while ((q = *p)) + { if (q->expire && now > q->expire) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name)); + SOAP_FREE(soap, q->name); + if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + { size_t domlen = 0; + if (q->domain) + { const char *s = strchr(q->domain, ':'); + if (s) + domlen = s - q->domain; + else + domlen = strlen(q->domain); + } + if ((!q->domain || !strncmp(q->domain, domain, domlen)) + && (!q->path || !strncmp(q->path, path, strlen(q->path))) + && (!q->secure || secure)) + { s = tmp; + if (q->version != version) + { sprintf(s, "$Version=%u;", q->version); + version = q->version; + } + if (q->name) + s += soap_encode_cookie(q->name, s, tmp-s+4080); + if (q->value && *q->value) + { *s++ = '='; + s += soap_encode_cookie(q->value, s, tmp-s+4080); + } + if (q->path && (int)strlen(q->path) < tmp-s+4080) + { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path)); + s += strlen(s); + } + if (q->domain && (int)strlen(q->domain) < tmp-s+4080) + sprintf(s, ";$Domain=\"%s\"", q->domain); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Cookie", tmp))) + return soap->error; + } + p = &q->next; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_getcookies(struct soap *soap, const char *val) +{ struct soap_cookie *p = NULL, *q; + const char *s; + char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + char *domain = NULL; + char *path = NULL; + unsigned int version = 0; + time_t now = time(NULL); + if (!val) + return; + s = val; + while (*s) + { s = soap_decode_key(tmp, sizeof(tmp), s); + if (!soap_tag_cmp(tmp, "$Version")) + { if ((s = soap_decode_val(tmp, sizeof(tmp), s))) + { if (p) + p->version = (int)atol(tmp); + else + version = (int)atol(tmp); + } + } + else if (!soap_tag_cmp(tmp, "$Path")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->path) + SOAP_FREE(soap, p->path); + p->path = t; + } + else + { if (path) + SOAP_FREE(soap, path); + path = t; + } + } + else if (!soap_tag_cmp(tmp, "$Domain")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->domain) + SOAP_FREE(soap, p->domain); + p->domain = t; + } + else + { if (domain) + SOAP_FREE(soap, domain); + domain = t; + } + } + else if (p && !soap_tag_cmp(tmp, "Path")) + { if (p->path) + SOAP_FREE(soap, p->path); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->path, tmp); + } + else + p->path = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Domain")) + { if (p->domain) + SOAP_FREE(soap, p->domain); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->domain, tmp); + } + else + p->domain = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Version")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->version = (unsigned int)atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Max-Age")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->expire = now + atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Expires")) + { struct tm T; + char a[3]; + static const char mns[] = "anebarprayunulugepctovec"; + s = soap_decode_val(tmp, sizeof(tmp), s); + if (strlen(tmp) > 20) + { memset((void*)&T, 0, sizeof(T)); + a[0] = tmp[4]; + a[1] = tmp[5]; + a[2] = '\0'; + T.tm_mday = (int)atol(a); + a[0] = tmp[8]; + a[1] = tmp[9]; + T.tm_mon = (strstr(mns, a) - mns) / 2; + a[0] = tmp[11]; + a[1] = tmp[12]; + T.tm_year = 100 + (int)atol(a); + a[0] = tmp[13]; + a[1] = tmp[14]; + T.tm_hour = (int)atol(a); + a[0] = tmp[16]; + a[1] = tmp[17]; + T.tm_min = (int)atol(a); + a[0] = tmp[19]; + a[1] = tmp[20]; + T.tm_sec = (int)atol(a); + p->expire = soap_timegm(&T); + } + } + else if (p && !soap_tag_cmp(tmp, "Secure")) + p->secure = 1; + else + { if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->name, tmp); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->value, tmp); + } + else + p->value = NULL; + p->domain = domain; + p->path = path; + p->expire = 0; + p->secure = 0; + p->version = version; + } + } + } + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if (domain) + SOAP_FREE(soap, domain); + if (path) + SOAP_FREE(soap, path); +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getenv_cookies(struct soap *soap) +{ struct soap_cookie *p; + const char *s; + char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + if (!(s = getenv("HTTP_COOKIE"))) + return SOAP_ERR; + do + { s = soap_decode_key(key, sizeof(key), s); + s = soap_decode_val(val, sizeof(val), s); + p = soap_set_cookie(soap, key, val, NULL, NULL); + if (p) + p->env = 1; + } while (*s); + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_copy_cookies(struct soap *soap) +{ struct soap_cookie *p, **q, *r; + q = &r; + for (p = soap->cookies; p; p = p->next) + { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + return r; + **q = *p; + if (p->name) + { if (((*q)->name = (char*)SOAP_MALLOC(soap, strlen(p->name)+1))) + strcpy((*q)->name, p->name); + } + if (p->value) + { if (((*q)->value = (char*)SOAP_MALLOC(soap, strlen(p->value)+1))) + strcpy((*q)->value, p->value); + } + if (p->domain) + { if (((*q)->domain = (char*)SOAP_MALLOC(soap, strlen(p->domain)+1))) + strcpy((*q)->domain, p->domain); + } + if (p->path) + { if (((*q)->path = (char*)SOAP_MALLOC(soap, strlen(p->path)+1))) + strcpy((*q)->path, p->path); + } + q = &(*q)->next; + } + *q = NULL; + return r; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_cookies(struct soap *soap) +{ struct soap_cookie *p; + for (p = soap->cookies; p; p = soap->cookies) + { soap->cookies = p->next; + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } +} + +/******************************************************************************/ +#endif /* WITH_COOKIES */ + +/******************************************************************************/ +#ifdef WITH_GZIP +#ifndef PALM_1 +static int +soap_getgziphdr(struct soap *soap) +{ int i; + soap_wchar c, f = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n")); + for (i = 0; i < 9; i++) + { if ((int)(c = soap_get1(soap) == EOF)) + return soap->error = SOAP_EOF; + if (i == 2) + f = c; + } + if (f & 0x04) /* FEXTRA */ + { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--) + if ((int)soap_get1(soap) == EOF) + return soap->error = SOAP_EOF; + } + if (f & 0x08) /* FNAME */ + do + c = soap_get1(soap); + while (c && (int)c != EOF); + if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */ + do + c = soap_get1(soap); + while (c && (int)f != EOF); + if ((int)c != EOF && (f & 0x01)) /* FHCRC */ + { if ((int)(c = soap_get1(soap)) != EOF) + c = soap_get1(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_recv(struct soap *soap) +{ soap_wchar c; + soap->error = SOAP_OK; + soap_free(soap); + soap_set_local_namespaces(soap); + soap->version = 0; /* don't assume we're parsing SOAP content by default */ +#ifndef WITH_NOIDREF + soap_free_iht(soap); +#endif + if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK) + soap->omode |= SOAP_IO_CHUNK; + soap->imode &= ~SOAP_IO; + soap->mode = soap->imode; + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + soap->ahead = 0; + soap->peeked = 0; + soap->level = 0; + soap->part = SOAP_BEGIN; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + *soap->endpoint = '\0'; + soap->action = NULL; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.chunksize = 0; + soap->dime.buflen = 0; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; + soap->xlist = NULL; +#endif +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->recvfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->recvfd, _O_BINARY); +#endif +#endif +#endif +#endif +#ifdef WITH_ZLIB + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.next_in = Z_NULL; + soap->d_stream.avail_in = 0; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + soap->z_ratio_in = 1.0; +#endif +#ifndef WITH_LEANER + if (soap->fprepareinit) + soap->fprepareinit(soap); +#endif + c = soap_getchar(soap); +#ifdef WITH_GZIP + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->mode |= SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_GZIP; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + /* should not chunk over plain transport, so why bother to check? */ + /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */ + /* soap->z_buflen = soap->bufidx; */ + /* else */ + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + c = soap_getchar(soap); + } +#endif +#ifndef WITH_LEANER + if (c == '-' && soap_get0(soap) == '-') + soap->mode |= SOAP_ENC_MIME; + else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20) + soap->mode |= SOAP_ENC_DIME; + else +#endif + { while (soap_blank(c)) + c = soap_getchar(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifndef WITH_NOHTTP + /* if not XML or (start of)BOM or MIME/DIME/ZLIB, assume HTTP header */ + if (c != '<' && c != 0xEF && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB))) + { soap->mode &= ~SOAP_IO; + soap->error = soap->fparse(soap); + if (soap->error && soap->error < SOAP_STOP) + { soap->keep_alive = 0; /* force close later */ + return soap->error; + } + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { soap->chunkbuflen = soap->buflen; + soap->buflen = soap->bufidx; + soap->chunksize = 0; + } +#ifndef WITH_LEANER + else if (soap->fpreparerecv && soap->buflen != soap->bufidx) + soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx); +#endif +#ifdef WITH_ZLIB + if (soap->zlib_in != SOAP_ZLIB_NONE) + { /* fparse should not use soap_unget to push back last char */ +#ifdef WITH_GZIP + c = soap_get1(soap); + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + } + else + { soap_revget1(soap); +#else + { +#endif + if (inflateInit(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n")); + } + soap->mode |= SOAP_ENC_ZLIB; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + } +#endif + if (soap->error) + { if (soap->error == SOAP_FORM && soap->fform) + { soap->error = soap->fform(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + } + return soap->error; + } + } +#endif +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + { if (soap_getmimehdr(soap)) + return soap->error; + if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + } + if (soap->mode & SOAP_ENC_DIME) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + soap->count = soap->buflen - soap->bufidx; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse(struct soap *soap) +{ char header[SOAP_HDRLEN], *s; + unsigned short get = 0, status = 0, k = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n")); + *soap->endpoint = '\0'; + soap->length = 0; + soap->userid = NULL; + soap->passwd = NULL; + soap->action = NULL; + soap->authrealm = NULL; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf)); + for (;;) + { if (soap_getline(soap, header, SOAP_HDRLEN)) + { if (soap->error == SOAP_EOF) + { soap->error = SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n")); + break; + } + return soap->error; + } + if (!*header) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header)); + s = strchr(header, ':'); + if (s) + { *s = '\0'; + do s++; + while (*s && *s <= 32); + if ((soap->error = soap->fparsehdr(soap, header, s))) + { if (soap->error < SOAP_STOP) + return soap->error; + status = soap->error; + soap->error = SOAP_OK; + } + } + } + if ((s = strchr(soap->msgbuf, ' '))) + { k = (unsigned short)soap_strtoul(s, &s, 10); + if (!soap_blank(*s)) + k = 0; + } + else + k = 0; + } while (k == 100); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing\n")); + s = strstr(soap->msgbuf, "HTTP/"); + if (s && s[7] != '1') + { if (soap->keep_alive == 1) + soap->keep_alive = 0; + if (k == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* k == 0 for HTTP request */ + { soap->imode |= SOAP_IO_CHUNK; + soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; + } + } + if (soap->keep_alive < 0) + soap->keep_alive = 1; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive)); + if (s && (((get = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5))) + { size_t m = strlen(soap->endpoint); + size_t n = m + (s - soap->msgbuf) - 5 - (!get); + if (n >= sizeof(soap->endpoint)) + n = sizeof(soap->endpoint) - 1; + strncpy(soap->path, soap->msgbuf + 4 + (!get), n - m); + soap->path[n - m] = '\0'; + strcat(soap->endpoint, soap->path); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint)); + if (get) + { soap->error = soap->fget(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + return soap->error; + } + if (status) + return soap->error = status; + return SOAP_OK; + } + if (k == 0 || (k >= 200 && k <= 299) || k == 400 || k == 500) + return SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", k)); + return soap_set_receiver_error(soap, "HTTP error", soap->msgbuf, k); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse_header(struct soap *soap, const char *key, const char *val) +{ if (!soap_tag_cmp(key, "Host")) + { +#ifdef WITH_OPENSSL + if (soap->imode & SOAP_ENC_SSL) + strcpy(soap->endpoint, "https://"); + else +#endif + strcpy(soap->endpoint, "http://"); + strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifndef WITH_LEANER + else if (!soap_tag_cmp(key, "Content-Type")) + { if (soap_get_header_attribute(soap, val, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + else if (soap_get_header_attribute(soap, val, "multipart/related") + || soap_get_header_attribute(soap, val, "multipart/form-data")) + { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary")); + soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start")); + soap->mode |= SOAP_ENC_MIME; + } + } +#endif + else if (!soap_tag_cmp(key, "Content-Length")) + soap->length = soap_strtoul(val, NULL, 10); + else if (!soap_tag_cmp(key, "Content-Encoding")) + { if (!soap_tag_cmp(val, "deflate")) +#ifdef WITH_ZLIB + soap->zlib_in = SOAP_ZLIB_DEFLATE; +#else + return SOAP_ZLIB_ERROR; +#endif + else if (!soap_tag_cmp(val, "gzip")) +#ifdef WITH_GZIP + soap->zlib_in = SOAP_ZLIB_GZIP; +#else + return SOAP_ZLIB_ERROR; +#endif + } +#ifdef WITH_ZLIB + else if (!soap_tag_cmp(key, "Accept-Encoding")) + { +#ifdef WITH_GZIP + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip")) + soap->zlib_out = SOAP_ZLIB_GZIP; + else +#endif + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate")) + soap->zlib_out = SOAP_ZLIB_DEFLATE; + else + soap->zlib_out = SOAP_ZLIB_NONE; + } +#endif + else if (!soap_tag_cmp(key, "Transfer-Encoding")) + { soap->mode &= ~SOAP_IO; + if (!soap_tag_cmp(val, "chunked")) + soap->mode |= SOAP_IO_CHUNK; + } + else if (!soap_tag_cmp(key, "Connection")) + { if (!soap_tag_cmp(val, "keep-alive")) + soap->keep_alive = -soap->keep_alive; + else if (!soap_tag_cmp(val, "close")) + soap->keep_alive = 0; + } +#ifndef WITH_LEAN + else if (!soap_tag_cmp(key, "Authorization")) + { if (!soap_tag_cmp(val, "Basic *")) + { int n; + char *s; + soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n); + soap->tmpbuf[n] = '\0'; + if ((s = strchr(soap->tmpbuf, ':'))) + { *s = '\0'; + soap->userid = soap_strdup(soap, soap->tmpbuf); + soap->passwd = soap_strdup(soap, s + 1); + } + } + } + else if (!soap_tag_cmp(key, "WWW-Authenticate")) + soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm")); + else if (!soap_tag_cmp(key, "Expect")) + { if (!soap_tag_cmp(val, "100-continue")) + { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL)) + || (soap->error = soap->fposthdr(soap, NULL, NULL))) + return soap->error; + } + } +#endif + else if (!soap_tag_cmp(key, "SOAPAction")) + { if (*val == '"') + { soap->action = soap_strdup(soap, val + 1); + soap->action[strlen(soap->action) - 1] = '\0'; + } + } + else if (!soap_tag_cmp(key, "Location")) + { strncpy(soap->endpoint, val, sizeof(soap->endpoint)); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifdef WITH_COOKIES + else if (!soap_tag_cmp(key, "Cookie") || !soap_tag_cmp(key, "Set-Cookie")) + soap_getcookies(soap, val); +#endif + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_get_header_attribute(struct soap *soap, const char *line, const char *key) +{ register const char *s = line; + if (s) + { while (*s) + { register short flag; + s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s); + flag = soap_tag_cmp(soap->tmpbuf, key); + s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s); + if (!flag) + return soap->tmpbuf; + } + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_key(char *buf, size_t len, const char *val) +{ return soap_decode(buf, len, val, "=,;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_val(char *buf, size_t len, const char *val) +{ if (*val != '=') + { *buf = '\0'; + return val; + } + return soap_decode(buf, len, val + 1, ",;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char* +soap_decode(char *buf, size_t len, const char *val, const char *sep) +{ const char *s; + char *t = buf; + for (s = val; *s; s++) + if (*s != ' ' && *s != '\t' && !strchr(sep, *s)) + break; + if (*s == '"') + { s++; + while (*s && *s != '"' && --len) + *t++ = *s++; + } + else + { while (soap_notblank(*s) && !strchr(sep, *s) && --len) + { if (*s == '%') + { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4) + + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0'); + s += 3; + } + else + *t++ = *s++; + } + } + *t = '\0'; + while (*s && !strchr(sep, *s)) + s++; + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_out(struct soap *soap) +{ +#ifndef WITH_LEANER + size_t n = 0; + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start) + { const char *s; + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + s = "application/dime"; + else if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + else + s = "text/xml; charset=utf-8"; + sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start); + n = strlen(soap->tmpbuf); + if (soap_send_raw(soap, soap->tmpbuf, n)) + return soap->error; + } + if (soap->mode & SOAP_IO_LENGTH) + soap->dime.size = soap->count; /* DIME in MIME correction */ + if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME)) + { if (soap_putdimehdr(soap)) + return soap->error; + } +#endif + soap->part = SOAP_IN_ENVELOPE; + return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope")) + return soap->error; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { soap->dime.size = soap->count - soap->dime.size; /* DIME in MIME correction */ + sprintf(soap->id, soap->dime_id_format, 0); + soap->dime.id = soap->id; + if (soap->local_namespaces) + { if (soap->local_namespaces[0].out) + soap->dime.type = (char*)soap->local_namespaces[0].out; + else + soap->dime.type = (char*)soap->local_namespaces[0].ns; + } + soap->dime.options = NULL; + soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI; + if (!soap->dime.first) + soap->dime.flags |= SOAP_DIME_ME; + soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + ((strlen(soap->dime.type)+3)&(~3)); + } + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); +#endif + soap->part = SOAP_END_ENVELOPE; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_in(struct soap *soap) +{ register struct Namespace *p; + soap->part = SOAP_IN_ENVELOPE; + if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0)) + return soap->error = SOAP_VERSIONMISMATCH; + p = soap->local_namespaces; + if (p) + { const char *ns = p[0].out; + if (!ns) + ns = p[0].ns; + if (!strcmp(ns, soap_env1)) + { soap->version = 1; /* make sure we use SOAP 1.1 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1)))) + strcpy(p[1].out, soap_enc1); + } + else if (!strcmp(ns, soap_env2)) + { soap->version = 2; /* make sure we use SOAP 1.2 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2)))) + strcpy(p[1].out, soap_enc2); + } + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_in(struct soap *soap) +{ soap->part = SOAP_END_ENVELOPE; + return soap_element_end_in(soap, "SOAP-ENV:Envelope"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_out(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap->version == 1) + soap->encoding = 1; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body")) + return soap->error; +#endif + if (soap_element(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Body")) + return soap->error; + soap->part = SOAP_END_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_in(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0)) + return soap->error; + if (!soap->body) + soap->part = SOAP_NO_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_in(struct soap *soap) +{ if (soap->part == SOAP_NO_BODY) + return SOAP_OK; + soap->part = SOAP_END_BODY; + return soap_element_end_in(soap, "SOAP-ENV:Body"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_header(struct soap *soap) +{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH) + soap->error = SOAP_OK; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_endpoint(struct soap *soap, const char *endpoint) +{ register const char *s; + register size_t i, n; + soap->endpoint[0] = '\0'; + soap->host[0] = '\0'; + soap->path[0] = '/'; + soap->path[1] = '\0'; + soap->port = 80; + if (!endpoint || !*endpoint) + return; + if (!strncmp(endpoint, "https:", 6)) + soap->port = 443; + strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1); + s = strchr(endpoint, ':'); + if (s && s[1] == '/' && s[2] == '/') + s += 3; + else + s = endpoint; + n = strlen(s); + if (n >= sizeof(soap->host)) + n = sizeof(soap->host) - 1; +#ifdef WITH_IPV6 + if (s[0] == '[') + { s++; + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == ']') + { s++; + break; + } + } + } + else + { for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } + } +#else + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } +#endif + soap->host[i] = '\0'; + if (s[i] == ':') + { soap->port = (int)atol(s + i + 1); + for (i++; i < n; i++) + if (s[i] == '/') + break; + } + if (s[i]) + { strncpy(soap->path, s + i, sizeof(soap->path)); + soap->path[sizeof(soap->path) - 1] = '\0'; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect(struct soap *soap, const char *endpoint, const char *action) +{ return soap_connect_command(soap, SOAP_POST, endpoint, action); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action) +{ char host[sizeof(soap->host)]; + int port; + size_t count; + soap->error = SOAP_OK; + strcpy(host, soap->host); /* save to compare */ + port = soap->port; /* save to compare */ + soap_set_endpoint(soap, endpoint); +#ifndef WITH_LEANER + if (soap->fconnect) + { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port))) + return soap->error; + } + else +#endif + if (soap->fopen && *soap->host) + { soap->status = http_command; + if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap)) + { soap->keep_alive = 0; /* to force close */ + soap->omode &= ~SOAP_IO_UDP; /* to force close */ + soap_closesock(soap); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port)); +#ifdef WITH_UDP + if (!strncmp(endpoint, "soap.udp:", 9)) + soap->omode |= SOAP_IO_UDP; +#endif + soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port); + if (soap->error) + return soap->error; + soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0); + } + } + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint) + { unsigned int k = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((k & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count))) + return soap->error; +#ifndef WITH_LEANER + if ((k & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = k; + } + else if (action) + soap->action = soap_strdup(soap, action); + if (http_command != SOAP_POST) + return soap_end_send(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n) +{ register int i; + register unsigned long m; + register char *p; + if (!t) + t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1); + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + t[0] = '\0'; + if (!s) + return p; + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + t += 4; + } + t[0] = '\0'; + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + t[i] = '='; + t[4] = '\0'; + } + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register int i, j, c; + register unsigned long m; + register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = (strlen(s) + 3) / 4 * 3; + t = (char*)soap_malloc(soap, l); + } + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + if (n) + *n = 0; + for (;;) + { for (i = 0; i < SOAP_BLKLEN; i++) + { m = 0; + j = 0; + while (j < 4) + { c = *s++; + if (c == '=' || !c) + { i *= 3; + switch (j) + { case 2: + *t++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *t++ = (char)((m >> 10) & 0xFF); + *t++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n += i; + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { m = (m << 6) + soap_base64i[c]; + j++; + } + } + *t++ = (char)((m >> 16) & 0xFF); + *t++ = (char)((m >> 8) & 0xFF); + *t++ = (char)(m & 0xFF); + if (l < 3) + { if (n) + *n += i; + return p; + } + l -= 3; + } + if (n) + *n += 3 * SOAP_BLKLEN; + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n) +{ register char *p; + if (!t) + t = (char*)soap_malloc(soap, 2 * n + 1); + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + t[0] = '\0'; + if (s) + { for (; n > 0; n--) + { register int m = *s++; + *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0')); + m &= 0x0F; + *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0')); + } + } + *t++ = '\0'; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = strlen(s) / 2; + t = (char*)soap_malloc(soap, l); + } + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + while (l) + { register int d1, d2; + d1 = *s++; + if (!d1) + break; + d2 = *s++; + if (!d2) + break; + *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + l--; + } + if (n) + *n = t - p; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthttphdr(struct soap *soap, int status, size_t count) +{ register const char *s; +#ifndef WITH_LEANER + register const char *r = NULL; +#endif + register int err; + if (status == SOAP_FILE && soap->http_content) + s = soap->http_content; + else if (status == SOAP_HTML) + s = "text/html; charset=utf-8"; + else if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + else + s = "text/xml; charset=utf-8"; +#ifndef WITH_LEANER + if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM)) + { if (soap->mode & SOAP_ENC_MTOM) + { r = s; + s = "application/xop+xml; charset=utf-8"; + } + else + s = "application/dime"; + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->status != SOAP_GET) + { register const char *t = strchr(s, ';'); + sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary); + if (t) + strncat(soap->tmpbuf, s, t - s); + else + strcat(soap->tmpbuf, s); + if (soap->mime.start) + { strcat(soap->tmpbuf, "\"; start=\""); + strcat(soap->tmpbuf, soap->mime.start); + } + strcat(soap->tmpbuf, "\""); + if (r) + { strcat(soap->tmpbuf, "; start-info=\""); + strcat(soap->tmpbuf, r); + strcat(soap->tmpbuf, "\""); + } + s = soap->tmpbuf; + } +#endif + if ((err = soap->fposthdr(soap, "Content-Type", s))) + return err; +#ifdef WITH_ZLIB + if (soap->omode & SOAP_ENC_ZLIB) + { +#ifdef WITH_GZIP + err = soap->fposthdr(soap, "Content-Encoding", "gzip"); +#else + err = soap->fposthdr(soap, "Content-Encoding", "deflate"); +#endif + if (err) + return err; + } +#endif +#ifndef WITH_LEANER + if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK) + err = soap->fposthdr(soap, "Transfer-Encoding", "chunked"); + else +#endif + if (count > 0) + { sprintf(soap->tmpbuf, "%lu", (unsigned long)count); + err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf); + } + if (err) + return err; + return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_get(struct soap *soap) +{ return SOAP_GET_METHOD; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count) +{ register const char *s; + register int err; + if (soap->status == SOAP_GET) + { s = "GET"; + count = 0; + } + else + s = "POST"; +#ifdef PALM + if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8)) +#else + if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6))) +#endif + return SOAP_OK; + if (soap->proxy_host && strncmp(endpoint, "https:", 6)) + sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version); + else + sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + if (port != 80) + sprintf(soap->tmpbuf, "%s:%d", host, port); + else + strcpy(soap->tmpbuf, host); + if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf)) + || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, SOAP_OK, count))) + return err; +#ifdef WITH_ZLIB +#ifdef WITH_GZIP + if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate"))) +#else + if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate"))) +#endif + return err; +#endif +#ifndef WITH_LEAN + if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf))) + return err; + } + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return err; + } +#endif +#ifdef WITH_COOKIES +#ifdef WITH_OPENSSL + if (soap_putcookies(soap, host, path, soap->ssl != NULL)) + return soap->error; +#else + if (soap_putcookies(soap, host, path, 0)) + return soap->error; +#endif +#endif + if (action && soap->version == 1) + { sprintf(soap->tmpbuf, "\"%s\"", action); + if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf))) + return err; + } + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_send_header(struct soap *soap, const char *s) +{ register const char *t; + do + { t = strchr(s, '\n'); /* disallow \n in HTTP headers */ + if (!t) + t = s + strlen(s); + if (soap_send_raw(soap, s, t - s)) + return soap->error; + s = t + 1; + } while (*t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post_header(struct soap *soap, const char *key, const char *val) +{ if (key) + { if (http_send_header(soap, key)) + return soap->error; + if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val))) + return soap->error; + } + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_response(struct soap *soap, int status, size_t count) +{ register int err; +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + httpOutputEnable(soap->rpmreqid); +#endif /* WMW_RPM_IO */ + if (!status || status == SOAP_HTML || status == SOAP_FILE) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "OK 200\n")); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +#endif /* WMW_RPM_IO */ + { sprintf(soap->tmpbuf, "HTTP/%s 200 OK", soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", "200 OK"))) + return err; + } + else if (status > 200 && status < 600) + { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status)); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; +#ifndef WITH_LEAN + if (status == 401) + { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", soap->authrealm ? soap->authrealm : "gSOAP Web Service"); + if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf))) + return err; + } + else if ((status >= 301 && status <= 303) || status == 307) + { if ((err = soap->fposthdr(soap, "Location", soap->endpoint))) + return err; + } +#endif + } + else + { const char *s = *soap_faultcode(soap); + if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender")) + s = "400 Bad Request"; + else + s = "500 Internal Server Error"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status)); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +#endif /* WMW_RPM_IO */ + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) + return err; + } + if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, status, count))) + return err; +#ifdef WITH_COOKIES + if (soap_putsetcookies(soap)) + return soap->error; +#endif + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_response(struct soap *soap, int status) +{ register size_t count; + if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */)) + && (status == SOAP_HTML || status == SOAP_FILE)) + { soap->omode &= ~SOAP_IO; + soap->omode |= SOAP_IO_STORE; + } + soap->status = status; + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML)) + { register int n = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((n & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fresponse(soap, status, count))) + return soap->error; +#ifndef WITH_LEANER + if ((n & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = n; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static const char* +soap_set_validation_fault(struct soap *soap, const char *s, const char *t) +{ if (*soap->tag) + sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag); + else + sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS); + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_fault(struct soap *soap) +{ const char **c = soap_faultcode(soap); + const char **s = soap_faultstring(soap); + if (!*c && !*s && soap->fseterror) + soap->fseterror(soap, c, s); + if (!*c) + { if (soap->version == 2) + *c = "SOAP-ENV:Sender"; + else + *c = "SOAP-ENV:Client"; + } + if (*s) + return; + switch (soap->error) + { +#ifndef WITH_LEAN + case SOAP_CLI_FAULT: + *s = "Client fault"; + break; + case SOAP_SVR_FAULT: + *s = "Server fault"; + break; + case SOAP_TAG_MISMATCH: + *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL); + break; + case SOAP_TYPE: + *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type); + break; + case SOAP_SYNTAX_ERROR: + *s = "Well-formedness violation"; + break; + case SOAP_NO_TAG: + *s = "No XML element tag"; + break; + case SOAP_MUSTUNDERSTAND: + *c = "SOAP-ENV:MustUnderstand"; + sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_VERSIONMISMATCH: + *c = "SOAP-ENV:VersionMismatch"; + *s = "SOAP version mismatch or invalid SOAP message"; + break; + case SOAP_DATAENCODINGUNKNOWN: + *c = "SOAP-ENV:DataEncodingUnknown"; + *s = "Unsupported SOAP data encoding"; + break; + case SOAP_NAMESPACE: + *s = soap_set_validation_fault(soap, "namespace mismatch", NULL); + break; + case SOAP_USER_ERROR: + *s = "User error"; + break; + case SOAP_FATAL_ERROR: + *s = "Fatal error"; + break; + case SOAP_NO_METHOD: + sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_GET_METHOD: + *s = "HTTP GET method not implemented"; + break; + case SOAP_EOM: + *s = "Out of memory"; + break; + case SOAP_IOB: + *s = "Array index out of bounds"; + break; + case SOAP_NULL: + *s = soap_set_validation_fault(soap, "nil not allowed", NULL); + break; + case SOAP_DUPLICATE_ID: + *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID"; + break; + case SOAP_MISSING_ID: + *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:MissingID"; + break; + case SOAP_HREF: + *s = soap_set_validation_fault(soap, "incompatible object ref ", soap->id); + break; + case SOAP_FAULT: + break; +#ifndef WITH_NOIO + case SOAP_UDP_ERROR: + *s = "Message too large for UDP packet"; + break; + case SOAP_TCP_ERROR: + *s = tcp_error(soap); + break; +#endif + case SOAP_HTTP_ERROR: + *s = "HTTP error"; + break; + case SOAP_SSL_ERROR: +#ifdef WITH_OPENSSL + *s = "SSL error"; +#else + *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL"; +#endif + break; + case SOAP_PLUGIN_ERROR: + *s = "Plugin registry error"; + break; + case SOAP_DIME_ERROR: + *s = "DIME format error"; + break; + case SOAP_DIME_HREF: + *s = "DIME href to missing attachment"; + break; + case SOAP_DIME_MISMATCH: + *s = "DIME version/transmission error"; + break; + case SOAP_DIME_END: + *s = "End of DIME error"; + break; + case SOAP_MIME_ERROR: + *s = "MIME format error"; + break; + case SOAP_MIME_HREF: + *s = "MIME href to missing attachment"; + break; + case SOAP_MIME_END: + *s = "End of MIME error"; + break; + case SOAP_ZLIB_ERROR: +#ifdef WITH_ZLIB + sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:""); + *s = soap->msgbuf; +#else + *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP"; +#endif + break; + case SOAP_REQUIRED: + *s = soap_set_validation_fault(soap, "missing required attribute", NULL); + break; + case SOAP_PROHIBITED: + *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL); + break; + case SOAP_OCCURS: + *s = soap_set_validation_fault(soap, "min/maxOccurs violation", NULL); + break; + case SOAP_LENGTH: + *s = soap_set_validation_fault(soap, "content length violation", NULL); + break; + case SOAP_STOP: + *s = "Stopped: no response sent"; + break; +#endif + case SOAP_EOF: +#ifndef WITH_NOIO + sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap)); + *s = soap->msgbuf; + break; +#else + *s = "End of file or no input"; + break; +#endif + default: +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN + if (soap->error > 200 && soap->error < 600) + { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error)); + *s = soap->msgbuf; + } + else +#endif +#endif + { sprintf(soap->msgbuf, "Error %d", soap->error); + *s = soap->msgbuf; + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_fault(struct soap *soap) +{ register int status = soap->error; + int r = 1; + if (status == SOAP_STOP) + return status; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error)); + soap->keep_alive = 0; /* to terminate connection */ + soap_set_fault(soap); +#ifndef WITH_NOIO +#ifndef WITH_LEAN + if (soap_valid_socket(soap->socket)) + { struct timeval timeout; + fd_set rfd, sfd; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&rfd); + FD_ZERO(&sfd); + FD_SET((SOAP_SOCKET)soap->socket, &rfd); + FD_SET((SOAP_SOCKET)soap->socket, &sfd); + r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, NULL, &timeout); + if (r > 0) + { if (!FD_ISSET((SOAP_SOCKET)soap->socket, &sfd) + || (FD_ISSET((SOAP_SOCKET)soap->socket, &rfd) + && recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0)) + r = 0; + } + } +#endif +#endif + if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && r > 0) + { soap->error = SOAP_OK; + soap_serializeheader(soap); + soap_serializefault(soap); + soap_begin_count(soap); + if (soap->mode & SOAP_IO_LENGTH) + { soap_envelope_begin_out(soap); + soap_putheader(soap); + soap_body_begin_out(soap); + soap_putfault(soap); + soap_body_end_out(soap); + soap_envelope_end_out(soap); + } + soap_end_count(soap); + if (soap_response(soap, status) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_putfault(soap) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap_closesock(soap); + soap_end_send(soap); + } + soap->error = status; + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_fault(struct soap *soap) +{ register int status = soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Receiving SOAP Fault\n")); + soap->error = SOAP_OK; + if (soap_getfault(soap)) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n")); + *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client"); + soap->error = status; + soap_set_fault(soap); + } + else + { register const char *s = *soap_faultcode(soap); + if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver")) + status = SOAP_SVR_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender")) + status = SOAP_CLI_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand")) + status = SOAP_MUSTUNDERSTAND; + else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch")) + status = SOAP_VERSIONMISMATCH; + else + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Fault code %s\n", s)); + status = SOAP_FAULT; + } + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + soap->error = status; + } + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_empty_response(struct soap *soap) +{ soap->count = 0; + if (soap_response(soap, SOAP_OK) || soap_end_send(soap)) + return soap_closesock(soap); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_empty_response(struct soap *soap) +{ if (soap_begin_recv(soap) || soap_end_recv(soap)) + return soap_closesock(soap); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +soap_strerror(struct soap *soap) +{ register int err = soap->errnum; + if (err) + { +#ifndef WIN32 + return strerror(err); +#else + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&soap->errorstr, sizeof(soap->errorstr), NULL); + return soap->errorstr; +#endif + } + return "Operation interrupted or timed out"; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail, int soaperror) +{ *soap_faultcode(soap) = faultcode; + if (faultsubcode) + *soap_faultsubcode(soap) = faultsubcode; + *soap_faultstring(soap) = faultstring; + if (faultdetail && *faultdetail) + { register const char **s = soap_faultdetail(soap); + if (s) + *s = faultdetail; + } + return soap->error = soaperror; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ char *r = NULL, *s = NULL, *t = NULL; + if (faultsubcode) + r = soap_strdup(soap, faultsubcode); + if (faultstring) + s = soap_strdup(soap, faultstring); + if (faultdetail) + t = soap_strdup(soap, faultdetail); + return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcode, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcode, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault(struct soap *soap, FILE *fd) +{ if (soap->error) + { const char *c, *v = NULL, *s, **d; + d = soap_faultcode(soap); + if (!*d) + soap_set_fault(soap); + c = *d; + if (soap->version == 2) + v = *soap_faultsubcode(soap); + s = *soap_faultstring(soap); + d = soap_faultdetail(soap); + fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]"); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault_location(struct soap *soap, FILE *fd) +{ +#ifndef WITH_LEAN + int i, j, c1, c2; + if (soap->error && soap->buflen > 0) + { i = (int)soap->bufidx - 1; + if (i <= 0) + i = 0; + c1 = soap->buf[i]; + soap->buf[i] = '\0'; + if ((int)soap->buflen >= i + 1024) + j = i + 1023; + else + j = (int)soap->buflen - 1; + c2 = soap->buf[j]; + soap->buf[j] = '\0'; + fprintf(fd, "%s%c\n** HERE **\n", soap->buf, c1); + if (soap->bufidx < soap->buflen) + fprintf(fd, "%s\n", soap->buf + soap->bufidx); + soap->buf[i] = c1; + soap->buf[j] = c2; + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg) +{ register struct soap_plugin *p; + register int r; + if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin)))) + return soap->error = SOAP_EOM; + p->id = NULL; + p->data = NULL; + p->fcopy = NULL; + p->fdelete = NULL; + r = fcreate(soap, p, arg); + if (!r && p->fdelete) + { p->next = soap->plugins; + soap->plugins = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id)); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r)); + SOAP_FREE(soap, p); + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void * +fplugin(struct soap *soap, const char *id) +{ register struct soap_plugin *p; + for (p = soap->plugins; p; p = p->next) + if (p->id == id || !strcmp(p->id, id)) + return p->data; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void * +SOAP_FMAC2 +soap_lookup_plugin(struct soap *soap, const char *id) +{ return soap->fplugin(soap, id); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif + diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h new file mode 100644 index 0000000..17ef597 --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h @@ -0,0 +1,2053 @@ +/* + +stdsoap2.h 2.7.6b + +gSOAP runtime + +gSOAP XML Web services tools +Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under one of the following licenses: +GPL, the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems, Inc., for the following additions (marked WR[...]): + - vxWorks compatible +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- +*/ + +#ifdef WITH_SOAPDEFS_H +# include "soapdefs.h" /* include user-defined stuff */ +#endif + +#ifndef _THREAD_SAFE +# define _THREAD_SAFE +#endif + +#ifndef OPENSERVER +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +#ifndef SOAP_FMAC1 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC1 +#endif + +#ifndef SOAP_FMAC2 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC2 +#endif + +#ifndef SOAP_FMAC3 /* (de)serializer declaration macro */ +# define SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC3S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC3S SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC4 /* (de)serializer declaration macro */ +# define SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC4S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC4S SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC5 /* stub/skeleton declaration macro */ +# define SOAP_FMAC5 +#endif + +#ifndef SOAP_FMAC6 /* stub/skeleton declaration macro */ +# define SOAP_FMAC6 +#endif + +#ifndef SOAP_CMAC /* class declaration macro */ +# define SOAP_CMAC +#endif + +#ifndef SOAP_NMAC /* namespace table declaration macro */ +# define SOAP_NMAC +#endif + +#ifndef SOAP_SOURCE_STAMP +# define SOAP_SOURCE_STAMP(str) +#endif + +/* gSOAP 2.7.4 and higher: fast look-aside buffering is stable */ +#ifndef WITH_FAST +# define WITH_FAST +#endif + +#ifdef WITH_LEANER +# ifndef WITH_LEAN +# define WITH_LEAN +# endif +#endif + +#ifdef WITH_LEAN +# ifdef WITH_COOKIES +# error "Cannot build WITH_LEAN code WITH_COOKIES enabled" +# endif +#endif + +#ifndef STDSOAP_H +#define STDSOAP_H + +#if defined(__vxworks) || defined(__VXWORKS__) +# define VXWORKS +#endif + +#ifdef _WIN32 +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef UNDER_CE +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef __BORLANDC__ +# ifdef __WIN32__ +# ifndef WIN32 +# define WIN32 +# endif +# endif +#endif + +#ifdef __CYGWIN__ +# ifndef CYGWIN +# define CYGWIN +# endif +#endif + +#ifdef __SYMBIAN32__ +# define SYMBIAN +# undef WIN32 +#endif + +#if defined(__palmos__) || defined(PALM_GCC) || defined(__PALMOS_TRAPS__) +# ifndef PALM +# define PALM +# endif +#endif + +#if defined(__hpux) +# ifndef HP_UX +# define HP_UX +# endif +#endif + +#if defined(__alpha) && !defined(__VMS) +# ifndef TRU64 +# define TRU64 +# endif +#endif + +#ifdef __MVS__ +# ifndef OS390 +# define OS390 +# endif +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +# ifdef WITH_OPENSSL +# ifndef HAVE_OPENSSL_SSL_H +# undef WITH_OPENSSL +# endif +# endif +#else +# if defined(UNDER_CE) +# define WITH_LEAN +# define HAVE_SSCANF +# elif defined(WIN32) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%I64d" +# define SOAP_ULONG_FORMAT "%I64u" +# elif defined(CYGWIN) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__APPLE__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(_AIXVERSION_431) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(HP_UX) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(FREEBSD) || defined(__FreeBSD__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_GETTIMEOFDAY +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%qd" +# define SOAP_ULONG_FORMAT "%qu" +# elif defined(__VMS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__GLIBC__) || defined(__GNU__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define HAVE_ISNAN +# elif defined(TRU64) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_GETTIMEOFDAY +# define HAVE_SYS_TIMEB_H +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define __USE_STD_IOSTREAM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +# elif defined(MAC_CARBON) +# define WITH_NOIO +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(PALM) +# define WITH_LEAN +# define HAVE_STRTOD /* strtod() is defined in palmFunctions.h */ +# include /* Needs to be included before unix headers */ +# include +# define IGNORE_STDIO_STUBS +# include +# define O_NONBLOCK FNONBIO +# include +# include "palmFunctions.h" +# elif defined(SYMBIAN) +# define WITH_LEAN +# define WITH_NONAMESPACES +# define HAVE_STRTOD /* use STRTOD since sscanf doesn't seem to work */ +# include +# include +# elif defined(VXWORKS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_PGMTIME_R +# define HAVE_PLOCALTIME_R +# define HAVE_MKTIME +# elif defined(OS390) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MB +# else +/* Default asumptions on supported functions */ +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# endif +#endif + +/* QNX does not have a working version of strtof */ +#if defined(__QNX__) || defined(QNX) +# undef HAVE_STRTOF +#endif + +#ifndef SOAP_LONG_FORMAT +# define SOAP_LONG_FORMAT "%lld" /* printf format for 64 bit ints */ +#endif + +#ifndef SOAP_ULONG_FORMAT +# define SOAP_ULONG_FORMAT "%llu" /* printf format for unsigned 64 bit ints */ +#endif + +#ifndef WITH_NOSTDLIB +# include +# ifndef PALM +# include +# include +# endif +# include +# include +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) +# include +# include +#endif + +#ifdef WITH_NOHTTP +# ifndef WITH_NOIO +# define WITH_NOIO +# undef WITH_COOKIES +# endif +#endif + +#ifndef UNDER_CE +# ifndef PALM +# ifndef WITH_NOIO +# include +# include +# endif +# ifndef WITH_LEAN +# ifdef HAVE_SYS_TIMEB_H +# include /* for ftime() */ +# endif +# include +# endif +# endif +#endif + +#ifdef OPENSERVER +# include +# include +# include + extern int h_errno; +#endif + +#ifndef WITH_NOIO +# ifndef WIN32 +# ifndef PALM +# include +# ifdef VXWORKS +# include +# include +# endif +# ifndef VXWORKS +# ifndef SYMBIAN +# include +# endif +# endif +# ifdef SUN_OS +# include /* SUN */ +# include /* SUN < 2.8 (?) */ +# endif +# ifdef VXWORKS +# ifdef _WRS_KERNEL +# include +# endif +# else +# include +# endif +# include +# ifdef OS390 +# include +# else +# include /* TCP_NODELAY */ +# endif +# include +# endif +# endif +#endif + +#ifdef WITH_FASTCGI +# include +#endif + +#ifdef WITH_OPENSSL +# define OPENSSL_NO_KRB5 +# include +# include +# include +# ifndef ALLOW_OLD_VERSIONS +# if (OPENSSL_VERSION_NUMBER < 0x00905100L) +# error "Must use OpenSSL 0.9.6 or later" +# endif +# endif +#endif + +#ifdef WITH_GZIP +# ifndef WITH_ZLIB +# define WITH_ZLIB +# endif +#endif + +#ifdef WITH_CASEINSENSITIVETAGS +# define SOAP_STRCMP soap_tag_cmp /* case insensitve XML element/attribute names */ +#else +# define SOAP_STRCMP strcmp /* case sensitive XML element/attribute names */ +#endif + +#ifdef WITH_ZLIB +# include +#endif + +#ifndef WITH_NOSTDLIB +# ifndef PALM +# include /* for isnan() */ +# endif +#endif + +/* #define DEBUG */ /* Uncomment to debug sending (in file SENT.log) receiving (in file RECV.log) and messages (in file TEST.log) */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +# ifndef UNDER_CE +# include +# include +# endif +# include +/* # include */ /* Alternative: use winsock2 (not available with eVC) */ +# ifdef WITH_IPV6 +# include +# include +# endif +#else +# ifdef VXWORKS +# include +# include +# include +# endif +# ifndef WITH_NOIO +# ifndef PALM +# include +# include +# include +# include +# endif +# endif +#endif + +/* Portability: define SOAP_SOCKLEN_T */ +#if defined(SOCKLEN_T) +# define SOAP_SOCKLEN_T SOCKLEN_T +#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) || defined(FREEBSD) || defined(__FreeBSD__) || defined(__QNX__) || defined(QNX) || defined(_AIX) +# define SOAP_SOCKLEN_T socklen_t +#elif defined(IRIX) || defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) +# define SOAP_SOCKLEN_T int +#else +# define SOAP_SOCKLEN_T size_t +#endif + +#ifdef WIN32 +# define SOAP_SOCKET SOCKET +#else +# define SOAP_SOCKET int +# define closesocket(n) close(n) +#endif + +#define SOAP_INVALID_SOCKET (-1) +#define soap_valid_socket(n) ((n) != SOAP_INVALID_SOCKET) + +#if defined(SYMBIAN) +# define LONG64 long +# define ULONG64 unsigned LONG64 +#elif !defined(WIN32) || defined(__GLIBC__) || defined(__GNU__) +# ifndef LONG64 +# define LONG64 long long +# define ULONG64 unsigned LONG64 +# endif +#elif defined(UNDER_CE) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#elif defined(__BORLANDC__) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#endif + +#if defined(WIN32) +# define soap_int32 __int32 +#elif defined(SYMBIAN) +# define soap_int32 long +#elif defined(PALM) +# define soap_int32 Int32 +#else +# define soap_int32 int32_t +#endif + +#ifdef WIN32 +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR WSAEINTR +# define SOAP_EAGAIN WSAEWOULDBLOCK +# define SOAP_EWOULDBLOCK WSAEWOULDBLOCK +# define SOAP_EINPROGRESS WSAEINPROGRESS +#else +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR EINTR +# define SOAP_EAGAIN EAGAIN +# ifdef SYMBIAN +# define SOAP_EWOULDBLOCK 9898 +# define SOAP_EINPROGRESS 9899 +# else +# define SOAP_EWOULDBLOCK EWOULDBLOCK +# define SOAP_EINPROGRESS EINPROGRESS +# endif +#endif + +#ifdef WIN32 +# ifdef UNDER_CE +# define soap_errno GetLastError() +# define soap_socket_errno GetLastError() +# else +# define soap_errno GetLastError() +# define soap_socket_errno WSAGetLastError() +# endif +#else +# ifndef WITH_NOIO +# define soap_errno errno +# define soap_socket_errno errno +# else +# define soap_errno 0 +# define soap_socket_errno 0 +# endif +#endif + +#ifndef SOAP_BUFLEN +# ifdef WITH_UDP +# define SOAP_BUFLEN (65536) /* max UDP packet size */ +# else +# ifndef WITH_LEAN +# define SOAP_BUFLEN (65536) /* buffer length for socket packets, also used by gethostbyname_r so don't make this too small */ +# else +# define SOAP_BUFLEN (2048) +# endif +# endif +#endif +#ifndef SOAP_LABLEN +# define SOAP_LABLEN (64) /* initial look-aside buffer length */ +#endif +#ifndef SOAP_PTRBLK +# define SOAP_PTRBLK (32) /* block allocation for pointer hash table chains */ +#endif +#ifndef SOAP_PTRHASH +# ifndef WITH_LEAN +# define SOAP_PTRHASH (1024) /* size of pointer analysis hash table (must be power of 2) */ +# else +# define SOAP_PTRHASH (32) +# endif +#endif +#ifndef SOAP_IDHASH +# ifndef WITH_LEAN +# define SOAP_IDHASH (1999) /* prime size of hash table for parsed id/ref */ +# else +# define SOAP_IDHASH (19) /* 19, 199 */ +# endif +#endif +#ifndef SOAP_BLKLEN +# ifndef WITH_LEAN +# define SOAP_BLKLEN (256) /* size of blocks to collect long strings and XML attributes */ +# else +# define SOAP_BLKLEN (32) +# endif +#endif +#ifndef SOAP_TAGLEN +# ifndef WITH_LEAN +# define SOAP_TAGLEN (256) /* maximum length of XML element tag/attribute name or host/path name + 1 */ +# else +# define SOAP_TAGLEN (64) +# endif +#endif +#ifndef SOAP_HDRLEN +# ifndef WITH_LEAN +# define SOAP_HDRLEN (8192) /* maximum length of HTTP header line (must be >4096 to read cookies) */ +# else +# define SOAP_HDRLEN (1024) +# endif +#endif +#ifndef SOAP_MAXDIMS +# ifndef WITH_LEAN +# define SOAP_MAXDIMS (16) /* maximum array dimensions (array nestings) must be less than 64 to protect soap->tmpbuf */ +# else +# define SOAP_MAXDIMS (4) +# endif +#endif + +#ifndef SOAP_MAXLOGS +# define SOAP_MAXLOGS (3) /* max number of debug logs per struct soap environment */ +# define SOAP_INDEX_RECV (0) +# define SOAP_INDEX_SENT (1) +# define SOAP_INDEX_TEST (2) +#endif + +#ifndef SOAP_MAXKEEPALIVE +# define SOAP_MAXKEEPALIVE (100) /* max iterations to keep server connection alive */ +#endif + +#ifndef SOAP_MAXARRAYSIZE +# define SOAP_MAXARRAYSIZE (100000) /* "trusted" max size of inbound SOAP array for compound array allocation */ +#endif + +#ifdef VXWORKS +# ifdef __INCmathh +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) isNan(num) +# endif +#endif + +#ifdef WIN32 +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) _isnan(num) +#endif + +#ifdef SUN_OS +# define soap_isnan(n) isnan(n) +#endif + +#if !defined(HAVE_ISNAN) && (defined(_MATH_H) || defined(_MATH_INCLUDED)) +# define HAVE_ISNAN +#endif + +#ifndef soap_isnan +# ifdef HAVE_ISNAN +# define soap_isnan(n) isnan(n) +# else +# define soap_isnan(_) (0) +# endif +#endif + +extern const struct soap_double_nan { unsigned int n1, n2; } soap_double_nan; + +#ifdef VXWORKS +# ifndef FLT_MAX +# define FLT_MAX _ARCH_FLT_MAX +# endif +# ifndef DBL_MAX +# define DBL_MAX _ARCH_DBL_MAX +# endif +#endif + +#ifndef FLT_NAN +# ifdef HAVE_ISNAN +# define FLT_NAN (*(float*)(void*)&soap_double_nan) +# else +# define FLT_NAN (0.0) +# endif +#endif + +#ifndef FLT_PINFTY +# if defined(FLT_MAX) +# define FLT_PINFTY FLT_MAX +# elif defined(HUGE_VALF) +# define FLT_PINFTY (float)HUGE_VALF +# elif defined(HUGE_VAL) +# define FLT_PINFTY (float)HUGE_VAL +# elif defined(FLOAT_MAX) +# define FLT_PINFTY FLOAT_MAX +# else +# define FLT_PINFTY (3.40282347e+38F) +# endif +#endif + +#ifndef FLT_NINFTY +# define FLT_NINFTY (-FLT_PINFTY) +#endif + +#ifndef DBL_NAN +# ifdef HAVE_ISNAN +# define DBL_NAN (*(double*)(void*)&soap_double_nan) +# else +# define DBL_NAN (0.0) +# endif +#endif + +#ifndef DBL_PINFTY +# if defined(DBL_MAX) +# define DBL_PINFTY DBL_MAX +# elif defined(HUGE_VALF) +# define DBL_PINFTY (double)HUGE_VALF +# elif defined(HUGE_VAL) +# define DBL_PINFTY (double)HUGE_VAL +# elif defined(DOUBLE_MAX) +# define DBL_PINFTY DOUBLE_MAX +# else +# define DBL_PINFTY (1.7976931348623157e+308) +# endif +#endif + +#ifndef DBL_NINFTY +# define DBL_NINFTY (-DBL_PINFTY) +#endif + +#define soap_ispinfd(n) ((n) >= DBL_PINFTY) +#define soap_ispinff(n) ((n) >= FLT_PINFTY) +#define soap_isninfd(n) ((n) <= DBL_NINFTY) +#define soap_isninff(n) ((n) <= FLT_NINFTY) + +/* gSOAP error codes */ + +#define SOAP_EOF EOF +#define SOAP_ERR EOF +#define SOAP_OK 0 +#define SOAP_CLI_FAULT 1 +#define SOAP_SVR_FAULT 2 +#define SOAP_TAG_MISMATCH 3 +#define SOAP_TYPE 4 +#define SOAP_SYNTAX_ERROR 5 +#define SOAP_NO_TAG 6 +#define SOAP_IOB 7 +#define SOAP_MUSTUNDERSTAND 8 +#define SOAP_NAMESPACE 9 +#define SOAP_USER_ERROR 10 +#define SOAP_FATAL_ERROR 11 +#define SOAP_FAULT 12 +#define SOAP_NO_METHOD 13 +#define SOAP_GET_METHOD 14 +#define SOAP_EOM 15 +#define SOAP_NULL 16 +#define SOAP_DUPLICATE_ID 17 +#define SOAP_MISSING_ID 18 +#define SOAP_HREF 19 +#define SOAP_UDP_ERROR 20 +#define SOAP_TCP_ERROR 21 +#define SOAP_HTTP_ERROR 22 +#define SOAP_SSL_ERROR 23 +#define SOAP_ZLIB_ERROR 24 +#define SOAP_DIME_ERROR 25 +#define SOAP_DIME_HREF 26 +#define SOAP_DIME_MISMATCH 27 +#define SOAP_DIME_END 28 +#define SOAP_MIME_ERROR 29 +#define SOAP_MIME_HREF 30 +#define SOAP_MIME_END 31 +#define SOAP_VERSIONMISMATCH 32 +#define SOAP_PLUGIN_ERROR 33 +#define SOAP_DATAENCODINGUNKNOWN 34 +#define SOAP_REQUIRED 35 +#define SOAP_PROHIBITED 36 +#define SOAP_OCCURS 37 +#define SOAP_LENGTH 38 + +#define soap_xml_error_check(e) ((e) == SOAP_TAG_MISMATCH || (e) == SOAP_TAG_END || (e) == SOAP_SYNTAX_ERROR || (e) == SOAP_NAMESPACE || (e) == SOAP_DUPLICATE_ID || (e) == SOAP_MISSING_ID || (e) == SOAP_REQUIRED || (e) == SOAP_PROHIBITED || (e) == SOAP_OCCURS || (e) == SOAP_LENGTH || (e) == SOAP_NULL || (e) == SOAP_HREF) +#define soap_soap_error_check(e) ((e) == SOAP_CLI_FAULT || (e) == SOAP_SVR_FAULT || (e) == SOAP_VERSIONMISMATCH || (e) == SOAP_MUSTUNDERSTAND || (e) == SOAP_FAULT || (e) == SOAP_NO_METHOD) +#define soap_tcp_error_check(e) ((e) == SOAP_EOF || (e) == SOAP_TCP_ERROR) +#define soap_ssl_error_check(e) ((e) == SOAP_SSL_ERROR) +#define soap_zlib_error_check(e) ((e) == SOAP_ZLIB_ERROR) +#define soap_http_error_check(e) ((e) == SOAP_HTTP_ERROR || (e) == SOAP_GET_METHOD || ((e) >= 100 && (e) < 600)) + +/* gSOAP HTTP response status codes 100 to 599 are reserved */ + +/* Codes 600 to 999 are user definable */ + +/* Exceptional gSOAP HTTP response status codes >= 1000 */ + +#define SOAP_STOP 1000 /* No HTTP response */ +#define SOAP_FORM 1001 /* Form request/response */ +#define SOAP_HTML 1002 /* Custom HTML response */ +#define SOAP_FILE 1003 /* Custom file-based response */ + +/* gSOAP HTTP method codes */ + +#define SOAP_POST 2000 +#define SOAP_GET 2001 + +/* gSOAP DIME */ + +#define SOAP_DIME_CF 0x01 +#define SOAP_DIME_ME 0x02 +#define SOAP_DIME_MB 0x04 +#define SOAP_DIME_VERSION 0x08 /* DIME version 1 */ +#define SOAP_DIME_MEDIA 0x10 +#define SOAP_DIME_ABSURI 0x20 + +/* gSOAP ZLIB */ + +#define SOAP_ZLIB_NONE 0x00 +#define SOAP_ZLIB_DEFLATE 0x01 +#define SOAP_ZLIB_INFLATE 0x02 +#define SOAP_ZLIB_GZIP 0x02 + +/* gSOAP transport, connection, and content encoding modes */ + +typedef soap_int32 soap_mode; + +#define SOAP_IO 0x00000003 /* IO mask */ +#define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */ +#define SOAP_IO_BUFFER 0x00000001 /* buffer output in packets of size SOAP_BUFLEN */ +#define SOAP_IO_STORE 0x00000002 /* store entire output to determine length for transport */ +#define SOAP_IO_CHUNK 0x00000003 /* use HTTP chunked transfer AND buffer packets */ + +#define SOAP_IO_UDP 0x00000004 +#define SOAP_IO_LENGTH 0x00000008 +#define SOAP_IO_KEEPALIVE 0x00000010 + +#define SOAP_ENC_LATIN 0x00800020 /* iso-8859-1 encoding */ +#define SOAP_ENC_XML 0x00000040 /* plain XML encoding, no HTTP header */ +#define SOAP_ENC_DIME 0x00000080 +#define SOAP_ENC_MIME 0x00000100 +#define SOAP_ENC_MTOM 0x00000200 +#define SOAP_ENC_ZLIB 0x00000400 +#define SOAP_ENC_SSL 0x00000800 + +#define SOAP_ENC 0x00000FFF /* IO and ENC mask */ + +#define SOAP_XML_STRICT 0x00001000 /* strict validation */ +#define SOAP_XML_INDENT 0x00002000 +#define SOAP_XML_CANONICAL 0x00004000 /* EXC C14N canonical XML */ +#define SOAP_XML_TREE 0x00008000 +#define SOAP_XML_GRAPH 0x00010000 +#define SOAP_XML_NIL 0x00020000 +#define SOAP_XML_DOM 0x00040000 +#define SOAP_XML_SEC 0x00080000 /* reserved for WS security */ + +#define SOAP_C_NOIOB 0x00100000 +#define SOAP_C_UTFSTRING 0x00200000 +#define SOAP_C_MBSTRING 0x00400000 + +#define SOAP_DOM_TREE 0x01000000 +#define SOAP_DOM_NODE 0x02000000 +#define SOAP_DOM_ASIS 0x04000000 + +#define SOAP_IO_DEFAULT SOAP_IO_FLUSH + +/* SSL client/server authentication settings */ + +#define SOAP_SSL_NO_AUTHENTICATION 0x00 /* for testing purposes */ +#define SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION 0x01 /* client requires server to authenticate */ +#define SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION 0x02 /* server requires client to authenticate */ + +#define SOAP_SSL_DEFAULT SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION + +/* */ + +#define SOAP_BEGIN 0 +#define SOAP_IN_ENVELOPE 2 +#define SOAP_IN_HEADER 3 +#define SOAP_END_HEADER 4 +#define SOAP_NO_BODY 5 +#define SOAP_IN_BODY 6 +#define SOAP_END_BODY 7 +#define SOAP_END_ENVELOPE 8 +#define SOAP_END 9 +#define SOAP_BEGIN_SECURITY 10 +#define SOAP_IN_SECURITY 11 +#define SOAP_END_SECURITY 12 + +/* DEBUG macros */ + +#ifndef WITH_LEAN +# ifdef DEBUG +# ifndef SOAP_DEBUG +# define SOAP_DEBUG +# endif +# endif +#endif + +#ifdef SOAP_DEBUG +# define SOAP_MALLOC(soap, size) soap_track_malloc(soap, __FILE__, __LINE__, size) +# define SOAP_FREE(soap, ptr) soap_track_free(soap, __FILE__, __LINE__, ptr) +#endif + +#ifndef SOAP_MALLOC /* use libc malloc */ +# define SOAP_MALLOC(soap, size) malloc(size) +#endif + +#ifndef SOAP_FREE /* use libc free */ +# define SOAP_FREE(soap, ptr) free(ptr) +#endif + +#ifdef SOAP_DEBUG +# ifndef SOAP_MESSAGE +# define SOAP_MESSAGE fprintf +# endif +# ifndef DBGLOG +# define DBGLOG(DBGFILE, CMD) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { FILE *fdebug = soap->fdebug[SOAP_INDEX_##DBGFILE];\ + CMD;\ + fflush(fdebug);\ + }\ + }\ +} +# endif +# ifndef DBGMSG +# define DBGMSG(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { fwrite((MSG), 1, (LEN), soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +# ifndef DGBFUN +# define DBGFUN(FNAME) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s()\n", __FILE__, __LINE__, FNAME)) +# define DBGFUN1(FNAME, FMT, ARG) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT")\n", __FILE__, __LINE__, FNAME, (ARG))) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2))) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2", "FMT3")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2), (ARG3))) +# endif +# ifndef DBGHEX +# define DBGHEX(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { int i; char *s;\ + for (s = (char*)(MSG), i = (LEN); i; i--)\ + fprintf(soap->fdebug[SOAP_INDEX_##DBGFILE], "%2.2hhX ", *s++);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +#else +# define DBGLOG(DBGFILE, CMD) +# define DBGMSG(DBGFILE, MSG, LEN) +# define DBGFUN(FNAME) +# define DBGFUN1(FNAME, FMT, ARG) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) +# define DBGHEX(DBGFILE, MSG, LEN) +#endif + +/* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to distinguish XML entities) */ +typedef soap_int32 soap_wchar; + +/* namespace table row */ +struct Namespace +{ const char *id; + const char *ns; + const char *in; + char *out; +}; + +/* namespace stack */ +struct soap_nlist +{ struct soap_nlist *next; + unsigned int level; /* nesting depth level */ + short index; /* corresponding entry in ns mapping table */ + char *ns; /* only set when parsed ns URI is not in the ns mapping table */ + char id[1]; /* the actual string value flows into the allocated region below this struct */ +}; + +/* block stack for nested block allocations */ +struct soap_blist +{ struct soap_blist *next; + char *ptr; + size_t size; +}; + +/* array layout */ +struct soap_array +{ void *__ptr; + int __size; +}; + +/* pointer serialization management */ +struct soap_plist +{ struct soap_plist *next; + const void *ptr; + const struct soap_array *array; + int type; + int id; + char mark1; + char mark2; +}; + +/* block allocation for pointer serialization management */ +struct soap_pblk +{ struct soap_pblk *next; + struct soap_plist plist[SOAP_PTRBLK]; +}; + +#ifdef SOAP_DEBUG +/* malloc/free tracking for debugging */ +struct soap_mlist +{ struct soap_mlist *next; + const void *ptr; + const char *file; + int line; + short live; +}; +#endif + +/* class allocation list */ +struct soap_clist +{ struct soap_clist *next; + void *ptr; + int type; + int size; + void (*fdelete)(struct soap_clist*); +}; + +/* attributes */ +struct soap_attribute +{ struct soap_attribute *next; + char *value; + size_t size; + char *ns; + short visible; + char name[1]; /* the actual name string flows into the allocated region below this struct */ +}; + +struct soap_cookie +{ struct soap_cookie *next; + char *name; + char *value; + char *domain; + char *path; + long expire; /* client-side: local time to expire; server-side: seconds to expire */ + unsigned int version; + short secure; + short session; /* server-side */ + short env; /* server-side: got cookie from client and should not be (re)send */ + short modified; /* server-side: client cookie was modified and should be send */ +}; + +#ifdef __cplusplus +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); + +class soap_multipart_iterator +{ public: + struct soap_multipart *content; + bool operator==(const soap_multipart_iterator& iter) const + { return content == iter.content; } + bool operator!=(const soap_multipart_iterator& iter) const + { return content != iter.content; } + struct soap_multipart &operator*() const + { return *content; } + soap_multipart_iterator &operator++() + { content = soap_next_multipart(content); return *this; } + soap_multipart_iterator() : content(NULL) + { } + soap_multipart_iterator(struct soap_multipart *p) : content(p) + { } +}; +#endif + +#ifndef WITH_LEANER +struct soap_dime +{ size_t count; + size_t size; + size_t chunksize; + size_t buflen; + char flags; + char *ptr; + const char *id; + const char *type; + const char *options; + struct soap_multipart *list; /* list of DIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +struct soap_mime +{ char *boundary; /* MIME boundary */ + const char *start; /* MIME start ID */ + struct soap_multipart *list; /* list of MIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* RFC2045 MIME content transfer encodings */ +enum soap_mime_encoding +{ SOAP_MIME_NONE, + SOAP_MIME_7BIT, + SOAP_MIME_8BIT, + SOAP_MIME_BINARY, + SOAP_MIME_QUOTED_PRINTABLE, + SOAP_MIME_BASE64, + SOAP_MIME_IETF_TOKEN, + SOAP_MIME_X_TOKEN +}; +#endif + +#ifndef WITH_LEANER +/* DIME/MIME multipart list */ +struct soap_multipart +{ struct soap_multipart *next; + char *ptr; /* points to raw data content */ + size_t size; /* size of data content */ + const char *id; /* DIME/MIME content ID or form data name */ + const char *type; /* DIME/MIME type (MIME type format) */ + const char *options; /* DIME options */ + enum soap_mime_encoding encoding; /* MIME Content-Transfer-Encoding */ + const char *location; /* MIME Content-Location (optional) */ + const char *description; /* MIME Content-Description (optional) */ +#ifdef __cplusplus + typedef soap_multipart_iterator iterator; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* attachment DIME and MTOM XOP forwarding */ +struct soap_xlist +{ struct soap_xlist *next; + unsigned char **ptr; + int *size; + char *id; + char **type; + char **options; +}; +#endif + +/******************************************************************************/ + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_attribute_iterator +{ public: + struct soap_dom_attribute *att; + const char *nstr; + const char *name; + bool operator==(const soap_dom_attribute_iterator&) const; + bool operator!=(const soap_dom_attribute_iterator&) const; + struct soap_dom_attribute &operator*() const; + soap_dom_attribute_iterator &operator++(); + soap_dom_attribute_iterator(); + soap_dom_attribute_iterator(struct soap_dom_attribute*); + ~soap_dom_attribute_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_attribute +{ struct soap_dom_attribute *next; + const char *nstr; + char *name; + char *data; + wchar_t *wide; + struct soap *soap; +#ifdef __cplusplus + typedef soap_dom_attribute_iterator iterator; + struct soap_dom_attribute &set(const char *nstr, const char *name); /* set namespace and name */ + struct soap_dom_attribute &set(const char *data); /* set data */ + soap_dom_attribute_iterator begin(); + soap_dom_attribute_iterator end(); + soap_dom_attribute_iterator find(const char *nstr, const char *name); + void unlink(); + soap_dom_attribute(); + soap_dom_attribute(struct soap *soap); + soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data); + ~soap_dom_attribute(); +#endif +}; +#endif + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_element_iterator +{ public: + struct soap_dom_element *elt; + const char *nstr; + const char *name; + int type; + bool operator==(const soap_dom_element_iterator&) const; + bool operator!=(const soap_dom_element_iterator&) const; + struct soap_dom_element &operator*() const; + soap_dom_element_iterator &operator++(); + soap_dom_element_iterator(); + soap_dom_element_iterator(struct soap_dom_element*); + ~soap_dom_element_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_element +{ struct soap_dom_element *next; /* next sibling */ + struct soap_dom_element *prnt; /* parent */ + struct soap_dom_element *elts; /* list of child elements */ + struct soap_dom_attribute *atts; /* list of attributes */ + const char *nstr; /* namespace string */ + char *name; /* element tag name */ + char *data; /* element content data (with SOAP_C_UTFSTRING flag set) */ + wchar_t *wide; /* element content data */ + int type; /* optional: serialized C/C++ data type */ + void *node; /* optional: pointer to serialized C/C++ data */ + char *head; /* leading whitespace to start tag */ + char *tail; /* leading whitespace to end tag */ + struct soap *soap; /* soap context that manages this node */ +#ifdef __cplusplus + typedef soap_dom_element_iterator iterator; + struct soap_dom_element &set(const char *nstr, const char *name); + struct soap_dom_element &set(const char *data); + struct soap_dom_element &set(void *node, int type); + struct soap_dom_element &add(struct soap_dom_element*); + struct soap_dom_element &add(struct soap_dom_element&); + struct soap_dom_element &add(struct soap_dom_attribute*); + struct soap_dom_element &add(struct soap_dom_attribute&); + soap_dom_element_iterator begin(); + soap_dom_element_iterator end(); + soap_dom_element_iterator find(const char *nstr, const char *name); + soap_dom_element_iterator find(int type); + void unlink(); + soap_dom_element(); + soap_dom_element(struct soap *soap); + soap_dom_element(struct soap *soap, const char *nstr, const char *name); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type); + ~soap_dom_element(); +#endif +}; +SOAP_FMAC1 const char* SOAP_FMAC2 soap_dom_current_nstr(struct soap *soap, const char *tag); +SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_dom_next_element(struct soap_dom_element *elt); +SOAP_FMAC1 struct soap_dom_attribute * SOAP_FMAC2 soap_dom_next_attribute(struct soap_dom_attribute *att); +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) +} +extern std::ostream &operator<<(std::ostream&, const struct soap_dom_element&); +extern std::istream &operator>>(std::istream&, struct soap_dom_element&); +extern "C" { +#endif + +/******************************************************************************/ + +struct soap +{ short version; /* 1 = SOAP1.1 and 2 = SOAP1.2 (set automatically from namespace URI in nsmap table) */ + short copy; /* 1 = copy of another soap struct */ + soap_mode mode; + soap_mode imode; + soap_mode omode; + const char *float_format; /* user-definable format string for floats (<1024 chars) */ + const char *double_format; /* user-definable format string for doubles (<1024 chars) */ + const char *dime_id_format; /* user-definable format string for integer DIME id ( 0, gives socket recv timeout in seconds, < 0 in usec */ + int send_timeout; /* when > 0, gives socket send timeout in seconds, < 0 in usec */ + int connect_timeout; /* when > 0, gives socket connect() timeout in seconds, < 0 in usec */ + int accept_timeout; /* when > 0, gives socket accept() timeout in seconds, < 0 in usec */ + int socket_flags; /* socket recv() and send() flags, e.g. set to MSG_NOSIGNAL to disable sigpipe */ + int connect_flags; /* connect() SOL_SOCKET sockopt flags, e.g. set to SO_DEBUG to debug socket */ + int bind_flags; /* bind() SOL_SOCKET sockopt flags, e.g. set to SO_REUSEADDR to enable reuse */ + int accept_flags; /* accept() SOL_SOCKET sockopt flags */ + const struct Namespace *namespaces; /* Pointer to global namespace mapping table */ + struct Namespace *local_namespaces; /* Local namespace mapping table */ + struct soap_nlist *nlist; /* namespace stack */ + struct soap_blist *blist; /* block allocation stack */ + struct soap_clist *clist; /* class instance allocation list */ + void *alist; /* memory allocation (malloc) list */ + struct soap_ilist *iht[SOAP_IDHASH]; + struct soap_plist *pht[SOAP_PTRHASH]; + struct soap_pblk *pblk; /* plist block allocation */ + short pidx; /* plist block allocation */ + struct SOAP_ENV__Header *header; + struct SOAP_ENV__Fault *fault; + int idnum; + void *user; /* to pass user-defined data */ + struct soap_plugin *plugins; /* linked list of plug-in data */ + char *userid; /* HTTP Basic authorization userid */ + char *passwd; /* HTTP Basic authorization passwd */ + int (*fpost)(struct soap*, const char*, const char*, int, const char*, const char*, size_t); + int (*fget)(struct soap*); + int (*fform)(struct soap*); + int (*fposthdr)(struct soap*, const char*, const char*); + int (*fresponse)(struct soap*, int, size_t); + int (*fparse)(struct soap*); + int (*fparsehdr)(struct soap*, const char*, const char*); + int (*fresolve)(struct soap*, const char*, struct in_addr* inaddr); + int (*fconnect)(struct soap*, const char*, const char*, int); + int (*fdisconnect)(struct soap*); + int (*fclosesocket)(struct soap*, SOAP_SOCKET); + int (*fshutdownsocket)(struct soap*, SOAP_SOCKET, int); + int (*fopen)(struct soap*, const char*, const char*, int); + int (*faccept)(struct soap*, int, struct sockaddr*, int *n); + int (*fclose)(struct soap*); + int (*fsend)(struct soap*, const char*, size_t); + size_t (*frecv)(struct soap*, char*, size_t); + int (*fpoll)(struct soap*); + void (*fseterror)(struct soap*, const char **c, const char **s); + int (*fignore)(struct soap*, const char*); + int (*fserveloop)(struct soap*); + void *(*fplugin)(struct soap*, const char*); +#ifndef WITH_LEANER + int (*fprepareinit)(struct soap*); + int (*fpreparesend)(struct soap*, const char*, size_t); + int (*fpreparerecv)(struct soap*, const char*, size_t); + int (*fpreparefinal)(struct soap*); + void *(*fdimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fdimewriteopen)(struct soap*, const char*, const char*, const char*); + void (*fdimereadclose)(struct soap*, void*); + void (*fdimewriteclose)(struct soap*, void*); + size_t (*fdimeread)(struct soap*, void*, char*, size_t); + int (*fdimewrite)(struct soap*, void*, const char*, size_t); +#endif + int master; + int socket; +#if defined(__cplusplus) && !defined(WITH_LEAN) + std::ostream *os; + std::istream *is; +#else + void *os; /* preserve alignment */ + void *is; /* preserve alignment */ +#endif +#ifndef UNDER_CE + int sendfd; + int recvfd; +#else + FILE *sendfd; + FILE *recvfd; +#endif +#ifdef WIN32 + char errorstr[256]; /* buf for FormatMessage() */ +#endif + size_t bufidx; /* index in soap.buf[] */ + size_t buflen; /* length of soap.buf[] content */ + soap_wchar ahead; /* parser lookahead */ + short cdata; /* CDATA parser state */ + short body; /* parsed XML element has a body or not */ + unsigned int level; /* XML nesting level */ + size_t count; /* message length counter */ + size_t length; /* message length as set by HTTP header */ +#ifdef WITH_FAST + char *labbuf; /* look-aside buffer */ + size_t lablen; /* look-aside buffer allocated length */ + size_t labidx; /* look-aside buffer index to available part */ +#endif + char buf[SOAP_BUFLEN];/* send and receive buffer */ + char tmpbuf[1024]; /* in/output buffer for HTTP headers, simpleType values, attribute names, and DIME >=1024 bytes */ + char msgbuf[1024]; /* output buffer for (error) messages <=1024 bytes */ + char tag[SOAP_TAGLEN]; + char id[SOAP_TAGLEN]; + char href[SOAP_TAGLEN]; + char type[SOAP_TAGLEN]; + char arrayType[SOAP_TAGLEN]; + char arraySize[SOAP_TAGLEN]; + char arrayOffset[SOAP_TAGLEN]; + short other; + short position; + int positions[SOAP_MAXDIMS]; + short root; + struct soap_attribute *attributes; /* attribute list */ + short encoding; /* when set, output encodingStyle */ + short mustUnderstand; /* a mustUnderstand element was parsed or is output */ + short keep_alive; /* connection should be kept open */ + short null; /* parsed XML is xsi:nil */ + short ns; /* when not set, output full xmlns bindings */ + short part; /* parsing state */ + short alloced; + short peeked; + size_t chunksize; + size_t chunkbuflen; + char endpoint[SOAP_TAGLEN]; + char path[SOAP_TAGLEN]; + char host[SOAP_TAGLEN]; + char *action; + char *authrealm; /* HTTP authentication realm */ + char *prolog; /* XML declaration prolog */ + unsigned long ip; /* IP number */ + int port; /* port number */ + unsigned int max_keep_alive; + const char *proxy_host; /* Proxy Server host name */ + int proxy_port; /* Proxy Server port (default = 8080) */ + const char *proxy_userid; /* Proxy Authorization user name */ + const char *proxy_passwd; /* Proxy Authorization password */ + int status; /* -1 when request, else error code to be returned by server */ + int error; + int errmode; + int errnum; +#ifndef WITH_LEANER + struct soap_dom_element *dom; + struct soap_dime dime; + struct soap_mime mime; + struct soap_xlist *xlist; +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + const char *logfile[SOAP_MAXLOGS]; + FILE *fdebug[SOAP_MAXLOGS]; + struct soap_mlist *mht[SOAP_PTRHASH]; +#endif +#ifndef WITH_LEAN + const char *c14ninclude; + const char *c14nexclude; + struct soap_cookie *cookies; + const char *cookie_domain; + const char *cookie_path; + int cookie_max; +#endif +#ifndef WITH_NOIO +#ifdef WITH_IPV6 + struct sockaddr_storage peer; /* IPv6: set by soap_accept and by UDP recv */ +#else + struct sockaddr_in peer; /* IPv4: set by soap_connect/soap_accept and by UDP recv */ +#endif + size_t peerlen; +#endif +#ifdef WITH_OPENSSL + int (*fsslauth)(struct soap*); + int (*fsslverify)(int, X509_STORE_CTX*); + BIO *bio; + SSL *ssl; + SSL_CTX *ctx; + short require_server_auth; + short require_client_auth; + short rsa; /* when set, use RSA instead of DH */ + const char *keyfile; + const char *password; + const char *dhfile; + const char *cafile; + const char *capath; + const char *crlfile; + const char *randfile; + SSL_SESSION *session; + char session_host[SOAP_TAGLEN]; + int session_port; +#endif +#ifdef WITH_ZLIB + short zlib_state; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_INFLATE */ + short zlib_in; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + short zlib_out; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + z_stream d_stream; /* decompression stream */ + char z_buf[SOAP_BUFLEN]; /* buffer */ + size_t z_buflen; + unsigned short z_level; /* compression level to be used (0=none, 1=fast to 9=best) */ + uLong z_crc; /* internal gzip crc */ + float z_ratio_in; /* detected compression ratio compressed_length/length of inbound message */ + float z_ratio_out; /* detected compression ratio compressed_length/length of outbound message */ +#endif +/* WR[ */ +#ifdef WMW_RPM_IO + void *rpmreqid; +#endif /* WMW_RPM_IO */ +/* ]WR */ +}; + +struct soap_code_map +{ long code; + const char *string; +}; + +/* forwarding list */ +struct soap_flist +{ struct soap_flist *next; + int type; + void *ptr; + unsigned int level; + void (*fcopy)(struct soap*, int, int, void*, const void*, size_t); +}; + +/* id-ref forwarding list */ +struct soap_ilist +{ struct soap_ilist *next; + int type; + size_t size; + void *link; + void *copy; + struct soap_flist *flist; + void *ptr; + unsigned int level; + char id[1]; /* the actual id string value flows into the allocated region below this struct */ +}; + +struct soap_plugin +{ struct soap_plugin *next; + const char *id; + void *data; + int (*fcopy)(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src); + void (*fdelete)(struct soap *soap, struct soap_plugin *p); /* should delete fields of plugin only and not free(p) */ +}; + +#ifndef WITH_NONAMESPACES +extern SOAP_NMAC struct Namespace namespaces[]; +#endif + +#ifndef WITH_LEAN +# define soap_get0(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx]) +# define soap_get1(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx++]) +#else +soap_wchar soap_get0(struct soap*); +soap_wchar soap_get1(struct soap*); +#endif + +#define soap_revget1(soap) ((soap)->bufidx--) +#define soap_unget(soap, c) ((soap)->ahead = c) +#define soap_register_plugin(soap, plugin) soap_register_plugin_arg(soap, plugin, NULL) +#define soap_imode(soap, n) ((soap)->mode = (soap)->imode = (n)) +#define soap_set_imode(soap, n) ((soap)->imode |= (n)) +#define soap_clr_imode(soap, n) ((soap)->imode &= ~(n)) +#define soap_omode(soap, n) ((soap)->mode = (soap)->omode = (n)) +#define soap_set_omode(soap, n) ((soap)->omode |= (n)) +#define soap_clr_omode(soap, n) ((soap)->omode &= ~(n)) +#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n)) +#define soap_clr_mode(soap, n) ((soap)->imode &= ~(n), (soap)->omode &= ~(n)) +#define soap_destroy(soap) soap_delete((soap), NULL) + +#ifdef HAVE_STRRCHR +# define soap_strrchr(s, t) strrchr(s, t) +#else + SOAP_FMAC1 char* SOAP_FMAC2 soap_strrchr(const char *s, int t); +#endif + +#ifdef HAVE_STRTOL +# define soap_strtol(s, t, b) strtol(s, t, b) +#else + SOAP_FMAC1 long SOAP_FMAC2 soap_strtol(const char *s, char **t, int b); +#endif + +#ifdef HAVE_STRTOUL +# define soap_strtoul(s, t, b) strtoul(s, t, b) +#else + SOAP_FMAC1 unsigned long SOAP_FMAC2 soap_strtoul(const char *s, char **t, int b); +#endif + +#if defined(WITH_OPENSSL) +# define soap_random soap_rand() +SOAP_FMAC1 int SOAP_FMAC2 soap_rand(); +#elif defined(HAVE_RANDOM) +# define soap_random (int)random() +#else +# define soap_random rand() +#endif + +#ifdef WITH_NOIDREF +# define soap_embedded(s, p, t) (0) +# define soap_id_lookup(s, i, p, t, n, k) (p) +# define soap_id_forward(s, h, p, st, tt, n, k, fc) (p) +# define soap_reference(s, a, t) (1) +# define soap_array_reference(s, p, a, n, t) (1) +# define soap_embed(s, p, a, n, t, pp) (0) +# define soap_embedded_id(s, i, p, t) (i) +# define soap_is_embedded(s, p) (0) +# define soap_is_single(s, p) (1) +# define soap_lookup_type(s, i) (0) +# define soap_getindependent(s) (0) +# define soap_putindependent(s) (0) +# define soap_getelement(s, n) (n) +# define soap_putelement(s, p, t, i, n) (0) +# define soap_markelement(s, p, n) (0) +#endif + +SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultsubcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultstring(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultdetail(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializeheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getheader(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializefault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putfault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getfault(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_poll(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect_command(struct soap*, int, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_bind(struct soap*, const char*, int, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_accept(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_accept(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_server_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_client_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_puthttphdr(struct soap*, int status, size_t count); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_get_header_attribute(struct soap*, const char*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_key(char*, size_t, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_val(char*, size_t, const char*); + +SOAP_FMAC1 size_t SOAP_FMAC2 soap_hash(const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_endpoint(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_get(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getchar(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_tag_cmp(const char*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_sender_error(struct soap*, const char*, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_receiver_error(struct soap*, const char*, const char*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_raw(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send2(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send3(struct soap*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_pututf8(struct soap*, unsigned long); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getutf8(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_putbase64(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_getbase64(struct soap*, int*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_puthex(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_gethex(struct soap*, int*); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_xop_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_dime_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +#endif + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup_id(struct soap*, void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup(struct soap*, const void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_enter(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_pointer_lookup(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_lookup(struct soap*, const char*); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_enter(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_resolve(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_embedded(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_reference(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_reference(struct soap*, const void *p, const struct soap_array *a, int n, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_embedded_id(struct soap*, int id, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_embedded(struct soap*, struct soap_plist*); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_single(struct soap*, struct soap_plist*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_embedded(struct soap*, struct soap_plist*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_send(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_send(struct soap*); + +SOAP_FMAC1 const struct soap_code_map* SOAP_FMAC2 soap_code(const struct soap_code_map*, const char *str); +SOAP_FMAC1 long SOAP_FMAC2 soap_int_code(const struct soap_code_map*, const char *str, long other); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_str_code(const struct soap_code_map*, long code); + +SOAP_FMAC1 int SOAP_FMAC2 soap_getline(struct soap*, char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_recv(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_malloc(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_dealloc(struct soap*, void*); +SOAP_FMAC1 struct soap_clist * SOAP_FMAC2 soap_link(struct soap*, void*, int, int, void (*fdelete)(struct soap_clist*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_unlink(struct soap*, const void*); +SOAP_FMAC1 void SOAP_FMAC2 soap_free(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_track_malloc(struct soap*, const char*, int, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_track_free(struct soap*, const char*, int, void*); + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_lookup_type(struct soap*, const char *id); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_lookup(struct soap*, const char *id, void **p, int t, size_t n, unsigned int k); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_forward(struct soap*, const char *id, void *p, int st, int tt, size_t n, unsigned int k, void(*fcopy)(struct soap*, int, int, void*, const void*, size_t)); +#endif +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_enter(struct soap*, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_size(const int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getoffsets(const char *, const int *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsize(const char *, const char *, int *); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsizes(const char *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getposition(const char *, int *); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsize(struct soap*, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizesoffsets(struct soap*, const char *, const int *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizes(struct soap*, const char *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffset(struct soap*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffsets(struct soap*, const int *, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_closesock(struct soap*); + +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new(void); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new1(soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new2(soap_mode, soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy(struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy_context(struct soap*,struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init1(struct soap*, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_init2(struct soap*, soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_done(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_cleanup(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_begin(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_end(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_delete(struct soap*, void*); + +#ifdef SOAP_DEBUG +SOAP_FMAC1 void SOAP_FMAC2 soap_set_recv_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_sent_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_test_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_close_logfiles(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_open_logfile(struct soap*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_token(struct soap*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_value(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_tag(struct soap*, const char*, const char *); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_array(struct soap*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element(struct soap*, const char*, int, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_out(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_begin_out(struct soap*, const char *tag, int id, const char *type, const char *offset); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_ref(struct soap*, const char *tag, int id, int href); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_href(struct soap*, const char *tag, int id, const char *ref, const char *val); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_null(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_id(struct soap*, const char *tag, int id, const void *p, const struct soap_array *a, int d, const char *type, int n); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_result(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_out(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_start_end_out(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_attribute(struct soap*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_in(struct soap*, const char *tag, int nillable); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_in(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_peek_element(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_retry(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_revert(struct soap*); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_strdup(struct soap*, const char*); +SOAP_FMAC1 const char * SOAP_FMAC2 soap_strsearch(const char *big, const char *little); + +SOAP_FMAC1 int SOAP_FMAC2 soap_string_out(struct soap*, const char *s, int flag); +SOAP_FMAC1 char* SOAP_FMAC2 soap_string_in(struct soap*, int, long, long); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_wstring_out(struct soap*, const wchar_t *s, int flag); +SOAP_FMAC1 wchar_t* SOAP_FMAC2 soap_wstring_in(struct soap*, int, long, long); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_namespace(struct soap*, const char *, const char*, int n1, int n2); + +SOAP_FMAC1 int SOAP_FMAC2 soap_set_namespaces(struct soap*, struct Namespace*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_local_namespaces(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_namespace(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_push_namespace(struct soap*, const char *,const char *); + +SOAP_FMAC1 int SOAP_FMAC2 soap_store_lab(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_append_lab(struct soap*, const char*, size_t); + +SOAP_FMAC1 int SOAP_FMAC2 soap_new_block(struct soap*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_push_block(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_size_block(struct soap*, size_t); +SOAP_FMAC1 char* SOAP_FMAC2 soap_first_block(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_next_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_block_size(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_save_block(struct soap*, char*, int); +SOAP_FMAC1 void SOAP_FMAC2 soap_end_block(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_out(struct soap*); +SOAP_FMAC1 int soap_envelope_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_out(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_header(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_response(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_empty_response(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_empty_response(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*); + +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault(struct soap*, FILE*); +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault_location(struct soap*, FILE*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_s2byte(struct soap*, const char*, char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2short(struct soap*, const char*, short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2int(struct soap*, const char*, int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2long(struct soap*, const char*, long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2LONG64(struct soap*, const char*, LONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2float(struct soap*, const char*, float*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2double(struct soap*, const char*, double*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedByte(struct soap*, const char*, unsigned char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedShort(struct soap*, const char*, unsigned short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedInt(struct soap*, const char*, unsigned int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedLong(struct soap*, const char*, unsigned long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2ULONG64(struct soap*, const char*, ULONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2string(struct soap*, const char*, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2QName(struct soap*, const char*, char**); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_s2dateTime(struct soap*, const char*, time_t*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2base64(struct soap*, const unsigned char*, char*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2hex(struct soap*, const unsigned char*, char*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_byte2s(struct soap*, char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_short2s(struct soap*, short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_int2s(struct soap*, int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_long2s(struct soap*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_LONG642s(struct soap*, LONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_float2s(struct soap*, float); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_double2s(struct soap*, double); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedByte2s(struct soap*, unsigned char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedShort2s(struct soap*, unsigned short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedInt2s(struct soap*, unsigned int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedLong2s(struct soap*, unsigned long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_ULONG642s(struct soap*, ULONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_QName2s(struct soap*, const char*); + +#ifndef WITH_LEAN +SOAP_FMAC1 const char* SOAP_FMAC2 soap_dateTime2s(struct soap*, time_t); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_base642s(struct soap*, const char*, char*, size_t, int*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_hex2s(struct soap*, const char*, char*, size_t, int*); +#endif + + +SOAP_FMAC1 int* SOAP_FMAC2 soap_inint(struct soap*, const char *tag, int *p, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_inbyte(struct soap*, const char *tag, char *p, const char *, int); +SOAP_FMAC1 long* SOAP_FMAC2 soap_inlong(struct soap*, const char *tag, long *p, const char *, int); +SOAP_FMAC1 LONG64* SOAP_FMAC2 soap_inLONG64(struct soap*, const char *tag, LONG64 *p, const char *, int); +SOAP_FMAC1 short* SOAP_FMAC2 soap_inshort(struct soap*, const char *tag, short *p, const char *, int); +SOAP_FMAC1 float* SOAP_FMAC2 soap_infloat(struct soap*, const char *tag, float *p, const char *, int); +SOAP_FMAC1 double* SOAP_FMAC2 soap_indouble(struct soap*, const char *tag, double *p, const char *, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_inunsignedByte(struct soap*, const char *tag, unsigned char *p, const char *, int); +SOAP_FMAC1 unsigned short* SOAP_FMAC2 soap_inunsignedShort(struct soap*, const char *tag, unsigned short *p, const char *, int); +SOAP_FMAC1 unsigned int* SOAP_FMAC2 soap_inunsignedInt(struct soap*, const char *tag, unsigned int *p, const char *, int); +SOAP_FMAC1 unsigned long* SOAP_FMAC2 soap_inunsignedLong(struct soap*, const char *tag, unsigned long *p, const char *, int); +SOAP_FMAC1 ULONG64* SOAP_FMAC2 soap_inULONG64(struct soap*, const char *tag, ULONG64 *p, const char *, int); +SOAP_FMAC1 char** SOAP_FMAC2 soap_instring(struct soap*, const char *tag, char **p, const char *, int, int, long, long); +SOAP_FMAC1 char** SOAP_FMAC2 soap_inliteral(struct soap*, const char *tag, char **p); + +#ifndef WITH_LEAN +SOAP_FMAC1 time_t* SOAP_FMAC2 soap_indateTime(struct soap*, const char *tag, time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwstring(struct soap*, const char *tag, wchar_t **p, const char *, int, long, long); +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwliteral(struct soap*, const char *tag, wchar_t **p); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_outbyte(struct soap*, const char *tag, int id, const char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outshort(struct soap*, const char *tag, int id, const short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outint(struct soap*, const char *tag, int id, const int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outlong(struct soap*, const char *tag, int id, const long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outLONG64(struct soap*, const char *tag, int id, const LONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outfloat(struct soap*, const char *tag, int id, const float *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outdouble(struct soap*, const char *tag, int id, const double *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedByte(struct soap*, const char *tag, int id, const unsigned char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedShort(struct soap*, const char *tag, int id, const unsigned short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedInt(struct soap*, const char *tag, int id, const unsigned int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedLong(struct soap*, const char *tag, int id, const unsigned long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outULONG64(struct soap*, const char *tag, int id, const ULONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outstring(struct soap*, const char *tag, int id, char *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outliteral(struct soap*, const char *tag, char *const*p); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_outdateTime(struct soap*, const char *tag, int id, const time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_outwstring(struct soap*, const char *tag, int id, wchar_t *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outwliteral(struct soap*, const char *tag, wchar_t *const*p); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_attachment(struct soap *, const char*, int, const void*, const struct soap_array*, const char*, const char*, const char*, int, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_move(struct soap*, long); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_tell(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_dime_option(struct soap*, unsigned short, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmimehdr(struct soap*, struct soap_multipart*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_mime(struct soap*, const char *boundary, const char *start); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_mime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_dime_attachment(struct soap*, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_mime_attachment(struct soap*, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description); +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_register_plugin_arg(struct soap*, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_lookup_plugin(struct soap*, const char*); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_attr_value(struct soap *soap, const char *name, int flag); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_attr(struct soap *soap, const char *name, const char *value); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_attr(struct soap *soap); + +#ifdef WITH_COOKIES +SOAP_FMAC1 size_t SOAP_FMAC2 soap_encode_cookie(const char*, char*, size_t); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_set_cookie(struct soap*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_env_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern long SOAP_FMAC2 soap_cookie_expire(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_expire(struct soap*, const char*, long, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_clr_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_clr_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_getenv_cookies(struct soap*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_copy_cookies(struct soap*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_free_cookies(struct soap*); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c new file mode 100644 index 0000000..959147e --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c @@ -0,0 +1,14172 @@ +/* + +stdsoap2.c[pp] 2.7.9b + +gSOAP runtime + +gSOAP XML Web services tools +Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under one of the following licenses: +GPL, the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems Inc., for the following additions under gSOAP public license: + - vxWorks compatible (#define VXWORKS) +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- + +Installation note: + +Win32 build needs winsock.dll (Visual C++ "wsock32.lib") +To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link" +tab (the project file needs to be selected in the file view) and add +"wsock32.lib" to the "Object/library modules" entry + +On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with +-fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack +when locally allocated data exceeds 64K. + +*/ + +#ifdef AS400 +# pragma convert(819) /* EBCDIC to ASCII */ +#endif + +#include "stdsoap2.h" + +#ifdef WIN32 +# pragma comment(lib, "wsock32.lib") +#endif + +#ifdef __cplusplus +SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.9b 2007-01-01 12:00:00 GMT") +extern "C" { +#else +SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.9 2007-01-01 12:00:00 GMT") +#endif + +/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */ +#ifndef SOAP_UNKNOWN_CHAR +#define SOAP_UNKNOWN_CHAR (127) +#endif + +/* EOF=-1 */ +#define SOAP_LT (soap_wchar)(-2) /* XML character '<' */ +#define SOAP_TT (soap_wchar)(-3) /* XML character '' */ +#define SOAP_QT (soap_wchar)(-5) /* XML character '"' */ +#define SOAP_AP (soap_wchar)(-6) /* XML character ''' */ + +#define soap_blank(c) ((c) >= 0 && (c) <= 32) +#define soap_notblank(c) ((c) > 32) + +#define soap_hash_ptr(p) ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1))) + +#ifdef SOAP_DEBUG +static void soap_init_logs(struct soap*); +static void soap_close_logfile(struct soap*, int); +static void soap_set_logfile(struct soap*, int, const char*); +#endif + +#ifdef SOAP_MEM_DEBUG +static void soap_init_mht(struct soap*); +static void soap_free_mht(struct soap*); +static void soap_track_unlink(struct soap*, const void*); +#endif + +#ifndef PALM_2 +static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int); +static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*); +static int soap_getattrval(struct soap*, char*, size_t, soap_wchar); +#endif + +#ifndef PALM_1 +static soap_wchar soap_char(struct soap*); +static soap_wchar soap_get_pi(struct soap*); +static int soap_isxdigit(int); +static void *fplugin(struct soap*, const char*); +#ifndef WITH_NOIDREF +static void soap_update_ptrs(struct soap*, char*, char*, char*, char*); +static int soap_has_copies(struct soap*, const char*, const char*); +static void soap_init_iht(struct soap*); +static void soap_free_iht(struct soap*); +static void soap_init_pht(struct soap*); +static void soap_free_pht(struct soap*); +#endif +#endif + +#ifndef WITH_LEAN +static const char *soap_set_validation_fault(struct soap*, const char*, const char*); +static int soap_isnumeric(struct soap*, const char*); +static time_t soap_timegm(struct tm*); +static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized); +static void soap_pop_ns(struct soap *soap); +static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n); +#endif + +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t); +static int soap_putdimefield(struct soap*, const char*, size_t); +static char *soap_getdimefield(struct soap*, size_t); +static void soap_select_mime_boundary(struct soap*); +static int soap_valid_mime_boundary(struct soap*); +static void soap_resolve_attachment(struct soap*, struct soap_multipart*); +#endif +#endif + +#ifdef WITH_GZIP +static int soap_getgziphdr(struct soap*); +#endif + +#ifdef WITH_OPENSSL +static int ssl_init_done = 0; +static int ssl_auth_init(struct soap*); +static int ssl_verify_callback(int, X509_STORE_CTX*); +static int ssl_password(char*, int, int, void *); +/* This callback is included for future references. It should not be deleted +static DH *ssl_tmp_dh(SSL*, int, int); +*/ +#endif + +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char *soap_decode(char*, size_t, const char*, const char*); +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar soap_getchunkchar(struct soap*); +static const char *http_error(struct soap*, int); +static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t); +static int http_get(struct soap*); +static int http_send_header(struct soap*, const char*); +static int http_post_header(struct soap*, const char*, const char*); +static int http_response(struct soap*, int, size_t); +static int http_parse(struct soap*); +static int http_parse_header(struct soap*, const char*, const char*); +#endif +#endif + +#ifndef WITH_NOIO +#ifndef PALM_1 +static int fsend(struct soap*, const char*, size_t); +static size_t frecv(struct soap*, char*, size_t); +static int tcp_init(struct soap*); +static const char *tcp_error(struct soap*); +#ifndef WITH_LEAN +static size_t frecv_stop(struct soap*, char*, size_t); +#endif +#ifndef WITH_IPV6 +static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr); +#endif +static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port); +static int tcp_accept(struct soap*, int, struct sockaddr*, int*); +static int tcp_disconnect(struct soap*); +static int tcp_closesocket(struct soap*, SOAP_SOCKET); +static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int); +static const char *soap_strerror(struct soap*); +#endif +#endif + +#if defined(PALM) && !defined(PALM_2) +unsigned short errno; +#endif + +#ifndef PALM_1 +static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/"; +static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/"; +static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope"; +static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding"; +static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc"; +#endif + +#ifndef PALM_1 +const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF}; +static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63"; +#endif + +#ifndef WITH_LEAN +static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t"; +/* Alternative indentation form for SOAP_XML_INDENT: +static const char soap_indent[21] = "\n "; +*/ +#endif + +#ifndef SOAP_CANARY +# define SOAP_CANARY (0xC0DE) +#endif + +static const char soap_padding[4] = "\0\0\0"; +#define SOAP_STR_PADDING (soap_padding) +#define SOAP_STR_EOS (soap_padding) +#define SOAP_NON_NULL (soap_padding) + +#ifndef WITH_LEAN +static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */ +{ { 160, "nbsp" }, + { 161, "iexcl" }, + { 162, "cent" }, + { 163, "pound" }, + { 164, "curren" }, + { 165, "yen" }, + { 166, "brvbar" }, + { 167, "sect" }, + { 168, "uml" }, + { 169, "copy" }, + { 170, "ordf" }, + { 171, "laquo" }, + { 172, "not" }, + { 173, "shy" }, + { 174, "reg" }, + { 175, "macr" }, + { 176, "deg" }, + { 177, "plusmn" }, + { 178, "sup2" }, + { 179, "sup3" }, + { 180, "acute" }, + { 181, "micro" }, + { 182, "para" }, + { 183, "middot" }, + { 184, "cedil" }, + { 185, "sup1" }, + { 186, "ordm" }, + { 187, "raquo" }, + { 188, "frac14" }, + { 189, "frac12" }, + { 190, "frac34" }, + { 191, "iquest" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acirc" }, + { 195, "Atilde" }, + { 196, "Auml" }, + { 197, "Aring" }, + { 198, "AElig" }, + { 199, "Ccedil" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecirc" }, + { 203, "Euml" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icirc" }, + { 207, "Iuml" }, + { 208, "ETH" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocirc" }, + { 213, "Otilde" }, + { 214, "Ouml" }, + { 215, "times" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucirc" }, + { 220, "Uuml" }, + { 221, "Yacute" }, + { 222, "THORN" }, + { 223, "szlig" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acirc" }, + { 227, "atilde" }, + { 228, "auml" }, + { 229, "aring" }, + { 230, "aelig" }, + { 231, "ccedil" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecirc" }, + { 235, "euml" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icirc" }, + { 239, "iuml" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocirc" }, + { 245, "otilde" }, + { 246, "ouml" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucirc" }, + { 252, "uuml" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "yuml" }, + { 0, NULL } +}; +#endif + +#ifndef WITH_NOIO +#ifndef WITH_LEAN +static const struct soap_code_map h_error_codes[] = +{ +#ifdef HOST_NOT_FOUND + { HOST_NOT_FOUND, "Host not found" }, +#endif +#ifdef TRY_AGAIN + { TRY_AGAIN, "Try Again" }, +#endif +#ifdef NO_RECOVERY + { NO_RECOVERY, "No Recovery" }, +#endif +#ifdef NO_DATA + { NO_DATA, "No Data" }, +#endif +#ifdef NO_ADDRESS + { NO_ADDRESS, "No Address" }, +#endif + { 0, NULL } +}; +#endif +#endif + +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN +static const struct soap_code_map h_http_error_codes[] = +{ { 200, "OK" }, + { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Time-out" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Large" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested range not satisfiable" }, + { 417, "Expectation Failed" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Time-out" }, + { 505, "HTTP Version not supported" }, + { 0, NULL } +}; +#endif +#endif + +#ifdef WITH_OPENSSL +static const struct soap_code_map h_ssl_error_codes[] = +{ +#define _SSL_ERROR(e) { e, #e } + _SSL_ERROR(SSL_ERROR_SSL), + _SSL_ERROR(SSL_ERROR_ZERO_RETURN), + _SSL_ERROR(SSL_ERROR_WANT_READ), + _SSL_ERROR(SSL_ERROR_WANT_WRITE), + _SSL_ERROR(SSL_ERROR_WANT_CONNECT), + _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP), + _SSL_ERROR(SSL_ERROR_SYSCALL), + { 0, NULL } +}; +#endif + +#ifndef WITH_LEANER +static const struct soap_code_map mime_codes[] = +{ { SOAP_MIME_7BIT, "7bit" }, + { SOAP_MIME_8BIT, "8bit" }, + { SOAP_MIME_BINARY, "binary" }, + { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" }, + { SOAP_MIME_BASE64, "base64" }, + { SOAP_MIME_IETF_TOKEN, "ietf-token" }, + { SOAP_MIME_X_TOKEN, "x-token" }, + { 0, NULL } +}; +#endif + +#ifdef WIN32 +static int tcp_done = 0; +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +fsend(struct soap *soap, const char *s, size_t n) +{ register int nwritten, err; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->os) + { soap->os->write(s, n); + if (soap->os->good()) + return SOAP_OK; + return SOAP_EOF; + } +#endif + while (n) + { if (soap_valid_socket(soap->socket)) + { +#ifndef WITH_LEAN + if (soap->send_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->send_timeout > 0) + { timeout.tv_sec = soap->send_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->send_timeout/1000000; + timeout.tv_usec = -soap->send_timeout%1000000; + } +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */ +#endif + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + return SOAP_EOF; + } + err = soap_socket_errno(soap->socket); + if (err != SOAP_EINTR && err != SOAP_EAGAIN) + { soap->errnum = err; + return SOAP_EOF; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + nwritten = SSL_write(soap->ssl, s, n); + else if (soap->bio) + nwritten = BIO_write(soap->bio, s, n); + else +#endif +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + { if (soap->peerlen) + nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); + else + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + /* retry and back-off algorithm */ + /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */ + if (nwritten < 0) + { struct timeval timeout; + fd_set fd; + int udp_repeat; + int udp_delay; +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */ +#endif + if ((soap->connect_flags & SO_BROADCAST)) + udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */ + else + udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */ + udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */ + do + { timeout.tv_sec = 0; + timeout.tv_usec = 1000 * udp_delay; /* ms */ + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + select((SOAP_SOCKET)(soap->socket + 1), NULL, NULL, &fd, &timeout); + if (soap->peerlen) + nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen); + else + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); + udp_delay <<= 1; + if (udp_delay > 500) /* UDP_UPPER_DELAY */ + udp_delay = 500; + } + while (nwritten < 0 && --udp_repeat > 0); + } + } + else +#endif +#if !defined(PALM) && !defined(AS400) + nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); +#else + nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags); +#endif + if (nwritten <= 0) + { +#ifdef WITH_OPENSSL + int err; + if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return SOAP_EOF; +#endif + err = soap_socket_errno(soap->socket); + if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN) + { soap->errnum = err; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + else + { +#ifdef WITH_FASTCGI + nwritten = fwrite((void*)s, 1, n, stdout); + fflush(stdout); +#else +#ifdef UNDER_CE + nwritten = fwrite(s, 1, n, soap->sendfd); +#else +#ifdef VXWORKS +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1; + else +#endif + nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w")); +#else + nwritten = write((SOAP_SOCKET)soap->sendfd, s, n); +#endif +#endif +#endif + if (nwritten <= 0) + { err = soap_errno; + if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN) + { soap->errnum = err; + return SOAP_EOF; + } + nwritten = 0; /* and call write() again */ + } + } + n -= nwritten; + s += nwritten; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_raw(struct soap *soap, const char *s, size_t n) +{ if (!n) + return SOAP_OK; + if (soap->mode & SOAP_IO_LENGTH) + { soap->count += n; +#ifndef WITH_LEANER + if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } + if (soap->mode & SOAP_IO) + { register size_t i = SOAP_BUFLEN - soap->bufidx; + while (n >= i) + { memcpy(soap->buf + soap->bufidx, s, i); + soap->bufidx = SOAP_BUFLEN; + if (soap_flush(soap)) + return soap->error; + s += i; + n -= i; + i = SOAP_BUFLEN; + } + memcpy(soap->buf + soap->bufidx, s, n); + soap->bufidx += n; + return SOAP_OK; + } + return soap_flush_raw(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush(struct soap *soap) +{ register int n = soap->bufidx; + if (n) + { soap->bufidx = 0; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->d_stream.next_in = (Byte*)soap->buf; + soap->d_stream.avail_in = (unsigned int)n; +#ifdef WITH_GZIP + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n); +#endif + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in)); + if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } + if (!soap->d_stream.avail_out) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN)) + return soap->error; + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (soap->d_stream.avail_in); + } + else +#endif + return soap_flush_raw(soap, soap->buf, n); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_flush_raw(struct soap *soap, const char *s, size_t n) +{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { register char *t; + if (!(t = (char*)soap_push_block(soap, n))) + return soap->error = SOAP_EOM; + memcpy(t, s, n); +#ifndef WITH_LEANER + if (soap->fpreparesend) + return soap->error = soap->fpreparesend(soap, s, n); +#endif + return SOAP_OK; + } +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { char t[16]; + sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n); + DBGMSG(SENT, t, strlen(t)); + if ((soap->error = soap->fsend(soap, t, strlen(t)))) + return soap->error; + soap->chunksize += n; + } + DBGMSG(SENT, s, n); +#endif + return soap->error = soap->fsend(soap, s, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send(struct soap *soap, const char *s) +{ if (s) + return soap_send_raw(soap, s, strlen(s)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send2(struct soap *soap, const char *s1, const char *s2) +{ if (soap_send(soap, s1)) + return soap->error; + return soap_send(soap, s2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3) +{ if (soap_send(soap, s1) + || soap_send(soap, s2)) + return soap->error; + return soap_send(soap, s3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static size_t +frecv(struct soap *soap, char *s, size_t n) +{ register int r; +#ifdef PALM + register int timeouts = 0; +#endif + soap->errnum = 0; +#if defined(__cplusplus) && !defined(WITH_LEAN) + if (soap->is) + { if (soap->is->good()) + return soap->is->read(s, n).gcount(); + return 0; + } +#endif + if (soap_valid_socket(soap->socket)) + { for (;;) + { +#ifndef WITH_LEAN + if (soap->recv_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->recv_timeout > 0) + { timeout.tv_sec = soap->recv_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->recv_timeout/1000000; + timeout.tv_usec = -soap->recv_timeout%1000000; + } +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + { soap->error = SOAP_FD_EXCEEDED; + return 0; /* Hint: MUST increase FD_SETSIZE */ + } +#endif + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + for (;;) + { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + return 0; + } + r = soap_socket_errno(soap->socket); + if (r != SOAP_EINTR && r != SOAP_EAGAIN) + { soap->errnum = r; + return 0; + } + } + } +#endif +#ifdef WITH_OPENSSL + if (soap->ssl) + { int err; + r = SSL_read(soap->ssl, s, n); + if (r > 0) + return (size_t)r; + err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + return 0; + } + else if (soap->bio) + { r = BIO_read(soap->bio, s, n); + if (r > 0) + return (size_t)r; + return 0; + } + else +#endif + { +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + r = recvfrom((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + soap->peerlen = (size_t)k; +#ifndef WITH_IPV6 + soap->ip = ntohl(soap->peer.sin_addr.s_addr); +#endif + } + else +#endif + r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags); +#ifdef PALM + /* CycleSyncDisplay(curStatusMsg); */ +#endif + if (r >= 0) + return (size_t)r; + r = soap_socket_errno(soap->socket); + if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK) + { soap->errnum = r; + return 0; + } + } +#ifndef WITH_LEAN + { struct timeval timeout; + fd_set fd; + timeout.tv_sec = 0; + timeout.tv_usec = 10000; +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + { soap->error = SOAP_FD_EXCEEDED; + return 0; /* Hint: MUST increase FD_SETSIZE */ + } +#endif + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); +#ifdef WITH_OPENSSL + if (soap->ssl && SSL_get_error(soap->ssl, r) == SSL_ERROR_WANT_WRITE) + r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout); + else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#else + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); +#endif + if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR) + { soap->errnum = r; + return 0; + } + } +#endif +#ifdef PALM + if (r < 0 && (r = soap_socket_errno(soap->socket)) == SOAP_EINTR) + { timeouts++; + if (timeouts > 10) + { soap->errnum = r; + return 0; + } + } +#endif + } + } +#ifdef WITH_FASTCGI + return fread(s, 1, n, stdin); +#else +#ifdef UNDER_CE + return fread(s, 1, n, soap->recvfd); +#else +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + r = httpBlockRead(soap->rpmreqid, s, n); + else +#endif + r = read((SOAP_SOCKET)soap->recvfd, s, n); + if (r >= 0) + return (size_t)r; + soap->errnum = soap_errno; + return 0; +#endif +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef WITH_NOIO +#ifndef PALM_1 +static size_t +frecv_stop(struct soap *soap, char *s, size_t n) +{ return 0; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static soap_wchar +soap_getchunkchar(struct soap *soap) +{ if (soap->bufidx < soap->buflen) + return soap->buf[soap->bufidx++]; + soap->bufidx = 0; + soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket)); + DBGMSG(RECV, soap->buf, soap->buflen); + if (soap->buflen) + return soap->buf[soap->bufidx++]; + return EOF; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +soap_isxdigit(int c) +{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_raw(struct soap *soap) +{ register size_t ret; +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { if (soap->d_stream.next_out == Z_NULL) + return EOF; + if (soap->d_stream.avail_in || !soap->d_stream.avail_out) + { register int r; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n")); + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + ret = soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)ret); + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + if (ret) + { soap->count += ret; + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n")); + DBGMSG(RECV, soap->buf, ret); + return SOAP_OK; + } + } + else if (r != Z_BUF_ERROR) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +zlib_again: + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize) + { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->buflen = soap->z_buflen; + } + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- compressed ----\n")); + } +#endif +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */ + { +chunk_again: + if (soap->chunksize) + { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + soap->chunksize -= ret; + } + else + { register soap_wchar c; + char *t, tmp[8]; + t = tmp; + if (!soap->chunkbuflen) + { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + soap->bufidx = 0; + if (!ret) + return soap->ahead = EOF; + } + else + soap->bufidx = soap->buflen; + soap->buflen = soap->chunkbuflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen)); + while (!soap_isxdigit((int)(c = soap_getchunkchar(soap)))) + { if ((int)c == EOF) + return soap->ahead = EOF; + } + do + *t++ = (char)c; + while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + if ((int)c == EOF) + return soap->ahead = EOF; + *t = '\0'; + soap->chunksize = soap_strtoul(tmp, &t, 16); + if (!soap->chunksize) + { soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n")); + while ((int)c != EOF && c != '\n') + c = soap_getchunkchar(soap); + return soap->ahead = EOF; + } + soap->buflen = soap->bufidx + soap->chunksize; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp)); + if (soap->buflen > soap->chunkbuflen) + { soap->buflen = soap->chunkbuflen; + soap->chunksize -= soap->buflen - soap->bufidx; + soap->chunkbuflen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx))); + } + else if (soap->chunkbuflen) + soap->chunksize = 0; + ret = soap->buflen - soap->bufidx; + if (!ret) + goto chunk_again; + } + } + else +#endif + { soap->bufidx = 0; + soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket)); + DBGMSG(RECV, soap->buf, ret); + } +#ifndef WITH_LEANER + if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret))) + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { register int r; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = (unsigned int)ret; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + r = inflate(&soap->d_stream, Z_NO_FLUSH); + if (r == Z_OK || r == Z_STREAM_END) + { soap->bufidx = 0; + soap->z_buflen = soap->buflen; + soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out; + if (soap->zlib_in == SOAP_ZLIB_GZIP) + soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret)); + if (!ret) + goto zlib_again; + if (r == Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out; + soap->d_stream.next_out = Z_NULL; + } + DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n")); + DBGMSG(RECV, soap->buf, ret); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:"")); + soap->d_stream.next_out = Z_NULL; + soap->error = SOAP_ZLIB_ERROR; + return EOF; + } + } +#endif + soap->count += ret; + return !ret; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_DIME) + { if (soap->dime.buflen) + { char *s; + int i; + unsigned char tmp[12]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n")); + soap->count += soap->dime.buflen - soap->buflen; + soap->buflen = soap->dime.buflen; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3)); + for (i = -(long)soap->dime.size&3; i > 0; i--) + { soap->bufidx++; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n")); + s = (char*)tmp; + for (i = 12; i > 0; i--) + { *s++ = soap->buf[soap->bufidx++]; + if (soap->bufidx >= soap->buflen) + if (soap_recv_raw(soap)) + return EOF; + } + soap->dime.flags = tmp[0] & 0x7; + soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size)); + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.size) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n")); + soap->dime.buflen = 0; + soap->dime.chunksize = 0; + } + soap->count = soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count)); + return SOAP_OK; + } + if (soap->dime.chunksize) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize)); + if (soap_recv_raw(soap)) + return EOF; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count)); + return SOAP_OK; + } + } +#endif + return soap_recv_raw(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getchar(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if (c != EOF) + soap->ahead = 0; + return c; + } + return soap_get1(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const struct soap_code_map* +SOAP_FMAC2 +soap_code(const struct soap_code_map *code_map, const char *str) +{ if (code_map && str) + { while (code_map->string) + { if (!strcmp(str, code_map->string)) /* case sensitive */ + return code_map; + code_map++; + } + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_code_int(const struct soap_code_map *code_map, const char *str, long other) +{ if (code_map) + { while (code_map->string) + { if (!soap_tag_cmp(str, code_map->string)) /* case insensitive */ + return code_map->code; + code_map++; + } + } + return other; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_code_str(const struct soap_code_map *code_map, long code) +{ if (!code_map) + return NULL; + while (code_map->code != code && code_map->string) + code_map++; + return code_map->string; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_code_bits(const struct soap_code_map *code_map, const char *str) +{ register long bits = 0; + if (code_map) + { while (str && *str) + { const struct soap_code_map *p; + for (p = code_map; p->string; p++) + { register size_t n = strlen(p->string); + if (!strncmp(p->string, str, n) && soap_blank(str[n])) + { bits |= p->code; + str += n; + while (*str > 0 && *str <= 32) + str++; + break; + } + } + if (!p->string) + return 0; + } + } + return bits; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code) +{ register char *t = soap->tmpbuf; + if (code_map) + { while (code_map->string) + { if (code_map->code & code) + { register const char *s = code_map->string; + if (t != soap->tmpbuf) + *t++ = ' '; + while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1) + *t++ = *s++; + if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1) + break; + } + code_map++; + } + } + *t = '\0'; + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_char(struct soap *soap) +{ char tmp[8]; + register int i; + register soap_wchar c; + register char *s = tmp; + for (i = 0; i < 7; i++) + { c = soap_get1(soap); + if (c == ';' || (int)c == EOF) + break; + *s++ = (char)c; + } + *s = '\0'; + if (*tmp == '#') + { if (tmp[1] == 'x' || tmp[1] == 'X') + return soap_strtol(tmp + 2, NULL, 16); + return atol(tmp + 1); + } + if (!strcmp(tmp, "lt")) + return '<'; + if (!strcmp(tmp, "gt")) + return '>'; + if (!strcmp(tmp, "amp")) + return '&'; + if (!strcmp(tmp, "quot")) + return '"'; + if (!strcmp(tmp, "apos")) + return '\''; +#ifndef WITH_LEAN + return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR); +#else + return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */ +#endif +} +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +#ifndef PALM_1 +soap_wchar +soap_get0(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx]; +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_LEAN +#ifndef PALM_1 +soap_wchar +soap_get1(struct soap *soap) +{ if (soap->bufidx >= soap->buflen && soap_recv(soap)) + return EOF; + return (unsigned char)soap->buf[soap->bufidx++]; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_get(struct soap *soap) +{ register soap_wchar c; + c = soap->ahead; + if (c) + { if ((int)c != EOF) + soap->ahead = 0; + } + else + c = soap_get1(soap); + while ((int)c != EOF) + { if (soap->cdata) + { if (c == ']') + { c = soap_get1(soap); + if (c == ']') + { c = soap_get0(soap); + if (c == '>') + { soap->cdata = 0; + soap_get1(soap); + c = soap_get1(soap); + } + else + { soap_unget(soap, ']'); + return ']'; + } + } + else + { soap_revget1(soap); + return ']'; + } + } + else + return c; + } + switch (c) + { case '<': + do c = soap_get1(soap); + while (soap_blank(c)); + if (c == '!' || c == '?' || c == '%') + { register int k = 1; + if (c == '!') + { c = soap_get1(soap); + if (c == '[') + { do c = soap_get1(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + break; + soap->cdata = 1; + c = soap_get1(soap); + continue; + } + if (c == '-' && (c = soap_get1(soap)) == '-') + { do + { c = soap_get1(soap); + if (c == '-' && (c = soap_get1(soap)) == '-') + break; + } while ((int)c != EOF); + } + } + else if (c == '?') + c = soap_get_pi(soap); + while ((int)c != EOF) + { if (c == '<') + k++; + else if (c == '>') + { if (--k <= 0) + break; + } + c = soap_get1(soap); + } + if ((int)c == EOF) + break; + c = soap_get1(soap); + continue; + } + if (c == '/') + return SOAP_TT; + soap_revget1(soap); + return SOAP_LT; + case '>': + return SOAP_GT; + case '"': + return SOAP_QT; + case '\'': + return SOAP_AP; + case '&': + return soap_char(soap) | 0x80000000; + } + break; + } + return c; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static soap_wchar +soap_get_pi(struct soap *soap) +{ char buf[64]; + register char *s = buf; + register int i = sizeof(buf); + register soap_wchar c = soap_getchar(soap); + /* This is a quick way to parse XML PI and we could use a callback instead to + * enable applications to intercept processing instructions */ + while ((int)c != EOF && c != '?') + { if (--i > 0) + { if (soap_blank(c)) + c = ' '; + *s++ = (char)c; + } + c = soap_getchar(soap); + } + *s = '\0'; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI \n", buf)); + if (!strncmp(buf, "xml ", 4)) + { s = strstr(buf, " encoding="); + if (s && s[10]) + { if (!soap_tag_cmp(s + 11, "iso-8859-1*") + || !soap_tag_cmp(s + 11, "latin1*")) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n")); + soap->mode |= SOAP_ENC_LATIN; + } + else if (!soap_tag_cmp(s + 11, "utf-8*")) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n")); + soap->mode &= ~SOAP_ENC_LATIN; + } + } + } + if ((int)c != EOF) + c = soap_getchar(soap); + return c; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_move(struct soap *soap, long n) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n)); + for (; n > 0; n--) + if ((int)soap_getchar(soap) == EOF) + return SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_tell(struct soap *soap) +{ return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pututf8(struct soap *soap, register unsigned long c) +{ char tmp[16]; + if (c < 0x80 && c >= 0x20) + { *tmp = (char)c; + return soap_send_raw(soap, tmp, 1); + } +#ifndef WITH_LEAN + if (c >= 0x80 && (soap->mode & SOAP_XML_CANONICAL)) + { register char *t = tmp; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + *t = '\0'; + } + else +#endif + sprintf(tmp, "&#%lu;", c); + return soap_send(soap, tmp); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +soap_wchar +SOAP_FMAC2 +soap_getutf8(struct soap *soap) +{ register soap_wchar c, c1, c2, c3, c4; + c = soap->ahead; + if (c > 0xFF) + { soap->ahead = 0; + return c; + } +again: + c = soap_get(soap); + if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN)) + return c; + c1 = soap_get1(soap); + if (c1 < 0x80) + { soap_revget1(soap); /* doesn't look like this is UTF8 */ + return c; + } + c1 &= 0x3F; + if (c < 0xE0) + return ((soap_wchar)(c & 0x1F) << 6) | c1; + c2 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c == 0xEF && c1 == 0x3B && c2 == 0x3F) /* ignore UTF-8 BOM */ + goto again; + if (c < 0xF0) + return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2; + c3 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xF8) + return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3; + c4 = (soap_wchar)soap_get1(soap) & 0x3F; + if (c < 0xFC) + return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; + return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthex(struct soap *soap, const unsigned char *s, int n) +{ char d[2]; + register int i; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (i = 0; i < n; i++) + { register int m = *s++; + d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0')); + m &= 0x0F; + d[1] = (char)(m + (m > 9 ? '7' : '0')); + if (soap_send_raw(soap, d, 2)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_gethex(struct soap *soap, int *n) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register char *s; + register int i, k; + if (soap_append_lab(soap, NULL, 0)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + for (i = 0; i < k; i++) + { register char d1, d2; + register soap_wchar c; + c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = (int)(soap->lablen - k + i); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN); + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register char d1, d2; + register soap_wchar c = soap_get(soap); + if (soap_isxdigit(c)) + { d1 = (char)c; + c = soap_get(soap); + if (soap_isxdigit(c)) + d2 = (char)c; + else + { soap_end_block(soap); + soap->error = SOAP_TYPE; + return NULL; + } + } + else + { unsigned char *p; + soap_unget(soap, c); + if (n) + *n = soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + return p; + } + *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putbase64(struct soap *soap, const unsigned char *s, int n) +{ register int i; + register unsigned long m; + char d[4]; + if (!s) + return SOAP_OK; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n))) + return soap->error; + return SOAP_OK; + } +#endif + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + d[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + d[i] = '='; + if (soap_send_raw(soap, d, 4)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +unsigned char* +SOAP_FMAC2 +soap_getbase64(struct soap *soap, int *n, int malloc_flag) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_string_in(soap, 0, -1, -1); + return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n); + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; + for (;;) + { register int i, k; + register char *s; + if (soap_append_lab(soap, NULL, 2)) + return NULL; + s = soap->labbuf + soap->labidx; + k = soap->lablen - soap->labidx; + soap->labidx = 3 * (soap->lablen / 3); + if (!s) + return NULL; + for (i = 0; i < k - 2; i += 3) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)(soap->lablen - k + i); + p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i); + if (p) + memcpy(p, soap->labbuf, soap->lablen - k + i); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c)) + { soap->error = SOAP_TYPE; + return NULL; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#else + if (soap_new_block(soap)) + return NULL; + for (;;) + { register int i; + register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ + if (!s) + { soap_end_block(soap); + return NULL; + } + for (i = 0; i < SOAP_BLKLEN; i++) + { register unsigned long m = 0; + register int j = 0; + do + { register soap_wchar c = soap_get(soap); + if (c == '=' || c < 0) + { unsigned char *p; + i *= 3; + switch (j) + { case 2: + *s++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *s++ = (char)((m >> 10) & 0xFF); + *s++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n = (int)soap_size_block(soap, i); + p = (unsigned char*)soap_save_block(soap, NULL, 0); + if (c >= 0) + { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT) + ; + } + soap_unget(soap, c); + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c)) + { soap->error = SOAP_TYPE; + return NULL; + } + } while (j < 4); + *s++ = (char)((m >> 16) & 0xFF); + *s++ = (char)((m >> 8) & 0xFF); + *s++ = (char)(m & 0xFF); + } + } +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ /* Check MTOM xop:Include element (within hex/base64Binary) */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + int body = soap->body; /* should save type too? */ + if (!soap_peek_element(soap)) + { if (!soap_element_begin_in(soap, "xop:Include", 0, NULL) && *soap->href) + { if (soap_dime_forward(soap, ptr, size, id, type, options)) + return soap->error; + } + if (soap->body && soap_element_end_in(soap, NULL)) + return soap->error; + } + soap->body = body; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options) +{ struct soap_xlist *xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist)); + *ptr = NULL; + *size = 0; + *id = soap_strdup(soap, soap->href); + *type = NULL; + *options = NULL; + if (!xp) + return soap->error = SOAP_EOM; + xp->next = soap->xlist; + xp->ptr = ptr; + xp->size = size; + xp->id = *id; + xp->type = type; + xp->options = options; + soap->xlist = xp; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_strdup(struct soap *soap, const char *s) +{ char *t = NULL; + if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1))) + strcpy(t, s); + return t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_new_block(struct soap *soap) +{ struct soap_blist *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist)); + if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist)))) + return SOAP_EOM; + p->next = soap->blist; + p->ptr = NULL; + p->size = 0; + soap->blist = p; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_push_block(struct soap *soap, size_t n) +{ char *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)soap->blist->size + (unsigned int)n)); + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + *(char**)p = soap->blist->ptr; + *(size_t*)(p + sizeof(char*)) = n; + soap->blist->ptr = p; + soap->blist->size += n; + return p + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_block(struct soap *soap) +{ char *p; + if (!soap->blist->ptr) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n")); + p = soap->blist->ptr; + soap->blist->size -= *(size_t*)(p + sizeof(char*)); + soap->blist->ptr = *(char**)p; + SOAP_FREE(soap, p); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2) +{ int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; +#ifndef WITH_LEANER + register struct soap_xlist *xp; +#endif + register void *p, **q; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + (p1-p2))); + ip->ptr = (char*)ip->ptr + (p1-p2); + } + for (q = &ip->link; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p)); + *q = (char*)p + (p1-p2); + } + } + for (q = &ip->copy; q; q = (void**)p) + { p = *q; + if (p && (char*)p >= start && (char*)p < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p)); + *q = (char*)p + (p1-p2); + } + } + for (fp = ip->flist; fp; fp = fp->next) + { if ((char*)fp->ptr >= start && (char*)fp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp)); + fp->ptr = (char*)fp->ptr + (p1-p2); + } + } + } + } +#ifndef WITH_LEANER + for (xp = soap->xlist; xp; xp = xp->next) + { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:"", xp->ptr, (char*)xp->ptr + (p1-p2))); + xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2)); + xp->size = (int*)((char*)xp->size + (p1-p2)); + xp->type = (char**)((char*)xp->type + (p1-p2)); + xp->options = (char**)((char*)xp->options + (p1-p2)); + } + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static int +soap_has_copies(struct soap *soap, register const char *start, register const char *end) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + register const char *p; + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { for (p = (const char*)ip->copy; p; p = *(const char**)p) + if (p >= start && p < end) + return SOAP_ERR; + for (fp = ip->flist; fp; fp = fp->next) + if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end) + return SOAP_ERR; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_resolve(struct soap *soap) +{ register int i; + register struct soap_ilist *ip; + register struct soap_flist *fp; + short flag; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr) + { register void *p, **q, *r; + q = (void**)ip->link; + ip->link = NULL; + r = ip->ptr; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id)); + while (q) + { p = *q; + *q = r; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r)); + q = (void**)p; + } + } + else if (*ip->id == '#') + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id)); + strcpy(soap->id, ip->id + 1); + return soap->error = SOAP_MISSING_ID; + } + } + } + do + { flag = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size)) + { if (ip->copy) + { register void *p, **q = (void**)ip->copy; + DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id)); + ip->copy = NULL; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size)); + p = *q; + memcpy(q, ip->ptr, ip->size); + q = (void**)p; + } while (q); + flag = 1; + } + for (fp = ip->flist; fp; fp = ip->flist) + { register unsigned int k = fp->level; + register void *p = ip->ptr; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); + while (ip->level < k) + { register void **q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return soap->error; + *q = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q)); + p = (void*)q; + k--; + } + if (fp->fcopy) + fp->fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size); + else + soap_fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size); + ip->flist = fp->next; + SOAP_FREE(soap, fp); + flag = 1; + } + } + } + } + } while (flag); +#ifdef SOAP_DEBUG + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = ip->next) + { if (ip->copy || ip->flist) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->id)); + } + } + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n")); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_size_block(struct soap *soap, size_t n) +{ if (soap->blist->ptr) + { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n; + *(size_t*)(soap->blist->ptr + sizeof(char*)) = n; + } + return soap->blist->size; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_first_block(struct soap *soap) +{ char *p, *q, *r; + p = soap->blist->ptr; + if (!p) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n")); + r = NULL; + do + { q = *(char**)p; + *(char**)p = r; + r = p; + p = q; + } while (p); + soap->blist->ptr = r; + return r + sizeof(char*) + sizeof(size_t); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_next_block(struct soap *soap) +{ char *p; + p = soap->blist->ptr; + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n")); + soap->blist->ptr = *(char**)p; + SOAP_FREE(soap, p); + if (soap->blist->ptr) + return soap->blist->ptr + sizeof(char*) + sizeof(size_t); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_block_size(struct soap *soap) +{ return *(size_t*)(soap->blist->ptr + sizeof(char*)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end_block(struct soap *soap) +{ struct soap_blist *bp; + char *p, *q; + bp = soap->blist; + if (bp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n")); + for (p = bp->ptr; p; p = q) + { q = *(char**)p; + SOAP_FREE(soap, p); + } + soap->blist = bp->next; + SOAP_FREE(soap, bp); + } + DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n")); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_save_block(struct soap *soap, char *p, int flag) +{ register size_t n; + register char *q, *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)soap->blist->size, soap->blist->ptr, p)); + if (soap->blist->size) + { if (!p) + p = (char*)soap_malloc(soap, soap->blist->size); + if (p) + { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap)) + { n = soap_block_size(soap); +#ifndef WITH_NOIDREF + if (flag) + soap_update_ptrs(soap, q, q + n, s, q); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s)); + memcpy(s, q, n); + s += n; + } + } + else + soap->error = SOAP_EOM; + } + soap_end_block(soap); + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsize(struct soap *soap, const char *type, int size) +{ return soap_putsizes(soap, type, &size, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizes(struct soap *soap, const char *type, const int *size, int dim) +{ return soap_putsizesoffsets(soap, type, size, NULL, dim); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim) +{ int i; + if (!type) + return NULL; + if (soap->version == 2) + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), " %d", size[i]); + } + else + { if (offset) + { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]); + } + else + { sprintf(soap->type, "%s[%d", type, size[0]); + for (i = 1; i < dim; i++) + sprintf(soap->type + strlen(soap->type), ",%d", size[i]); + } + strcat(soap->type, "]"); + } + return soap->type; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffset(struct soap *soap, int offset) +{ return soap_putoffsets(soap, &offset, 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_putoffsets(struct soap *soap, const int *offset, int dim) +{ register int i; + sprintf(soap->arrayOffset, "[%d", offset[0]); + for (i = 1; i < dim; i++) + sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]); + strcat(soap->arrayOffset, "]"); + return soap->arrayOffset; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_size(const int *size, int dim) +{ register int i, n = size[0]; + for (i = 1; i < dim; i++) + n *= size[i]; + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getoffsets(const char *attr, const int *size, int *offset, int dim) +{ register int i, j = 0; + if (offset) + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += offset[i] = (int)atol(attr); + attr = strchr(attr, ','); + } + else + for (i = 0; i < dim && attr && *attr; i++) + { attr++; + j *= size[i]; + j += (int)atol(attr); + attr = strchr(attr, ','); + } + return j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsize(const char *attr1, const char *attr2, int *j) +{ register int n, k; + char *s; + *j = 0; + if (!*attr1) + return -1; + if (*attr1 == '[') + attr1++; + n = 1; + for (;;) + { k = (int)soap_strtol(attr1, &s, 10); + n *= k; + if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1) + return -1; + attr1 = strchr(s, ','); + if (!attr1) + attr1 = strchr(s, ' '); + if (attr2 && *attr2) + { attr2++; + *j *= k; + k = (int)soap_strtol(attr2, &s, 10); + *j += k; + if (k < 0) + return -1; + attr2 = s; + } + if (!attr1) + break; + attr1++; + } + return n - *j; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getsizes(const char *attr, int *size, int dim) +{ register int i, k, n; + if (!*attr) + return -1; + i = strlen(attr); + n = 1; + do + { for (i = i-1; i >= 0; i--) + if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ') + break; + k = (int)atol(attr + i + 1); + n *= size[--dim] = k; + if (k < 0 || n > SOAP_MAXARRAYSIZE) + return -1; + } while (i >= 0 && attr[i] != '['); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getposition(const char *attr, int *pos) +{ register int i, n; + if (!*attr) + return -1; + n = 0; + i = 1; + do + { pos[n++] = (int)atol(attr + i); + while (attr[i] && attr[i] != ',' && attr[i] != ']') + i++; + if (attr[i] == ',') + i++; + } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']'); + return n; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_push_namespace(struct soap *soap, const char *id, const char *ns) +{ register struct soap_nlist *np; + register struct Namespace *p; + register short i = -1; + register size_t n, k; + n = strlen(id); + k = strlen(ns) + 1; + p = soap->local_namespaces; + if (p) + { for (i = 0; p->id; p++, i++) + { if (p->ns && !strcmp(ns, p->ns)) + { if (p->out) + { SOAP_FREE(soap, p->out); + p->out = NULL; + } + break; + } + if (p->out) + { if (!strcmp(ns, p->out)) + break; + } + else if (p->in) + { if (!soap_tag_cmp(ns, p->in)) + { if ((p->out = (char*)SOAP_MALLOC(soap, k))) + strcpy(p->out, ns); + break; + } + } + } + if (!p || !p->id) + i = -1; + } + if (i >= 0) + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k); + if (!np) + return soap->error = SOAP_EOM; + np->next = soap->nlist; + soap->nlist = np; + np->level = soap->level; + np->index = i; + strcpy(np->id, id); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns)); + if (i < 0) + { np->ns = np->id + n + 1; + strcpy(np->ns, ns); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns)); + } + else + { np->ns = NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id)); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_pop_namespace(struct soap *soap) +{ register struct soap_nlist *np; + while (soap->nlist && soap->nlist->level >= soap->level) + { np = soap->nlist->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id)); + SOAP_FREE(soap, soap->nlist); + soap->nlist = np; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2) +{ register struct soap_nlist *np = soap->nlist; + while (np && (strncmp(np->id, id1, n1) || np->id[n1])) + np = np->next; + if (np) + { if (np->index < 0 + || (soap->local_namespaces[np->index].id + && (strncmp(soap->local_namespaces[np->index].id, id2, n2) + || soap->local_namespaces[np->index].id[n2]))) + return SOAP_NAMESPACE; + return SOAP_OK; + } + if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2)) + return SOAP_OK; + return SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_current_namespace(struct soap *soap, const char *tag) +{ register struct soap_nlist *np; + register const char *s; + np = soap->nlist; + if (!(s = strchr(tag, ':'))) + { while (np && *np->id) /* find default namespace, if present */ + np = np->next; + } + else + { while (np && (strncmp(np->id, tag, s - tag) || np->id[s - tag])) + np = np->next; + if (!np) + soap->error = SOAP_NAMESPACE; + } + if (np) + { if (np->index >= 0) + return soap->namespaces[np->index].ns; + if (np->ns) + return soap_strdup(soap, np->ns); + } + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_tag_cmp(const char *s, const char *t) +{ for (;;) + { register int c1 = *s; + register int c2 = *t; + if (!c1 || c1 == '"') + break; + if (c2 != '-') + { if (c1 != c2) + { if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + } + if (c1 != c2) + { if (c2 != '*') + return 1; + c2 = *++t; + if (!c2) + return 0; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + for (;;) + { c1 = *s; + if (!c1 || c1 == '"') + break; + if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1)) + return 0; + s++; + } + break; + } + } + s++; + t++; + } + if (*t == '*' && !t[1]) + return 0; + return *t; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_tag(struct soap *soap, const char *tag1, const char *tag2) +{ register const char *s, *t; + if (!tag1 || !tag2 || !*tag2) + return SOAP_OK; + s = strchr(tag1, ':'); + t = strchr(tag2, ':'); + if (t) + { if (s) + { if (t[1] && SOAP_STRCMP(s + 1, t + 1)) + return SOAP_TAG_MISMATCH; + if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + } + else if (SOAP_STRCMP(tag1, t + 1)) + return SOAP_TAG_MISMATCH; + else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); + return SOAP_TAG_MISMATCH; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; + } + if (s) + { if (SOAP_STRCMP(s + 1, tag2)) + return SOAP_TAG_MISMATCH; + } + else if (SOAP_STRCMP(tag1, tag2)) + return SOAP_TAG_MISMATCH; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2)); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_array(struct soap *soap, const char *type) +{ if (*soap->arrayType) + if (soap_match_tag(soap, soap->arrayType, type) + && soap_match_tag(soap, soap->arrayType, "xsd:anyType") + && soap_match_tag(soap, soap->arrayType, "xsd:ur-type") + ) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type)); + return SOAP_TAG_MISMATCH; + } + return SOAP_OK; +} +#endif + +/******************************************************************************\ + * + * SSL + * +\******************************************************************************/ + +#ifdef WITH_OPENSSL +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_rand() +{ unsigned char buf[4]; + if (!ssl_init_done) + soap_ssl_init(); + RAND_pseudo_bytes(buf, 4); + return *(int*)buf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_server_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *dhfile, const char *randfile, const char *sid) +{ int err; + soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->dhfile = dhfile; + soap->randfile = randfile; + soap->ssl_flags = flags | (dhfile == NULL ? SOAP_SSL_RSA : 0); + if (!(err = soap->fsslauth(soap))) + { if (sid) + SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid)); + } + return err; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile) +{ soap->keyfile = keyfile; + soap->password = password; + soap->cafile = cafile; + soap->capath = capath; + soap->dhfile = NULL; + soap->ssl_flags = flags; + soap->randfile = randfile; + return soap->fsslauth(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_ssl_init() +{ /* Note: for MT systems, the main program MUST call soap_ssl_init() before any threads are started */ + if (!ssl_init_done) + { ssl_init_done = 1; + SSL_library_init(); +#ifndef WITH_LEAN + SSL_load_error_strings(); +#endif + if (!RAND_load_file("/dev/urandom", 1024)) + { char buf[1024]; + RAND_seed(buf, sizeof(buf)); + while (!RAND_status()) + { int r = rand(); + RAND_seed(&r, sizeof(int)); + } + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_ssl_error(struct soap *soap, int ret) +{ int err = SSL_get_error(soap->ssl, ret); + const char *msg = soap_code_str(h_ssl_error_codes, err); + if (msg) + strcpy(soap->msgbuf, msg); + else + return ERR_error_string(err, soap->msgbuf); + if (ERR_peek_error()) + { unsigned long r; + strcat(soap->msgbuf, "\n"); + while ((r = ERR_get_error())) + ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf)); + } + else + { switch (ret) + { case 0: + strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information."); + break; + case -1: + sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno)); + break; + } + } + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_password(char *buf, int num, int rwflag, void *userdata) +{ if (num < (int)strlen((char*)userdata) + 1) + return 0; + return strlen(strcpy(buf, (char*)userdata)); +} +#endif + +/******************************************************************************/ +/* This callback is included for future references. It should not be deleted +#ifndef PALM_2 +static DH * +ssl_tmp_dh(SSL *ssl, int is_export, int keylength) +{ static DH *dh512 = NULL; + static DH *dh1024 = NULL; + DH *dh; + switch (keylength) + { case 512: + if (!dh512) + { BIO *bio = BIO_new_file("dh512.pem", "r"); + if (bio) + { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + return dh512; + } + } + else + return dh512; + default: + if (!dh1024) + { BIO *bio = BIO_new_file("dh1024.pem", "r"); + if (bio) + { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } + dh = dh1024; + } + return dh; +} +#endif +*/ + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_auth_init(struct soap *soap) +{ long flags; + int mode; + if (!ssl_init_done) + soap_ssl_init(); + if (!soap->ctx) + { if (!(soap->ctx = SSL_CTX_new(SSLv23_method()))) + return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR); + } + if (soap->randfile) + { if (!RAND_load_file(soap->randfile, -1)) + return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR); + } + if (soap->cafile || soap->capath) + { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath)) + return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR); + if (soap->cafile && (soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + SSL_CTX_set_client_CA_list(soap->ctx, SSL_load_client_CA_file(soap->cafile)); + } + if (!SSL_CTX_set_default_verify_paths(soap->ctx)) + return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR); +/* This code assumes a typical scenario, see alternative code below */ + if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR); + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); + } +/* Suggested alternative approach to check cafile first before the key file: + if (soap->password) + { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); + SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); + } + if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile)) + { if (soap->keyfile) + { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) + return soap_set_receiver_error(soap, "SSL error", "Can't read certificate or key file", SOAP_SSL_ERROR); + if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) + return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); + } + } +*/ + if ((soap->ssl_flags & SOAP_SSL_RSA)) + { RSA *rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL); + if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa)) + { if (rsa) + RSA_free(rsa); + return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR); + } + RSA_free(rsa); + } + else if (soap->dhfile) + { DH *dh = 0; + BIO *bio; + bio = BIO_new_file(soap->dhfile, "r"); + if (!bio) + return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR); + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0) + { if (dh) + DH_free(dh); + return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR); + } + DH_free(dh); + } + flags = (SSL_OP_ALL | SSL_OP_NO_SSLv2); + if ((soap->ssl_flags & SOAP_SSLv3)) + flags |= SSL_OP_NO_TLSv1; + if ((soap->ssl_flags & SOAP_TLSv1)) + flags |= SSL_OP_NO_SSLv3; + SSL_CTX_set_options(soap->ctx, flags); + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + mode = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + else if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION)) + mode = SSL_VERIFY_PEER; + else + mode = SSL_VERIFY_NONE; + SSL_CTX_set_verify(soap->ctx, mode, soap->fsslverify); +#if (OPENSSL_VERSION_NUMBER < 0x00905100L) + SSL_CTX_set_verify_depth(soap->ctx, 1); +#else + SSL_CTX_set_verify_depth(soap->ctx, 9); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static int +ssl_verify_callback(int ok, X509_STORE_CTX *store) +{ +#ifdef SOAP_DEBUG + if (!ok) + { char data[256]; + X509 *cert = X509_STORE_CTX_get_current_cert(store); + fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); + X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate issuer %s\n", data); + X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data)); + fprintf(stderr, "certificate subject %s\n", data); + } +#endif + /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */ + return ok; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_ssl_accept(struct soap *soap) +{ BIO *bio; + int i, r; + if (!soap_valid_socket(soap->socket)) + return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR); + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + return SOAP_INVALID_SOCKET; + if (!soap->ssl) + { soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + } + else + SSL_clear(soap->ssl); + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { u_long nonblocking = 1; + ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)&nonblocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK); +#endif + bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); + i = 100; /* 100 * 0.1 ms retries */ + while ((r = SSL_accept(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + { struct timeval timeout; + fd_set fd; + if (i-- <= 0) + break; + timeout.tv_sec = 0; + timeout.tv_usec = 100000; +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */ +#endif + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->socket, &fd); + r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout); + if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR) + { soap->errnum = r; + return SOAP_EOF; + } + } + else + { soap->errnum = err; + break; + } + } +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { u_long blocking = 0; + ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)&blocking); + } +#else + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + if (r <= 0) + { soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR); + soap_closesock(soap); + return SOAP_SSL_ERROR; + } + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION)) + { X509 *peer; + int err; + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_closesock(soap); + return soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in soap_ssl_accept()", SOAP_SSL_ERROR); + } + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_closesock(soap); + return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR); + } + X509_free(peer); + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#endif /* WITH_OPENSSL */ + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_init(struct soap *soap) +{ soap->errmode = 1; +#ifdef WIN32 + if (tcp_done) + return 0; + else + { WSADATA w; + if (WSAStartup(MAKEWORD(1, 1), &w)) + return -1; + tcp_done = 1; + } +#endif + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_done(struct soap *soap) +{ +#ifdef SOAP_DEBUG + int i; +#endif + if (soap_check_state(soap)) + return; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Done with context\n")); + soap_free_temp(soap); + while (soap->clist) + { struct soap_clist *p = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = p; + } + soap->keep_alive = 0; /* to force close the socket */ + soap_closesock(soap); +#ifdef WITH_COOKIES + soap_free_cookies(soap); +#endif + while (soap->plugins) + { register struct soap_plugin *p = soap->plugins->next; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id)); + if (soap->plugins->fcopy || soap->state == SOAP_INIT) + soap->plugins->fdelete(soap, soap->plugins); + SOAP_FREE(soap, soap->plugins); + soap->plugins = p; + } + soap->fplugin = fplugin; + soap->fmalloc = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fheader = NULL; +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinal = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; +#ifdef WITH_OPENSSL + if (soap->session) + { SSL_SESSION_free(soap->session); + soap->session = NULL; + } +#endif + if (soap->state == SOAP_INIT) + { if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } +#ifdef WITH_OPENSSL + if (soap->ctx) + { SSL_CTX_free(soap->ctx); + soap->ctx = NULL; + } +#endif + } +#ifdef SOAP_DEBUG + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n")); + for (i = 0; i < SOAP_MAXLOGS; i++) + { if (soap->logfile[i]) + { SOAP_FREE(soap, (void*)soap->logfile[i]); + soap->logfile[i] = NULL; + } + soap_close_logfile(soap, i); + } + soap_free_mht(soap); + soap->state = 0; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_cleanup(struct soap *soap) +{ soap_done(soap); +#ifdef WIN32 + if (!tcp_done) + return; + tcp_done = 0; + WSACleanup(); +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +tcp_error(struct soap *soap) +{ register const char *msg = NULL; + switch (soap->errmode) + { case 0: + msg = soap_strerror(soap); + break; + case 1: + msg = "WSAStartup failed"; + break; + case 2: + { +#ifndef WITH_LEAN + msg = soap_code_str(h_error_codes, soap->errnum); + if (!msg) +#endif + { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum); + msg = soap->msgbuf; + } + } + } + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static const char* +http_error(struct soap *soap, int status) +{ register const char *msg = SOAP_STR_EOS; +#ifndef WITH_LEAN + msg = soap_code_str(h_http_error_codes, status); + if (!msg) + msg = SOAP_STR_EOS; +#endif + return msg; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_IPV6 +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr) +{ soap_int32 iadd = -1; + struct hostent hostent, *host = &hostent; +#ifdef VXWORKS + int hostint; + /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */ + iadd = inet_addr((char*)addr); +#else +#if defined(_AIXVERSION_431) || defined(TRU64) + struct hostent_data ht_data; +#endif +#ifdef AS400 + iadd = inet_addr((void*)addr); +#else + iadd = inet_addr(addr); +#endif +#endif + if (iadd != -1) + { memcpy(inaddr, &iadd, sizeof(iadd)); + return SOAP_OK; + } +#if defined(__GLIBC__) + if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0) + host = NULL; +#elif defined(_AIXVERSION_431) || defined(TRU64) + memset((void*)&ht_data, 0, sizeof(ht_data)); + if (gethostbyname_r(addr, &hostent, &ht_data) < 0) + { host = NULL; + soap->errnum = h_errno; + } +#elif defined(HAVE_GETHOSTBYNAME_R) + host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum); +#elif defined(VXWORKS) + /* If the DNS resolver library resolvLib has been configured in the vxWorks + * image, a query for the host IP address is sent to the DNS server, if the + * name was not found in the local host table. */ + hostint = hostGetByName((char*)addr); + if (hostint == ERROR) + { host = NULL; + soap->errnum = soap_errno; + } +#else +#ifdef AS400 + if (!(host = gethostbyname((void*)addr))) + soap->errnum = h_errno; +#else + if (!(host = gethostbyname(addr))) + soap->errnum = h_errno; +#endif +#endif + if (!host) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n")); + return SOAP_ERR; + } +#ifdef VXWORKS + inaddr->s_addr = hostint; +#else + memcpy(inaddr, host->h_addr, host->h_length); +#endif + return SOAP_OK; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) +{ +#ifdef WITH_IPV6 + struct addrinfo hints, *res, *ressave; +#endif + register int err, fd; +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->socket)) + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + if (tcp_init(soap)) + { soap->errnum = 0; + soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->errmode = 0; +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + soap->errmode = 2; + if (soap->proxy_host) + err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res); + else + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res); + if (err) + { soap_set_sender_error(soap, gai_strerror(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + ressave = res; +again: + fd = (int)socket(res->ai_family, res->ai_socktype, res->ai_protocol); + soap->errmode = 0; +#else +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + fd = (int)socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + fd = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + if (fd < 0) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->connect_flags == SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + else if (soap->connect_flags && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port)); +#ifndef WITH_IPV6 + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (soap->proxy_host) + { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)soap->proxy_port); + } + else + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->peer.sin_port = htons((short)port); + } + soap->errmode = 0; + if ((soap->omode & SOAP_IO_UDP)) + return fd; +#endif +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { u_long nonblocking = 1; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&nonblocking)); /* modified to use fd */ + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { u_long blocking = 0; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking)); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + for (;;) + { +#ifdef WITH_IPV6 + if (connect((SOAP_SOCKET)fd, res->ai_addr, res->ai_addrlen)) +#else + if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer))) +#endif + { +#ifndef WITH_LEAN + if (soap->connect_timeout && (soap_socket_errno(fd) == SOAP_EINPROGRESS || soap_socket_errno(fd) == SOAP_EWOULDBLOCK)) + { struct timeval timeout; + SOAP_SOCKLEN_T k; + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + { soap->error = SOAP_FD_EXCEEDED; + return SOAP_INVALID_SOCKET; /* Hint: MUST increase FD_SETSIZE */ + } +#endif + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)fd, &fds); + for (;;) + { register int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + r = soap_socket_errno(fd); + if (r != SOAP_EINTR) + { soap->errnum = r; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + k = (SOAP_SOCKLEN_T)sizeof(soap->errnum); + if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum) /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ + break; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + if (!soap->errnum) + soap->errnum = soap_socket_errno(fd); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + else +#endif +#ifdef WITH_IPV6 + if (res->ai_next) + { res = res->ai_next; + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + goto again; + } + else +#endif + err = soap_socket_errno(fd); + if (err && err != SOAP_EINTR) + { soap->errnum = err; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n")); + soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + else + break; + } +#ifdef WITH_IPV6 + soap->peerlen = 0; /* IPv6: already connected so use send() */ + freeaddrinfo(ressave); +#endif +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { u_long blocking = 0; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking)); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = fd; + soap->imode &= ~SOAP_ENC_SSL; + soap->omode &= ~SOAP_ENC_SSL; + if (!soap_tag_cmp(endpoint, "https:*")) + { +#ifdef WITH_OPENSSL + BIO *bio; + int r; + if (soap->proxy_host) + { unsigned int k = soap->omode; /* make sure we only parse HTTP */ + size_t n = soap->count; /* save the content length */ + char *userid, *passwd; + char endp[sizeof(soap->endpoint)]; + soap->omode &= ~SOAP_ENC; /* mask IO and ENC */ + soap->omode |= SOAP_IO_BUFFER; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to %s proxy server\n", soap->proxy_http_version)); + sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->proxy_http_version); + if (soap_begin_send(soap) + || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL))) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } +#ifndef WITH_LEAN + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return soap->error; + } + } +#endif + if ((soap->error = soap->fposthdr(soap, NULL, NULL)) + || soap_flush(soap)) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->omode = k; + k = soap->imode; + soap->imode &= ~SOAP_ENC; /* mask IO and ENC */ + strcpy(endp, soap->endpoint); + userid = soap->userid; /* preserve */ + passwd = soap->passwd; /* preserve */ + if ((soap->error = soap->fparse(soap))) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + strcpy(soap->endpoint, endp); /* restore */ + soap->userid = userid; /* restore */ + soap->passwd = passwd; /* restore */ + soap->imode = k; /* restore */ + soap->count = n; /* restore */ + if (soap_begin_send(soap)) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + if (!soap->ctx && (soap->error = soap->fsslauth(soap))) + { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + soap->ssl = SSL_new(soap->ctx); + if (!soap->ssl) + { soap->fclosesocket(soap, (SOAP_SOCKET)fd); + soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; + } + if (soap->session) + { if (!strcmp(soap->session_host, host) && soap->session_port == port) + SSL_set_session(soap->ssl, soap->session); + SSL_SESSION_free(soap->session); + soap->session = NULL; + } + soap->imode |= SOAP_ENC_SSL; + soap->omode |= SOAP_ENC_SSL; + bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE); + SSL_set_bio(soap->ssl, bio, bio); +#ifndef WITH_LEAN + if (soap->connect_timeout) +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { u_long nonblocking = 1; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&nonblocking)); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK); +#endif +#endif + for (;;) + { if ((r = SSL_connect(soap->ssl)) <= 0) + { int err = SSL_get_error(soap->ssl, r); + if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) + { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (soap->connect_timeout) + { struct timeval timeout; + fd_set fds; + if (soap->connect_timeout > 0) + { timeout.tv_sec = soap->connect_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->connect_timeout/1000000; + timeout.tv_usec = -soap->connect_timeout%1000000; + } +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + { soap->error = SOAP_FD_EXCEEDED; + return SOAP_INVALID_SOCKET; /* Hint: MUST increase FD_SETSIZE */ + } +#endif + FD_ZERO(&fds); + FD_SET((SOAP_SOCKET)fd, &fds); + for (;;) + { int r = select((SOAP_SOCKET)(fd + 1), &fds, NULL, &fds, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n")); + soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + continue; + } + } + break; + } +#ifndef WITH_LEAN + if (soap->connect_timeout) +#ifdef WIN32 + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { u_long blocking = 0; + ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking)); + } +#else + fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK); +#endif +#endif + if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION)) + { int err; + // TODO: add callback to verify server + if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK) + { soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + if (!(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK)) + { X509_NAME *subj; + int ext_count; + int ok = 0; + X509 *peer; + peer = SSL_get_peer_certificate(soap->ssl); + if (!peer) + { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + ext_count = X509_get_ext_count(peer); + if (ext_count > 0) + { int i; + for (i = 0; i < ext_count; i++) + { X509_EXTENSION *ext = X509_get_ext(peer, i); + const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); + if (ext_str && !strcmp(ext_str, "subjectAltName")) + { X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext); + void *ext_data; + unsigned char *data; + STACK_OF(CONF_VALUE) *val; + int j; + if (!meth) + break; + data = ext->value->data; +#if (OPENSSL_VERSION_NUMBER > 0x00907000L) + if (meth->it) + ext_data = ASN1_item_d2i(NULL, &data, ext->value->length, ASN1_ITEM_ptr(meth->it)); + else + { /* OpenSSL not perfectly portable at this point (?): + Some compilers appear to prefer + meth->d2i(NULL, (const unsigned char**)&data, ... + */ + ext_data = meth->d2i(NULL, &data, ext->value->length); + } +#else + ext_data = meth->d2i(NULL, &data, ext->value->length); +#endif + val = meth->i2v(meth, ext_data, NULL); + for (j = 0; j < sk_CONF_VALUE_num(val); j++) + { CONF_VALUE *nval = sk_CONF_VALUE_value(val, j); + if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host)) + { ok = 1; + break; + } + } + } + if (ok) + break; + } + } + if (!ok && (subj = X509_get_subject_name(peer))) + { int i = -1; + do + { ASN1_STRING *name; + i = X509_NAME_get_index_by_NID(subj, NID_commonName, i); + if (i == -1) + break; + name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i)); + if (name && !soap_tag_cmp((const char*)name, host)) + ok = 1; + else + { unsigned char *tmp = NULL; + ASN1_STRING_to_UTF8(&tmp, name); + if (tmp) + { if (!soap_tag_cmp((const char*)tmp, host)) + ok = 1; + OPENSSL_free(tmp); + } + } + } while (!ok); + } + X509_free(peer); + if (!ok) + { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR); + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + return SOAP_INVALID_SOCKET; + } + } + } +#else + soap->fclosesocket(soap, (SOAP_SOCKET)fd); + soap->error = SOAP_SSL_ERROR; + return SOAP_INVALID_SOCKET; +#endif + } + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_bind(struct soap *soap, const char *host, int port, int backlog) +{ +#ifdef WITH_IPV6 + struct addrinfo *addrinfo = NULL; + struct addrinfo hints; + struct addrinfo res; + int err; +#endif +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + if (soap_valid_socket(soap->master)) + { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master); + soap->master = SOAP_INVALID_SOCKET; + } + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 1; + if (tcp_init(soap)) + { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef WITH_IPV6 + memset((void*)&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + hints.ai_socktype = SOCK_DGRAM; + else +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + soap->errmode = 2; + err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo); + if (addrinfo) + { res = *addrinfo; + soap->peer = *((struct sockaddr_storage*)addrinfo->ai_addr); + soap->peerlen = addrinfo->ai_addrlen; + res.ai_addr = (struct sockaddr*)&soap->peer; + res.ai_addrlen = soap->peerlen; + freeaddrinfo(addrinfo); + } + if (err) + { soap_set_receiver_error(soap, gai_strerror(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + soap->master = socket(res.ai_family, res.ai_socktype, res.ai_protocol); +#else +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0); + else +#endif + soap->master = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + soap->errmode = 0; + if (!soap_valid_socket(soap->master)) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + soap->socket = soap->master; +#endif +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(soap->master, F_SETFD, 1); +#endif +#endif +#ifndef WITH_LEAN + if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->master); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif +#endif +#ifdef WITH_IPV6 + soap->errmode = 0; + if (bind((SOAP_SOCKET)soap->master, res.ai_addr, res.ai_addrlen)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#else + soap->peerlen = sizeof(soap->peer); + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->peer.sin_family = AF_INET; + soap->errmode = 2; + if (host) + { if (soap->fresolve(soap, host, &soap->peer.sin_addr)) + { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } + else + soap->peer.sin_addr.s_addr = htonl(INADDR_ANY); + soap->peer.sin_port = htons((short)port); + soap->errmode = 0; + if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&soap->peer, soap->peerlen)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +#endif + if (!(soap->omode & SOAP_IO_UDP) && listen((SOAP_SOCKET)soap->master, backlog)) + { soap->errnum = soap_socket_errno(soap->master); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n")); + soap_closesock(soap); + soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + return soap->master; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_poll(struct soap *soap) +{ +#ifndef WITH_LEAN + struct timeval timeout; + fd_set rfd, sfd, xfd; + int r; + timeout.tv_sec = 0; + timeout.tv_usec = 0; +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */ +#endif + FD_ZERO(&rfd); + FD_ZERO(&sfd); + FD_ZERO(&xfd); + if (soap_valid_socket(soap->socket)) + { FD_SET((SOAP_SOCKET)soap->socket, &rfd); + FD_SET((SOAP_SOCKET)soap->socket, &sfd); + FD_SET((SOAP_SOCKET)soap->socket, &xfd); + r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, &xfd, &timeout); + if (r > 0 && FD_ISSET((SOAP_SOCKET)soap->socket, &xfd)) + r = -1; + } + else if (soap_valid_socket(soap->master)) + { FD_SET((SOAP_SOCKET)soap->master, &sfd); + r = select((SOAP_SOCKET)(soap->master + 1), NULL, &sfd, NULL, &timeout); + } + else + return SOAP_OK; + if (r > 0) + { +#ifdef WITH_OPENSSL + if (soap->imode & SOAP_ENC_SSL) + { + if (soap_valid_socket(soap->socket) + && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd) + && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd) + || SSL_peek(soap->ssl, soap->tmpbuf, 1) > 0)) + return SOAP_OK; + } + else +#endif + if (soap_valid_socket(soap->socket) + && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd) + && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd) + || recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0)) + return SOAP_OK; + } + else if (r < 0) + { soap->errnum = soap_socket_errno(soap->master); + if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno(soap->master) != SOAP_EINTR) + { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR); + return soap->error = SOAP_TCP_ERROR; + } + } + else + soap->errnum = 0; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r)); + return SOAP_EOF; +#else + return SOAP_OK; +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n) +{ int fd; + fd = (int)accept((SOAP_SOCKET)s, a, (SOAP_SOCKLEN_T*)n); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */ +#ifdef SOCKET_CLOSE_ON_EXEC +#ifdef WIN32 +#ifndef UNDER_CE + SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); +#endif +#else + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif +#endif + return fd; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_accept(struct soap *soap) +{ int n = (int)sizeof(soap->peer); +#ifndef WITH_LEAN + int len = SOAP_BUFLEN; + int set = 1; +#endif + soap->error = SOAP_OK; +#ifdef WITH_UDP + if ((soap->omode & SOAP_IO_UDP)) + return soap->socket = soap->master; +#endif + memset((void*)&soap->peer, 0, sizeof(soap->peer)); + soap->socket = SOAP_INVALID_SOCKET; + soap->errmode = 0; + soap->keep_alive = 0; + if (soap_valid_socket(soap->master)) + { register int err; + for (;;) + { +#ifndef WITH_LEAN + if (soap->accept_timeout) + { struct timeval timeout; + fd_set fd; + if (soap->accept_timeout > 0) + { timeout.tv_sec = soap->accept_timeout; + timeout.tv_usec = 0; + } + else + { timeout.tv_sec = -soap->accept_timeout/1000000; + timeout.tv_usec = -soap->accept_timeout%1000000; + } +#ifndef WIN32 + if ((int)soap->socket >= (int)FD_SETSIZE) + { soap->error = SOAP_FD_EXCEEDED; + return SOAP_INVALID_SOCKET; /* Hint: MUST increase FD_SETSIZE */ + } +#endif + FD_ZERO(&fd); + FD_SET((SOAP_SOCKET)soap->master, &fd); + for (;;) + { register int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout); + if (r > 0) + break; + if (!r) + { soap->errnum = 0; + soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + r = soap_socket_errno(soap->master); + if (r != SOAP_EINTR) + { soap->errnum = r; + soap_closesock(soap); + soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } + } +#if defined(WIN32) + { u_long nonblocking = 1; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking); + } +#elif defined(VXWORKS) + { u_long nonblocking = 1; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&nonblocking)); + } +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK); +#endif + } + else +#if defined(WIN32) + { u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + } +#elif defined(VXWORKS) + { u_long blocking = 0; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&blocking)); + } +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); +#endif +#endif + soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n); + soap->peerlen = (size_t)n; + if (soap_valid_socket(soap->socket)) + { +#ifdef WITH_IPV6 +/* Use soap->host to store the numeric form of the remote host */ + getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host)); + soap->ip = 0; /* info stored in soap->peer and soap->host */ + soap->port = 0; /* info stored in soap->peer and soap->host */ +#else + soap->ip = ntohl(soap->peer.sin_addr.s_addr); + soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF)); +#endif +#ifndef WITH_LEAN + if (soap->accept_flags == SO_LINGER) + { struct linger linger; + memset((void*)&linger, 0, sizeof(linger)); + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + else if (soap->accept_flags && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#ifdef TCP_NODELAY + if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int))) + { soap->errnum = soap_socket_errno(soap->socket); + soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } +#endif +#endif + if (soap->accept_timeout) + { +#if defined(WIN32) + u_long blocking = 0; + ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking); + ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking); +#elif defined(VXWORKS) + u_long blocking = 0; + ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&blocking)); + ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&blocking)); +#elif defined(PALM) + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK); +#elif defined(SYMBIAN) + long blocking = 0; + ioctl((SOAP_SOCKET)soap->master, 0/*FIONBIO*/, &blocking); +#else + fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK); + fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK); +#endif + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + return soap->socket; + } + err = soap_socket_errno(soap->socket); + if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host)); + soap->errnum = err; + soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR); + soap_closesock(soap); + return SOAP_INVALID_SOCKET; + } + } + } + else + { soap->errnum = 0; + soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR); + return SOAP_INVALID_SOCKET; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_disconnect(struct soap *soap) +{ +#ifdef WITH_OPENSSL + if (soap->ssl) + { int r, s = 0; + if (soap->session) + SSL_SESSION_free(soap->session); + if (*soap->host) + { soap->session = SSL_get1_session(soap->ssl); + if (soap->session) + { strcpy(soap->session_host, soap->host); + soap->session_port = soap->port; + } + } + r = SSL_shutdown(soap->ssl); + if (r != 1) + { s = ERR_get_error(); + if (s) + { if (soap_valid_socket(soap->socket)) + { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); + soap->socket = SOAP_INVALID_SOCKET; + } + r = SSL_shutdown(soap->ssl); + } + } + DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r))); + SSL_free(soap->ssl); + soap->ssl = NULL; + if (s) + return SOAP_SSL_ERROR; + ERR_remove_state(0); + } +#endif + if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP)) + { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2); + soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket); + soap->socket = SOAP_INVALID_SOCKET; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_closesocket(struct soap *soap, SOAP_SOCKET fd) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd)); + return soap_closesocket(fd); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static int +tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how)); + return shutdown(fd, how); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_closesock(struct soap *soap) +{ register int status = soap->error; + if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive) + { if (soap->fclose && (soap->error = soap->fclose(soap))) + return soap->error; + soap->keep_alive = 0; + } +#ifdef WITH_ZLIB + if (soap->zlib_state == SOAP_ZLIB_DEFLATE) + deflateEnd(&soap->d_stream); + else if (soap->zlib_state == SOAP_ZLIB_INFLATE) + inflateEnd(&soap->d_stream); + soap->zlib_state = SOAP_ZLIB_NONE; +#endif + return soap->error = status; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_hash(register const char *s) +{ register size_t h = 0; + while (*s) + h = 65599*h + *s++; + return h % SOAP_IDHASH; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_pht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n")); + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new1(soap_mode mode) +{ return soap_new2(mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new() +{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_new2(soap_mode imode, soap_mode omode) +{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap)); + if (soap) + soap_init2(soap, imode, omode); + return soap; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free(struct soap *soap) +{ soap_done(soap); + free(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_del(struct soap *soap) +{ free(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_pht(struct soap *soap) +{ register struct soap_pblk *pb, *next; + register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n")); + for (pb = soap->pblk; pb; pb = next) + { next = pb->next; + SOAP_FREE(soap, pb); + } + soap->pblk = NULL; + soap->pidx = 0; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->pht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type) +{ register int i; + struct soap_plist *pp; + if (soap->version != 1) + soap->encoding = 1; + if (a) + i = soap_array_pointer_lookup(soap, p, a, n, type, &pp); + else + i = soap_pointer_lookup(soap, p, type, &pp); + if (i) + { if (soap_is_embedded(soap, pp) + || soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + return i; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (p) + { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next) + { if (pp->ptr == p && pp->type == type) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register size_t h; + register struct soap_plist *pp; + if (!soap->pblk || soap->pidx >= SOAP_PTRBLK) + { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk)); + if (!pb) + { soap->error = SOAP_EOM; + return 0; + } + pb->next = soap->pblk; + soap->pblk = pb; + soap->pidx = 0; + } + *ppp = pp = &soap->pblk->plist[soap->pidx++]; + if (a) + h = soap_hash_ptr(a->__ptr); + else + h = soap_hash_ptr(p); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1)); + pp->next = soap->pht[h]; + pp->type = type; + pp->mark1 = 0; + pp->mark2 = 0; + pp->ptr = p; + pp->array = a; + soap->pht[h] = pp; + pp->id = ++soap->idnum; + return pp->id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) +{ register struct soap_plist *pp; + *ppp = NULL; + if (!p || !a->__ptr) + return 0; + for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next) + { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr) + { register int i; + for (i = 0; i < n; i++) + if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i]) + break; + if (i == n) + { *ppp = pp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id)); + return pp->id; + } + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_count(struct soap *soap) +{ +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME)) + soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME; + else +#endif + { soap->mode = soap->omode; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE + || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML)) +#ifndef WITH_LEANER + && !soap->fpreparesend +#endif + )) + soap->mode &= ~SOAP_IO_LENGTH; + else + soap->mode |= SOAP_IO_LENGTH; + } +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (!(soap->mode & SOAP_ENC_DIME)) + soap->mode &= ~SOAP_IO_LENGTH; + if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + soap->mode |= SOAP_ENC_MIME; + else + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); + soap->dime.list = soap->dime.last; /* keep track of last DIME attachment */ +#endif + soap->count = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->part = SOAP_BEGIN; + soap->idnum = 0; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); +#ifndef WITH_LEANER + soap->dime.count = 0; /* count # of attachments */ + soap->dime.size = 0; /* accumulate total size of attachments */ + if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE) + return soap->error = soap->fprepareinit(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_count(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->fpreparefinal) + return soap->error = soap->fpreparefinal(soap); +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n")); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_send(struct soap *soap) +{ soap->error = SOAP_OK; + soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME)); +#ifdef WITH_ZLIB + if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH) + { if (soap->mode & SOAP_ENC_XML) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } +#endif +#ifdef WITH_UDP + if ((soap->mode & SOAP_IO_UDP)) + { soap->mode |= SOAP_ENC_XML; + if (soap->count > SOAP_BUFLEN) + return soap->error = SOAP_UDP_ERROR; + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket)) + { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML)) + soap->mode |= SOAP_IO_BUFFER; + else + soap->mode |= SOAP_IO_STORE; + } + soap->mode &= ~SOAP_IO_LENGTH; + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap_new_block(soap); + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH)) + soap->mode |= SOAP_XML_TREE; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME)) + { soap->mode |= SOAP_ENC_MIME; + soap->mode &= ~SOAP_ENC_DIME; + } + else + soap->mode &= ~SOAP_ENC_MTOM; + if (soap->mode & SOAP_ENC_MIME) + soap_select_mime_boundary(soap); +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */ +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->sendfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY); +#endif +#endif +#endif +#endif +#endif + if (soap->mode & SOAP_IO) + { soap->bufidx = 0; + soap->buflen = 0; + } + soap->chunksize = 0; + soap->ns = 0; + soap->null = 0; + soap->position = 0; + soap->mustUnderstand = 0; + soap->encoding = 0; + soap->idnum = 0; + soap->level = 0; + soap_clr_attr(soap); + soap_set_local_namespaces(soap); +#ifdef WITH_ZLIB + soap->z_ratio_out = 1.0; + if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE) + { +#ifdef WITH_GZIP + memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10); + soap->d_stream.next_out = (Byte*)soap->z_buf + 10; + soap->d_stream.avail_out = SOAP_BUFLEN - 10; + soap->z_crc = crc32(0L, NULL, 0); + if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) +#else + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK) +#endif + return soap->error = SOAP_ZLIB_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n")); + soap->zlib_state = SOAP_ZLIB_DEFLATE; + } +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count)); + soap->part = SOAP_BEGIN; +#ifndef WITH_LEANER + if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE) + soap->fprepareinit(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_embedded(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (soap_pointer_lookup(soap, p, t, &pp)) + { pp->mark1 = 1; + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t)); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_reference(struct soap *soap, const void *p, int t) +{ struct soap_plist *pp; + if (!p || (soap->mode & SOAP_XML_TREE)) + return 1; + if (soap_pointer_lookup(soap, p, t, &pp)) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp)) + { pp->mark1 = 0; + pp->mark2 = 0; + } + else + return 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t) +{ register int i; + struct soap_plist *pp; + if (!p || !a->__ptr) + return 1; + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (i) + { if (pp->mark1 == 0) + { pp->mark1 = 2; + pp->mark2 = 2; + } + } + else if (!soap_pointer_enter(soap, p, a, n, t, &pp)) + return 1; + else + { pp->mark1 = 0; + pp->mark2 = 0; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p dim=%d type=%d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2)); + return pp->mark1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_embedded_id(struct soap *soap, int id, const void *p, int t) +{ struct soap_plist *pp; + if (soap->mode & SOAP_XML_TREE) + return id; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (id < 0) + { id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 2; + else + pp->mark2 = 2; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id multiref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return -1; + } + return id; + } + if (id < 0) + id = soap_pointer_lookup(soap, p, t, &pp); + else if (id && !soap_pointer_lookup(soap, p, t, &pp)) + return 0; + if (id && pp) + { if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id embedded ref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2)); + } + return id; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2)); + if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER) + { if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 != 0; + return pp->mark2 != 0; + } + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 1; + return pp->mark2 == 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_is_single(struct soap *soap, struct soap_plist *pp) +{ if (soap->part == SOAP_IN_HEADER) + return 1; + if (!pp) + return 0; + if (soap->mode & SOAP_IO_LENGTH) + return pp->mark1 == 0; + return pp->mark2 == 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_embedded(struct soap *soap, struct soap_plist *pp) +{ if (!pp) + return; + if (soap->mode & SOAP_IO_LENGTH) + pp->mark1 = 1; + else + pp->mark2 = 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t) +{ struct soap_plist *pp; + int i; + if (!p || !a->__ptr || (!aid && !atype)) + return soap_element_id(soap, tag, id, p, a, n, type, t); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:"")); + i = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + if (!i) + { i = soap_pointer_enter(soap, p, a, n, t, &pp); + if (!i) + { soap->error = SOAP_EOM; + return -1; + } + } + if (id <= 0) + id = i; + if (!aid) + { sprintf(soap->tmpbuf, soap->dime_id_format, id); + aid = soap_strdup(soap, soap->tmpbuf); + } + /* Add MTOM xop:Include element when necessary */ + /* TODO: this code to be obsoleted with new import/xop.h conventions */ + if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include")) + { if (soap_element_begin_out(soap, tag, 0, type) + || soap_element_href(soap, "xop:Include", 0, "href", aid) + || soap_element_end_out(soap, tag)) + return soap->error; + } + else if (soap_element_href(soap, tag, 0, "href", aid)) + return soap->error; + if (soap->mode & SOAP_IO_LENGTH) + { if (pp->mark1 != 3) + { struct soap_multipart *content; + if (soap->mode & SOAP_ENC_MTOM) + content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size); + else + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size); + if (!content) + { soap->error = SOAP_EOM; + return -1; + } + if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */ + { if (soap->mode & SOAP_ENC_MTOM) + { char *s = (char*)soap_malloc(soap, strlen(aid) - 1); + if (s) + { *s = '<'; + strcpy(s + 1, aid + 4); + strcat(s, ">"); + content->id = s; + } + } + else + content->id = aid + 4; + } + else + content->id = aid; + content->type = atype; + content->options = aoptions; + content->encoding = SOAP_MIME_BINARY; + pp->mark1 = 3; + } + } + else + pp->mark2 = 3; + return -1; +} +#endif +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_init_iht(struct soap *soap) +{ register int i; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + soap->iht[i] = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_1 +static void +soap_free_iht(struct soap *soap) +{ register int i; + register struct soap_ilist *ip, *p; + register struct soap_flist *fp, *fq; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n")); + for (i = 0; i < SOAP_IDHASH; i++) + { for (ip = soap->iht[i]; ip; ip = p) + { for (fp = ip->flist; fp; fp = fq) + { fq = fp->next; + SOAP_FREE(soap, fp); + } + p = ip->next; + SOAP_FREE(soap, ip); + } + soap->iht[i] = NULL; + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_lookup(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next) + if (!strcmp(ip->id, id)) + return ip; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_ilist * +SOAP_FMAC2 +soap_enter(struct soap *soap, const char *id) +{ register size_t h; + register struct soap_ilist *ip; + ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id)); + if (ip) + { h = soap_hash(id); + strcpy(ip->id, id); + ip->next = soap->iht[h]; + soap->iht[h] = ip; + return ip; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_malloc(struct soap *soap, size_t n) +{ register char *p; + if (!n) + return (void*)SOAP_NON_NULL; + if (!soap) + return SOAP_MALLOC(soap, n); + if (soap->fmalloc) + p = (char*)soap->fmalloc(soap, n); + else + { n += sizeof(short); + n += (-(long)n) & (sizeof(void*)-1); /* align at 4-, 8- or 16-byte boundary */ + if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t)))) + { soap->error = SOAP_EOM; + return NULL; + } + /* set the canary to detect corruption */ + *(short*)(p + n - sizeof(short)) = (short)SOAP_CANARY; + /* keep chain of alloced cells for destruction */ + *(void**)(p + n) = soap->alist; + *(size_t*)(p + n + sizeof(void*)) = n; + soap->alist = p + n; + } + soap->alloced = 1; + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_init_mht(struct soap *soap) +{ register int i; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + soap->mht[i] = NULL; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_free_mht(struct soap *soap) +{ register int i; + register struct soap_mlist *mp, *mq; + for (i = 0; i < (int)SOAP_PTRHASH; i++) + { for (mp = soap->mht[i]; mp; mp = mq) + { mq = mp->next; + if (mp->live) + fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr); + free(mp); + } + soap->mht[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_track_malloc(struct soap *soap, const char *file, int line, size_t size) +{ register void *p = malloc(size); + if (soap) + { register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist)); + if (soap->fdebug[SOAP_INDEX_TEST]) + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p)); + mp->next = soap->mht[h]; + mp->ptr = p; + mp->file = file; + mp->line = line; + mp->live = 1; + soap->mht[h] = mp; + } + return p; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_track_free(struct soap *soap, const char *file, int line, void *p) +{ register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + { if (mp->live) + { free(p); + if (soap->fdebug[SOAP_INDEX_TEST]) + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p)); + mp->live = 0; + } + else + fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line); + } + else + fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_MEM_DEBUG +static void +soap_track_unlink(struct soap *soap, const void *p) +{ register size_t h = soap_hash_ptr(p); + register struct soap_mlist *mp; + for (mp = soap->mht[h]; mp; mp = mp->next) + if (mp->ptr == p) + break; + if (mp) + mp->live = 0; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_dealloc(struct soap *soap, void *p) +{ if (soap_check_state(soap)) + return; + if (p) + { register char **q; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { + if (*(short*)(char*)(*q - sizeof(short)) != (short)SOAP_CANARY) + { fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n")); + DBGHEX(TEST, *q - 200, 200); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n")); + soap->error = SOAP_MOE; + return; + } + if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p)); + SOAP_FREE(soap, p); + return; + } + } + soap_delete(soap, p); + } + else + { register char *q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n")); + while (soap->alist) + { q = (char*)soap->alist; + if (*(short*)(char*)(q - sizeof(short)) != (short)SOAP_CANARY) + { fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n")); + DBGHEX(TEST, q - 200, 200); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n")); + soap->error = SOAP_MOE; + return; + } + soap->alist = *(void**)q; + q -= *(size_t*)(q + sizeof(void*)); + SOAP_FREE(soap, q); + } + } + /* we must assume these were deallocated: */ + soap->action = NULL; + soap->fault = NULL; + soap->header = NULL; + soap->userid = NULL; + soap->passwd = NULL; + soap->authrealm = NULL; +#ifndef WITH_LEANER + soap_clr_mime(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_delete(struct soap *soap, void *p) +{ register struct soap_clist **cp; + if (soap_check_state(soap)) + return; + cp = &soap->clist; + if (p) + { while (*cp) + { if (p == (*cp)->ptr) + { register struct soap_clist *q = *cp; + *cp = q->next; + q->fdelete(q); + SOAP_FREE(soap, q); + return; + } + cp = &(*cp)->next; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p)); + } + else + { while (*cp) + { register struct soap_clist *q = *cp; + *cp = q->next; + q->fdelete(q); + SOAP_FREE(soap, q); + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +struct soap_clist * +SOAP_FMAC2 +soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*)) +{ register struct soap_clist *cp; + if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist)))) + { cp->next = soap->clist; + cp->type = t; + cp->size = n; + cp->ptr = p; + cp->fdelete = fdelete; + soap->clist = cp; + } + return cp; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_unlink(struct soap *soap, const void *p) +{ register char **q; + register struct soap_clist **cp; + if (!soap || !p) + return; + for (q = (char**)&soap->alist; *q; q = *(char***)q) + { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) + { *q = **(char***)q; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p)); +#ifdef SOAP_DEBUG + soap_track_unlink(soap, p); +#endif + return; + } + } + for (cp = &soap->clist; *cp; cp = &(*cp)->next) + { if (p == (*cp)->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p)); + q = (char**)*cp; + *cp = (*cp)->next; + SOAP_FREE(soap, q); + return; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_lookup_type(struct soap *soap, const char *id) +{ register struct soap_ilist *ip; + if (id && *id) + { ip = soap_lookup(soap, id); + if (ip) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type)); + return ip->type; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id)); + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k) +{ struct soap_ilist *ip; + void **q; + if (!p || !id || !*id) + return p; + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n)); + ip->type = t; + ip->size = n; + ip->link = p; + ip->copy = NULL; + ip->flist = NULL; + ip->ptr = NULL; + ip->level = k; + *p = NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n)); + if (ip->type != t) + { strcpy(soap->id, id); + soap->error = SOAP_HREF; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t)); + return NULL; + } + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + if (!q) + return NULL; + *p = (void*)q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + *p = ip->ptr; + } + else if (ip->level > k) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id)); + while (ip->level > k) + { void *s, **r = &ip->link; + q = (void**)ip->link; + while (q) + { *r = (void*)soap_malloc(soap, sizeof(void*)); + s = *q; + *q = *r; + r = (void**)*r; + q = (void**)s; + } + *r = NULL; + ip->size = n; + ip->copy = NULL; + ip->level = ip->level - 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n)); + while (ip->level < k) + { q = (void**)soap_malloc(soap, sizeof(void*)); + *p = q; + p = q; + k--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n")); + } + q = (void**)ip->link; + ip->link = p; + *p = (void*)q; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIDREF +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t)) +{ struct soap_ilist *ip; + if (!p || !href || !*href) + return p; + ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */ + if (!ip) + { ip = soap_enter(soap, href); /* new hash table entry for string id */ + ip->type = st; + ip->size = n; + ip->link = NULL; + ip->copy = NULL; + ip->ptr = NULL; + ip->level = 0; + ip->flist = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry href='%s' type=%d size=%lu level=%d location=%p\n", href, st, (unsigned long)n, k, p)); + } + else if (ip->type != st || (ip->level == k && ip->size != n)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n)); + strcpy(soap->id, href); + soap->error = SOAP_HREF; + return NULL; + } + if (fcopy || n < sizeof(void*) || *href != '#') + { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist)); + if (!fp) + { soap->error = SOAP_EOM; + return NULL; + } + fp->next = ip->flist; + fp->type = tt; + fp->ptr = p; + fp->level = k; + fp->len = len; + if (fcopy) + fp->fcopy = fcopy; + else + fp->fcopy = soap_fcopy; + ip->flist = fp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u len=%lu href='%s'\n", st, tt, (unsigned long)n, p, k, (unsigned long)len, href)); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href)); + *(void**)p = ip->copy; + ip->copy = p; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void* +SOAP_FMAC2 +soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)) +{ +#ifndef WITH_NOIDREF + struct soap_ilist *ip; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + soap->alloced = 0; + if (!p) + { if (finstantiate) + p = finstantiate(soap, t, type, arrayType, &n); + else + p = soap_malloc(soap, n); + if (p) + soap->alloced = 1; + } +#ifndef WITH_NOIDREF + if (!id || !*id) +#endif + return p; +#ifndef WITH_NOIDREF + ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */ + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p)); + if (!ip) + { ip = soap_enter(soap, id); /* new hash table entry for string id */ + ip->type = t; + ip->link = NULL; + ip->copy = NULL; + ip->flist = NULL; + ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%lu level=%u location=%p\n", id, t, (unsigned long)n, k, p)); + } + else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n)); + strcpy(soap->id, id); + soap->error = SOAP_HREF; + return NULL; + } + else if (ip->ptr) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id)); + strcpy(soap->id, id); + soap->error = SOAP_DUPLICATE_ID; + return NULL; + } + else + { ip->size = n; + ip->ptr = p; + ip->level = k; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update entry id='%s' type=%d location=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k)); + } + return ip->ptr; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n) +{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n)); + memcpy(p, q, n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_send(struct soap *soap) +{ +#ifndef WITH_LEANER + if (soap->dime.list) + { /* SOAP body referenced attachments must appear first */ + soap->dime.last->next = soap->dime.first; + soap->dime.first = soap->dime.list->next; + soap->dime.list->next = NULL; + soap->dime.last = soap->dime.list; + } + if (soap_putdime(soap) || soap_putmime(soap)) + return soap->error; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n")); + if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */ + { if (soap_flush(soap)) +#ifdef WITH_ZLIB + { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + } + return soap->error; + } +#else + return soap->error; +#endif +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { int r; + soap->d_stream.avail_in = 0; + do + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n")); + r = deflate(&soap->d_stream, Z_FINISH); + if (soap->d_stream.avail_out != SOAP_BUFLEN) + { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out)) + { soap->zlib_state = SOAP_ZLIB_NONE; + deflateEnd(&soap->d_stream); + return soap->error; + } + soap->d_stream.next_out = (Byte*)soap->z_buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + } + } while (r == Z_OK); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out)); + soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in; + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_state = SOAP_ZLIB_NONE; + if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:"")); + return soap->error = SOAP_ZLIB_ERROR; + } +#ifdef WITH_GZIP + soap->z_buf[0] = soap->z_crc & 0xFF; + soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF; + soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF; + soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF; + soap->z_buf[4] = soap->d_stream.total_in & 0xFF; + soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF; + soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF; + soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF; + if (soap_flush_raw(soap, soap->z_buf, 8)) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc)); +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) + { char *p; +#ifndef WITH_NOHTTP + if (!(soap->mode & SOAP_ENC_XML)) + { soap->mode--; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size)); + if (soap->status >= SOAP_POST) + soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size); + else if (soap->status != SOAP_STOP) + soap->error = soap->fresponse(soap, soap->status, soap->blist->size); + if (soap->error || soap_flush(soap)) + return soap->error; + soap->mode++; + } +#endif + for (p = soap_first_block(soap); p; p = soap_next_block(soap)) + { DBGMSG(SENT, p, soap_block_size(soap)); + if ((soap->error = soap->fsend(soap, p, soap_block_size(soap)))) + { soap_end_block(soap); + return soap->error; + } + } + soap_end_block(soap); + } +#ifndef WITH_LEANER + else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { DBGMSG(SENT, "\r\n0\r\n\r\n", 7); + if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7))) + return soap->error; + } +#endif + } +#ifdef WITH_TCPFIN +#ifdef WITH_OPENSSL + if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#else + if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP)) + soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */ +#endif +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n")); + soap->omode &= ~SOAP_XML_SEC; + soap->count = 0; + soap->part = SOAP_END; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_end_recv(struct soap *soap) +{ soap->part = SOAP_END; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap)) + return soap->error; + soap->dime.list = soap->dime.first; + soap->dime.first = NULL; + soap->dime.last = NULL; + /* Check if MIME attachments and mime-post-check flag is set, if set call soap_resolve() and return */ + if (soap->mode & SOAP_ENC_MIME) + { if (soap->mode & SOAP_MIME_POSTCHECK) + { soap_resolve(soap); + return SOAP_OK; + } + if (soap_getmime(soap)) + return soap->error; + } + soap->mime.list = soap->mime.first; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + if (soap->xlist) + { struct soap_multipart *content; + for (content = soap->mime.list; content; content = content->next) + soap_resolve_attachment(soap, content); + } +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n")); +#ifdef WITH_ZLIB + if (soap->mode & SOAP_ENC_ZLIB) + { soap->mode &= ~SOAP_ENC_ZLIB; + memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN); + soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf; + soap->buflen = soap->z_buflen; + soap->zlib_state = SOAP_ZLIB_NONE; + if (inflateEnd(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; +#ifdef WITH_GZIP + if (soap->zlib_in == SOAP_ZLIB_GZIP) + { soap_wchar c; + short i; + for (i = 0; i < 8; i++) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + soap->z_buf[i] = (char)c; + } + if (soap->z_crc != ((uLong)(unsigned char)soap->z_buf[0] | ((uLong)(unsigned char)soap->z_buf[1] << 8) | ((uLong)(unsigned char)soap->z_buf[2] << 16) | ((uLong)(unsigned char)soap->z_buf[3] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc)); + return soap->error = SOAP_ZLIB_ERROR; + } + if (soap->d_stream.total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24))) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n")); + return soap->error = SOAP_ZLIB_ERROR; + } + } +#endif + } +#endif + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */ + ; + if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap))) + return soap->error; +#ifndef WITH_NOIDREF + if (soap_resolve(soap)) + return soap->error; +#endif +#ifndef WITH_LEANER + if (soap->xlist) + { if (soap->mode & SOAP_ENC_MTOM) + return soap->error = SOAP_MIME_HREF; + return soap->error = SOAP_DIME_HREF; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_temp(struct soap *soap) +{ register struct Namespace *ns; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n")); + while (soap->nlist) + { register struct soap_nlist *np = soap->nlist->next; + SOAP_FREE(soap, soap->nlist); + soap->nlist = np; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n")); + while (soap->blist) + soap_end_block(soap); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n")); + while (soap->attributes) + { register struct soap_attribute *tp = soap->attributes->next; + if (soap->attributes->value) + SOAP_FREE(soap, soap->attributes->value); + SOAP_FREE(soap, soap->attributes); + soap->attributes = tp; + } +#ifdef WITH_FAST + if (soap->labbuf) + SOAP_FREE(soap, soap->labbuf); + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; +#endif + ns = soap->local_namespaces; + if (ns) + { for (; ns->id; ns++) + { if (ns->out) + { if (soap->encodingStyle == ns->out) + soap->encodingStyle = SOAP_STR_EOS; + SOAP_FREE(soap, ns->out); + ns->out = NULL; + } + if (soap->encodingStyle == ns->ns) + soap->encodingStyle = SOAP_STR_EOS; + } + SOAP_FREE(soap, soap->local_namespaces); + soap->local_namespaces = NULL; + } +#ifndef WITH_LEANER + while (soap->xlist) + { struct soap_xlist *xp = soap->xlist->next; + SOAP_FREE(soap, soap->xlist); + soap->xlist = xp; + } +#endif +#ifndef WITH_NOIDREF + soap_free_pht(soap); + soap_free_iht(soap); +#endif +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_init_logs(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + { soap->logfile[i] = NULL; + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_open_logfile(struct soap *soap, int i) +{ if (soap->logfile[i]) + soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a"); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_close_logfile(struct soap *soap, int i) +{ if (soap->fdebug[i]) + { fclose(soap->fdebug[i]); + soap->fdebug[i] = NULL; + } +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_close_logfiles(struct soap *soap) +{ int i; + for (i = 0; i < SOAP_MAXLOGS; i++) + soap_close_logfile(soap, i); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +static void +soap_set_logfile(struct soap *soap, int i, const char *logfile) +{ char *s = NULL; + soap_close_logfile(soap, i); + if (soap->logfile[i]) + SOAP_FREE(soap, (void*)soap->logfile[i]); + if (logfile) + if ((s = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1))) + strcpy(s, logfile); + soap->logfile[i] = s; +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_recv_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_sent_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile); +} +#endif + +/******************************************************************************/ +#ifdef SOAP_DEBUG +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_test_logfile(struct soap *soap, const char *logfile) +{ soap_set_logfile(soap, SOAP_INDEX_TEST, logfile); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy(struct soap *soap) +{ return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +struct soap* +SOAP_FMAC2 +soap_copy_context(struct soap *copy, struct soap *soap) +{ if (soap_check_state(soap)) + return NULL; + if (copy) + { register struct soap_plugin *p; + memcpy(copy, soap, sizeof(struct soap)); + copy->state = SOAP_COPY; + copy->error = SOAP_OK; + copy->userid = NULL; + copy->passwd = NULL; + copy->nlist = NULL; + copy->blist = NULL; + copy->clist = NULL; + copy->alist = NULL; + copy->attributes = NULL; + copy->labbuf = NULL; + copy->lablen = 0; + copy->labidx = 0; +#ifdef SOAP_DEBUG + soap_init_mht(copy); +#endif + copy->local_namespaces = NULL; +#ifndef WITH_NOIDREF + soap_init_iht(copy); + soap_init_pht(copy); +#endif + copy->header = NULL; + copy->fault = NULL; + copy->action = NULL; +#ifndef WITH_LEAN +#ifdef WITH_COOKIES + copy->cookies = soap_copy_cookies(copy, soap); +#else + copy->cookies = NULL; +#endif +#endif +#ifdef SOAP_DEBUG + soap_init_logs(copy); + soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]); + soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]); + soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]); +#endif + copy->plugins = NULL; + for (p = soap->plugins; p; p = p->next) + { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin)); + if (!q) + return NULL; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id)); + *q = *p; + if (p->fcopy && (soap->error = p->fcopy(copy, q, p))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not copy plugin '%s'\n", p->id)); + SOAP_FREE(copy, q); + return NULL; + } + q->next = copy->plugins; + copy->plugins = q; + } + } + else + soap->error = SOAP_EOM; + return copy; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_copy_stream(struct soap *copy, struct soap *soap) +{ copy->mode = soap->mode; + copy->imode = soap->imode; + copy->omode = soap->omode; + copy->socket = soap->socket; + copy->recv_timeout = soap->recv_timeout; + copy->send_timeout = soap->send_timeout; +#if defined(__cplusplus) && !defined(WITH_LEAN) + copy->os = soap->os; + copy->is = soap->is; +#endif + copy->sendfd = soap->sendfd; + copy->recvfd = soap->recvfd; + copy->bufidx = soap->bufidx; + copy->buflen = soap->buflen; + copy->ahead = soap->ahead; + copy->cdata = soap->cdata; + copy->chunksize = soap->chunksize; + copy->chunkbuflen = soap->chunkbuflen; + copy->keep_alive = soap->keep_alive; + copy->max_keep_alive = soap->max_keep_alive; +#ifndef WITH_NOIO + copy->peer = soap->peer; + copy->peerlen = soap->peerlen; +#endif +#ifdef WITH_OPENSSL + copy->bio = soap->bio; + copy->ssl = soap->ssl; + copy->ctx = soap->ctx; +#endif +#ifdef WITH_ZLIB + copy->zlib_state = soap->zlib_state; + copy->zlib_in = soap->zlib_in; + copy->zlib_out = soap->zlib_out; + copy->d_stream = soap->d_stream; + copy->z_buflen = soap->z_buflen; + copy->z_level = soap->z_level; + copy->z_crc = soap->z_crc; + copy->z_ratio_in = soap->z_ratio_in; + copy->z_ratio_out = soap->z_ratio_out; + memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf)); +#endif + memcpy(copy->buf, soap->buf, sizeof(soap->buf)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init(struct soap *soap) +{ soap->state = SOAP_INIT; + soap->version = 0; + soap_imode(soap, SOAP_IO_DEFAULT); + soap_omode(soap, SOAP_IO_DEFAULT); + soap->plugins = NULL; + soap->user = NULL; + soap->userid = NULL; + soap->passwd = NULL; +#ifndef WITH_NOHTTP + soap->fpost = http_post; + soap->fget = http_get; + soap->fform = NULL; + soap->fposthdr = http_post_header; + soap->fresponse = http_response; + soap->fparse = http_parse; + soap->fparsehdr = http_parse_header; +#endif + soap->fheader = NULL; + soap->fconnect = NULL; + soap->fdisconnect = NULL; +#ifndef WITH_NOIO +#ifndef WITH_IPV6 + soap->fresolve = tcp_gethost; +#else + soap->fresolve = NULL; +#endif + soap->faccept = tcp_accept; + soap->fopen = tcp_connect; + soap->fclose = tcp_disconnect; + soap->fclosesocket = tcp_closesocket; + soap->fshutdownsocket = tcp_shutdownsocket; + soap->fsend = fsend; + soap->frecv = frecv; + soap->fpoll = soap_poll; +#else + soap->fopen = NULL; + soap->fclose = NULL; + soap->fpoll = NULL; +#endif + soap->fseterror = NULL; + soap->fignore = NULL; + soap->fserveloop = NULL; + soap->fplugin = fplugin; + soap->fmalloc = NULL; +#ifndef WITH_LEANER + soap->fprepareinit = NULL; + soap->fpreparesend = NULL; + soap->fpreparerecv = NULL; + soap->fpreparefinal = NULL; + soap->fdimereadopen = NULL; + soap->fdimewriteopen = NULL; + soap->fdimereadclose = NULL; + soap->fdimewriteclose = NULL; + soap->fdimeread = NULL; + soap->fdimewrite = NULL; + soap->fmimereadopen = NULL; + soap->fmimewriteopen = NULL; + soap->fmimereadclose = NULL; + soap->fmimewriteclose = NULL; + soap->fmimeread = NULL; + soap->fmimewrite = NULL; +#endif + soap->float_format = "%G"; + soap->double_format = "%lG"; + soap->dime_id_format = "cid:id%d"; /* default DIME id format */ + soap->http_version = "1.1"; + soap->proxy_http_version = "1.0"; + soap->http_content = NULL; + soap->actor = NULL; + soap->max_keep_alive = SOAP_MAXKEEPALIVE; + soap->keep_alive = 0; + soap->recv_timeout = 0; + soap->send_timeout = 0; + soap->connect_timeout = 0; + soap->accept_timeout = 0; + soap->socket_flags = 0; + soap->connect_flags = 0; + soap->bind_flags = 0; + soap->accept_flags = 0; + soap->ip = 0; + soap->labbuf = NULL; + soap->lablen = 0; + soap->labidx = 0; + soap->encodingStyle = SOAP_STR_EOS; +#ifndef WITH_NONAMESPACES + soap->namespaces = namespaces; +#else + soap->namespaces = NULL; +#endif + soap->local_namespaces = NULL; + soap->nlist = NULL; + soap->blist = NULL; + soap->clist = NULL; + soap->alist = NULL; + soap->attributes = NULL; + soap->header = NULL; + soap->fault = NULL; + soap->master = SOAP_INVALID_SOCKET; + soap->socket = SOAP_INVALID_SOCKET; + soap->os = NULL; + soap->is = NULL; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; + soap->xlist = NULL; +#endif +#ifndef UNDER_CE + soap->recvfd = 0; + soap->sendfd = 1; +#else + soap->recvfd = stdin; + soap->sendfd = stdout; +#endif + soap->host[0] = '\0'; + soap->port = 0; + soap->action = NULL; + soap->proxy_host = NULL; + soap->proxy_port = 8080; + soap->proxy_userid = NULL; + soap->proxy_passwd = NULL; + soap->authrealm = NULL; + soap->prolog = NULL; +#ifdef WITH_OPENSSL + if (!ssl_init_done) + soap_ssl_init(); + soap->fsslauth = ssl_auth_init; + soap->fsslverify = ssl_verify_callback; + soap->bio = NULL; + soap->ssl = NULL; + soap->ctx = NULL; + soap->ssl_flags = SOAP_SSL_DEFAULT; + soap->keyfile = NULL; + soap->password = NULL; + soap->dhfile = NULL; + soap->cafile = NULL; + soap->capath = NULL; + soap->crlfile = NULL; + soap->randfile = NULL; + soap->session = NULL; +#endif +#ifdef WITH_ZLIB + soap->zlib_state = SOAP_ZLIB_NONE; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.zalloc = NULL; + soap->d_stream.zfree = NULL; + soap->d_stream.opaque = NULL; + soap->z_level = 6; +#endif +#ifndef WITH_LEAN + soap->c14ninclude = NULL; + soap->c14nexclude = NULL; + soap->cookies = NULL; + soap->cookie_domain = NULL; + soap->cookie_path = NULL; + soap->cookie_max = 32; +#endif +#ifdef SOAP_DEBUG + soap_init_mht(soap); + soap_init_logs(soap); +#endif +#ifdef WMW_RPM_IO + soap->rpmreqid = NULL; +#endif +#ifdef PALM + palmNetLibOpen(); +#endif +#ifndef WITH_NOIDREF + soap_init_iht(soap); + soap_init_pht(soap); +#endif +#ifdef SOAP_DEBUG + soap_set_recv_logfile(soap, "RECV.log"); + soap_set_sent_logfile(soap, "SENT.log"); + soap_set_test_logfile(soap, "TEST.log"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing context\n")); +#endif + soap_begin(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init1(struct soap *soap, soap_mode mode) +{ soap_init2(soap, mode, mode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_init2(struct soap *soap, soap_mode imode, soap_mode omode) +{ soap_init(soap); + soap_imode(soap, imode); + soap_omode(soap, omode); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_begin(struct soap *soap) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reinitializing context\n")); + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0); + soap->null = 0; + soap->position = 0; + soap->encoding = 0; + soap->mustUnderstand = 0; + soap->mode = 0; + soap->ns = 0; + soap->part = SOAP_END; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + soap->error = SOAP_OK; + soap->peeked = 0; + soap->ahead = 0; + soap->idnum = 0; + soap->level = 0; + soap->endpoint[0] = '\0'; +#ifndef WITH_LEANER + soap->dime.chunksize = 0; + soap->dime.buflen = 0; +#endif + soap_free_temp(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_end(struct soap *soap) +{ register struct soap_clist *cp; + if (soap_check_state(soap)) + return; + soap_free_temp(soap); + soap_dealloc(soap, NULL); + while (soap->clist) + { cp = soap->clist->next; + SOAP_FREE(soap, soap->clist); + soap->clist = cp; + } + soap_closesock(soap); +#ifdef SOAP_DEBUG + soap_close_logfiles(soap); +#endif +#ifdef PALM + palmNetLibClose(); +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_namespaces(struct soap *soap, const struct Namespace *p) +{ register struct Namespace *ns = soap->local_namespaces; + register struct soap_nlist *np, *nq, *nr; + register unsigned int level = soap->level; + soap->namespaces = p; + soap->local_namespaces = NULL; + soap_set_local_namespaces(soap); + /* reverse the namespace list */ + np = soap->nlist; + soap->nlist = NULL; + if (np) + { nq = np->next; + np->next = NULL; + while (nq) + { nr = nq->next; + nq->next = np; + np = nq; + nq = nr; + } + } + /* then push on new stack */ + while (np) + { register const char *s; + soap->level = np->level; /* preserve element nesting level */ + s = np->ns; + if (!s && np->index >= 0 && ns) + { s = ns[np->index].out; + if (!s) + s = ns[np->index].ns; + } + if (s && soap_push_namespace(soap, np->id, s)) + return soap->error; + nq = np; + np = np->next; + SOAP_FREE(soap, nq); + } + if (ns) + { register int i; + for (i = 0; ns[i].id; i++) + { if (ns[i].out) + { SOAP_FREE(soap, ns[i].out); + ns[i].out = NULL; + } + } + SOAP_FREE(soap, ns); + } + soap->level = level; /* restore level */ + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_local_namespaces(struct soap *soap) +{ if (soap->namespaces && !soap->local_namespaces) + { register const struct Namespace *ns1; + register struct Namespace *ns2; + register size_t n = 1; + for (ns1 = soap->namespaces; ns1->id; ns1++) + n++; + n *= sizeof(struct Namespace); + ns2 = (struct Namespace*)SOAP_MALLOC(soap, n); + if (ns2) + { memcpy(ns2, soap->namespaces, n); + if (ns2[0].ns) + { if (!strcmp(ns2[0].ns, soap_env1)) + soap->version = 1; + else + soap->version = 2; + } + soap->local_namespaces = ns2; + } + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_strsearch(const char *big, const char *little) +{ size_t n = strlen(little); + const char *s = big; + while (s) + { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' ')) + return s; + s = strchr(s, ' '); + if (s) + s++; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_nlist * +SOAP_FMAC2 +soap_lookup_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np; + for (np = soap->nlist; np; np = np->next) + { if (!strncmp(np->id, tag, n) && !np->id[n]) + return np; + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static struct soap_nlist * +soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized) +{ register struct soap_nlist *np; + size_t n, k; + if (soap_strsearch(soap->c14nexclude, id)) + return NULL; + if (!utilized) + { for (np = soap->nlist; np; np = np->next) + { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns))) + break; + } + if (np) + { if ((np->level < soap->level || !np->ns) && np->index == 1) + utilized = 1; + else + return NULL; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns?ns:"(null)", utilized)); + n = strlen(id); + if (ns) + k = strlen(ns); + else + k = 0; + np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1); + if (!np) + { soap->error = SOAP_EOM; + return NULL; + } + np->next = soap->nlist; + soap->nlist = np; + strcpy(np->id, id); + if (ns) + { np->ns = np->id + n + 1; + strcpy(np->ns, ns); + } + else + np->ns = NULL; + np->level = soap->level; + np->index = utilized; + return np; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static void +soap_utilize_ns(struct soap *soap, const char *tag, size_t n) +{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Utilizing namespace of '%s'\n", tag)); + if (np) + { if (np->index == 0) + soap_push_ns(soap, np->id, np->ns, 1); + } + else if (strncmp(tag, "xml", 3)) + { strncpy(soap->tmpbuf, tag, n); + soap->tmpbuf[n] = '\0'; + soap_push_ns(soap, soap->tmpbuf, NULL, 1); + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static void +soap_pop_ns(struct soap *soap) +{ soap_pop_namespace(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element(struct soap *soap, const char *tag, int id, const char *type) +{ +#ifdef WITH_XMLNS + register const char *s; +#endif + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:"")); +#ifdef WITH_DOM + if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS)) + { register struct soap_nlist *np; + /* wsu:Id found: clear xmlns renderings, so re-emit them for exc-c14n */ + for (np = soap->nlist; np; np = np->next) + { if (np->index == 2) + np->index = 0; + } + } + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error = SOAP_EOM; + elt->soap = soap; + elt->next = NULL; + elt->prnt = soap->dom; + elt->name = soap_strdup(soap, tag); + elt->elts = NULL; + elt->atts = NULL; + elt->nstr = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->node = NULL; + elt->type = 0; + elt->head = NULL; + elt->tail = NULL; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + } + else + { +#endif + soap->level++; +#ifndef WITH_LEAN + if (!soap->ns) + { if (!(soap->mode & SOAP_XML_CANONICAL) + && soap_send(soap, soap->prolog ? soap->prolog : "\n")) + return soap->error; + } + else if (soap->mode & SOAP_XML_INDENT) + { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + soap->body = 1; + } +#endif +#ifdef WITH_XMLNS + s = strchr(tag, ':'); + if (s && strncmp(tag, "SOAP-ENV", s - tag)) + { struct Namespace *ns = soap->local_namespaces; + size_t n = s - tag; + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, s + 1)) + return soap->error; + if (soap->nlist && !strncmp(soap->nlist->id, tag, n) && !soap->nlist->id[n]) + ns = NULL; + for (; ns && ns->id; ns++) + { if (*ns->id && (ns->out || ns->ns) && !strncmp(ns->id, tag, n) && !ns->id[n]) + { soap_push_ns(soap, ns->id, ns->out ? ns->out : ns->ns, 0); + if (soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns)) + return soap->error; + break; + } + } + } + else +#endif + if (soap_send_raw(soap, "<", 1) + || soap_send(soap, tag)) + return soap->error; +#ifdef WITH_DOM + } +#endif + if (!soap->ns) + { struct Namespace *ns; + for (ns = soap->local_namespaces; ns && ns->id; ns++) + { if (*ns->id && (ns->out || ns->ns)) + { sprintf(soap->tmpbuf, "xmlns:%s", ns->id); + if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns)) + return soap->error; + } + } + } + soap->ns = 1; /* start with 0 or 2, but should be one to continue */ +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *t = strchr(tag, ':'); + if (t) + soap_utilize_ns(soap, tag, t - tag); + } +#endif + if (id > 0) + { sprintf(soap->tmpbuf, "_%d", id); + if (soap_attribute(soap, "id", soap->tmpbuf)) + return soap->error; + } + if (type && *type && (!(soap->mode & SOAP_XML_SEC) || soap->part == SOAP_IN_BODY)) + { if (soap_attribute(soap, "xsi:type", type)) + return soap->error; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { const char *t = strchr(type, ':'); + if (t) + soap_utilize_ns(soap, type, t - type); + } +#endif + } + if (soap->null && soap->position > 0) + { register int i; + sprintf(soap->tmpbuf, "[%d", soap->positions[0]); + for (i = 1; i < soap->position; i++) + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]); + strcat(soap->tmpbuf, "]"); + if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf)) + return soap->error; + } + if (soap->mustUnderstand) + { if (soap->actor && *soap->actor) + { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor)) + return soap->error; + } + if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1")) + return soap->error; + soap->mustUnderstand = 0; + } + if (soap->encoding) + { if (soap->encodingStyle && soap->local_namespaces) + { if (!*soap->encodingStyle) + { if (soap->local_namespaces[1].out) + soap->encodingStyle = soap->local_namespaces[1].out; + else + soap->encodingStyle = soap->local_namespaces[1].ns; + } + if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle)) + return soap->error; + } + soap->encoding = 0; + } + soap->null = 0; + soap->position = 0; + if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL)) + soap->part = SOAP_IN_SECURITY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type) +{ if (*tag == '-') + return SOAP_OK; + if (soap_element(soap, tag, id, type)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRRCHR +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_strrchr(const char *s, int t) +{ register char *r = NULL; + while (*s) + if (*s++ == t) + r = (char*)s - 1; + return r; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOL +SOAP_FMAC1 +long +SOAP_FMAC2 +soap_strtol(const char *s, char **t, int b) +{ register long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { short neg = 0; + if (*s == '-') + { s++; + neg = 1; + } + else if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 214748364 && (n > 214748364 || c >= '8')) + break; + n *= 10; + n += c - '0'; + s++; + } + if (neg) + n = -n; + } + else /* b == 16 and value is always positive */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x07FFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef HAVE_STRTOUL +SOAP_FMAC1 +unsigned long +SOAP_FMAC2 +soap_strtoul(const char *s, char **t, int b) +{ unsigned long n = 0; + register int c; + while (*s > 0 && *s <= 32) + s++; + if (b == 10) + { if (*s == '+') + s++; + while ((c = *s) && c >= '0' && c <= '9') + { if (n >= 429496729 && (n > 429496729 || c >= '6')) + break; + n *= 10; + n += c - '0'; + s++; + } + } + else /* b == 16 */ + { while ((c = *s)) + { if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + if (n > 0x0FFFFFFF) + break; + n <<= 4; + n += c; + s++; + } + } + if (t) + *t = (char*)s; + return n; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset) +{ if (soap_element(soap, tag, id, "SOAP-ENC:Array")) + return soap->error; + if (soap->version == 2) + { const char *s; + s = soap_strrchr(type, '['); + if ((size_t)(s - type) < sizeof(soap->tmpbuf)) + { strncpy(soap->tmpbuf, type, s - type); + soap->tmpbuf[s - type] = '\0'; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf))) + return soap->error; + if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1))) + return soap->error; + } + } + else + { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset))) + return soap->error; + if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type))) + return soap->error; + } +#ifndef WITH_LEAN + if (type && *type && (soap->mode & SOAP_XML_CANONICAL)) + { const char *s = strchr(type, ':'); + if (s) + soap_utilize_ns(soap, type, s - type); + } +#endif + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_start_end_out(struct soap *soap, const char *tag) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_nlist *np; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->name) + { const char *s = strchr(tp->name, ':'); + if (s) + soap_utilize_ns(soap, tp->name, s - tp->name); + } + } + for (np = soap->nlist; np; np = np->next) + { if (np->index == 1 && np->ns) + { sprintf(soap->tmpbuf, "xmlns:%s", np->id); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enabling utilized binding (level=%u) %s='%s'\n", np->level, soap->tmpbuf, np->ns)); + soap_set_attr(soap, soap->tmpbuf, np->ns); + np->index = 2; + } + } + } +#endif +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { register struct soap_dom_attribute **att; + att = &soap->dom->atts; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error = SOAP_EOM; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, tp->name); + (*att)->data = soap_strdup(soap, tp->value); + (*att)->wide = NULL; + (*att)->soap = soap; + att = &(*att)->next; + tp->visible = 0; + } + } + return SOAP_OK; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible) + { +#ifdef WITH_XMLNS + const char *s = strchr(tp->name, ':'); + if (s) + { size_t n = s - tp->name; + if (soap->nlist && !strncmp(soap->nlist->id, tp->name, n) && !soap->nlist->id[n]) + s++; + else + s = tp->name; + if (soap_send(soap, " ") || soap_send(soap, s)) + return soap->error; + } + else +#endif + if (soap_send(soap, " ") || soap_send(soap, tp->name)) + return soap->error; + if (tp->visible == 2 && tp->value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, tp->value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + tp->visible = 0; + } + } + if (tag) + { +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { if (soap_send_raw(soap, ">", 1) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; + } +#endif + soap->level--; /* decrement level just before /> */ + if (soap_send_raw(soap, "/>", 2)) + return soap->error; + return SOAP_OK; + } + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_out(struct soap *soap, const char *tag) +{ if (*tag == '-') + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + soap_pop_ns(soap); + if (soap->mode & SOAP_XML_INDENT) + { if (!soap->body) + { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1)) + return soap->error; + } + soap->body = 0; + } +#endif +#ifdef WITH_XMLNS + { const char *s = strchr(tag, ':'); + if (s && strncmp(tag, "SOAP-ENV", s - tag)) + { soap_pop_ns(soap); + tag = s + 1; + } + } +#endif + if (soap_send_raw(soap, "error; + soap->level--; /* decrement level just before > */ + return soap_send_raw(soap, ">", 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_ref(struct soap *soap, const char *tag, int id, int href) +{ register int n = 0; + const char *s = "href"; + if (soap->version == 2) + { s = "SOAP-ENC:ref"; + n = 1; + } + sprintf(soap->href, "#_%d", href); + return soap_element_href(soap, tag, id, s, soap->href + n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val) +{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val)); + if (soap_element(soap, tag, id, NULL) + || soap_attribute(soap, ref, val) + || soap_element_start_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_null(struct soap *soap, const char *tag, int id, const char *type) +{ struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + if (tp->visible) + break; + if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL)) + { if (soap_element(soap, tag, id, type)) + return soap->error; + if (soap->part != SOAP_IN_HEADER && soap->encodingStyle) + if (soap_attribute(soap, "xsi:nil", "true")) + return soap->error; + return soap_element_start_end_out(soap, tag); + } + soap->null = 1; + soap->position = 0; + soap->mustUnderstand = 0; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_id(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, int n, const char *type, int t) +{ if (!p || (a && !a->__ptr)) + { soap_element_null(soap, tag, id, type); + return -1; + } +#ifndef WITH_NOIDREF + if (soap->mode & SOAP_XML_TREE) + return 0; + if (id < 0) + { struct soap_plist *pp; + if (a) + id = soap_array_pointer_lookup(soap, p, a, n, t, &pp); + else + id = soap_pointer_lookup(soap, p, t, &pp); + if (id) + { if (soap_is_embedded(soap, pp)) + { soap_element_ref(soap, tag, 0, id); + return -1; + } + if (soap_is_single(soap, pp)) + return 0; + soap_set_embedded(soap, pp); + } + } + return id; +#else + return 0; +#endif +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + if (soap_element(soap, "SOAP-RPC:result", 0, NULL) + || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc) + || soap_element_start_end_out(soap, NULL) + || soap_string_out(soap, tag, 0) + || soap_element_end_out(soap, "SOAP-RPC:result")) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_check_result(struct soap *soap, const char *tag) +{ if (soap->version == 2 && soap->encodingStyle) + { soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1); + /* should compare tag to element's QName value? */ + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_attribute(struct soap *soap, const char *name, const char *value) +{ +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom) + { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + a->next = soap->dom->atts; + a->nstr = NULL; + a->name = soap_strdup(soap, name); + a->data = soap_strdup(soap, value); + a->wide = NULL; + a->soap = soap; + soap->dom->atts = a; + return SOAP_OK; + } +#endif +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { /* TODO: consider using this code to handle default namespace bindings + if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0')) + { if (name[5] == ':') + soap_push_ns(soap, name + 6, value, 0); + else + soap_push_ns(soap, "", value, 0); + } + */ + if (!strncmp(name, "xmlns:", 6)) + soap_push_ns(soap, name + 6, value, 0); + else if (soap_set_attr(soap, name, value)) + return soap->error; + } + else +#endif + { if (soap_send(soap, " ") || soap_send(soap, name)) + return soap->error; + if (value) + if (soap_send_raw(soap, "=\"", 2) + || soap_string_out(soap, value, 1) + || soap_send_raw(soap, "\"", 1)) + return soap->error; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const char *type) +{ if (!soap_peek_element(soap)) + { if (soap->other) + return soap->error = SOAP_TAG_MISMATCH; + if (tag && *tag == '-') + return SOAP_OK; + if (!(soap->error = soap_match_tag(soap, soap->tag, tag))) + { soap->peeked = 0; + if (soap->body) + soap->level++; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" )); + if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT)) + return soap->error = SOAP_NULL; + if (type && *soap->type && soap_match_tag(soap, soap->type, type)) + return soap->error = SOAP_TYPE; + } + } + else if (soap->error == SOAP_NO_TAG && tag && *tag == '-') + soap->error = SOAP_OK; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_element_end_in(struct soap *soap, const char *tag) +{ register soap_wchar c; + register char *s; + register const char *t; + register int n = 0; + if (tag && *tag == '-') + return SOAP_OK; + soap->level--; + soap_pop_namespace(soap); +#ifdef WITH_DOM + /* this whitespace or mixed content is not insignificant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1)) + return soap->error; + if (soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + if (soap->peeked) + { if (soap->error == SOAP_NO_TAG) + soap->error = SOAP_OK; + if (*soap->tag) + n++; + soap->peeked = 0; + } + do + { while (((c = soap_get(soap)) != SOAP_TT)) + { if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (c == SOAP_LT) + n++; + else if (c == '/') + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + else + soap_unget(soap, c); + } + } + } while (n--); + s = soap->tag; + n = sizeof(soap->tag); + while (soap_notblank(c = soap_get(soap))) + { if (--n > 0) + *s++ = (char)c; + } + *s = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + while (soap_blank(c)) + c = soap_get(soap); + if (c != SOAP_GT) + return soap->error = SOAP_SYNTAX_ERROR; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"")); + if (!tag || !*tag) + return SOAP_OK; + if ((s = strchr(soap->tag, ':'))) + s++; + else + s = soap->tag; + if ((t = strchr(tag, ':'))) + t++; + else + t = tag; + if (!SOAP_STRCMP(s, t)) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n")); + return soap->error = SOAP_SYNTAX_ERROR; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_attr_value(struct soap *soap, const char *name, int flag) +{ register struct soap_attribute *tp; + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && !soap_match_tag(soap, tp->name, name)) + break; + } + if (tp) + { if (flag == 2 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_PROHIBITED; + else + return tp->value; + } + else if (flag == 1 && (soap->mode & SOAP_XML_STRICT)) + soap->error = SOAP_REQUIRED; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_attr(struct soap *soap, const char *name, const char *value) +{ register struct soap_attribute *tp; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:"")); + for (tp = soap->attributes; tp; tp = tp->next) + { if (!strcmp(tp->name, name)) + break; + } + if (!tp) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name)); + if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name)))) + return soap->error = SOAP_EOM; + tp->ns = NULL; +#ifndef WITH_LEAN + if (soap->mode & SOAP_XML_CANONICAL) + { struct soap_attribute **tpp = &soap->attributes; + const char *s = strchr(name, ':'); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inserting attribute %s for c14n\n", name)) + if (!strncmp(name, "xmlns", 5)) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0) + break; + } + else if (!s) + { for (; *tpp; tpp = &(*tpp)->next) + if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0)) + break; + } + else + { int k; + for (; *tpp; tpp = &(*tpp)->next) + { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name]) + { if (!tp->ns) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p (%s)\n", name, (*tpp)->ns, (*tpp)->ns)); + tp->ns = (*tpp)->ns; + } + } + else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0))) + break; + } + } + tp->next = *tpp; + *tpp = tp; + } + else +#endif + { tp->next = soap->attributes; + soap->attributes = tp; + } + strcpy(tp->name, name); + tp->value = NULL; + } + else if (tp->visible) + { return SOAP_OK; + } + else if (value && tp->value && tp->size <= strlen(value)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value)); + SOAP_FREE(soap, tp->value); + tp->value = NULL; + tp->ns = NULL; + } + if (value) + { if (!tp->value) + { tp->size = strlen(value) + 1; + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value for %s (%p)\n", tp->name, tp->value)); + } + strcpy(tp->value, value); + if (!strncmp(tp->name, "xmlns:", 6)) + tp->ns = tp->value; + tp->visible = 2; +#ifndef WITH_LEAN + if (!strcmp(name, "wsu:Id")) + { soap->part = SOAP_BEGIN_SECURITY; + strncpy(soap->id, value, sizeof(soap->id)); + soap->id[sizeof(soap->id)-1] = '\0'; + } +#endif + } + else + tp->visible = 1; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_attr(struct soap *soap) +{ register struct soap_attribute *tp; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_CANONICAL)) + { while (soap->attributes) + { tp = soap->attributes->next; + if (soap->attributes->value) + SOAP_FREE(soap, soap->attributes->value); + SOAP_FREE(soap, soap->attributes); + soap->attributes = tp; + } + } + else +#endif + { for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d) +{ register size_t i; + for (i = 0; i < n; i++) + { register soap_wchar c = soap_get(soap); + switch (c) + { + case SOAP_TT: + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + *s++ = '<'; + break; + case SOAP_GT: + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + *s++ = '>'; + break; + case SOAP_QT: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '"'; + break; + case SOAP_AP: + if (c == d) + { *s = '\0'; + return SOAP_OK; + } + *s++ = '\''; + break; + case '\t': + case '\n': + case '\r': + case ' ': + case '/': + if (d == ' ') + { soap_unget(soap, c); + *s = '\0'; + return SOAP_OK; + } + default: + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + } + return soap->error = SOAP_EOM; +} +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_store_lab(struct soap *soap, const char *s, size_t n) +{ soap->labidx = 0; + return soap_append_lab(soap, s, n); +} +#endif +#endif + +/******************************************************************************/ +#ifdef WITH_FAST +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_append_lab(struct soap *soap, const char *s, size_t n) +{ if (soap->labidx + n >= soap->lablen) + { register char *t = soap->labbuf; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen)); + if (soap->lablen == 0) + soap->lablen = SOAP_LABLEN; + while (soap->labidx + n >= soap->lablen) + soap->lablen <<= 1; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen)); + soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen); + if (!soap->labbuf) + { if (t) + SOAP_FREE(soap, t); + return soap->error = SOAP_EOM; + } + if (t) + { memcpy(soap->labbuf, t, soap->labidx); + SOAP_FREE(soap, t); + } + } + if (s) + { memcpy(soap->labbuf + soap->labidx, s, n); + soap->labidx += n; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_peek_element(struct soap *soap) +{ +#ifdef WITH_DOM + register struct soap_dom_attribute **att = NULL; + register char *lead = NULL; +#endif + register struct soap_attribute *tp; + const char *t; + register char *s; + register soap_wchar c; + register int i; + if (soap->peeked) + { if (!*soap->tag) + return soap->error = SOAP_NO_TAG; + return SOAP_OK; + } + soap->peeked = 1; + c = soap_getutf8(soap); +#ifdef WITH_DOM + /* whitespace leading to start tag is not insignificant for DOM */ + if (soap_blank(c)) + { soap->labidx = 0; + do + { if (soap_append_lab(soap, NULL, 0)) + return SOAP_EOM; + s = soap->labbuf + soap->labidx; + i = soap->lablen - soap->labidx; + soap->labidx = soap->lablen; + while (soap_blank(c) && i--) + { *s++ = c; + c = soap_getutf8(soap); + } + } + while (soap_blank(c)); + *s = '\0'; + lead = soap_strdup(soap, soap->labbuf); + } +#else + while (soap_blank(c)) + c = soap_getutf8(soap); +#endif + if (c != SOAP_LT) + { *soap->tag = '\0'; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifdef WITH_DOM + /* whitespace leading to end tag is not insignificant for DOM */ + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->tail = soap_strdup(soap, lead); +#endif + return soap->error = SOAP_NO_TAG; + } + s = soap->tag; + do c = soap_get1(soap); + while (soap_blank(c)); + i = sizeof(soap->tag); + while (c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF) + { if (--i > 0) + *s++ = (char)c; + c = soap_get1(soap); + } + while (soap_blank(c)) + c = soap_get1(soap); + *s = '\0'; + soap->id[0] = '\0'; + soap->href[0] = '\0'; + soap->type[0] = '\0'; + soap->arrayType[0] = '\0'; + soap->arraySize[0] = '\0'; + soap->arrayOffset[0] = '\0'; + soap->other = 0; + soap->root = -1; + soap->position = 0; + soap->null = 0; + soap->mustUnderstand = 0; +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { register struct soap_dom_element *elt; + elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + if (!elt) + return soap->error = SOAP_EOM; + elt->next = NULL; + elt->nstr = NULL; + elt->name = soap_strdup(soap, soap->tag); + elt->prnt = soap->dom; + elt->elts = NULL; + elt->atts = NULL; + elt->data = NULL; + elt->wide = NULL; + elt->type = 0; + elt->node = NULL; + elt->head = lead; + elt->tail = NULL; + elt->soap = soap; + if (soap->dom) + { struct soap_dom_element *p = soap->dom->elts; + if (p) + { while (p->next) + p = p->next; + p->next = elt; + } + else + soap->dom->elts = elt; + } + soap->dom = elt; + att = &elt->atts; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + tp->visible = 0; + while ((int)c != EOF && c != '>' && c != '/') + { s = soap->tmpbuf; + i = sizeof(soap->tmpbuf); + while (c != '=' && c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF) + { if (--i > 0) + *s++ = (char)c; + c = soap_get1(soap); + } + *s = '\0'; + if (i == sizeof(soap->tmpbuf)) + return soap->error = SOAP_SYNTAX_ERROR; +#ifdef WITH_DOM + /* add attribute name to dom */ + if (att) + { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + if (!*att) + return soap->error = SOAP_EOM; + (*att)->next = NULL; + (*att)->nstr = NULL; + (*att)->name = soap_strdup(soap, soap->tmpbuf); + (*att)->data = NULL; + (*att)->wide = NULL; + (*att)->soap = soap; + } +#endif + if (!strncmp(soap->tmpbuf, "xmlns", 5)) + { if (soap->tmpbuf[5] == ':') + { soap->tmpbuf[5] = '\0'; + t = soap->tmpbuf + 6; + } + else if (soap->tmpbuf[5]) + t = NULL; + else + t = SOAP_STR_EOS; + } + else + t = NULL; + for (tp = soap->attributes; tp; tp = tp->next) + { if (!SOAP_STRCMP(tp->name, soap->tmpbuf)) + break; + } + if (!tp) + { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf)); + if (!tp) + return soap->error = SOAP_EOM; + strcpy(tp->name, soap->tmpbuf); + tp->value = NULL; + tp->size = 0; + tp->next = soap->attributes; + soap->attributes = tp; + } + while (soap_blank(c)) + c = soap_get1(soap); + if (c == '=') + { do c = soap_getutf8(soap); + while (soap_blank(c)); + if (c != SOAP_QT && c != SOAP_AP) + { soap_unget(soap, c); + c = ' '; /* blank delimiter */ + } + if (soap_getattrval(soap, tp->value, tp->size, c)) + { +#ifdef WITH_FAST + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_store_lab(soap, tp->value, tp->size)) + return soap->error; + if (tp->value) + SOAP_FREE(soap, tp->value); + for (;;) + { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + soap->labidx = soap->lablen; + if (soap_append_lab(soap, NULL, 0)) + return soap->error; + } + else + break; + } + if (soap->labidx) + tp->size = soap->lablen; + else + { tp->size = strlen(soap->labbuf) + 1; + if (tp->size < SOAP_LABLEN) + tp->size = SOAP_LABLEN; + } + if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size))) + return soap->error = SOAP_EOM; + strcpy(tp->value, soap->labbuf); +#else + size_t n; + if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + if (soap_new_block(soap)) + return soap->error; + for (;;) + { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN))) + return soap->error; + if (soap_getattrval(soap, s, SOAP_BLKLEN, c)) + { if (soap->error != SOAP_EOM) + return soap->error; + soap->error = SOAP_OK; + } + else + break; + } + n = tp->size + soap->blist->size; + if (!(s = (char*)SOAP_MALLOC(soap, n))) + return soap->error = SOAP_EOM; + if (tp->value) + { memcpy(s, tp->value, tp->size); + SOAP_FREE(soap, tp->value); + } + soap_save_block(soap, s + tp->size, 0); + tp->value = s; + tp->size = n; +#endif + } + do c = soap_get1(soap); + while (soap_blank(c)); + tp->visible = 2; /* seen this attribute w/ value */ +#ifdef WITH_DOM + if (att) + (*att)->data = soap_strdup(soap, tp->value); +#endif + } + else + tp->visible = 1; /* seen this attribute w/o value */ +#ifdef WITH_DOM + if (att) + att = &(*att)->next; +#endif + if (t && tp->value) + { if (soap_push_namespace(soap, t, tp->value)) + return soap->error; + tp->visible = 0; + } + } +#ifdef WITH_DOM + if (att) + { soap->dom->nstr = soap_current_namespace(soap, soap->tag); + for (att = &soap->dom->atts; *att; att = &(*att)->next) + (*att)->nstr = soap_current_namespace(soap, (*att)->name); + } +#endif + if ((int)c == EOF) + return soap->error = SOAP_EOF; + if (!(soap->body = (c != '/'))) + do c = soap_get1(soap); + while (soap_blank(c)); +#ifdef WITH_DOM + if (soap->mode & SOAP_XML_DOM) + { if (!soap->body && soap->dom->prnt) + soap->dom = soap->dom->prnt; + } +#endif + for (tp = soap->attributes; tp; tp = tp->next) + { if (tp->visible && tp->value) + { if (!strcmp(tp->name, "id")) + { if (soap->version > 0 + || (soap->mode & SOAP_XML_GRAPH)) + { *soap->id = '#'; + strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2); + soap->id[sizeof(soap->id)-1] = '\0'; + } + } + else if (!strcmp(tp->name, "href")) + { if (soap->version == 1 + || (soap->mode & SOAP_XML_GRAPH) + || (soap->mode & SOAP_ENC_MTOM)) + { strncpy(soap->href, tp->value, sizeof(soap->href) - 1); + soap->href[sizeof(soap->href)-1] = '\0'; + } + } + else if (!soap_match_tag(soap, tp->name, "xsi:type")) + { strncpy(soap->type, tp->value, sizeof(soap->type) - 1); + soap->type[sizeof(soap->type)-1] = '\0'; + } + else if ((!soap_match_tag(soap, tp->name, "xsi:null") + || !soap_match_tag(soap, tp->name, "xsi:nil")) + && (!strcmp(tp->value, "1") + || !strcmp(tp->value, "true"))) + { soap->null = 1; + } + else if (soap->version == 1) + { if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType")) + { s = soap_strrchr(tp->value, '['); + if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType)) + { strncpy(soap->arrayType, tp->value, s - tp->value); + soap->arrayType[s - tp->value] = '\0'; + strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1); + } + else + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + soap->arraySize[sizeof(soap->arrayType)-1] = '\0'; + soap->arrayType[sizeof(soap->arrayType)-1] = '\0'; + } + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:offset")) + strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset)); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:position")) + soap->position = soap_getposition(tp->value, soap->positions); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:root")) + soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor")) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next")) + soap->other = 1; + } + } + else if (soap->version == 2) + { if (!strcmp(tp->name, "ref") + || !soap_match_tag(soap, tp->name, "SOAP-ENC:ref")) + { *soap->href = '#'; + strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2); + soap->href[sizeof(soap->href)-1] = '\0'; + } + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:itemType")) + strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize")) + strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1); + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand") + && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true"))) + soap->mustUnderstand = 1; + else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:role")) + { if ((!soap->actor || strcmp(soap->actor, tp->value)) + && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next")) + soap->other = 1; + } + } + } + } + return soap->error = SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_retry(struct soap *soap) +{ soap->error = SOAP_OK; + soap_revert(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_revert(struct soap *soap) +{ if (!soap->peeked) + { soap->peeked = 1; + if (soap->body) + soap->level--; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level)); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_string_out(struct soap *soap, const char *s, int flag) +{ register const char *t; + register soap_wchar c; + register soap_wchar mask = 0xFFFFFF80UL; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { soap->dom->data = soap_strdup(soap, s); + return SOAP_OK; + } +#endif + if (soap->mode & SOAP_C_UTFSTRING) + mask = 0; + t = s; + while ((c = *t++)) + { switch (c) + { + case 0x09: + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 0x0A: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + } + break; + case 0x0D: + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, " ", 5)) + return soap->error; + s = t; + break; + case '&': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&", 5)) + return soap->error; + s = t; + break; + case '<': + if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "<", 4)) + return soap->error; + s = t; + break; + case '>': + if (!flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, ">", 4)) + return soap->error; + s = t; + } + break; + case '"': + if (flag) + { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, """, 6)) + return soap->error; + s = t; + } + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_MBTOWC + if (soap->mode & SOAP_C_MBSTRING) + { wchar_t wc; + register int m = mbtowc(&wc, t - 1, MB_CUR_MAX); + if (m > 0 && wc != c) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc)) + return soap->error; + s = t += m - 1; + continue; + } + } +#endif +#endif + if ((c & mask) || !(c & 0xFFFFFFE0UL)) + { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c)) + return soap->error; + s = t; + } + } + } + return soap_send_raw(soap, s, t - s - 1); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) +{ register char *s; + char *t = NULL; + register size_t i; + register long l = 0; + register int n = 0; + register int m = 0; + register soap_wchar c; +#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB) + char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8]; +#else + char buf[8]; +#endif + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n")); + if (soap->peeked) + { if (!soap->body) + return NULL; + if (*soap->tag) + { n = 1; + soap->peeked = 0; +#ifndef WITH_LEAN + t = soap->tmpbuf; + t[0] = '<'; + strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 1); + strncat(t, ">", sizeof(soap->tmpbuf)); + m = strlen(soap->tag) + 2; +#endif + } + } +#ifdef WITH_CDATA + if (!flag) + { register int state = 0; +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + c = soap_getchar(soap); + if ((int)c == EOF) + goto end; + if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN)) + { soap_unget(soap, c); + c = soap_getutf8(soap); + if (soap->mode & SOAP_C_UTFSTRING) + { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + } + switch (state) + { case 1: + if (c == ']') + state = 4; + *s++ = c; + continue; + case 2: + if (c == '-') + state = 6; + *s++ = c; + continue; + case 3: + if (c == '?') + state = 8; + *s++ = c; + continue; + /* CDATA */ + case 4: + if (c == ']') + state = 5; + else + state = 1; + *s++ = c; + continue; + case 5: + if (c == '>') + state = 0; + else + state = 1; + *s++ = c; + continue; + /* comment */ + case 6: + if (c == '-') + state = 7; + else + state = 2; + *s++ = c; + continue; + case 7: + if (c == '>') + state = 0; + else + state = 2; + *s++ = c; + continue; + /* PI */ + case 8: + if (c == '>') + state = 0; + else + state = 3; + *s++ = c; + continue; + } + switch (c) + { + case '/': + if (n > 0) + { c = soap_getchar(soap); + if (c == '>') + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + c = soap_getchar(soap); + if (c == '/') + { if (n == 0) + { c = SOAP_TT; + goto end; + } + n--; + } + else if (c == '!') + { c = soap_getchar(soap); + if (c == '[') + { do c = soap_getchar(soap); + while ((int)c != EOF && c != '['); + if ((int)c == EOF) + goto end; + t = (char*)"![CDATA["; + m = 8; + state = 1; + } + else if (c == '-') + { if ((c = soap_getchar(soap)) == '-') + state = 2; + t = (char*)"!-"; + m = 2; + soap_unget(soap, c); + } + else + { t = (char*)"!"; + m = 1; + soap_unget(soap, c); + } + *s++ = '<'; + break; + } + else if (c == '?') + state = 3; + else + n++; + soap_unget(soap, c); + *s++ = '<'; + break; + case '>': + *s++ = '>'; + break; + case '"': + *s++ = '"'; + break; + default: +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } + } +#endif +#ifdef WITH_FAST + soap->labidx = 0; /* use look-aside buffer */ +#else + if (soap_new_block(soap)) + return NULL; +#endif + for (;;) + { +#ifdef WITH_FAST + register size_t k; + if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ + return NULL; + s = soap->labbuf + soap->labidx; /* space to populate */ + k = soap->lablen - soap->labidx; /* number of bytes available */ + soap->labidx = soap->lablen; /* claim this space */ +#else + register size_t k = SOAP_BLKLEN; + if (!(s = (char*)soap_push_block(soap, k))) + return NULL; +#endif + for (i = 0; i < k; i++) + { if (m > 0) + { *s++ = *t++; /* copy multibyte characters */ + m--; + continue; + } + if (soap->mode & SOAP_C_UTFSTRING) + { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP) + { c &= 0x7FFFFFFF; + t = buf; + if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + m = (int)(t - buf) - 1; + t = buf; + *s++ = *t++; + continue; + } + } + else + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + t = (char*)"/"; + m = 1; + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_get(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<' | 0x80000000: + if (flag) + *s++ = '<'; + else + { *s++ = '&'; + t = (char*)"lt;"; + m = 3; + } + break; + case '>' | 0x80000000: + if (flag) + *s++ = '>'; + else + { *s++ = '&'; + t = (char*)"gt;"; + m = 3; + } + break; + case '&' | 0x80000000: + if (flag) + *s++ = '&'; + else + { *s++ = '&'; + t = (char*)"amp;"; + m = 4; + } + break; + case '"' | 0x80000000: + if (flag) + *s++ = '"'; + else + { *s++ = '&'; + t = (char*)"quot;"; + m = 5; + } + break; + case '\'' | 0x80000000: + if (flag) + *s++ = '\''; + else + { *s++ = '&'; + t = (char*)"apos;"; + m = 5; + } + break; + default: + if ((int)c == EOF) + goto end; +#ifndef WITH_LEANER +#ifdef HAVE_WCTOMB + if (soap->mode & SOAP_C_MBSTRING) + { m = wctomb(buf, c & 0x7FFFFFFF); + if (m >= 1 && m <= (int)MB_CUR_MAX) + { t = buf; + *s++ = *t++; + m--; + } + else + { *s++ = SOAP_UNKNOWN_CHAR; + m = 0; + } + } + else +#endif +#endif + *s++ = (char)(c & 0xFF); + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; +#ifdef WITH_FAST + t = soap_strdup(soap, soap->labbuf); +#else + soap_size_block(soap, i+1); + t = soap_save_block(soap, NULL, 0); +#endif + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { if (flag == 3) + soap->dom->tail = t; + else + soap->dom->data = t; + } +#endif + if (flag == 2) + if (soap_s2QName(soap, t, &t)) + return NULL; + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) +{ const char *t; + char tmp; + register soap_wchar c; +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + { wchar_t *r = (wchar_t*)s; + int n = 1; + while (*r++) + n++; + soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t)); + while (n--) + *r++ = *s++; + return SOAP_OK; + } +#endif + while ((c = *s++)) + { switch (c) + { + case 0x09: + if (flag) + t = " "; + else + t = "\t"; + break; + case 0x0A: + if (flag || !(soap->mode & SOAP_XML_CANONICAL)) + t = " "; + else + t = "\n"; + break; + case 0x0D: + t = " "; + break; + case '&': + t = "&"; + break; + case '<': + t = "<"; + break; + case '>': + if (flag) + t = ">"; + else + t = ">"; + break; + case '"': + if (flag) + t = """; + else + t = "\""; + break; + default: + if (c >= 0x20 && c < 0x80) + { tmp = (char)c; + if (soap_send_raw(soap, &tmp, 1)) + return soap->error; + } + else if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + continue; + } + if (soap_send(soap, t)) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t * +SOAP_FMAC2 +soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) +{ wchar_t *s; + register int i, n = 0; + register long l = 0; + register soap_wchar c; + const char *t = NULL; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n")); + if (soap->peeked) + { if (!soap->body) + return NULL; + if (*soap->tag) + { n = 1; + soap->peeked = 0; + } + } + if (soap_new_block(soap)) + return NULL; + for (;;) + { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN))) + return NULL; + for (i = 0; i < SOAP_BLKLEN; i++) + { if (t) + { *s++ = (wchar_t)*t++; + if (!*t) + t = NULL; + continue; + } + c = soap_getutf8(soap); + switch (c) + { + case SOAP_TT: + if (n == 0) + goto end; + n--; + *s++ = '<'; + soap_unget(soap, '/'); + break; + case SOAP_LT: + n++; + *s++ = '<'; + break; + case SOAP_GT: + *s++ = '>'; + break; + case SOAP_QT: + *s++ = '"'; + break; + case SOAP_AP: + *s++ = '\''; + break; + case '/': + if (n > 0) + { c = soap_getutf8(soap); + if (c == SOAP_GT) + n--; + soap_unget(soap, c); + } + *s++ = '/'; + break; + case '<': + if (flag) + *s++ = (soap_wchar)'<'; + else + { *s++ = (soap_wchar)'&'; + t = "lt;"; + } + break; + case '>': + if (flag) + *s++ = (soap_wchar)'>'; + else + { *s++ = (soap_wchar)'&'; + t = "gt;"; + } + break; + case '"': + if (flag) + *s++ = (soap_wchar)'"'; + else + { *s++ = (soap_wchar)'&'; + t = "quot;"; + } + break; + default: + if ((int)c == EOF) + goto end; + *s++ = (wchar_t)c & 0x7FFFFFFF; + } + l++; + if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + } + } +end: + soap_unget(soap, c); + *s = '\0'; + soap_size_block(soap, sizeof(wchar_t) * (i + 1)); + if ((soap->mode & SOAP_XML_STRICT) && l < minlen) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen)); + soap->error = SOAP_LENGTH; + return NULL; + } + s = (wchar_t*)soap_save_block(soap, NULL, 0); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->wide = s; +#endif + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_int2s(struct soap *soap, int n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2int(struct soap *soap, const char *s, int *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = (int)soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int * +SOAP_FMAC2 +soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(int), 0, NULL); + else if (p) + { if (soap_s2int(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_long2s(struct soap *soap, long n) +{ sprintf(soap->tmpbuf, "%ld", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2long(struct soap *soap, const char *s, long *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = soap_strtol(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +long * +SOAP_FMAC2 +soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(long), 0, NULL); + else if (p) + { if (soap_s2long(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_LONG642s(struct soap *soap, LONG64 n) +{ sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_LONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOLL + char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = strtoll(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +# ifdef HAVE_SSCANF + if (sscanf(s, SOAP_LONG_FORMAT, p) != 1) +# endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +LONG64 * +SOAP_FMAC2 +soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (LONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(LONG64), 0, NULL); + else if (p) + { if (soap_s2LONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_byte2s(struct soap *soap, char n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2byte(struct soap *soap, const char *s, char *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -128 || n > 127) + soap->error = SOAP_TYPE; + *p = (char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(char), 0, NULL); + else if (p) + { if (soap_s2byte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_short2s(struct soap *soap, short n) +{ return soap_long2s(soap, (long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_long2s(soap, (long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2short(struct soap *soap, const char *s, short *p) +{ if (s) + { long n; + char *r; + n = soap_strtol(s, &r, 10); + if (s == r || *r || n < -32768 || n > 32767) + soap->error = SOAP_TYPE; + *p = (short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +short * +SOAP_FMAC2 +soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(short), 0, NULL); + else if (p) + { if (soap_s2short(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_float2s(struct soap *soap, float n) +{ char *s; + if (soap_isnan((double)n)) + s = "NaN"; + else if (soap_ispinff(n)) + s = "INF"; + else if (soap_isninff(n)) + s = "-INF"; + else + { char *t; + s = soap->tmpbuf; + sprintf(soap->tmpbuf, soap->float_format, n); + t = strchr(s, ','); /* convert decimal comma to DP */ + if (t) + *t = '.'; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_float2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2float(struct soap *soap, const char *s, float *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = FLT_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = FLT_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = FLT_NAN; + else + { +/* On some systems, strtof appears to be broken or doesn't link: use with caution */ +#if defined(HAVE_STRTOF) + char *r; + *p = strtof((char*)s, &r); + if (*r) +#elif defined(HAVE_STRTOD) + char *r; + *p = (float)strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, "%g", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static int soap_isnumeric(struct soap *soap, const char *type) +{ if (soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":float") + && soap_match_tag(soap, soap->type, ":double") + && soap_match_tag(soap, soap->type, ":decimal") + && soap_match_tag(soap, soap->type, ":integer") + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":negativeInteger") + && soap_match_tag(soap, soap->type, ":nonPositiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":long") + && soap_match_tag(soap, soap->type, ":int") + && soap_match_tag(soap, soap->type, ":short") + && soap_match_tag(soap, soap->type, ":byte") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return SOAP_ERR; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +float * +SOAP_FMAC2 +soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL); + if (*soap->href) + p = (float*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(float), 0, NULL); + else if (p) + { if (soap_s2float(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_double2s(struct soap *soap, double n) +{ char *s; + if (soap_isnan(n)) + s = "NaN"; + else if (soap_ispinfd(n)) + s = "INF"; + else if (soap_isninfd(n)) + s = "-INF"; + else + { char *t; + s = soap->tmpbuf; + sprintf(soap->tmpbuf, soap->double_format, n); + t = strchr(s, ','); /* convert decimal comma to DP */ + if (t) + *t = '.'; + } + return s; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_double2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2double(struct soap *soap, const char *s, double *p) +{ if (s) + { if (!*s) + return soap->error = SOAP_TYPE; + if (!soap_tag_cmp(s, "INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "+INF")) + *p = DBL_PINFTY; + else if (!soap_tag_cmp(s, "-INF")) + *p = DBL_NINFTY; + else if (!soap_tag_cmp(s, "NaN")) + *p = DBL_NAN; + else + { +#ifdef HAVE_STRTOD + char *r; + *p = strtod(s, &r); + if (*r) +#endif +#ifdef HAVE_SSCANF + if (sscanf(s, "%lg", p) != 1) + soap->error = SOAP_TYPE; +#else + soap->error = SOAP_TYPE; +#endif + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +double * +SOAP_FMAC2 +soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type != '\0' && soap_isnumeric(soap, type)) + return NULL; +#endif + p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL); + if (*soap->href) + p = (double*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(double), 0, NULL); + else if (p) + { if (soap_s2double(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedByte2s(struct soap *soap, unsigned char n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 255) + soap->error = SOAP_TYPE; + *p = (unsigned char)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned char * +SOAP_FMAC2 +soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned char), 0, NULL); + else if (p) + { if (soap_s2unsignedByte(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedShort2s(struct soap *soap, unsigned short n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p) +{ if (s) + { unsigned long n; + char *r; + n = soap_strtoul(s, &r, 10); + if (s == r || *r || n > 65535) + soap->error = SOAP_TYPE; + *p = (unsigned short)n; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned short * +SOAP_FMAC2 +soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned short), 0, NULL); + else if (p) + { if (soap_s2unsignedShort(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedInt2s(struct soap *soap, unsigned int n) +{ return soap_unsignedLong2s(soap, (unsigned long)n); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = (unsigned int)soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned int * +SOAP_FMAC2 +soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned int), 0, NULL); + else if (p) + { if (soap_s2unsignedInt(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_unsignedLong2s(struct soap *soap, unsigned long n) +{ sprintf(soap->tmpbuf, "%lu", n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p) +{ if (s) + { char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = soap_strtoul(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +unsigned long * +SOAP_FMAC2 +soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; +#ifndef WITH_LEAN + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } +#endif + p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL); + if (*soap->href) + p = (unsigned long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned long), 0, NULL); + else if (p) + { if (soap_s2unsignedLong(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_ULONG642s(struct soap *soap, ULONG64 n) +{ sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_ULONG642s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p) +{ if (s) + { +#ifdef HAVE_STRTOULL + char *r; +#ifndef WITH_NOIO +#ifndef WITH_LEAN + soap_reset_errno; +#endif +#endif + *p = strtoull(s, &r, 10); + if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r +#ifndef WITH_NOIO +#ifndef WITH_LEAN + || soap_errno == SOAP_ERANGE +#endif +#endif + ) +#else +# ifdef HAVE_SSCANF + if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1) +# endif +#endif + soap->error = SOAP_TYPE; + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +ULONG64 * +SOAP_FMAC2 +soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":positiveInteger") + && soap_match_tag(soap, soap->type, ":nonNegativeInteger") + && soap_match_tag(soap, soap->type, ":unsignedLong") + && soap_match_tag(soap, soap->type, ":unsignedInt") + && soap_match_tag(soap, soap->type, ":unsignedShort") + && soap_match_tag(soap, soap->type, ":unsignedByte")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL); + if (*soap->href) + p = (ULONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(ULONG64), 0, NULL); + else if (p) + { if (soap_s2ULONG64(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2string(struct soap *soap, const char *s, char **t) +{ *t = NULL; + if (s) + { if (!(*t = soap_strdup(soap, s))) + return soap->error = SOAP_EOM; + if (!(soap->mode & (SOAP_ENC_LATIN | SOAP_C_UTFSTRING))) + { /* TODO: consider truncating UTF8 to ASCII for regular XML attribute strings? */ + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2QName(struct soap *soap, const char *s, char **t) +{ if (s) + { struct soap_nlist *np = soap->nlist; + const char *p; + /* if there is no namespace stack, or prefix is "xml" then pass string */ + if (!np || !strncmp(s, "xml:", 4)) + { *t = soap_strdup(soap, s); + return SOAP_OK; + } + /* else we normalize the QName by replacing its prefix */ + p = strchr(s, ':'); + if (p) + { register int n = p - s; + while (np && (strncmp(np->id, s, n) || np->id[n])) + np = np->next; + p++; + } + else + { while (np && *np->id) + np = np->next; + p = s; + } + if (np) + { if (np->index >= 0 && soap->local_namespaces) + { register const char *q = soap->local_namespaces[np->index].id; + if (q) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2))) + sprintf(*t, "%s:%s", q, p); + return SOAP_OK; + } + } + if (np->ns) + { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4))) + sprintf(*t, "\"%s\":%s", np->ns, p); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:"")); + return soap->error = SOAP_NAMESPACE; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s)); + if ((*t = (char*)soap_malloc(soap, strlen(p) + 4))) + sprintf(*t, "\"\":%s", p); + } + else + *t = NULL; + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_QName2s(struct soap *soap, const char *s) +{ struct Namespace *p; + char *t; + int n; + if (!s || *s != '"') + { +#ifndef WITH_LEAN + if (s && (soap->mode & SOAP_XML_CANONICAL)) + { t = (char*)strchr(s, ':'); + if (t) + soap_utilize_ns(soap, s, t - s); + } +#endif + return s; + } + s++; + if ((p = soap->local_namespaces)) + { for (; p->id; p++) + { if (p->ns) + if (!soap_tag_cmp(s, p->ns)) + break; + if (p->in) + if (!soap_tag_cmp(s, p->in)) + break; + } + if (p && p->id) + { s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s)); + strcpy(t, p->id); + strcat(t, s + 1); + return t; + } + } + } + t = (char*)strchr(s, '"'); + if (t) + n = t - s; + else + n = 0; + t = soap_strdup(soap, s); + t[n] = '\0'; + sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++); + soap_set_attr(soap, soap->tmpbuf, t); + s = strchr(s, '"'); + if (s) + { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6); + strcpy(t, soap->tmpbuf + 6); + strcat(t, s + 1); + } + return t; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2wchar(struct soap *soap, const char *s, wchar_t **t) +{ wchar_t *r; + if (!s) + *t = NULL; + else + { *t = r = (wchar_t*)soap_malloc(soap, sizeof(wchar_t) * (strlen(s) + 1)); + if (!r) + return soap->error; + if (soap->mode & SOAP_ENC_LATIN) + { while (*s) + *r++ = (wchar_t)*s++; + } + else + { /* Convert UTF8 to wchar */ + while (*s) + { register soap_wchar c, c1, c2, c3, c4; + c = *s++; + if (c < 0x80) + *r++ = (wchar_t)c; + else + { c1 = (soap_wchar)*s++ & 0x3F; + if (c < 0xE0) + *r++ = (wchar_t)(((soap_wchar)(c & 0x1F) << 6) | c1); + else + { c2 = (soap_wchar)*s++ & 0x3F; + if (c < 0xF0) + *r++ = (wchar_t)(((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2); + else + { c3 = (soap_wchar)*s++ & 0x3F; + if (c < 0xF8) + *r++ = (wchar_t)(((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3); + else + { c4 = (soap_wchar)*s++ & 0x3F; + if (c < 0xFC) + *r++ = (wchar_t)(((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4); + else + *r++ = (wchar_t)(((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(*s++ & 0x3F)); + } + } + } + } + } + } + *r = L'\0'; + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_wchar2s(struct soap *soap, const wchar_t *s) +{ register soap_wchar c; + register char *r, *t; + const wchar_t *q = s; + size_t n = 0; + while ((c = *q++)) + { if (c > 0 && c < 0x80) + n++; + else + n += 6; + } + r = t = (char*)soap_malloc(soap, n + 1); + if (r) + { /* Convert wchar to UTF8 */ + while ((c = *s++)) + { if (c > 0 && c < 0x80) + *t++ = (char)c; + else + { if (c < 0x0800) + *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); + else + { if (c < 0x010000) + *t++ = (char)(0xE0 | ((c >> 12) & 0x0F)); + else + { if (c < 0x200000) + *t++ = (char)(0xF0 | ((c >> 18) & 0x07)); + else + { if (c < 0x04000000) + *t++ = (char)(0xF8 | ((c >> 24) & 0x03)); + else + { *t++ = (char)(0xFC | ((c >> 30) & 0x01)); + *t++ = (char)(0x80 | ((c >> 24) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 18) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 12) & 0x3F)); + } + *t++ = (char)(0x80 | ((c >> 6) & 0x3F)); + } + *t++ = (char)(0x80 | (c & 0x3F)); + } + } + *t = '\0'; + } + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0) + return soap->error; + if (!**p && (soap->mode & SOAP_C_NILSTRING)) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, id, type) + || soap_string_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->body) + { *p = soap_string_in(soap, flag, minlen, maxlen); + if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL)) + return NULL; + } + else if (soap->null) + *p = NULL; + else + *p = (char*)SOAP_STR_EOS; + if (*soap->href) + p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) +{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n); + if (id < 0) + return soap->error; + if (!**p && (soap->mode & SOAP_C_NILSTRING)) + return soap_element_null(soap, tag, id, type); + if (soap_element_begin_out(soap, tag, id, type) + || soap_wstring_out(soap, *p, 0) + || soap_element_end_out(soap, tag)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->body) + { *p = soap_wstring_in(soap, 1, minlen, maxlen); + if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL)) + return NULL; + } + else if (soap->null) + *p = NULL; + else + *p = (wchar_t*)SOAP_STR_EOS; + if (*soap->href) + p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0); + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static time_t +soap_timegm(struct tm *T) +{ +#if defined(HAVE_TIMEGM) + return timegm(T); +#else + time_t t, g, z; +#ifdef HAVE_GMTIME_R + struct tm tm, *tmp = &tm; +#else + struct tm *tmp; +#endif + t = mktime(T); + if (t == -1) + return -1; +#ifdef HAVE_GMTIME_R + gmtime_r(&t, tmp); +#else + tmp = gmtime(&t); +#endif + tmp->tm_isdst = 0; + g = mktime(tmp); + if (g == -1) + return -1; + z = g - t; + return t - z; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_dateTime2s(struct soap *soap, time_t n) +{ struct tm T, *pT = &T; +#if defined(HAVE_GMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PGMTIME_R) + if (gmtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_PGMTIME) + if (gmtime(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GMTIME) + if ((pT = gmtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT); +#elif defined(HAVE_GETTIMEOFDAY) + struct timezone tz; + memset((void*)&tz, 0, sizeof(tz)); +# if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +# else + if ((pT = localtime(&n))) + { struct timeval tv; + gettimeofday(&tv, &tz); + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60); + } +#endif +#elif defined(HAVE_FTIME) + struct timeb t; + memset((void*)&t, 0, sizeof(t)); +# if defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + { +#ifdef __BORLANDC__ + ::ftime(&t); +#else + ftime(&t); +#endif + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } + /* The following defines were added for VxWorks*/ +# elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60); + } +# else + if ((pT = localtime(&n))) + { +#ifdef __BORLANDC__ + ::ftime(&t); +#else + ftime(&t); +#endif + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60); + } +# endif +#elif defined(HAVE_LOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); + /* The following defines were added for VxWorks*/ +#elif defined(HAVE_PLOCALTIME_R) + if (localtime_r(&n, pT)) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#else + if ((pT = localtime(&n))) + strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT); +#endif + else + strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z"); + return soap->tmpbuf; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n) +{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type) + || soap_string_out(soap, soap_dateTime2s(soap, *p), 0)) + return soap->error; + return soap_element_end_out(soap, tag); +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_s2dateTime(struct soap *soap, const char *s, time_t *p) +{ if (s) + { struct tm T; + char zone[32]; + const char *t; + memset((void*)&T, 0, sizeof(T)); + zone[sizeof(zone)-1] = '\0'; + if (strchr(s, '-')) + t = "%d-%d-%dT%d:%d:%d%31s"; + else if (strchr(s, ':')) + t = "%4d%2d%2dT%d:%d:%d%31s"; + else /* parse non-XSD-standard alternative ISO 8601 format */ + t = "%4d%2d%2dT%2d%2d%2d%31s"; + sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone); + if (T.tm_year == 1) + T.tm_year = 70; + else + T.tm_year -= 1900; + T.tm_mon--; + if (*zone) + { if (*zone == '.') + { for (s = zone + 1; *s; s++) + if (*s < '0' || *s > '9') + break; + } + else + s = zone; + if (*s == '+' || *s == '-') + { int h = 0, m = 0; + if (s[3] == ':') + { sscanf(s, "%d:%d", &h, &m); + if (h < 0) + m = -m; + } + else + { m = (int)atol(s); + h = m / 100; + m = m % 100; + } + T.tm_hour -= h; + T.tm_min -= m; + } + T.tm_isdst = 0; + *p = soap_timegm(&T); + } + else + { T.tm_isdst = -1; + *p = mktime(&T); /* no time zone: suppose it is localtime? */ + } + } + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +time_t * +SOAP_FMAC2 +soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char *type, int t) +{ if (soap_element_begin_in(soap, tag, 0, NULL)) + return NULL; + if (*soap->type + && soap_match_tag(soap, soap->type, type) + && soap_match_tag(soap, soap->type, ":dateTime")) + { soap->error = SOAP_TYPE; + soap_revert(soap); + return NULL; + } + p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL); + if (*soap->href) + p = (time_t*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(time_t), 0, NULL); + else if (p) + { if (soap_s2dateTime(soap, soap_value(soap), p)) + return NULL; + } + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outliteral(struct soap *soap, const char *tag, char *const*p, const char *type) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + if (soap_element(soap, t, 0, type) + || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS) + || soap_element_start_end_out(soap, NULL)) + return soap->error; + } + else + { t = tag; + if (soap_element_begin_out(soap, t, 0, type)) + return soap->error; + } + } + if (p && *p) + { if (soap_send(soap, *p)) + return soap->error; + } + if (t) + return soap_element_end_out(soap, t); + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +char ** +SOAP_FMAC2 +soap_inliteral(struct soap *soap, const char *tag, char **p) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (char**)soap_malloc(soap, sizeof(char*)))) + return NULL; + if (soap->body) + *p = soap_string_in(soap, 0, -1, -1); + else if (soap->null) + *p = NULL; + else + *p = (char*)SOAP_STR_EOS; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p, const char *type) +{ int i; + const char *t = NULL; + if (tag && *tag != '-') + { if (soap->local_namespaces && (t = strchr(tag, ':'))) + { strncpy(soap->tmpbuf, tag, t-tag); + soap->tmpbuf[t-tag] = '\0'; + for (i = 0; soap->local_namespaces[i].id; i++) + if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id)) + break; + t++; + if (soap_element(soap, t, 0, type) + || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS) + || soap_element_start_end_out(soap, NULL)) + return soap->error; + } + else + { t = tag; + if (soap_element_begin_out(soap, t, 0, type)) + return soap->error; + } + if (soap_send(soap, soap->tmpbuf)) + return soap->error; + } + if (p) + { wchar_t c; + const wchar_t *s = *p; + while ((c = *s++)) + { if (soap_pututf8(soap, (unsigned long)c)) + return soap->error; + } + } + if (t) + return soap_element_end_out(soap, t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_2 +SOAP_FMAC1 +wchar_t ** +SOAP_FMAC2 +soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p) +{ if (soap_element_begin_in(soap, tag, 1, NULL)) + { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT) + return NULL; + soap->error = SOAP_OK; + } + if (!p) + if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*)))) + return NULL; + if (soap->body) + *p = soap_wstring_in(soap, 0, -1, -1); + else if (soap->null) + *p = NULL; + else + *p = (wchar_t*)SOAP_STR_EOS; + if (soap->body && soap_element_end_in(soap, tag)) + return NULL; + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +const char * +SOAP_FMAC2 +soap_value(struct soap *soap) +{ register size_t i; + register soap_wchar c = 0; + register char *s = soap->tmpbuf; + if (!soap->body) + return SOAP_STR_EOS; + do c = soap_get(soap); + while (soap_blank(c)); + for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++) + { if (c == SOAP_TT || (int)c == EOF) + break; + *s++ = (char)c; + c = soap_get(soap); + } + for (s--; i > 0; i--, s--) + { if (!soap_blank(*s)) + break; + } + s[1] = '\0'; + if ((int)c == EOF || c == SOAP_TT) + soap_unget(soap, c); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf)); +#ifdef WITH_DOM + if ((soap->mode & SOAP_XML_DOM) && soap->dom) + soap->dom->data = soap_strdup(soap, soap->tmpbuf); +#endif + return soap->tmpbuf; /* return non-null pointer */ +} +#endif + +/******************************************************************************/ +#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP) +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getline(struct soap *soap, char *s, int len) +{ int i = len; + soap_wchar c = 0; + for (;;) + { while (--i > 0) + { c = soap_getchar(soap); + if (c == '\r' || c == '\n') + break; + if ((int)c == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (c != '\n') + c = soap_getchar(soap); /* got \r, now get \n */ + if (c == '\n') + { *s = '\0'; + if (i+1 == len) /* empty line: end of HTTP/MIME header */ + break; + c = soap_unget(soap, soap_getchar(soap)); + if (c != ' ' && c != '\t') /* HTTP line continuation? */ + break; + } + else if ((int)c == EOF) + return soap->error = SOAP_EOF; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static size_t +soap_count_attachments(struct soap *soap) +{ +#ifndef WITH_LEANER + register struct soap_multipart *content; + register size_t count = soap->count; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count)); + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n")); + for (content = soap->dime.first; content; content = content->next) + { count += 12 + ((content->size+3)&(~3)); + if (content->id) + count += ((strlen(content->id)+3)&(~3)); + if (content->type) + count += ((strlen(content->type)+3)&(~3)); + if (content->options) + count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary) + { register size_t n = strlen(soap->mime.boundary); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { register const char *s; + /* count \r\n--boundary\r\n */ + count += 6 + n; + /* count Content-Type: ...\r\n */ + if (content->type) + count += 16 + strlen(content->type); + /* count Content-Transfer-Encoding: ...\r\n */ + s = soap_code_str(mime_codes, content->encoding); + if (s) + count += 29 + strlen(s); + /* count Content-ID: ...\r\n */ + if (content->id) + count += 14 + strlen(content->id); + /* count Content-Location: ...\r\n */ + if (content->location) + count += 20 + strlen(content->location); + /* count Content-Description: ...\r\n */ + if (content->description) + count += 23 + strlen(content->description); + /* count \r\n...content */ + count += 2 + content->size; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size)); + } + /* count \r\n--boundary-- */ + count += 6 + n; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count)); + return count; +#else + return soap->count; +#endif +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_putdimefield(struct soap *soap, const char *s, size_t n) +{ if (soap_send_raw(soap, s, n)) + return soap->error; + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_dime_option(struct soap *soap, unsigned short optype, const char *option) +{ size_t n; + char *s = NULL; + if (option) + { n = strlen(option); + s = (char*)soap_malloc(soap, n + 5); + if (s) + { s[0] = optype >> 8; + s[1] = optype & 0xFF; + s[2] = n >> 8; + s[3] = n & 0xFF; + strcpy(s + 4, option); + } + } + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdimehdr(struct soap *soap) +{ unsigned char tmp[12]; + size_t optlen = 0, idlen = 0, typelen = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:"")); + if (soap->dime.options) + optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4; + if (soap->dime.id) + idlen = strlen(soap->dime.id); + if (soap->dime.type) + typelen = strlen(soap->dime.type); + tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7); + tmp[1] = soap->dime.flags & 0xF0; + tmp[2] = optlen >> 8; + tmp[3] = optlen & 0xFF; + tmp[4] = idlen >> 8; + tmp[5] = idlen & 0xFF; + tmp[6] = typelen >> 8; + tmp[7] = typelen & 0xFF; + tmp[8] = soap->dime.size >> 24; + tmp[9] = (soap->dime.size >> 16) & 0xFF; + tmp[10] = (soap->dime.size >> 8) & 0xFF; + tmp[11] = soap->dime.size & 0xFF; + if (soap_send_raw(soap, (char*)tmp, 12) + || soap_putdimefield(soap, soap->dime.options, optlen) + || soap_putdimefield(soap, soap->dime.id, idlen) + || soap_putdimefield(soap, soap->dime.type, typelen)) + return soap->error; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putdime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_DIME)) + return SOAP_OK; + for (content = soap->dime.first; content; content = content->next) + { void *handle; + soap->dime.size = content->size; + soap->dime.id = content->id; + soap->dime.type = content->type; + soap->dime.options = content->options; + soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA; + if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n")); + return soap->error; + } + if (!size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)) + { size_t chunksize = sizeof(soap->tmpbuf); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n")); + do + { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size)); + if (size < chunksize) + { soap->dime.flags &= ~SOAP_DIME_CF; + if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + } + else + soap->dime.flags |= SOAP_DIME_CF; + soap->dime.size = size; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, soap->tmpbuf, size)) + break; + if (soap->dime.id) + { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA); + soap->dime.id = NULL; + soap->dime.type = NULL; + soap->dime.options = NULL; + } + } while (size >= chunksize); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap)) + return soap->error; + do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n")); + if (soap->fdimereadclose) + soap->fdimereadclose(soap, handle); + } + else + { if (!content->next) + soap->dime.flags |= SOAP_DIME_ME; + if (soap_putdimehdr(soap) + || soap_putdimefield(soap, (char*)content->ptr, content->size)) + return soap->error; + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static char * +soap_getdimefield(struct soap *soap, size_t n) +{ register soap_wchar c; + register int i; + register char *s; + char *p = NULL; + if (n) + { p = (char*)soap_malloc(soap, n + 1); + if (p) + { s = p; + for (i = n; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + *s++ = (char)c; + } + *s = '\0'; + if ((soap->error = soap_move(soap, -(long)n&3))) + return NULL; + } + else + soap->error = SOAP_EOM; + } + return p; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdimehdr(struct soap *soap) +{ register soap_wchar c; + register char *s; + register int i; + unsigned char tmp[12]; + size_t optlen, idlen, typelen; + if (!(soap->mode & SOAP_ENC_DIME)) + return soap->error = SOAP_DIME_END; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n")); + if (soap->dime.buflen || soap->dime.chunksize) + { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap)))) + return soap->error = SOAP_EOF; + soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */ + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n")); + return SOAP_OK; + } + s = (char*)tmp; + for (i = 12; i > 0; i--) + { if ((int)(c = soap_getchar(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION) + return soap->error = SOAP_DIME_MISMATCH; + soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0); + optlen = (tmp[2] << 8) | tmp[3]; + idlen = (tmp[4] << 8) | tmp[5]; + typelen = (tmp[6] << 8) | tmp[7]; + soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11]; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags)); + if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error) + return soap->error; + if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error) + return soap->error; + if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error) + return soap->error; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:"", soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:"")); + if (soap->dime.flags & SOAP_DIME_ME) + soap->mode &= ~SOAP_ENC_DIME; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getdime(struct soap *soap) +{ while (soap->dime.flags & SOAP_DIME_CF) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap_move(soap, soap->dime.size)) + return soap->error = SOAP_EOF; + } + if (soap_move(soap, ((soap->dime.size+3)&(~3))-soap_tell(soap))) + return soap->error = SOAP_EOF; + for (;;) + { register struct soap_multipart *content; + if (soap_getdimehdr(soap)) + break; + if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error)) + { const char *id, *type, *options; + size_t size, n; + if (!soap->dime.ptr) + return soap->error; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + for (;;) + { size = soap->dime.size; + for (;;) + { n = soap->buflen - soap->bufidx; + if (size < n) + n = size; + if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n))) + break; + size -= n; + if (!size) + { soap->bufidx += n; + break; + } + if (soap_recv(soap)) + { soap->error = SOAP_EOF; + goto end; + } + } + if (soap_move(soap, -(long)soap->dime.size&3)) + { soap->error = SOAP_EOF; + break; + } + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + break; + } +end: + if (soap->fdimewriteclose) + soap->fdimewriteclose(soap, (void*)soap->dime.ptr); + soap->dime.size = 0; + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else if (soap->dime.flags & SOAP_DIME_CF) + { const char *id, *type, *options; + register soap_wchar c; + register char *s; + register int i; + id = soap->dime.id; + type = soap->dime.type; + options = soap->dime.options; + if (soap_new_block(soap)) + return SOAP_EOM; + for (;;) + { s = (char*)soap_push_block(soap, soap->dime.size); + if (!s) + return soap->error = SOAP_EOM; + for (i = soap->dime.size; i > 0; i--) + { if ((int)(c = soap_get1(soap)) == EOF) + return soap->error = SOAP_EOF; + *s++ = (char)c; + } + if (soap_move(soap, -(long)soap->dime.size&3)) + return soap->error = SOAP_EOF; + if (!(soap->dime.flags & SOAP_DIME_CF)) + break; + if (soap_getdimehdr(soap)) + return soap->error; + } + soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */ + if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0))) + return soap->error; + soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */ + soap->dime.id = id; + soap->dime.type = type; + soap->dime.options = options; + } + else + soap->dime.ptr = soap_getdimefield(soap, soap->dime.size); + content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size); + if (!content) + return soap->error = SOAP_EOM; + content->id = soap->dime.id; + content->type = soap->dime.type; + content->options = soap->dime.options; + if (soap->error) + return soap->error; + soap_resolve_attachment(soap, content); + } + if (soap->error != SOAP_DIME_END) + return soap->error; + return soap->error = SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmimehdr(struct soap *soap) +{ struct soap_multipart *content; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + while (!*soap->msgbuf); + if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-') + { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1; + /* remove white space */ + while (soap_blank(*s)) + s--; + s[1] = '\0'; + if (soap->mime.boundary) + { if (strcmp(soap->msgbuf + 2, soap->mime.boundary)) + return soap->error = SOAP_MIME_ERROR; + } + else + soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2); + if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + } + if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL)) + return soap->error = SOAP_EOM; + content = soap->mime.last; + for (;;) + { register char *key = soap->msgbuf; + register char *val; + if (!*key) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key)); + val = strchr(soap->msgbuf, ':'); + if (val) + { *val = '\0'; + do val++; + while (*val && *val <= 32); + if (!soap_tag_cmp(key, "Content-ID")) + content->id = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Location")) + content->location = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Disposition")) + content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name")); + else if (!soap_tag_cmp(key, "Content-Type")) + content->type = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Description")) + content->description = soap_strdup(soap, val); + else if (!soap_tag_cmp(key, "Content-Transfer-Encoding")) + content->encoding = (enum soap_mime_encoding)soap_code_int(mime_codes, val, (long)SOAP_MIME_NONE); + } + if (soap_getline(soap, key, sizeof(soap->msgbuf))) + return soap->error; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getmime(struct soap *soap) +{ while (soap_get_mime_attachment(soap, NULL)) + ; + return soap->error; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_post_check_mime_attachments(struct soap *soap) +{ soap->imode |= SOAP_MIME_POSTCHECK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_check_mime_attachments(struct soap *soap) +{ if (soap->mode & SOAP_MIME_POSTCHECK) + return soap_get_mime_attachment(soap, NULL) != NULL; + return 0; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart * +SOAP_FMAC2 +soap_get_mime_attachment(struct soap *soap, void *handle) +{ register soap_wchar c = 0; + register size_t i, m = 0; + register char *s, *t = NULL; + register struct soap_multipart *content; + register short flag = 0; + if (!(soap->mode & SOAP_ENC_MIME)) + return NULL; + content = soap->mime.last; + if (!content) + { if (soap_getmimehdr(soap)) + return NULL; + content = soap->mime.last; + } + else if (content != soap->mime.first) + { if (soap->fmimewriteopen && ((content->ptr = (char*)soap->fmimewriteopen(soap, (void*)handle, content->id, content->type, content->description, content->encoding)) || soap->error)) + { if (!content->ptr) + return NULL; + } + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:"")); + if (!content->ptr && soap_new_block(soap)) + { soap->error = SOAP_EOM; + return NULL; + } + for (;;) + { if (content->ptr) + s = soap->tmpbuf; + else if (!(s = (char*)soap_push_block(soap, sizeof(soap->tmpbuf)))) + { soap->error = SOAP_EOM; + return NULL; + } + for (i = 0; i < sizeof(soap->tmpbuf); i++) + { if (m > 0) + { *s++ = *t++; + m--; + } + else + { if (!flag) + { c = soap_get1(soap); + if ((int)c == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + } + if (flag || c == '\r') + { t = soap->msgbuf; + memset(t, 0, sizeof(soap->msgbuf)); + strcpy(t, "\n--"); + if (soap->mime.boundary) + strncat(t, soap->mime.boundary, sizeof(soap->msgbuf)-4); + do c = soap_getchar(soap); + while (c == *t++); + if ((int)c == EOF) + { soap->error = SOAP_EOF; + return NULL; + } + if (!*--t) + goto end; + *t = (char)c; + flag = (c == '\r'); + m = t - soap->msgbuf + 1 - flag; + t = soap->msgbuf; + c = '\r'; + } + *s++ = (char)c; + } + } + if (content->ptr && soap->fmimewrite) + { if ((soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i))) + break; + } + } +end: + *s = '\0'; /* force 0-terminated */ + if (content->ptr) + { if (!soap->error && soap->fmimewrite) + soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i); + if (soap->fmimewriteclose) + soap->fmimewriteclose(soap, (void*)content->ptr); + if (soap->error) + return NULL; + } + else + { content->size = soap_size_block(soap, i+1)-1; + content->ptr = soap_save_block(soap, NULL, 0); + } + soap_resolve_attachment(soap, content); + if (c == '-' && soap_getchar(soap) == '-') + { soap->mode &= ~SOAP_ENC_MIME; + if ((soap->mode & SOAP_MIME_POSTCHECK) && soap_end_recv(soap)) + return NULL; + } + else + { while (c != '\r' && (int)c != EOF && soap_blank(c)) + c = soap_getchar(soap); + if (c != '\r' || soap_getchar(soap) != '\n') + { soap->error = SOAP_MIME_ERROR; + return NULL; + } + if (soap_getmimehdr(soap)) + return NULL; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_match_cid(struct soap *soap, const char *s, const char *t) +{ register size_t n; + if (!s) + return 1; + if (!strcmp(s, t)) + return 0; + if (!strncmp(s, "cid:", 4)) + s += 4; + n = strlen(t); + if (*t == '<') + { t++; + n -= 2; + } + if (!strncmp(s, t, n) && !s[n]) + return 0; + soap_decode(soap->tmpbuf, sizeof(soap->tmpbuf), s, SOAP_STR_EOS); + if (!strncmp(soap->tmpbuf, t, n) && !soap->tmpbuf[n]) + return 0; + return 1; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_resolve_attachment(struct soap *soap, struct soap_multipart *content) +{ if (content->id) + { register struct soap_xlist **xp = &soap->xlist; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id)); + while (*xp) + { register struct soap_xlist *xq = *xp; + if (!soap_match_cid(soap, xq->id, content->id)) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id)); + *xp = xq->next; + *xq->ptr = (unsigned char*)content->ptr; + *xq->size = (int)content->size; + *xq->type = (char*)content->type; + if (content->options) + *xq->options = (char*)content->options; + else + *xq->options = (char*)content->description; + SOAP_FREE(soap, xq); + } + else + xp = &(*xp)->next; + } + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmimehdr(struct soap *soap, struct soap_multipart *content) +{ const char *s; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:"")); + if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n")) + return soap->error; + if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n")) + return soap->error; + s = soap_code_str(mime_codes, content->encoding); + if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n")) + return soap->error; + if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n")) + return soap->error; + if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n")) + return soap->error; + if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n")) + return soap->error; + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putmime(struct soap *soap) +{ struct soap_multipart *content; + if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary) + return SOAP_OK; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n")); + for (content = soap->mime.first; content; content = content->next) + { void *handle; + if (soap->fmimereadopen && ((handle = soap->fmimereadopen(soap, (void*)content->ptr, content->id, content->type, content->description)) || soap->error)) + { size_t size = content->size; + if (!handle) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimereadopen failed\n")); + return soap->error; + } + if (soap_putmimehdr(soap, content)) + return soap->error; + if (!size) + { if ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming MIME\n")); + do + { size = soap->fmimeread(soap, handle, soap->tmpbuf, sizeof(soap->tmpbuf)); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread returned %lu bytes\n", (unsigned long)size)); + if (soap_send_raw(soap, soap->tmpbuf, size)) + break; + } while (size); + } + else + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error: cannot chunk streaming MIME (no HTTP chunking)\n")); + } + } + else + { do + { size_t bufsize; + if (size < sizeof(soap->tmpbuf)) + bufsize = size; + else + bufsize = sizeof(soap->tmpbuf); + if (!(bufsize = soap->fmimeread(soap, handle, soap->tmpbuf, bufsize))) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size)); + soap->error = SOAP_EOF; + break; + } + if (soap_send_raw(soap, soap->tmpbuf, bufsize)) + break; + size -= bufsize; + } while (size); + } + if (soap->fmimereadclose) + soap->fmimereadclose(soap, handle); + } + else + { if (soap_putmimehdr(soap, content) + || soap_send_raw(soap, content->ptr, content->size)) + return soap->error; + } + } + return soap_send3(soap, "\r\n--", soap->mime.boundary, "--"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_dime(struct soap *soap) +{ soap->omode |= SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_mime(struct soap *soap, const char *boundary, const char *start) +{ soap->omode |= SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = soap_strdup(soap, boundary); + soap->mime.start = soap_strdup(soap, start); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_dime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_DIME; + soap->dime.first = NULL; + soap->dime.last = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_mime(struct soap *soap) +{ soap->omode &= ~SOAP_ENC_MIME; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static struct soap_multipart* +soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size) +{ struct soap_multipart *content; + content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart)); + if (content) + { content->next = NULL; + content->ptr = ptr; + content->size = size; + content->id = NULL; + content->type = NULL; + content->options = NULL; + content->encoding = SOAP_MIME_NONE; + content->location = NULL; + content->description = NULL; + if (!*first) + *first = content; + if (*last) + (*last)->next = content; + *last = content; + } + return content; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->options = soap_dime_option(soap, optype, option); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description) +{ struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size); + if (!content) + return SOAP_EOM; + content->id = soap_strdup(soap, id); + content->type = soap_strdup(soap, type); + content->encoding = encoding; + content->location = soap_strdup(soap, location); + content->description = soap_strdup(soap, description); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +SOAP_FMAC1 +struct soap_multipart* +SOAP_FMAC2 +soap_next_multipart(struct soap_multipart *content) +{ if (content) + return content->next; + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static void +soap_select_mime_boundary(struct soap *soap) +{ while (!soap->mime.boundary || soap_valid_mime_boundary(soap)) + { register char *s = soap->mime.boundary; + register size_t n = 0; + if (s) + n = strlen(s); + if (n < 16) + { n = 64; + s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1); + if (!s) + return; + } + strcpy(s, "=="); + s += 2; + n -= 4; + while (n) + { *s++ = soap_base64o[soap_random & 0x3F]; + n--; + } + strcpy(s, "=="); + } + if (!soap->mime.start) + soap->mime.start = ""; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_LEANER +#ifndef PALM_1 +static int +soap_valid_mime_boundary(struct soap *soap) +{ register struct soap_multipart *content; + register size_t k; + if (soap->fmimeread) + return SOAP_OK; + k = strlen(soap->mime.boundary); + for (content = soap->mime.first; content; content = content->next) + { if (content->ptr && content->size >= k) + { register const char *p = (const char*)content->ptr; + register size_t i; + for (i = 0; i < content->size - k; i++, p++) + { if (!strncmp(p, soap->mime.boundary, k)) + return SOAP_ERR; + } + } + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************\ + * + * HTTP cookie handling + * +\******************************************************************************/ + +#ifdef WITH_COOKIES +/******************************************************************************/ +SOAP_FMAC1 +size_t +SOAP_FMAC2 +soap_encode_cookie(const char *s, char *t, size_t len) +{ register int c; + register size_t n = len; + while ((c = *s++) && --n > 0) + { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c)) + *t++ = c; + else if (n > 2) + { *t++ = '%'; + *t++ = (c >> 4) + (c > 159 ? '7' : '0'); + c &= 0xF; + *t++ = c + (c > 9 ? '7' : '0'); + n -= 2; + } + else + break; + } + *t = '\0'; + return len - n; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + size_t n; + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + path = SOAP_STR_EOS; + else if (*path == '/') + path++; + n = strlen(path); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain?domain:"(null)", path?path:"(null)")); + for (p = soap->cookies; p; p = p->next) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->env)); + if (!strcmp(p->name, name) + && p->domain + && p->path + && !strcmp(p->domain, domain) + && !strncmp(p->path, path, n)) + break; + } + return p; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + int n; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie: %s=%s domain=%s path=%s\n", name, value?value:"(null)", domain?domain:"(null)", path?path:"(null)")); + if (!domain) + domain = soap->cookie_domain; + if (!path) + path = soap->cookie_path; + if (!path) + path = SOAP_STR_EOS; + else if (*path == '/') + path++; + q = soap_cookie(soap, name, domain, path); + if (!q) + { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1))) + strcpy(q->name, name); + q->value = NULL; + q->domain = NULL; + q->path = NULL; + q->expire = -1; + q->maxage = -1; + q->version = 1; + q->secure = 0; + q->modified = 0; + for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--) + if (!strcmp((*p)->name, name) && (*p)->path && path && strcmp((*p)->path, path) < 0) + break; + if (n) + { q->next = *p; + *p = q; + } + else + { SOAP_FREE(soap, q->name); + SOAP_FREE(soap, q); + q = NULL; + } + } + } + else + q->modified = 1; + if (q) + { if (q->value) + { SOAP_FREE(soap, q->value); + q->value = NULL; + } + if (q->domain) + { SOAP_FREE(soap, q->domain); + q->domain = NULL; + } + if (q->path) + { SOAP_FREE(soap, q->path); + q->path = NULL; + } + if (value && *value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1))) + strcpy(q->value, value); + if (domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1))) + strcpy(q->domain, domain); + if (path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1))) + strcpy(q->path, path); + q->session = 1; + q->env = 0; + } + return q; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie **p, *q; + if (!domain) + domain = soap->cookie_domain; + if (!domain) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name?name:"(null)")); + return; + } + if (!path) + path = soap->cookie_path; + if (!path) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name?name:"(null)")); + return; + } + if (*path == '/') + path++; + for (p = &soap->cookies, q = *p; q; q = *p) + { if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path))) + { if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + p = &q->next; + } +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +char * +SOAP_FMAC2 +soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path)) && p->env) + return p->value; + return NULL; +} + +/******************************************************************************/ +SOAP_FMAC1 +time_t +SOAP_FMAC2 +soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + return p->expire; + return -1; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path) +{ struct soap_cookie *p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain?domain:"(null)", path?path:"(null)")); + if ((p = soap_cookie(soap, name, domain, path))) + { p->maxage = expire; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 1; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path) +{ struct soap_cookie *p; + if ((p = soap_cookie(soap, name, domain, path))) + { p->session = 0; + p->modified = 1; + return SOAP_OK; + } + return SOAP_ERR; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putsetcookies(struct soap *soap) +{ struct soap_cookie *p; + char *s, tmp[4096]; + const char *t; + for (p = soap->cookies; p; p = p->next) + { if (p->modified || !p->env) + { s = tmp; + if (p->name) + s += soap_encode_cookie(p->name, s, tmp-s+4064); + if (p->value && *p->value) + { *s++ = '='; + s += soap_encode_cookie(p->value, s, tmp-s+4064); + } + if (p->domain && (int)strlen(p->domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", p->domain); + else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064) + sprintf(s, ";Domain=\"%s\"", soap->cookie_domain); + strcat(s, ";Path=/"); + if (p->path) + t = p->path; + else + t = soap->cookie_path; + if (t) + { if (*t == '/') + t++; + if ((int)strlen(t) < tmp-s+4064) + strcat(s, t); + } + s += strlen(s); + if (p->version > 0 && s-tmp < 4060) + { sprintf(s, ";Version=%u", p->version); + s += strlen(s); + } + if (p->maxage >= 0 && s-tmp < 4060) + { sprintf(s, ";Max-Age=%ld", p->maxage); + s += strlen(s); + } + if (p->secure && s-tmp < 4073) + strcpy(s, ";Secure"); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp))) + return soap->error; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure) +{ struct soap_cookie **p, *q; + unsigned int version = 0; + time_t now = time(NULL); + char *s, tmp[4096]; + p = &soap->cookies; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path)); + if (*path == '/') + path++; + while ((q = *p)) + { if (q->expire && now > q->expire) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name)); + SOAP_FREE(soap, q->name); + if (q->value) + SOAP_FREE(soap, q->value); + if (q->domain) + SOAP_FREE(soap, q->domain); + if (q->path) + SOAP_FREE(soap, q->path); + *p = q->next; + SOAP_FREE(soap, q); + } + else + { size_t domlen = 0; + if (q->domain) + { const char *s = strchr(q->domain, ':'); + if (s) + domlen = s - q->domain; + else + domlen = strlen(q->domain); + } + if ((!q->domain || !strncmp(q->domain, domain, domlen)) + && (!q->path || !strncmp(q->path, path, strlen(q->path))) + && (!q->secure || secure)) + { s = tmp; + if (q->version != version) + { sprintf(s, "$Version=%u;", q->version); + version = q->version; + } + if (q->name) + s += soap_encode_cookie(q->name, s, tmp-s+4080); + if (q->value && *q->value) + { *s++ = '='; + s += soap_encode_cookie(q->value, s, tmp-s+4080); + } + if (q->path && *q->path && (int)strlen(q->path) < tmp-s+4080) + { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path)); + s += strlen(s); + } + if (q->domain && (int)strlen(q->domain) < tmp-s+4080) + sprintf(s, ";$Domain=\"%s\"", q->domain); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp)); + if ((soap->error = soap->fposthdr(soap, "Cookie", tmp))) + return soap->error; + } + p = &q->next; + } + } + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_getcookies(struct soap *soap, const char *val) +{ struct soap_cookie *p = NULL, *q; + const char *s; + char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + char *domain = NULL; + char *path = NULL; + unsigned int version = 0; + time_t now = time(NULL); + if (!val) + return; + s = val; + while (*s) + { s = soap_decode_key(tmp, sizeof(tmp), s); + if (!soap_tag_cmp(tmp, "$Version")) + { if ((s = soap_decode_val(tmp, sizeof(tmp), s))) + { if (p) + p->version = (int)atol(tmp); + else + version = (int)atol(tmp); + } + } + else if (!soap_tag_cmp(tmp, "$Path")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->path) + SOAP_FREE(soap, p->path); + p->path = t; + } + else + { if (path) + SOAP_FREE(soap, path); + path = t; + } + } + else if (!soap_tag_cmp(tmp, "$Domain")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(t, tmp); + } + else + t = NULL; + if (p) + { if (p->domain) + SOAP_FREE(soap, p->domain); + p->domain = t; + } + else + { if (domain) + SOAP_FREE(soap, domain); + domain = t; + } + } + else if (p && !soap_tag_cmp(tmp, "Path")) + { if (p->path) + SOAP_FREE(soap, p->path); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->path, tmp); + } + else + p->path = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Domain")) + { if (p->domain) + SOAP_FREE(soap, p->domain); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1))) + strcpy(p->domain, tmp); + } + else + p->domain = NULL; + } + else if (p && !soap_tag_cmp(tmp, "Version")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->version = (unsigned int)atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Max-Age")) + { s = soap_decode_val(tmp, sizeof(tmp), s); + p->expire = now + atol(tmp); + } + else if (p && !soap_tag_cmp(tmp, "Expires")) + { struct tm T; + char a[3]; + static const char mns[] = "anebarprayunulugepctovec"; + s = soap_decode_val(tmp, sizeof(tmp), s); + if (strlen(tmp) > 20) + { memset((void*)&T, 0, sizeof(T)); + a[0] = tmp[4]; + a[1] = tmp[5]; + a[2] = '\0'; + T.tm_mday = (int)atol(a); + a[0] = tmp[8]; + a[1] = tmp[9]; + T.tm_mon = (strstr(mns, a) - mns) / 2; + a[0] = tmp[11]; + a[1] = tmp[12]; + T.tm_year = 100 + (int)atol(a); + a[0] = tmp[13]; + a[1] = tmp[14]; + T.tm_hour = (int)atol(a); + a[0] = tmp[16]; + a[1] = tmp[17]; + T.tm_min = (int)atol(a); + a[0] = tmp[19]; + a[1] = tmp[20]; + T.tm_sec = (int)atol(a); + p->expire = soap_timegm(&T); + } + } + else if (p && !soap_tag_cmp(tmp, "Secure")) + p->secure = 1; + else + { if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie)))) + { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->name, tmp); + s = soap_decode_val(tmp, sizeof(tmp), s); + if (*tmp) + { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1); + strcpy(p->value, tmp); + } + else + p->value = NULL; + if (domain) + p->domain = domain; + else + { p->domain = (char*)SOAP_MALLOC(soap, strlen(soap->host)+1); + strcpy(p->domain, soap->host); + } + if (path) + p->path = path; + else + { p->path = (char*)SOAP_MALLOC(soap, strlen(soap->path)+1); + strcpy(p->path, soap->path); + } + p->expire = 0; + p->secure = 0; + p->version = version; + } + } + } + if (p) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure)); + if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path))) + { q->version = p->version; + q->expire = p->expire; + q->secure = p->secure; + q->env = 1; + } + if (p->name) + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } + if (domain) + SOAP_FREE(soap, domain); + if (path) + SOAP_FREE(soap, path); +} + +/******************************************************************************/ +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_getenv_cookies(struct soap *soap) +{ struct soap_cookie *p; + const char *s; + char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */ + if (!(s = getenv("HTTP_COOKIE"))) + return SOAP_ERR; + do + { s = soap_decode_key(key, sizeof(key), s); + s = soap_decode_val(val, sizeof(val), s); + p = soap_set_cookie(soap, key, val, NULL, NULL); + if (p) + p->env = 1; + } while (*s); + return SOAP_OK; +} + +/******************************************************************************/ +SOAP_FMAC1 +struct soap_cookie* +SOAP_FMAC2 +soap_copy_cookies(struct soap *copy, struct soap *soap) +{ struct soap_cookie *p, **q, *r; + q = &r; + for (p = soap->cookies; p; p = p->next) + { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(copy, sizeof(struct soap_cookie)))) + return r; + **q = *p; + if (p->name) + { if (((*q)->name = (char*)SOAP_MALLOC(copy, strlen(p->name)+1))) + strcpy((*q)->name, p->name); + } + if (p->value) + { if (((*q)->value = (char*)SOAP_MALLOC(copy, strlen(p->value)+1))) + strcpy((*q)->value, p->value); + } + if (p->domain) + { if (((*q)->domain = (char*)SOAP_MALLOC(copy, strlen(p->domain)+1))) + strcpy((*q)->domain, p->domain); + } + if (p->path) + { if (((*q)->path = (char*)SOAP_MALLOC(copy, strlen(p->path)+1))) + strcpy((*q)->path, p->path); + } + q = &(*q)->next; + } + *q = NULL; + return r; +} + +/******************************************************************************/ +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_free_cookies(struct soap *soap) +{ struct soap_cookie *p; + for (p = soap->cookies; p; p = soap->cookies) + { soap->cookies = p->next; + SOAP_FREE(soap, p->name); + if (p->value) + SOAP_FREE(soap, p->value); + if (p->domain) + SOAP_FREE(soap, p->domain); + if (p->path) + SOAP_FREE(soap, p->path); + SOAP_FREE(soap, p); + } +} + +/******************************************************************************/ +#endif /* WITH_COOKIES */ + +/******************************************************************************/ +#ifdef WITH_GZIP +#ifndef PALM_1 +static int +soap_getgziphdr(struct soap *soap) +{ int i; + soap_wchar c, f = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n")); + for (i = 0; i < 9; i++) + { if ((int)(c = soap_get1(soap) == EOF)) + return soap->error = SOAP_EOF; + if (i == 2) + f = c; + } + if (f & 0x04) /* FEXTRA */ + { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--) + { if ((int)soap_get1(soap) == EOF) + return soap->error = SOAP_EOF; + } + } + if (f & 0x08) /* FNAME */ + { do + c = soap_get1(soap); + while (c && (int)c != EOF); + } + if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */ + { do + c = soap_get1(soap); + while (c && (int)c != EOF); + } + if ((int)c != EOF && (f & 0x01)) /* FHCRC */ + { if ((int)(c = soap_get1(soap)) != EOF) + c = soap_get1(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_begin_recv(struct soap *soap) +{ soap_wchar c; + soap->error = SOAP_OK; + soap_free_temp(soap); + soap_set_local_namespaces(soap); + soap->version = 0; /* don't assume we're parsing SOAP content by default */ +#ifndef WITH_NOIDREF + soap_free_iht(soap); +#endif + if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK) + soap->omode |= SOAP_IO_CHUNK; + soap->imode &= ~SOAP_IO; + soap->mode = soap->imode; + if (!soap->keep_alive) + { soap->buflen = 0; + soap->bufidx = 0; + } + if (!(soap->mode & SOAP_IO_KEEPALIVE)) + soap->keep_alive = 0; + soap->ahead = 0; + soap->peeked = 0; + soap->level = 0; + soap->part = SOAP_BEGIN; + soap->alloced = 0; + soap->count = 0; + soap->length = 0; + soap->cdata = 0; + *soap->endpoint = '\0'; + soap->action = NULL; + soap->status = 0; +#ifndef WITH_LEANER + soap->dom = NULL; + soap->dime.chunksize = 0; + soap->dime.buflen = 0; + soap->dime.list = NULL; + soap->dime.first = NULL; + soap->dime.last = NULL; + soap->mime.list = NULL; + soap->mime.first = NULL; + soap->mime.last = NULL; + soap->mime.boundary = NULL; + soap->mime.start = NULL; + soap->xlist = NULL; +#endif +#ifdef WIN32 +#ifndef UNDER_CE +#ifndef WITH_FASTCGI + if (!soap_valid_socket(soap->socket)) +#ifdef __BORLANDC__ + setmode((SOAP_SOCKET)soap->recvfd, O_BINARY); +#else + _setmode((SOAP_SOCKET)soap->recvfd, _O_BINARY); +#endif +#endif +#endif +#endif +#ifdef WITH_ZLIB + soap->mode &= ~SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_NONE; + soap->zlib_out = SOAP_ZLIB_NONE; + soap->d_stream.next_in = Z_NULL; + soap->d_stream.avail_in = 0; + soap->d_stream.next_out = (Byte*)soap->buf; + soap->d_stream.avail_out = SOAP_BUFLEN; + soap->z_ratio_in = 1.0; +#endif +#ifndef WITH_LEANER + if (soap->fprepareinit) + soap->fprepareinit(soap); +#endif + c = soap_getchar(soap); +#ifdef WITH_GZIP + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->mode |= SOAP_ENC_ZLIB; + soap->zlib_in = SOAP_ZLIB_GZIP; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + /* should not chunk over plain transport, so why bother to check? */ + /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */ + /* soap->z_buflen = soap->bufidx; */ + /* else */ + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + c = soap_getchar(soap); + } +#endif +#ifndef WITH_LEANER + if (c == '-' && soap_get0(soap) == '-') + soap->mode |= SOAP_ENC_MIME; + else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20) + soap->mode |= SOAP_ENC_DIME; + else +#endif + { while (soap_blank(c)) + c = soap_getchar(soap); + } + if ((int)c == EOF) + return soap->error = SOAP_EOF; + soap_unget(soap, c); +#ifndef WITH_NOHTTP + /* if not XML or (start of)BOM or MIME/DIME/ZLIB, assume HTTP header */ + if (c != '<' && c != 0xEF && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB))) + { soap->mode &= ~SOAP_IO; + soap->error = soap->fparse(soap); + if (soap->error && soap->error < SOAP_STOP) + { soap->keep_alive = 0; /* force close later */ + return soap->error; + } + if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) + { soap->chunkbuflen = soap->buflen; + soap->buflen = soap->bufidx; + soap->chunksize = 0; + } +#ifndef WITH_LEANER + else if (soap->fpreparerecv && soap->buflen != soap->bufidx) + soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx); +#endif + /* Note: fparse should not use soap_unget to push back last char */ + if (soap_get0(soap) == (int)EOF) + { if (soap->status == 200) + return soap->error = SOAP_NO_DATA; + return soap->error = soap->status; + } +#ifdef WITH_ZLIB + if (soap->zlib_in != SOAP_ZLIB_NONE) +#ifdef WITH_GZIP + { c = soap_get1(soap); + if (c == 0x1F) + { if (soap_getgziphdr(soap)) + return soap->error; + if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + soap->z_crc = crc32(0L, NULL, 0); + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n")); + } + else + { soap_revget1(soap); +#else + { +#endif + if (inflateInit(&soap->d_stream) != Z_OK) + return soap->error = SOAP_ZLIB_ERROR; + soap->zlib_state = SOAP_ZLIB_INFLATE; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n")); + } + soap->mode |= SOAP_ENC_ZLIB; + memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN); + soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx); + soap->d_stream.avail_in = soap->buflen - soap->bufidx; + soap->z_buflen = soap->buflen; + soap->buflen = soap->bufidx; + } +#endif + if (soap->error) + { if (soap->error == SOAP_FORM && soap->fform) + { soap->error = soap->fform(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + } + return soap->error; + } + } +#endif +#ifndef WITH_LEANER + if (soap->mode & SOAP_ENC_MIME) + { if (soap_getmimehdr(soap)) + return soap->error; + if (soap->mime.start) + { do + { if (!soap->mime.last->id) + break; + if (!soap_match_cid(soap, soap->mime.start, soap->mime.last->id)) + break; + } while (soap_get_mime_attachment(soap, NULL)); + } + if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + } + if (soap->mode & SOAP_ENC_DIME) + { if (soap_getdimehdr(soap)) + return soap->error; + if (soap->dime.flags & SOAP_DIME_CF) + { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n")); + soap->dime.chunksize = soap->dime.size; + if (soap->buflen - soap->bufidx >= soap->dime.chunksize) + { soap->dime.buflen = soap->buflen; + soap->buflen = soap->bufidx + soap->dime.chunksize; + } + else + soap->dime.chunksize -= soap->buflen - soap->bufidx; + } + soap->count = soap->buflen - soap->bufidx; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse(struct soap *soap) +{ char header[SOAP_HDRLEN], *s; + unsigned short get = 0, status = 0, k = 0; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n")); + *soap->endpoint = '\0'; + soap->length = 0; + soap->userid = NULL; + soap->passwd = NULL; + soap->action = NULL; + soap->authrealm = NULL; + do + { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf))) + return soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf)); + for (;;) + { if (soap_getline(soap, header, SOAP_HDRLEN)) + { if (soap->error == SOAP_EOF) + { soap->error = SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n")); + break; + } + return soap->error; + } + if (!*header) + break; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header)); + s = strchr(header, ':'); + if (s) + { *s = '\0'; + do s++; + while (*s && *s <= 32); + if ((soap->error = soap->fparsehdr(soap, header, s))) + { if (soap->error < SOAP_STOP) + return soap->error; + status = soap->error; + soap->error = SOAP_OK; + } + } + } + if ((s = strchr(soap->msgbuf, ' '))) + { k = (unsigned short)soap_strtoul(s, &s, 10); + if (!soap_blank(*s)) + k = 0; + } + else + k = 0; + } while (k == 100); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing, status = %d\n", k)); + s = strstr(soap->msgbuf, "HTTP/"); + if (s && s[7] != '1') + { if (soap->keep_alive == 1) + soap->keep_alive = 0; + if (k == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* k == 0 for HTTP request */ + { soap->imode |= SOAP_IO_CHUNK; + soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; + } + } + if (soap->keep_alive < 0) + soap->keep_alive = 1; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive)); + if (s && (((get = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5))) + { size_t m = strlen(soap->endpoint); + size_t n = m + (s - soap->msgbuf) - 5 - (!get); + if (n >= sizeof(soap->endpoint)) + n = sizeof(soap->endpoint) - 1; + strncpy(soap->path, soap->msgbuf + 4 + (!get), n - m); + soap->path[n - m] = '\0'; + strcat(soap->endpoint, soap->path); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint)); + if (get) + { soap->error = soap->fget(soap); + if (soap->error == SOAP_OK) + soap->error = SOAP_STOP; /* prevents further processing */ + return soap->error; + } + if (status) + return soap->error = status; + } + soap->status = k; + if (k == 0 || k == 200 || (((k > 200 && k <= 299) || k == 400 || k == 500) && ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || soap->length > 0))) + return SOAP_OK; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", k)); + return soap_set_receiver_error(soap, "HTTP Error", soap->msgbuf, k); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_parse_header(struct soap *soap, const char *key, const char *val) +{ if (!soap_tag_cmp(key, "Host")) + { +#ifdef WITH_OPENSSL + if (soap->imode & SOAP_ENC_SSL) + strcpy(soap->endpoint, "https://"); + else +#endif + strcpy(soap->endpoint, "http://"); + strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifndef WITH_LEANER + else if (!soap_tag_cmp(key, "Content-Type")) + { soap->http_content = soap_strdup(soap, val); + if (soap_get_header_attribute(soap, val, "application/dime")) + soap->mode |= SOAP_ENC_DIME; + else if (soap_get_header_attribute(soap, val, "multipart/related") + || soap_get_header_attribute(soap, val, "multipart/form-data")) + { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary")); + soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start")); + soap->mode |= SOAP_ENC_MIME; + } + } +#endif + else if (!soap_tag_cmp(key, "Content-Length")) + soap->length = soap_strtoul(val, NULL, 10); + else if (!soap_tag_cmp(key, "Content-Encoding")) + { if (!soap_tag_cmp(val, "deflate")) +#ifdef WITH_ZLIB + soap->zlib_in = SOAP_ZLIB_DEFLATE; +#else + return SOAP_ZLIB_ERROR; +#endif + else if (!soap_tag_cmp(val, "gzip")) +#ifdef WITH_GZIP + soap->zlib_in = SOAP_ZLIB_GZIP; +#else + return SOAP_ZLIB_ERROR; +#endif + } +#ifdef WITH_ZLIB + else if (!soap_tag_cmp(key, "Accept-Encoding")) + { +#ifdef WITH_GZIP + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip")) + soap->zlib_out = SOAP_ZLIB_GZIP; + else +#endif + if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate")) + soap->zlib_out = SOAP_ZLIB_DEFLATE; + else + soap->zlib_out = SOAP_ZLIB_NONE; + } +#endif + else if (!soap_tag_cmp(key, "Transfer-Encoding")) + { soap->mode &= ~SOAP_IO; + if (!soap_tag_cmp(val, "chunked")) + soap->mode |= SOAP_IO_CHUNK; + } + else if (!soap_tag_cmp(key, "Connection")) + { if (!soap_tag_cmp(val, "keep-alive")) + soap->keep_alive = -soap->keep_alive; + else if (!soap_tag_cmp(val, "close")) + soap->keep_alive = 0; + } +#ifndef WITH_LEAN + else if (!soap_tag_cmp(key, "Authorization")) + { if (!soap_tag_cmp(val, "Basic *")) + { int n; + char *s; + soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n); + soap->tmpbuf[n] = '\0'; + if ((s = strchr(soap->tmpbuf, ':'))) + { *s = '\0'; + soap->userid = soap_strdup(soap, soap->tmpbuf); + soap->passwd = soap_strdup(soap, s + 1); + } + } + } + else if (!soap_tag_cmp(key, "WWW-Authenticate")) + soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm")); + else if (!soap_tag_cmp(key, "Expect")) + { if (!soap_tag_cmp(val, "100-continue")) + { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL)) + || (soap->error = soap->fposthdr(soap, NULL, NULL))) + return soap->error; + } + } +#endif + else if (!soap_tag_cmp(key, "SOAPAction")) + { if (*val == '"') + { soap->action = soap_strdup(soap, val + 1); + soap->action[strlen(soap->action) - 1] = '\0'; + } + } + else if (!soap_tag_cmp(key, "Location")) + { strncpy(soap->endpoint, val, sizeof(soap->endpoint)); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + } +#ifdef WITH_COOKIES + else if (!soap_tag_cmp(key, "Cookie") + || !soap_tag_cmp(key, "Cookie2") + || !soap_tag_cmp(key, "Set-Cookie") + || !soap_tag_cmp(key, "Set-Cookie2")) + soap_getcookies(soap, val); +#endif + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_get_header_attribute(struct soap *soap, const char *line, const char *key) +{ register const char *s = line; + if (s) + { while (*s) + { register short flag; + s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s); + flag = soap_tag_cmp(soap->tmpbuf, key); + s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s); + if (!flag) + return soap->tmpbuf; + } + } + return NULL; +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_key(char *buf, size_t len, const char *val) +{ return soap_decode(buf, len, val, "=,;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_decode_val(char *buf, size_t len, const char *val) +{ if (*val != '=') + { *buf = '\0'; + return val; + } + return soap_decode(buf, len, val + 1, ",;"); +} +#endif +#endif + +/******************************************************************************/ +#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER) +#ifndef PALM_1 +static const char* +soap_decode(char *buf, size_t len, const char *val, const char *sep) +{ const char *s; + char *t = buf; + for (s = val; *s; s++) + if (*s != ' ' && *s != '\t' && !strchr(sep, *s)) + break; + if (*s == '"') + { s++; + while (*s && *s != '"' && --len) + *t++ = *s++; + } + else + { while (soap_notblank(*s) && !strchr(sep, *s) && --len) + { if (*s == '%') + { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4) + + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0'); + s += 3; + } + else + *t++ = *s++; + } + } + *t = '\0'; + while (*s && !strchr(sep, *s)) + s++; + return s; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_out(struct soap *soap) +{ +#ifndef WITH_LEANER + size_t n = 0; + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start && strlen(soap->mime.boundary) + strlen(soap->mime.start) < sizeof(soap->tmpbuf) - 80 ) + { const char *s; + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + s = "application/dime"; + else if (soap->version == 2) + { if (soap->mode & SOAP_ENC_MTOM) + s = "application/xop+xml; charset=utf-8; type=application/soap+xml"; + else + s = "application/soap+xml; charset=utf-8"; + } + else + s = "text/xml; charset=utf-8"; + sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start); + n = strlen(soap->tmpbuf); + if (soap_send_raw(soap, soap->tmpbuf, n)) + return soap->error; + } + if (soap->mode & SOAP_IO_LENGTH) + soap->dime.size = soap->count; /* DIME in MIME correction */ + if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME)) + { if (soap_putdimehdr(soap)) + return soap->error; + } +#endif + soap->part = SOAP_IN_ENVELOPE; + return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope")) + return soap->error; +#ifndef WITH_LEANER + if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + { soap->dime.size = soap->count - soap->dime.size; /* DIME in MIME correction */ + sprintf(soap->id, soap->dime_id_format, 0); + soap->dime.id = soap->id; + if (soap->local_namespaces) + { if (soap->local_namespaces[0].out) + soap->dime.type = (char*)soap->local_namespaces[0].out; + else + soap->dime.type = (char*)soap->local_namespaces[0].ns; + } + soap->dime.options = NULL; + soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI; + if (!soap->dime.first) + soap->dime.flags |= SOAP_DIME_ME; + soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + (soap->dime.type ? ((strlen(soap->dime.type)+3)&(~3)) : 0); + } + if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) + return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3); +#endif + soap->part = SOAP_END_ENVELOPE; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_begin_in(struct soap *soap) +{ register struct Namespace *p; + soap->part = SOAP_IN_ENVELOPE; + if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0, NULL)) + { +#ifndef WITH_LEAN + if (!soap_element_begin_in(soap, "html", 0, NULL)) + { /* get HTML from buffer, stop receiving to avoid HTML parsing issues */ + char *s; +#ifndef WITH_NOIO + size_t (*f)(struct soap*, char*, size_t) = soap->frecv; + soap->frecv = frecv_stop; +#endif + soap_revert(soap); + s = soap_string_in(soap, 1, -1, -1); +#ifndef WITH_NOIO + soap->frecv = f; +#endif + return soap_set_receiver_error(soap, "HTTP Error", s, SOAP_HTTP_ERROR); + } +#endif + return soap->error = SOAP_VERSIONMISMATCH; + } + p = soap->local_namespaces; + if (p) + { const char *ns = p[0].out; + if (!ns) + ns = p[0].ns; + if (!strcmp(ns, soap_env1)) + { soap->version = 1; /* make sure we use SOAP 1.1 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1)))) + strcpy(p[1].out, soap_enc1); + } + else if (!strcmp(ns, soap_env2)) + { soap->version = 2; /* make sure we use SOAP 1.2 */ + if (p[1].out) + SOAP_FREE(soap, p[1].out); + if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2)))) + strcpy(p[1].out, soap_enc2); + } + } + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_envelope_end_in(struct soap *soap) +{ soap->part = SOAP_END_ENVELOPE; + return soap_element_end_in(soap, "SOAP-ENV:Envelope"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_out(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap->version == 1) + soap->encoding = 1; +#ifndef WITH_LEAN + if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body")) + return soap->error; +#endif + if (soap_element(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + return soap_element_start_end_out(soap, NULL); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_out(struct soap *soap) +{ if (soap_element_end_out(soap, "SOAP-ENV:Body")) + return soap->error; + soap->part = SOAP_END_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_begin_in(struct soap *soap) +{ soap->part = SOAP_IN_BODY; + if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0, NULL)) + return soap->error; + if (!soap->body) + soap->part = SOAP_NO_BODY; + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_body_end_in(struct soap *soap) +{ if (soap->part == SOAP_NO_BODY) + return SOAP_OK; + soap->part = SOAP_END_BODY; + return soap_element_end_in(soap, "SOAP-ENV:Body"); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_header(struct soap *soap) +{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH) + soap->error = SOAP_OK; + else if (soap->error == SOAP_OK && soap->fheader) + soap->error = soap->fheader(soap); + return soap->error; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_endpoint(struct soap *soap, const char *endpoint) +{ register const char *s; + register size_t i, n; + soap->endpoint[0] = '\0'; + soap->host[0] = '\0'; + soap->path[0] = '/'; + soap->path[1] = '\0'; + soap->port = 80; + if (!endpoint || !*endpoint) + return; +#ifdef WITH_OPENSSL + if (!soap_tag_cmp(endpoint, "https:*")) + soap->port = 443; +#endif + strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1); + soap->endpoint[sizeof(soap->endpoint) - 1] = '\0'; + s = strchr(endpoint, ':'); + if (s && s[1] == '/' && s[2] == '/') + s += 3; + else + s = endpoint; + n = strlen(s); + if (n >= sizeof(soap->host)) + n = sizeof(soap->host) - 1; +#ifdef WITH_IPV6 + if (s[0] == '[') + { s++; + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == ']') + { s++; + break; + } + } + } + else + { for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } + } +#else + for (i = 0; i < n; i++) + { soap->host[i] = s[i]; + if (s[i] == '/' || s[i] == ':') + break; + } +#endif + soap->host[i] = '\0'; + if (s[i] == ':') + { soap->port = (int)atol(s + i + 1); + for (i++; i < n; i++) + if (s[i] == '/') + break; + } + if (s[i]) + { strncpy(soap->path, s + i, sizeof(soap->path)); + soap->path[sizeof(soap->path) - 1] = '\0'; + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect(struct soap *soap, const char *endpoint, const char *action) +{ return soap_connect_command(soap, SOAP_POST, endpoint, action); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action) +{ char host[sizeof(soap->host)]; + int port; + size_t count; + soap->error = SOAP_OK; + strcpy(host, soap->host); /* save to compare */ + port = soap->port; /* save to compare */ + soap_set_endpoint(soap, endpoint); +#ifndef WITH_LEANER + if (soap->fconnect) + { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port))) + return soap->error; + } + else +#endif + if (soap->fopen && *soap->host) + { soap->status = http_command; + if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap)) + { soap->keep_alive = 0; /* to force close */ + soap->omode &= ~SOAP_IO_UDP; /* to force close */ + soap_closesock(soap); + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port)); +#ifdef WITH_UDP + if (!strncmp(endpoint, "soap.udp:", 9)) + soap->omode |= SOAP_IO_UDP; +#endif + soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port); + if (soap->error) + return soap->error; + soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0); + } + } + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + soap->action = soap_strdup(soap, action); + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint) + { unsigned int k = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((k & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count))) + return soap->error; +#ifndef WITH_LEANER + if ((k & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = k; + } + if (http_command != SOAP_POST) + return soap_end_send(soap); +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n) +{ register int i; + register unsigned long m; + register char *p; + if (!t) + t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1); + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + t[0] = '\0'; + if (!s) + return p; + for (; n > 2; n -= 3, s += 3) + { m = s[0]; + m = (m << 8) | s[1]; + m = (m << 8) | s[2]; + for (i = 4; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + t += 4; + } + t[0] = '\0'; + if (n > 0) + { m = 0; + for (i = 0; i < n; i++) + m = (m << 8) | *s++; + for (; i < 3; i++) + m <<= 8; + for (i++; i > 0; m >>= 6) + t[--i] = soap_base64o[m & 0x3F]; + for (i = 3; i > n; i--) + t[i] = '='; + t[4] = '\0'; + } + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register int i, j, c; + register unsigned long m; + register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = (strlen(s) + 3) / 4 * 3; + t = (char*)soap_malloc(soap, l); + } + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + if (n) + *n = 0; + for (;;) + { for (i = 0; i < SOAP_BLKLEN; i++) + { m = 0; + j = 0; + while (j < 4) + { c = *s++; + if (c == '=' || !c) + { i *= 3; + switch (j) + { case 2: + *t++ = (char)((m >> 4) & 0xFF); + i++; + break; + case 3: + *t++ = (char)((m >> 10) & 0xFF); + *t++ = (char)((m >> 2) & 0xFF); + i += 2; + } + if (n) + *n += i; + return p; + } + c -= '+'; + if (c >= 0 && c <= 79) + { int b = soap_base64i[c]; + if (b >= 64) + { soap->error = SOAP_TYPE; + return NULL; + } + m = (m << 6) + b; + j++; + } + else if (!soap_blank(c)) + { soap->error = SOAP_TYPE; + return NULL; + } + } + *t++ = (char)((m >> 16) & 0xFF); + *t++ = (char)((m >> 8) & 0xFF); + *t++ = (char)(m & 0xFF); + if (l < 3) + { if (n) + *n += i; + return p; + } + l -= 3; + } + if (n) + *n += 3 * SOAP_BLKLEN; + } +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +char* +SOAP_FMAC2 +soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n) +{ register char *p; + if (!t) + t = (char*)soap_malloc(soap, 2 * n + 1); + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + t[0] = '\0'; + if (s) + { for (; n > 0; n--) + { register int m = *s++; + *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0')); + m &= 0x0F; + *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0')); + } + } + *t++ = '\0'; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +SOAP_FMAC1 +const char* +SOAP_FMAC2 +soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n) +{ register const char *p; + if (!s || !*s) + { if (n) + *n = 0; + if (soap->error) + return NULL; + return SOAP_NON_NULL; + } + if (!t) + { l = strlen(s) / 2; + t = (char*)soap_malloc(soap, l); + } + if (!t) + { soap->error = SOAP_EOM; + return NULL; + } + p = t; + while (l) + { register int d1, d2; + d1 = *s++; + if (!d1) + break; + d2 = *s++; + if (!d2) + break; + *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0'); + l--; + } + if (n) + *n = t - p; + return p; +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_puthttphdr(struct soap *soap, int status, size_t count) +{ register const char *s = "text/xml; charset=utf-8"; + register int err = SOAP_OK; +#ifndef WITH_LEANER + register const char *r = NULL; +#endif + if (status == SOAP_FILE && soap->http_content) + s = soap->http_content; + else if (status == SOAP_HTML) + s = "text/html; charset=utf-8"; + else if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)) + { if (soap->version == 2) + s = "application/soap+xml; charset=utf-8"; + } +#ifndef WITH_LEANER + if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM)) + { if (soap->mode & SOAP_ENC_MTOM) + { r = s; + s = "application/xop+xml; charset=utf-8"; + } + else + s = "application/dime"; + } + if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->status != SOAP_GET && strlen(soap->mime.boundary) + strlen(soap->mime.start ? soap->mime.start : SOAP_STR_EOS) < sizeof(soap->tmpbuf) - 80) + { register const char *t = strchr(s, ';'); + sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary); + if (t) + strncat(soap->tmpbuf, s, t - s); + else + strcat(soap->tmpbuf, s); + if (soap->mime.start) + { strcat(soap->tmpbuf, "\"; start=\""); + strcat(soap->tmpbuf, soap->mime.start); + } + strcat(soap->tmpbuf, "\""); + if (r) + { strcat(soap->tmpbuf, "; start-info=\""); + strcat(soap->tmpbuf, r); + strcat(soap->tmpbuf, "\""); + } + s = soap->tmpbuf; + } +#endif + if (s && (err = soap->fposthdr(soap, "Content-Type", s))) + return err; +#ifdef WITH_ZLIB + if (soap->omode & SOAP_ENC_ZLIB) + { +#ifdef WITH_GZIP + err = soap->fposthdr(soap, "Content-Encoding", "gzip"); +#else + err = soap->fposthdr(soap, "Content-Encoding", "deflate"); +#endif + if (err) + return err; + } +#endif +#ifndef WITH_LEANER + if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK) + err = soap->fposthdr(soap, "Transfer-Encoding", "chunked"); + else +#endif + if (s && soap->status != SOAP_GET) + { sprintf(soap->tmpbuf, "%lu", (unsigned long)count); + err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf); + } + if (err) + return err; + return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close"); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_get(struct soap *soap) +{ return SOAP_GET_METHOD; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count) +{ register const char *s; + register int err; + if (soap->status == SOAP_GET) + s = "GET"; + else + s = "POST"; +#ifdef PALM + if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8)) +#else + if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6))) +#endif + return SOAP_OK; + if (strlen(endpoint) + strlen(soap->http_version) > sizeof(soap->tmpbuf) - 80) + return soap->error = SOAP_EOM; + if (soap->proxy_host && soap_tag_cmp(endpoint, "https:*")) + sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version); + else + sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + if (port != 80) + sprintf(soap->tmpbuf, "%s:%d", host, port); + else + strcpy(soap->tmpbuf, host); + if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf)) + || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, SOAP_OK, count))) + return err; +#ifdef WITH_ZLIB +#ifdef WITH_GZIP + if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate"))) +#else + if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate"))) +#endif + return err; +#endif +#ifndef WITH_LEAN + if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf))) + return err; + } + if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761) + { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd); + strcpy(soap->tmpbuf, "Basic "); + soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262)); + if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf))) + return err; + } +#endif +#ifdef WITH_COOKIES +#ifdef WITH_OPENSSL + if (soap_putcookies(soap, host, path, soap->ssl != NULL)) + return soap->error; +#else + if (soap_putcookies(soap, host, path, 0)) + return soap->error; +#endif +#endif + if (soap->version == 1 || (action && *action && strlen(action) < sizeof(soap->tmpbuf) - 2)) + { sprintf(soap->tmpbuf, "\"%s\"", action?action:""); + if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf))) + return err; + } + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_send_header(struct soap *soap, const char *s) +{ register const char *t; + do + { t = strchr(s, '\n'); /* disallow \n in HTTP headers */ + if (!t) + t = s + strlen(s); + if (soap_send_raw(soap, s, t - s)) + return soap->error; + s = t + 1; + } while (*t); + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_post_header(struct soap *soap, const char *key, const char *val) +{ if (key) + { if (http_send_header(soap, key)) + return soap->error; + if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val))) + return soap->error; + } + return soap_send_raw(soap, "\r\n", 2); +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +static int +http_response(struct soap *soap, int status, size_t count) +{ register int err; +#ifdef WMW_RPM_IO + if (soap->rpmreqid) + httpOutputEnable(soap->rpmreqid); +#endif + if (strlen(soap->http_version) > 4) + return soap->error = SOAP_EOM; + if (!status || status == SOAP_HTML || status == SOAP_FILE) + { const char *s; + if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)) + s = "200 OK"; + else + s = "202 ACCEPTED"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s)); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +#endif + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) + return err; + } + else if (status >= 200 && status < 600) + { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status)); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; +#ifndef WITH_LEAN + if (status == 401) + { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", strlen(soap->authrealm) < sizeof(soap->tmpbuf) - 14 ? soap->authrealm : "gSOAP Web Service"); + if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf))) + return err; + } + else if ((status >= 301 && status <= 303) || status == 307) + { if ((err = soap->fposthdr(soap, "Location", soap->endpoint))) + return err; + } +#endif + } + else + { const char *s = *soap_faultcode(soap); + if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender")) + s = "400 Bad Request"; + else + s = "500 Internal Server Error"; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status)); +#ifdef WMW_RPM_IO + if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ +#else + if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ +#endif + { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); + if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) + return err; + } + else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */ + return err; + } + if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7")) + || (err = soap_puthttphdr(soap, status, count))) + return err; +#ifdef WITH_COOKIES + if (soap_putsetcookies(soap)) + return soap->error; +#endif + return soap->fposthdr(soap, NULL, NULL); +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_response(struct soap *soap, int status) +{ register size_t count; + if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */)) + && (status == SOAP_HTML || status == SOAP_FILE)) + { soap->omode &= ~SOAP_IO; + soap->omode |= SOAP_IO_STORE; + } + soap->status = status; + count = soap_count_attachments(soap); + if (soap_begin_send(soap)) + return soap->error; +#ifndef WITH_NOHTTP + if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML)) + { register int n = soap->mode; + soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); + if ((n & SOAP_IO) != SOAP_IO_FLUSH) + soap->mode |= SOAP_IO_BUFFER; + if ((soap->error = soap->fresponse(soap, status, count))) + return soap->error; +#ifndef WITH_LEANER + if ((n & SOAP_IO) == SOAP_IO_CHUNK) + { if (soap_flush(soap)) + return soap->error; + } +#endif + soap->mode = n; + } +#endif + return SOAP_OK; +} +#endif + +/******************************************************************************/ +#ifndef WITH_LEAN +static const char* +soap_set_validation_fault(struct soap *soap, const char *s, const char *t) +{ if (*soap->tag) + sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag); + else + sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS); + return soap->msgbuf; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_set_fault(struct soap *soap) +{ const char **c = soap_faultcode(soap); + const char **s = soap_faultstring(soap); + if (soap->fseterror) + soap->fseterror(soap, c, s); + if (!*c) + { if (soap->version == 2) + *c = "SOAP-ENV:Sender"; + else + *c = "SOAP-ENV:Client"; + } + if (*s) + return; + switch (soap->error) + { +#ifndef WITH_LEAN + case SOAP_CLI_FAULT: + *s = "Client fault"; + break; + case SOAP_SVR_FAULT: + *s = "Server fault"; + break; + case SOAP_TAG_MISMATCH: + *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL); + break; + case SOAP_TYPE: + *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type); + break; + case SOAP_SYNTAX_ERROR: + *s = "Well-formedness violation"; + break; + case SOAP_NO_TAG: + *s = "No XML element tag"; + break; + case SOAP_MUSTUNDERSTAND: + *c = "SOAP-ENV:MustUnderstand"; + sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_VERSIONMISMATCH: + *c = "SOAP-ENV:VersionMismatch"; + *s = "SOAP version mismatch or invalid SOAP message"; + break; + case SOAP_DATAENCODINGUNKNOWN: + *c = "SOAP-ENV:DataEncodingUnknown"; + *s = "Unsupported SOAP data encoding"; + break; + case SOAP_NAMESPACE: + *s = soap_set_validation_fault(soap, "namespace mismatch", NULL); + break; + case SOAP_USER_ERROR: + *s = "User error"; + break; + case SOAP_FATAL_ERROR: + *s = "Fatal error"; + break; + case SOAP_NO_METHOD: + sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag); + *s = soap->msgbuf; + break; + case SOAP_NO_DATA: + *s = "Data required for operation"; + break; + case SOAP_GET_METHOD: + *s = "HTTP GET method not implemented"; + break; + case SOAP_EOM: + *s = "Out of memory"; + break; + case SOAP_MOE: + *s = "Memory overflow or corruption error"; + break; + case SOAP_IOB: + *s = "Array index out of bounds"; + break; + case SOAP_NULL: + *s = soap_set_validation_fault(soap, "nil not allowed", NULL); + break; + case SOAP_DUPLICATE_ID: + *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID"; + break; + case SOAP_MISSING_ID: + *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id); + if (soap->version == 2) + *soap_faultsubcode(soap) = "SOAP-ENC:MissingID"; + break; + case SOAP_HREF: + *s = soap_set_validation_fault(soap, "incompatible object ref ", soap->id); + break; + case SOAP_FAULT: + break; +#ifndef WITH_NOIO + case SOAP_UDP_ERROR: + *s = "Message too large for UDP packet"; + break; + case SOAP_TCP_ERROR: + *s = tcp_error(soap); + break; +#endif + case SOAP_HTTP_ERROR: + *s = "An HTTP processing error occurred"; + break; + case SOAP_SSL_ERROR: +#ifdef WITH_OPENSSL + *s = "SSL error"; +#else + *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL"; +#endif + break; + case SOAP_PLUGIN_ERROR: + *s = "Plugin registry error"; + break; + case SOAP_DIME_ERROR: + *s = "DIME format error"; + break; + case SOAP_DIME_HREF: + *s = "DIME href to missing attachment"; + break; + case SOAP_DIME_MISMATCH: + *s = "DIME version/transmission error"; + break; + case SOAP_DIME_END: + *s = "End of DIME error"; + break; + case SOAP_MIME_ERROR: + *s = "MIME format error"; + break; + case SOAP_MIME_HREF: + *s = "MIME href to missing attachment"; + break; + case SOAP_MIME_END: + *s = "End of MIME error"; + break; + case SOAP_ZLIB_ERROR: +#ifdef WITH_ZLIB + sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:""); + *s = soap->msgbuf; +#else + *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP"; +#endif + break; + case SOAP_REQUIRED: + *s = soap_set_validation_fault(soap, "missing required attribute", NULL); + break; + case SOAP_PROHIBITED: + *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL); + break; + case SOAP_OCCURS: + *s = soap_set_validation_fault(soap, "min/maxOccurs violation", NULL); + break; + case SOAP_LENGTH: + *s = soap_set_validation_fault(soap, "content length violation", NULL); + break; + case SOAP_FD_EXCEEDED: + *s = "Maximum number of open connections was reached"; + break; + case SOAP_STOP: + *s = "Stopped: no response sent"; + break; +#endif + case SOAP_EOF: +#ifndef WITH_NOIO + sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap)); + *s = soap->msgbuf; + break; +#else + *s = "End of file or no input"; + break; +#endif + default: +#ifndef WITH_NOHTTP +#ifndef WITH_LEAN + if (soap->error > 200 && soap->error < 600) + { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error)); + *s = soap->msgbuf; + } + else +#endif +#endif + { sprintf(soap->msgbuf, "Error %d", soap->error); + *s = soap->msgbuf; + } + } +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_fault(struct soap *soap) +{ register int status = soap->error; + int r = 1; + if (status == SOAP_STOP) + return status; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error)); + soap->keep_alive = 0; /* to terminate connection */ + soap_set_fault(soap); +#ifndef WITH_NOIO +#ifndef WITH_LEAN + if (soap_valid_socket(soap->socket)) + { struct timeval timeout; + fd_set rfd, sfd; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&rfd); + FD_ZERO(&sfd); + FD_SET((SOAP_SOCKET)soap->socket, &rfd); + FD_SET((SOAP_SOCKET)soap->socket, &sfd); + r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, NULL, &timeout); + if (r > 0) + { if (!FD_ISSET((SOAP_SOCKET)soap->socket, &sfd) + || (FD_ISSET((SOAP_SOCKET)soap->socket, &rfd) + && recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0)) + r = 0; + } + } +#endif +#endif + if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && r > 0) + { soap->error = SOAP_OK; + soap_serializeheader(soap); + soap_serializefault(soap); + soap_begin_count(soap); + if (soap->mode & SOAP_IO_LENGTH) + { soap_envelope_begin_out(soap); + soap_putheader(soap); + soap_body_begin_out(soap); + soap_putfault(soap); + soap_body_end_out(soap); + soap_envelope_end_out(soap); + } + soap_end_count(soap); + if (soap_response(soap, status) + || soap_envelope_begin_out(soap) + || soap_putheader(soap) + || soap_body_begin_out(soap) + || soap_putfault(soap) + || soap_body_end_out(soap) + || soap_envelope_end_out(soap)) + return soap_closesock(soap); + soap_end_send(soap); + } + soap->error = status; + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_fault(struct soap *soap) +{ register int status = soap->error; + DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Receiving SOAP Fault\n")); + soap->error = SOAP_OK; + if (soap_getfault(soap)) + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n")); + *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client"); + soap->error = status; + soap_set_fault(soap); + } + else + { register const char *s = *soap_faultcode(soap); + if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver")) + status = SOAP_SVR_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender")) + status = SOAP_CLI_FAULT; + else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand")) + status = SOAP_MUSTUNDERSTAND; + else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch")) + status = SOAP_VERSIONMISMATCH; + else + { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Fault code %s\n", s)); + status = SOAP_FAULT; + } + if (soap_body_end_in(soap) + || soap_envelope_end_in(soap) + || soap_end_recv(soap)) + return soap_closesock(soap); + soap->error = status; + } + return soap_closesock(soap); +} +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_send_empty_response(struct soap *soap, int status) +{ register soap_mode m = soap->omode; + soap->count = 0; + if ((m & SOAP_IO) == SOAP_IO_CHUNK) + { soap->omode &= ~SOAP_IO_CHUNK; + soap->omode |= SOAP_IO_BUFFER; + } + if (soap_response(soap, status) || soap_end_send(soap)) + { soap->omode = m; + return soap_closesock(soap); + } + soap->omode = m; + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOHTTP +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_recv_empty_response(struct soap *soap) +{ if (soap_begin_recv(soap) || soap_end_recv(soap)) + { if (soap->error != 202) + return soap_closesock(soap); + soap->error = SOAP_OK; + } + return SOAP_OK; +} +#endif +#endif + +/******************************************************************************/ +#ifndef WITH_NOIO +#ifndef PALM_1 +static const char* +soap_strerror(struct soap *soap) +{ register int err = soap->errnum; + if (err) + { +#ifndef WIN32 + return strerror(err); +#else +#ifndef UNDER_CE + DWORD len; + *soap->msgbuf = '\0'; + len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)soap->msgbuf, (DWORD)sizeof(soap->msgbuf), NULL); +#else + DWORD i, len; + *soap->msgbuf = '\0'; + len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)soap->msgbuf, (DWORD)(sizeof(soap->msgbuf)/sizeof(TCHAR)), NULL); + for (i = 0; i <= len; i++) + { if (((TCHAR*)soap->msgbuf)[i] < 0x80) + soap->msgbuf[i] = (char)((TCHAR*)soap->msgbuf)[i]; + else + soap->msgbuf[i] = '?'; + } +#endif + return soap->msgbuf; +#endif + } + return "Operation interrupted or timed out"; +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail, int soaperror) +{ *soap_faultcode(soap) = faultcode; + if (faultsubcode) + *soap_faultsubcode(soap) = faultsubcode; + *soap_faultstring(soap) = faultstring; + if (faultdetail && *faultdetail) + { register const char **s = soap_faultdetail(soap); + if (s) + *s = faultdetail; + } + return soap->error = soaperror; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror) +{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetail, soaperror); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +static int +soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ char *r = NULL, *s = NULL, *t = NULL; + if (faultsubcode) + r = soap_strdup(soap, faultsubcode); + if (faultstring) + s = soap_strdup(soap, faultstring); + if (faultdetail) + t = soap_strdup(soap, faultdetail); + return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcode, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail) +{ return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail) +{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcode, faultstring, faultdetail); +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault(struct soap *soap, FILE *fd) +{ if (soap_check_state(soap)) + fprintf(fd, "Error: soap struct not initialized\n"); + else if (soap->error) + { const char *c, *v = NULL, *s, **d; + d = soap_faultcode(soap); + if (!*d) + soap_set_fault(soap); + c = *d; + if (soap->version == 2) + v = *soap_faultsubcode(soap); + s = *soap_faultstring(soap); + d = soap_faultdetail(soap); + fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]"); + } +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 +void +SOAP_FMAC2 +soap_print_fault_location(struct soap *soap, FILE *fd) +{ +#ifndef WITH_LEAN + int i, j, c1, c2; + if (soap->error && soap->bufidx <= soap->buflen && soap->buflen > 0 && soap->buflen <= SOAP_BUFLEN) + { i = (int)soap->bufidx - 1; + if (i <= 0) + i = 0; + c1 = soap->buf[i]; + soap->buf[i] = '\0'; + if ((int)soap->buflen >= i + 1024) + j = i + 1023; + else + j = (int)soap->buflen - 1; + c2 = soap->buf[j]; + soap->buf[j] = '\0'; + fprintf(fd, "%s%c\n\n", soap->buf, c1); + if (soap->bufidx < soap->buflen) + fprintf(fd, "%s\n", soap->buf + soap->bufidx); + soap->buf[i] = c1; + soap->buf[j] = c2; + } +#endif +} +#endif +#endif + +/******************************************************************************/ +#ifndef PALM_1 +SOAP_FMAC1 +int +SOAP_FMAC2 +soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg) +{ register struct soap_plugin *p; + register int r; + if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin)))) + return soap->error = SOAP_EOM; + p->id = NULL; + p->data = NULL; + p->fcopy = NULL; + p->fdelete = NULL; + r = fcreate(soap, p, arg); + if (!r && p->fdelete) + { p->next = soap->plugins; + soap->plugins = p; + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id)); + return SOAP_OK; + } + DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r)); + SOAP_FREE(soap, p); + return r; +} +#endif + +/******************************************************************************/ +#ifndef PALM_1 +static void * +fplugin(struct soap *soap, const char *id) +{ register struct soap_plugin *p; + for (p = soap->plugins; p; p = p->next) + if (p->id == id || !strcmp(p->id, id)) + return p->data; + return NULL; +} +#endif + +/******************************************************************************/ +#ifndef PALM_2 +SOAP_FMAC1 +void * +SOAP_FMAC2 +soap_lookup_plugin(struct soap *soap, const char *id) +{ return soap->fplugin(soap, id); +} +#endif + +/******************************************************************************/ +#ifdef __cplusplus +} +#endif + +/******************************************************************************\ + * + * C++ soap struct methods + * +\******************************************************************************/ + +#ifdef __cplusplus +#ifndef WITH_LEAN +soap::soap() +{ soap_init(this); +} +#endif +#endif + +/******************************************************************************/ +#ifdef __cplusplus +#ifndef WITH_LEAN +soap::soap(soap_mode m) +{ soap_init1(this, m); +} +#endif +#endif + +/******************************************************************************/ +#ifdef __cplusplus +#ifndef WITH_LEAN +soap::soap(soap_mode im, soap_mode om) +{ soap_init2(this, im, om); +} +#endif +#endif + +/******************************************************************************/ +#ifdef __cplusplus +#ifndef WITH_LEAN +soap::soap(struct soap& soap) +{ soap_copy_context(this, &soap); +} +#endif +#endif + +/******************************************************************************/ +#ifdef __cplusplus +#ifndef WITH_LEAN +soap::~soap() +{ soap_destroy(this); + soap_end(this); + soap_done(this); +} +#endif +#endif + +/******************************************************************************/ diff --git a/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h new file mode 100644 index 0000000..2a8928b --- /dev/null +++ b/org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h @@ -0,0 +1,2166 @@ +/* + +stdsoap2.h 2.7.9b + +gSOAP runtime + +gSOAP XML Web services tools +Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved. +This part of the software is released under one of the following licenses: +GPL, the gSOAP public license, or Genivia's license for commercial use. +-------------------------------------------------------------------------------- +Contributors: + +Wind River Systems, Inc., for the following additions (marked WR[...]): + - vxWorks compatible +-------------------------------------------------------------------------------- +gSOAP public license. + +The contents of this file are subject to the gSOAP Public License Version 1.3 +(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.cs.fsu.edu/~engelen/soaplicense.html +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the License. + +The Initial Developer of the Original Code is Robert A. van Engelen. +Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved. +-------------------------------------------------------------------------------- +GPL license. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +Author contact information: +engelen@genivia.com / engelen@acm.org +-------------------------------------------------------------------------------- +A commercial use license is available from Genivia, Inc., contact@genivia.com +-------------------------------------------------------------------------------- +*/ + +#ifdef WITH_SOAPDEFS_H +# include "soapdefs.h" /* include user-defined stuff */ +#endif + +#ifndef _THREAD_SAFE +# define _THREAD_SAFE +#endif + +#ifndef OPENSERVER +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +#ifndef SOAP_FMAC1 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC1 +#endif + +#ifndef SOAP_FMAC2 /* stdsoap2.h declaration macro */ +# define SOAP_FMAC2 +#endif + +#ifndef SOAP_FMAC3 /* (de)serializer declaration macro */ +# define SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC3S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC3S SOAP_FMAC3 +#endif + +#ifndef SOAP_FMAC4 /* (de)serializer declaration macro */ +# define SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC4S /* string converter for (de)serializer declaration macro */ +# define SOAP_FMAC4S SOAP_FMAC4 +#endif + +#ifndef SOAP_FMAC5 /* stub/skeleton declaration macro */ +# define SOAP_FMAC5 +#endif + +#ifndef SOAP_FMAC6 /* stub/skeleton declaration macro */ +# define SOAP_FMAC6 +#endif + +#ifndef SOAP_CMAC /* class declaration macro */ +# define SOAP_CMAC +#endif + +#ifndef SOAP_NMAC /* namespace table declaration macro */ +# define SOAP_NMAC +#endif + +#ifndef SOAP_SOURCE_STAMP +# define SOAP_SOURCE_STAMP(str) +#endif + +/* gSOAP 2.7.4 and higher: fast look-aside buffering is stable */ +#ifndef WITH_FAST +# define WITH_FAST +#endif + +#ifdef WITH_LEANER +# ifndef WITH_LEAN +# define WITH_LEAN +# endif +#endif + +#ifdef WITH_LEAN +# ifdef WITH_COOKIES +# error "Cannot build WITH_LEAN code WITH_COOKIES enabled" +# endif +#endif + +#ifndef STDSOAP_H +#define STDSOAP_H + +#if defined(__vxworks) || defined(__VXWORKS__) +# define VXWORKS +#endif + +#ifdef _WIN32 +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef _WIN32_WCE +# ifndef UNDER_CE +# define UNDER_CE _WIN32_WCE +# endif +#endif + +#ifdef UNDER_CE +# ifndef WIN32 +# define WIN32 +# endif +#endif + +#ifdef __BORLANDC__ +# ifdef __WIN32__ +# ifndef WIN32 +# define WIN32 +# endif +# endif +#endif + +#ifdef __CYGWIN__ +# ifndef CYGWIN +# define CYGWIN +# endif +#endif + +#ifdef __SYMBIAN32__ +# define SYMBIAN +# undef WIN32 +#endif + +#if defined(__palmos__) || defined(PALM_GCC) || defined(__PALMOS_TRAPS__) +# ifndef PALM +# define PALM +# endif +#endif + +#if defined(__hpux) +# ifndef HP_UX +# define HP_UX +# endif +#endif + +#if defined(__alpha) && !defined(__VMS) +# ifndef TRU64 +# define TRU64 +# endif +#endif + +#ifdef __MVS__ +# ifndef OS390 +# define OS390 +# endif +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +# ifdef WITH_OPENSSL +# ifndef HAVE_OPENSSL_SSL_H +# undef WITH_OPENSSL +# endif +# endif +#else +# if defined(UNDER_CE) +# define WITH_LEAN +# define HAVE_SSCANF +# elif defined(WIN32) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%I64d" +# define SOAP_ULONG_FORMAT "%I64u" +# elif defined(CYGWIN) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__APPLE__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(_AIXVERSION_431) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(HP_UX) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(FREEBSD) || defined(__FreeBSD__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_GETTIMEOFDAY +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%qd" +# define SOAP_ULONG_FORMAT "%qu" +# elif defined(__VMS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__GLIBC__) || defined(__GNU__) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_STRTOLL +# define HAVE_STRTOULL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_TIMEGM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define HAVE_ISNAN +# elif defined(TRU64) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_GETTIMEOFDAY +# define HAVE_SYS_TIMEB_H +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define __USE_STD_IOSTREAM +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +# elif defined(MAC_CARBON) +# define WITH_NOIO +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(PALM) +# define WITH_LEAN +# define HAVE_STRTOD /* strtod() is defined in palmFunctions.h */ +# include /* Needs to be included before unix headers */ +# include +# define IGNORE_STDIO_STUBS +# include +# define O_NONBLOCK FNONBIO +# include +# include "palmFunctions.h" +# elif defined(SYMBIAN) +# define WITH_LEAN +# define WITH_NONAMESPACES +# define HAVE_STRTOD /* use STRTOD since sscanf doesn't seem to work */ +# include +# include +# elif defined(VXWORKS) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_PGMTIME_R +# define HAVE_PLOCALTIME_R +# define HAVE_MKTIME +# elif defined(OS390) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(AS400) +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# elif defined(__QNX__) || defined(QNX) +/* QNX does not have a working version of strtof */ +# undef HAVE_STRTOF +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# define LONG64 long +# define ULONG64 unsigned LONG64 +# define SOAP_LONG_FORMAT "%ld" +# define SOAP_ULONG_FORMAT "%lu" +# else +/* Default asumptions on supported functions */ +# define HAVE_STRRCHR +# define HAVE_STRTOD +# define HAVE_SSCANF +# define HAVE_STRTOL +# define HAVE_STRTOUL +# define HAVE_SYS_TIMEB_H +# define HAVE_FTIME +# define HAVE_RAND_R +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GMTIME_R +# define HAVE_LOCALTIME_R +# define HAVE_WCTOMB +# define HAVE_MBTOWC +# endif +#endif + +#ifndef SOAP_LONG_FORMAT +# define SOAP_LONG_FORMAT "%lld" /* printf format for 64 bit ints */ +#endif + +#ifndef SOAP_ULONG_FORMAT +# define SOAP_ULONG_FORMAT "%llu" /* printf format for unsigned 64 bit ints */ +#endif + +#ifndef WITH_NOSTDLIB +# include +# ifndef PALM +# include +# include +# endif +# include +# include +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) +# include +# include +#endif + +#ifdef WITH_NOHTTP +# ifndef WITH_NOIO +# define WITH_NOIO +# undef WITH_COOKIES +# endif +#endif + +#ifndef UNDER_CE +# ifndef PALM +# ifndef WITH_NOIO +# include +# include +# endif +# ifndef WITH_LEAN +# ifdef HAVE_SYS_TIMEB_H +# include /* for ftime() */ +# endif +# include +# endif +# endif +#endif + +#ifdef OPENSERVER +# include +# include +# include + extern int h_errno; +#endif + +#ifndef WITH_NOIO +# ifndef WIN32 +# ifndef PALM +# include +# ifdef VXWORKS +# include +# include +# endif +# ifndef VXWORKS +# ifndef SYMBIAN +# include +# endif +# endif +# ifdef SUN_OS +# include /* SUN */ +# include /* SUN < 2.8 (?) */ +# endif +# ifdef VXWORKS +# ifdef _WRS_KERNEL +# include +# endif +# else +# include +# endif +# include +# ifdef OS390 +# include +# else +# include /* TCP_NODELAY */ +# endif +# include +# endif +# endif +#endif + +#ifdef WITH_FASTCGI +# include +#endif + +#ifdef WITH_OPENSSL +# define OPENSSL_NO_KRB5 +# include +# include +# include +# include +# include +# ifndef ALLOW_OLD_VERSIONS +# if (OPENSSL_VERSION_NUMBER < 0x00905100L) +# error "Must use OpenSSL 0.9.6 or later" +# endif +# endif +#endif + +#ifdef WITH_GZIP +# ifndef WITH_ZLIB +# define WITH_ZLIB +# endif +#endif + +#ifdef WITH_CASEINSENSITIVETAGS +# define SOAP_STRCMP soap_tag_cmp /* case insensitve XML element/attribute names */ +#else +# define SOAP_STRCMP strcmp /* case sensitive XML element/attribute names */ +#endif + +#ifdef WITH_ZLIB +# include +#endif + +#ifndef WITH_NOSTDLIB +# ifndef PALM +# include /* for isnan() */ +# endif +#endif + +/* #define DEBUG */ /* Uncomment to debug sending (in file SENT.log) receiving (in file RECV.log) and messages (in file TEST.log) */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +# ifndef UNDER_CE +# include +# include +# endif +# include +/* # include */ /* Alternative: use winsock2 (not available with eVC) */ +# ifdef WITH_IPV6 +# include +# include +# endif +#else +# ifdef VXWORKS +# include +# include +# include +# endif +# ifndef WITH_NOIO +# ifndef PALM +# include +# include +# include +# include +# endif +# endif +#endif + +/* Portability: define SOAP_SOCKLEN_T */ +#if defined(_AIX) +# define SOAP_SOCKLEN_T socklen_t +#elif defined(SOCKLEN_T) +# define SOAP_SOCKLEN_T SOCKLEN_T +#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) || defined(FREEBSD) || defined(__FreeBSD__) || defined(__QNX__) || defined(QNX) +# define SOAP_SOCKLEN_T socklen_t +#elif defined(IRIX) || defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS) +# define SOAP_SOCKLEN_T int +#else +# define SOAP_SOCKLEN_T size_t +#endif + +#ifndef SOAP_SOCKET +# ifdef WIN32 +# define SOAP_SOCKET SOCKET +# define soap_closesocket(n) closesocket(n) +# else +# define SOAP_SOCKET int +# define soap_closesocket(n) close(n) +# endif +#endif + +#define SOAP_INVALID_SOCKET (-1) +#define soap_valid_socket(n) ((n) != SOAP_INVALID_SOCKET) + +#ifndef FD_SETSIZE +# define FD_SETSIZE (1024) +#endif + +#if defined(SYMBIAN) +# define LONG64 long +# define ULONG64 unsigned LONG64 +#elif !defined(WIN32) || defined(CYGWIN) || defined(__GLIBC__) || defined(__GNU__) +# ifndef LONG64 +# define LONG64 long long +# define ULONG64 unsigned LONG64 +# endif +#elif defined(UNDER_CE) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#elif defined(__BORLANDC__) +# define LONG64 __int64 +# define ULONG64 unsigned LONG64 +#endif + +#if defined(WIN32) && !defined(CYGWIN) +# define soap_int32 __int32 +#elif defined(SYMBIAN) +# define soap_int32 long +#elif defined(PALM) +# define soap_int32 Int32 +#else +# define soap_int32 int32_t +#endif + +#ifdef WIN32 +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR WSAEINTR +# define SOAP_EAGAIN WSAEWOULDBLOCK +# define SOAP_EWOULDBLOCK WSAEWOULDBLOCK +# define SOAP_EINPROGRESS WSAEINPROGRESS +#else +# define SOAP_ERANGE ERANGE +# define SOAP_EINTR EINTR +# define SOAP_EAGAIN EAGAIN +# ifdef SYMBIAN +# define SOAP_EWOULDBLOCK 9898 +# define SOAP_EINPROGRESS 9899 +# else +# define SOAP_EWOULDBLOCK EWOULDBLOCK +# define SOAP_EINPROGRESS EINPROGRESS +# endif +#endif + +#ifdef WIN32 +# ifdef UNDER_CE +# define soap_errno GetLastError() +# define soap_socket_errno(s) GetLastError() +# define soap_reset_errno SetLastError(0) +# else +# define soap_errno GetLastError() +# define soap_socket_errno(s) WSAGetLastError() +# define soap_reset_errno SetLastError(0) +# endif +#else +# ifndef WITH_NOIO +# define soap_errno errno +# define soap_socket_errno(s) errno +# define soap_reset_errno (errno = 0) +# else +# define soap_errno 0 +# define soap_socket_errno(s) 0 +# define soap_reset_errno +# endif +#endif + +#ifndef SOAP_BUFLEN +# ifdef WITH_UDP +# define SOAP_BUFLEN (65536) /* max UDP packet size */ +# else +# ifndef WITH_LEAN +# define SOAP_BUFLEN (65536) /* buffer length for socket packets, also used by gethostbyname_r so don't make this too small */ +# else +# define SOAP_BUFLEN (2048) +# endif +# endif +#endif +#ifndef SOAP_LABLEN +# define SOAP_LABLEN (256) /* initial look-aside buffer length */ +#endif +#ifndef SOAP_PTRBLK +# define SOAP_PTRBLK (32) /* block allocation for pointer hash table chains */ +#endif +#ifndef SOAP_PTRHASH +# ifndef WITH_LEAN +# define SOAP_PTRHASH (1024) /* size of pointer analysis hash table (must be power of 2) */ +# else +# define SOAP_PTRHASH (32) +# endif +#endif +#ifndef SOAP_IDHASH +# ifndef WITH_LEAN +# define SOAP_IDHASH (1999) /* prime size of hash table for parsed id/ref */ +# else +# define SOAP_IDHASH (19) /* 19, 199 */ +# endif +#endif +#ifndef SOAP_BLKLEN +# ifndef WITH_LEAN +# define SOAP_BLKLEN (256) /* size of blocks to collect long strings and XML attributes */ +# else +# define SOAP_BLKLEN (32) +# endif +#endif +#ifndef SOAP_TAGLEN +# ifndef WITH_LEAN +# define SOAP_TAGLEN (1024) /* maximum length of XML element tag/attribute name or host/path name + 1 */ +# else +# define SOAP_TAGLEN (64) +# endif +#endif +#ifndef SOAP_HDRLEN +# ifndef WITH_LEAN +# define SOAP_HDRLEN (8192) /* maximum length of HTTP header line (must be >4096 to read cookies) */ +# else +# define SOAP_HDRLEN (1024) +# endif +#endif +#ifndef SOAP_MAXDIMS +# ifndef WITH_LEAN +# define SOAP_MAXDIMS (16) /* maximum array dimensions (array nestings) must be less than 64 to protect soap->tmpbuf */ +# else +# define SOAP_MAXDIMS (4) +# endif +#endif + +#ifndef SOAP_MAXLOGS +# define SOAP_MAXLOGS (3) /* max number of debug logs per struct soap environment */ +# define SOAP_INDEX_RECV (0) +# define SOAP_INDEX_SENT (1) +# define SOAP_INDEX_TEST (2) +#endif + +#ifndef SOAP_MAXKEEPALIVE +# define SOAP_MAXKEEPALIVE (100) /* max iterations to keep server connection alive */ +#endif + +#ifndef SOAP_MAXARRAYSIZE +# define SOAP_MAXARRAYSIZE (100000) /* "trusted" max size of inbound SOAP array for compound array allocation */ +#endif + +#ifdef VXWORKS +# ifdef __INCmathh +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) isNan(num) +# endif +#endif + +#ifdef WIN32 +# include +# ifndef HAVE_ISNAN +# define HAVE_ISNAN +# endif +# define soap_isnan(num) _isnan(num) +#endif + +#ifdef SUN_OS +# define HAVE_ISNAN +#endif + +#ifdef __APPLE__ +# ifdef __cplusplus +# ifndef isnan +extern "C" int isnan(double); +# endif +# endif +# define HAVE_ISNAN +#endif + +#if !defined(HAVE_ISNAN) && (defined(_MATH_H) || defined(_MATH_INCLUDED)) +# define HAVE_ISNAN +#endif + +extern const struct soap_double_nan { unsigned int n1, n2; } soap_double_nan; + +#ifdef VXWORKS +# ifndef FLT_MAX +# define FLT_MAX _ARCH_FLT_MAX +# endif +# ifndef DBL_MAX +# define DBL_MAX _ARCH_DBL_MAX +# endif +#endif + +#ifndef FLT_NAN +# define FLT_NAN (*(float*)(void*)&soap_double_nan) +#endif + +#ifndef FLT_PINFTY +# if defined(FLT_MAX) +# define FLT_PINFTY FLT_MAX +# elif defined(HUGE_VALF) +# define FLT_PINFTY (float)HUGE_VALF +# elif defined(HUGE_VAL) +# define FLT_PINFTY (float)HUGE_VAL +# elif defined(FLOAT_MAX) +# define FLT_PINFTY FLOAT_MAX +# else +# define FLT_PINFTY (3.40282347e+38F) +# endif +#endif + +#ifndef FLT_NINFTY +# define FLT_NINFTY (-FLT_PINFTY) +#endif + +#ifndef DBL_NAN +# define DBL_NAN (*(double*)(void*)&soap_double_nan) +#endif + +#ifndef DBL_PINFTY +# if defined(DBL_MAX) +# define DBL_PINFTY DBL_MAX +# elif defined(HUGE_VALF) +# define DBL_PINFTY (double)HUGE_VALF +# elif defined(HUGE_VAL) +# define DBL_PINFTY (double)HUGE_VAL +# elif defined(DOUBLE_MAX) +# define DBL_PINFTY DOUBLE_MAX +# else +# define DBL_PINFTY (1.7976931348623157e+308) +# endif +#endif + +#ifndef DBL_NINFTY +# define DBL_NINFTY (-DBL_PINFTY) +#endif + +#ifndef soap_isnan +# ifdef HAVE_ISNAN +# define soap_isnan(n) isnan(n) +# else +# define soap_isnan(n) (0) +# endif +#endif + +#define soap_ispinfd(n) ((n) >= DBL_PINFTY) +#define soap_ispinff(n) ((n) >= FLT_PINFTY) +#define soap_isninfd(n) ((n) <= DBL_NINFTY) +#define soap_isninff(n) ((n) <= FLT_NINFTY) + +/* gSOAP error codes */ + +#define SOAP_EOF EOF +#define SOAP_ERR EOF +#define SOAP_OK 0 +#define SOAP_CLI_FAULT 1 +#define SOAP_SVR_FAULT 2 +#define SOAP_TAG_MISMATCH 3 +#define SOAP_TYPE 4 +#define SOAP_SYNTAX_ERROR 5 +#define SOAP_NO_TAG 6 +#define SOAP_IOB 7 +#define SOAP_MUSTUNDERSTAND 8 +#define SOAP_NAMESPACE 9 +#define SOAP_USER_ERROR 10 +#define SOAP_FATAL_ERROR 11 +#define SOAP_FAULT 12 +#define SOAP_NO_METHOD 13 +#define SOAP_NO_DATA 14 +#define SOAP_GET_METHOD 15 +#define SOAP_EOM 16 +#define SOAP_MOE 17 +#define SOAP_NULL 18 +#define SOAP_DUPLICATE_ID 19 +#define SOAP_MISSING_ID 20 +#define SOAP_HREF 21 +#define SOAP_UDP_ERROR 22 +#define SOAP_TCP_ERROR 23 +#define SOAP_HTTP_ERROR 24 +#define SOAP_SSL_ERROR 25 +#define SOAP_ZLIB_ERROR 26 +#define SOAP_DIME_ERROR 27 +#define SOAP_DIME_HREF 28 +#define SOAP_DIME_MISMATCH 29 +#define SOAP_DIME_END 30 +#define SOAP_MIME_ERROR 31 +#define SOAP_MIME_HREF 32 +#define SOAP_MIME_END 33 +#define SOAP_VERSIONMISMATCH 34 +#define SOAP_PLUGIN_ERROR 35 +#define SOAP_DATAENCODINGUNKNOWN 36 +#define SOAP_REQUIRED 37 +#define SOAP_PROHIBITED 38 +#define SOAP_OCCURS 39 +#define SOAP_LENGTH 40 +#define SOAP_FD_EXCEEDED 41 + +#define soap_xml_error_check(e) ((e) == SOAP_TAG_MISMATCH || (e) == SOAP_TAG_END || (e) == SOAP_SYNTAX_ERROR || (e) == SOAP_NAMESPACE || (e) == SOAP_DUPLICATE_ID || (e) == SOAP_MISSING_ID || (e) == SOAP_REQUIRED || (e) == SOAP_PROHIBITED || (e) == SOAP_OCCURS || (e) == SOAP_LENGTH || (e) == SOAP_NULL || (e) == SOAP_HREF) +#define soap_soap_error_check(e) ((e) == SOAP_CLI_FAULT || (e) == SOAP_SVR_FAULT || (e) == SOAP_VERSIONMISMATCH || (e) == SOAP_MUSTUNDERSTAND || (e) == SOAP_FAULT || (e) == SOAP_NO_METHOD) +#define soap_tcp_error_check(e) ((e) == SOAP_EOF || (e) == SOAP_TCP_ERROR) +#define soap_ssl_error_check(e) ((e) == SOAP_SSL_ERROR) +#define soap_zlib_error_check(e) ((e) == SOAP_ZLIB_ERROR) +#define soap_http_error_check(e) ((e) == SOAP_HTTP_ERROR || (e) == SOAP_GET_METHOD || (e) == SOAP_NO_DATA || ((e) >= 100 && (e) < 600)) + +/* gSOAP HTTP response status codes 100 to 599 are reserved */ + +/* Codes 600 to 999 are user definable */ + +/* Exceptional gSOAP HTTP response status codes >= 1000 */ + +#define SOAP_STOP 1000 /* No HTTP response */ +#define SOAP_FORM 1001 /* Form request/response */ +#define SOAP_HTML 1002 /* Custom HTML response */ +#define SOAP_FILE 1003 /* Custom file-based response */ + +/* gSOAP HTTP method codes */ + +#define SOAP_POST 2000 +#define SOAP_GET 2001 + +/* gSOAP DIME */ + +#define SOAP_DIME_CF 0x01 +#define SOAP_DIME_ME 0x02 +#define SOAP_DIME_MB 0x04 +#define SOAP_DIME_VERSION 0x08 /* DIME version 1 */ +#define SOAP_DIME_MEDIA 0x10 +#define SOAP_DIME_ABSURI 0x20 + +/* gSOAP ZLIB */ + +#define SOAP_ZLIB_NONE 0x00 +#define SOAP_ZLIB_DEFLATE 0x01 +#define SOAP_ZLIB_INFLATE 0x02 +#define SOAP_ZLIB_GZIP 0x02 + +/* gSOAP transport, connection, and content encoding modes */ + +typedef soap_int32 soap_mode; + +#define SOAP_IO 0x00000003 /* IO mask */ +#define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */ +#define SOAP_IO_BUFFER 0x00000001 /* buffer output in packets of size SOAP_BUFLEN */ +#define SOAP_IO_STORE 0x00000002 /* store entire output to determine length for transport */ +#define SOAP_IO_CHUNK 0x00000003 /* use HTTP chunked transfer AND buffer packets */ + +#define SOAP_IO_UDP 0x00000004 /* TCP or UDP */ + +#define SOAP_IO_LENGTH 0x00000008 /* calc message length (internal) */ +#define SOAP_IO_KEEPALIVE 0x00000010 /* keep connection alive */ + +#define SOAP_ENC_LATIN 0x00000020 /* accept iso-8859-1 encoding */ +#define SOAP_ENC_XML 0x00000040 /* plain XML encoding, no HTTP header */ +#define SOAP_ENC_DIME 0x00000080 +#define SOAP_ENC_MIME 0x00000100 +#define SOAP_ENC_MTOM 0x00000200 +#define SOAP_ENC_ZLIB 0x00000400 +#define SOAP_ENC_SSL 0x00000800 + +#define SOAP_ENC 0x00000FFF /* IO and ENC mask */ + +#define SOAP_XML_STRICT 0x00001000 /* apply strict validation */ +#define SOAP_XML_INDENT 0x00002000 /* emit indented XML */ +#define SOAP_XML_CANONICAL 0x00004000 /* EXC C14N canonical XML */ +#define SOAP_XML_TREE 0x00008000 /* emit XML tree (no id/ref) */ +#define SOAP_XML_GRAPH 0x00010000 +#define SOAP_XML_NIL 0x00020000 +#define SOAP_XML_DOM 0x00040000 +#define SOAP_XML_SEC 0x00080000 /* reserved for WS security */ + +#define SOAP_C_NOIOB 0x00100000 /* don't fault on array index out of bounds (just ignore) */ +#define SOAP_C_UTFSTRING 0x00200000 /* (de)serialize strings with UTF8 content */ +#define SOAP_C_MBSTRING 0x00400000 /* (de)serialize strings with multi-byte content */ +#define SOAP_C_NILSTRING 0x00800000 /* serialize empty strings as nil (omitted) */ + +#define SOAP_DOM_TREE 0x01000000 +#define SOAP_DOM_NODE 0x02000000 +#define SOAP_DOM_ASIS 0x04000000 + +#define SOAP_MIME_POSTCHECK 0x10000000 /* MIME flag (internal) */ + +#define SOAP_IO_DEFAULT SOAP_IO_FLUSH + +/* SSL client/server authentication settings */ + +#define SOAP_SSL_NO_AUTHENTICATION 0x00 /* for testing purposes */ +#define SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION 0x01 /* client requires server to authenticate */ +#define SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION 0x02 /* server requires client to authenticate */ +#define SOAP_SSL_SKIP_HOST_CHECK 0x04 /* client does not check the common name of the host in certificate */ +#define SOAP_SSL_RSA 0x06 /* use RSA */ +#define SOAP_SSLv3_TLSv1 0x00 /* SSL v3 and TLS v1 support by default */ +#define SOAP_SSLv3 0x10 /* SSL v3 only */ +#define SOAP_TLSv1 0x20 /* TLS v1 only */ + +#define SOAP_SSL_DEFAULT (SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION | SOAP_SSLv3_TLSv1) + +/* state */ + +#define SOAP_INIT 1 +#define SOAP_COPY 2 + +#define soap_check_state(soap) (!(soap) || ((soap)->state != SOAP_INIT && (soap)->state != SOAP_COPY)) + +/* part */ + +#define SOAP_BEGIN 0 +#define SOAP_IN_ENVELOPE 2 +#define SOAP_IN_HEADER 3 +#define SOAP_END_HEADER 4 +#define SOAP_NO_BODY 5 +#define SOAP_IN_BODY 6 +#define SOAP_END_BODY 7 +#define SOAP_END_ENVELOPE 8 +#define SOAP_END 9 +#define SOAP_BEGIN_SECURITY 10 +#define SOAP_IN_SECURITY 11 +#define SOAP_END_SECURITY 12 + +/* DEBUG macros */ + +#ifndef WITH_LEAN +# ifdef DEBUG +# ifndef SOAP_DEBUG +# define SOAP_DEBUG +# endif +# ifndef SOAP_MEM_DEBUG +# define SOAP_MEM_DEBUG +# endif +# endif +#endif + +#ifdef SOAP_MEM_DEBUG +# ifndef SOAP_MALLOC +# define SOAP_MALLOC(soap, size) soap_track_malloc(soap, __FILE__, __LINE__, size) +# endif +# ifndef SOAP_FREE +# define SOAP_FREE(soap, ptr) soap_track_free(soap, __FILE__, __LINE__, ptr) +# endif +#endif + +#ifndef SOAP_MALLOC /* use libc malloc */ +# define SOAP_MALLOC(soap, size) malloc(size) +#endif + +#ifndef SOAP_FREE /* use libc free */ +# define SOAP_FREE(soap, ptr) free(ptr) +#endif + +#ifdef SOAP_DEBUG +# ifndef SOAP_MESSAGE +# define SOAP_MESSAGE fprintf +# endif +# ifndef DBGLOG +# define DBGLOG(DBGFILE, CMD) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile((struct soap*)soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { FILE *fdebug = soap->fdebug[SOAP_INDEX_##DBGFILE];\ + CMD;\ + fflush(fdebug);\ + }\ + }\ +} +# endif +# ifndef DBGMSG +# define DBGMSG(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile((struct soap*)soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { fwrite((MSG), 1, (LEN), soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +# ifndef DGBFUN +# define DBGFUN(FNAME) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s()\n", __FILE__, __LINE__, FNAME)) +# define DBGFUN1(FNAME, FMT, ARG) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT")\n", __FILE__, __LINE__, FNAME, (ARG))) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2))) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): %s("FMT1", "FMT2", "FMT3")\n", __FILE__, __LINE__, FNAME, (ARG1), (ARG2), (ARG3))) +# endif +# ifndef DBGHEX +# define DBGHEX(DBGFILE, MSG, LEN) \ +{ if (soap)\ + { if (!soap->fdebug[SOAP_INDEX_##DBGFILE])\ + soap_open_logfile(soap, SOAP_INDEX_##DBGFILE);\ + if (soap->fdebug[SOAP_INDEX_##DBGFILE])\ + { int i; char *s;\ + for (s = (char*)(MSG), i = (LEN); i; i--)\ + fprintf(soap->fdebug[SOAP_INDEX_##DBGFILE], "%2.2X ", (int)*s++&0xFF);\ + fflush(soap->fdebug[SOAP_INDEX_##DBGFILE]);\ + }\ + }\ +} +# endif +#else +# define DBGLOG(DBGFILE, CMD) +# define DBGMSG(DBGFILE, MSG, LEN) +# define DBGFUN(FNAME) +# define DBGFUN1(FNAME, FMT, ARG) +# define DBGFUN2(FNAME, FMT1, ARG1, FMT2, ARG2) +# define DBGFUN3(FNAME, FMT1, ARG1, FMT2, ARG2, FMT3, ARG3) +# define DBGHEX(DBGFILE, MSG, LEN) +#endif + +/* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to distinguish XML entities) */ +typedef soap_int32 soap_wchar; + +/* namespace table row */ +struct Namespace +{ const char *id; + const char *ns; + const char *in; + char *out; +}; + +/* namespace stack */ +struct soap_nlist +{ struct soap_nlist *next; + unsigned int level; /* nesting depth level */ + short index; /* corresponding entry in ns mapping table */ + char *ns; /* only set when parsed ns URI is not in the ns mapping table */ + char id[1]; /* the actual string value flows into the allocated region below this struct */ +}; + +/* block stack for nested block allocations */ +struct soap_blist +{ struct soap_blist *next; + char *ptr; + size_t size; +}; + +/* array layout */ +struct soap_array +{ void *__ptr; + int __size; +}; + +/* pointer serialization management */ +struct soap_plist +{ struct soap_plist *next; + const void *ptr; + const struct soap_array *array; + int type; + int id; + char mark1; + char mark2; +}; + +/* block allocation for pointer serialization management */ +struct soap_pblk +{ struct soap_pblk *next; + struct soap_plist plist[SOAP_PTRBLK]; +}; + +#ifdef SOAP_MEM_DEBUG +/* malloc/free tracking for debugging */ +struct soap_mlist +{ struct soap_mlist *next; + const void *ptr; + const char *file; + int line; + short live; +}; +#endif + +/* class allocation list */ +struct soap_clist +{ struct soap_clist *next; + void *ptr; + int type; + int size; + void (*fdelete)(struct soap_clist*); +}; + +/* attributes */ +struct soap_attribute +{ struct soap_attribute *next; + char *value; + size_t size; + char *ns; + short visible; + char name[1]; /* the actual name string flows into the allocated region below this struct */ +}; + +#ifndef WITH_LEAN +struct soap_cookie +{ struct soap_cookie *next; + char *name; + char *value; + char *domain; + char *path; + time_t expire; /* client-side: local time to expire */ + long maxage; /* server-side: seconds to expire */ + unsigned int version; + short secure; + short session; /* server-side */ + short env; /* server-side: got cookie from client and should not be (re)send */ + short modified; /* server-side: client cookie was modified and should be send */ +}; +#endif + +#ifdef __cplusplus +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); + +class soap_multipart_iterator +{ public: + struct soap_multipart *content; + bool operator==(const soap_multipart_iterator& iter) const + { return content == iter.content; } + bool operator!=(const soap_multipart_iterator& iter) const + { return content != iter.content; } + struct soap_multipart &operator*() const + { return *content; } + soap_multipart_iterator &operator++() + { content = soap_next_multipart(content); return *this; } + soap_multipart_iterator() : content(NULL) + { } + soap_multipart_iterator(struct soap_multipart *p) : content(p) + { } +}; +#endif + +#ifndef WITH_LEANER +struct soap_dime +{ size_t count; + size_t size; + size_t chunksize; + size_t buflen; + char flags; + char *ptr; + const char *id; + const char *type; + const char *options; + struct soap_multipart *list; /* list of DIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +struct soap_mime +{ char *boundary; /* MIME boundary */ + const char *start; /* MIME start ID */ + struct soap_multipart *list; /* list of MIME attachments received */ + struct soap_multipart *first, *last; /* temporary in/out queue */ +#ifdef __cplusplus + soap_multipart_iterator begin() + { soap_multipart_iterator iter(list); return iter; }; + soap_multipart_iterator end() + { soap_multipart_iterator iter(NULL); return iter; }; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* RFC2045 MIME content transfer encodings */ +enum soap_mime_encoding +{ SOAP_MIME_NONE, + SOAP_MIME_7BIT, + SOAP_MIME_8BIT, + SOAP_MIME_BINARY, + SOAP_MIME_QUOTED_PRINTABLE, + SOAP_MIME_BASE64, + SOAP_MIME_IETF_TOKEN, + SOAP_MIME_X_TOKEN +}; +#endif + +#ifndef WITH_LEANER +/* DIME/MIME multipart list */ +struct soap_multipart +{ struct soap_multipart *next; + char *ptr; /* points to raw data content */ + size_t size; /* size of data content */ + const char *id; /* DIME/MIME content ID or form data name */ + const char *type; /* DIME/MIME type (MIME type format) */ + const char *options; /* DIME options */ + enum soap_mime_encoding encoding; /* MIME Content-Transfer-Encoding */ + const char *location; /* MIME Content-Location (optional) */ + const char *description; /* MIME Content-Description (optional) */ +#ifdef __cplusplus + typedef soap_multipart_iterator iterator; +#endif +}; +#endif + +#ifndef WITH_LEANER +/* attachment DIME and MTOM XOP forwarding */ +struct soap_xlist +{ struct soap_xlist *next; + unsigned char **ptr; + int *size; + char *id; + char **type; + char **options; +}; +#endif + +/******************************************************************************/ + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_attribute_iterator +{ public: + struct soap_dom_attribute *att; + const char *nstr; + const char *name; + bool operator==(const soap_dom_attribute_iterator&) const; + bool operator!=(const soap_dom_attribute_iterator&) const; + struct soap_dom_attribute &operator*() const; + soap_dom_attribute_iterator &operator++(); + soap_dom_attribute_iterator(); + soap_dom_attribute_iterator(struct soap_dom_attribute*); + ~soap_dom_attribute_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_attribute +{ struct soap_dom_attribute *next; + const char *nstr; + char *name; + char *data; + wchar_t *wide; + struct soap *soap; +#ifdef __cplusplus + typedef soap_dom_attribute_iterator iterator; + struct soap_dom_attribute &set(const char *nstr, const char *name); /* set namespace and name */ + struct soap_dom_attribute &set(const char *data); /* set data */ + soap_dom_attribute_iterator begin(); + soap_dom_attribute_iterator end(); + soap_dom_attribute_iterator find(const char *nstr, const char *name); + void unlink(); + soap_dom_attribute(); + soap_dom_attribute(struct soap *soap); + soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data); + ~soap_dom_attribute(); +#endif +}; +#endif + +#ifndef WITH_LEANER +#ifdef __cplusplus +class soap_dom_element_iterator +{ public: + struct soap_dom_element *elt; + const char *nstr; + const char *name; + int type; + bool operator==(const soap_dom_element_iterator&) const; + bool operator!=(const soap_dom_element_iterator&) const; + struct soap_dom_element &operator*() const; + soap_dom_element_iterator &operator++(); + soap_dom_element_iterator(); + soap_dom_element_iterator(struct soap_dom_element*); + ~soap_dom_element_iterator(); +}; +#endif +#endif + +#ifndef WITH_LEANER +struct soap_dom_element +{ struct soap_dom_element *next; /* next sibling */ + struct soap_dom_element *prnt; /* parent */ + struct soap_dom_element *elts; /* list of child elements */ + struct soap_dom_attribute *atts; /* list of attributes */ + const char *nstr; /* namespace string */ + char *name; /* element tag name */ + char *data; /* element content data (with SOAP_C_UTFSTRING flag set) */ + wchar_t *wide; /* element content data */ + int type; /* optional: serialized C/C++ data type */ + void *node; /* optional: pointer to serialized C/C++ data */ + char *head; /* leading whitespace to start tag */ + char *tail; /* leading whitespace to end tag */ + struct soap *soap; /* soap context that manages this node */ +#ifdef __cplusplus + typedef soap_dom_element_iterator iterator; + struct soap_dom_element &set(const char *nstr, const char *name); + struct soap_dom_element &set(const char *data); + struct soap_dom_element &set(void *node, int type); + struct soap_dom_element &add(struct soap_dom_element*); + struct soap_dom_element &add(struct soap_dom_element&); + struct soap_dom_element &add(struct soap_dom_attribute*); + struct soap_dom_element &add(struct soap_dom_attribute&); + soap_dom_element_iterator begin(); + soap_dom_element_iterator end(); + soap_dom_element_iterator find(const char *nstr, const char *name); + soap_dom_element_iterator find(int type); + void unlink(); + soap_dom_element(); + soap_dom_element(struct soap *soap); + soap_dom_element(struct soap *soap, const char *nstr, const char *name); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data); + soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type); + ~soap_dom_element(); +#endif +}; +SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_dom_next_element(struct soap_dom_element *elt); +SOAP_FMAC1 struct soap_dom_attribute * SOAP_FMAC2 soap_dom_next_attribute(struct soap_dom_attribute *att); +#endif + +#if defined(__cplusplus) && !defined(WITH_LEAN) +} +extern std::ostream &operator<<(std::ostream&, const struct soap_dom_element&); +extern std::istream &operator>>(std::istream&, struct soap_dom_element&); +extern "C" { +#endif + +/******************************************************************************/ + +#ifdef WIN32 +# ifdef SOAP_STD_EXPORTS +# define SOAP_STD_API __declspec(dllexport) +# else +# define SOAP_STD_API +# endif +#else +# define SOAP_STD_API +#endif + +struct SOAP_STD_API soap +{ short state; /* 0 = uninitialized, 1 = initialized, 2 = copy of another soap struct */ + short version; /* 1 = SOAP1.1 and 2 = SOAP1.2 (set automatically from namespace URI in nsmap table) */ + soap_mode mode; + soap_mode imode; + soap_mode omode; + const char *float_format; /* user-definable format string for floats (<1024 chars) */ + const char *double_format; /* user-definable format string for doubles (<1024 chars) */ + const char *dime_id_format; /* user-definable format string for integer DIME id ( 0, gives socket recv timeout in seconds, < 0 in usec */ + int send_timeout; /* when > 0, gives socket send timeout in seconds, < 0 in usec */ + int connect_timeout; /* when > 0, gives socket connect() timeout in seconds, < 0 in usec */ + int accept_timeout; /* when > 0, gives socket accept() timeout in seconds, < 0 in usec */ + int socket_flags; /* socket recv() and send() flags, e.g. set to MSG_NOSIGNAL to disable sigpipe */ + int connect_flags; /* connect() SOL_SOCKET sockopt flags, e.g. set to SO_DEBUG to debug socket */ + int bind_flags; /* bind() SOL_SOCKET sockopt flags, e.g. set to SO_REUSEADDR to enable reuse */ + int accept_flags; /* accept() SOL_SOCKET sockopt flags */ + const struct Namespace *namespaces; /* Pointer to global namespace mapping table */ + struct Namespace *local_namespaces; /* Local namespace mapping table */ + struct soap_nlist *nlist; /* namespace stack */ + struct soap_blist *blist; /* block allocation stack */ + struct soap_clist *clist; /* class instance allocation list */ + void *alist; /* memory allocation (malloc) list */ + struct soap_ilist *iht[SOAP_IDHASH]; + struct soap_plist *pht[SOAP_PTRHASH]; + struct soap_pblk *pblk; /* plist block allocation */ + short pidx; /* plist block allocation */ + struct SOAP_ENV__Header *header; + struct SOAP_ENV__Fault *fault; + int idnum; + void *user; /* to pass user-defined data */ + struct soap_plugin *plugins; /* linked list of plug-in data */ + char *userid; /* HTTP Basic authorization userid */ + char *passwd; /* HTTP Basic authorization passwd */ + int (*fpost)(struct soap*, const char*, const char*, int, const char*, const char*, size_t); + int (*fget)(struct soap*); + int (*fform)(struct soap*); + int (*fposthdr)(struct soap*, const char*, const char*); + int (*fresponse)(struct soap*, int, size_t); + int (*fparse)(struct soap*); + int (*fparsehdr)(struct soap*, const char*, const char*); + int (*fheader)(struct soap*); + int (*fresolve)(struct soap*, const char*, struct in_addr* inaddr); + int (*fconnect)(struct soap*, const char*, const char*, int); + int (*fdisconnect)(struct soap*); + int (*fclosesocket)(struct soap*, SOAP_SOCKET); + int (*fshutdownsocket)(struct soap*, SOAP_SOCKET, int); + int (*fopen)(struct soap*, const char*, const char*, int); + int (*faccept)(struct soap*, int, struct sockaddr*, int *n); + int (*fclose)(struct soap*); + int (*fsend)(struct soap*, const char*, size_t); + size_t (*frecv)(struct soap*, char*, size_t); + int (*fpoll)(struct soap*); + void (*fseterror)(struct soap*, const char **c, const char **s); + int (*fignore)(struct soap*, const char*); + int (*fserveloop)(struct soap*); + void *(*fplugin)(struct soap*, const char*); + void *(*fmalloc)(struct soap*, size_t); +#ifndef WITH_LEANER + int (*fprepareinit)(struct soap*); + int (*fpreparesend)(struct soap*, const char*, size_t); + int (*fpreparerecv)(struct soap*, const char*, size_t); + int (*fpreparefinal)(struct soap*); + void *(*fdimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fdimewriteopen)(struct soap*, const char*, const char*, const char*); + void (*fdimereadclose)(struct soap*, void*); + void (*fdimewriteclose)(struct soap*, void*); + size_t (*fdimeread)(struct soap*, void*, char*, size_t); + int (*fdimewrite)(struct soap*, void*, const char*, size_t); + void *(*fmimereadopen)(struct soap*, void*, const char*, const char*, const char*); + void *(*fmimewriteopen)(struct soap*, void*, const char*, const char*, const char*, enum soap_mime_encoding); + void (*fmimereadclose)(struct soap*, void*); + void (*fmimewriteclose)(struct soap*, void*); + size_t (*fmimeread)(struct soap*, void*, char*, size_t); + int (*fmimewrite)(struct soap*, void*, const char*, size_t); +#endif + int master; + int socket; +#if defined(__cplusplus) && !defined(WITH_LEAN) + std::ostream *os; + std::istream *is; +#else + void *os; /* preserve alignment */ + void *is; /* preserve alignment */ +#endif +#ifndef UNDER_CE + int sendfd; + int recvfd; +#else + FILE *sendfd; + FILE *recvfd; +#endif + size_t bufidx; /* index in soap.buf[] */ + size_t buflen; /* length of soap.buf[] content */ + soap_wchar ahead; /* parser lookahead */ + short cdata; /* CDATA parser state */ + short body; /* parsed XML element has a body or not */ + unsigned int level; /* XML nesting level */ + size_t count; /* message length counter */ + size_t length; /* message length as set by HTTP header */ + char *labbuf; /* look-aside buffer */ + size_t lablen; /* look-aside buffer allocated length */ + size_t labidx; /* look-aside buffer index to available part */ + char buf[SOAP_BUFLEN];/* send and receive buffer */ + char tmpbuf[1024]; /* in/output buffer for HTTP/MIME headers, simpleType values, attribute names, and DIME must be >=1024 bytes */ + char msgbuf[1024]; /* in/output buffer for messages >=1024 bytes */ + char tag[SOAP_TAGLEN]; + char id[SOAP_TAGLEN]; + char href[SOAP_TAGLEN]; + char type[SOAP_TAGLEN]; + char arrayType[SOAP_TAGLEN]; + char arraySize[SOAP_TAGLEN]; + char arrayOffset[SOAP_TAGLEN]; + short other; + short position; + int positions[SOAP_MAXDIMS]; + short root; + struct soap_attribute *attributes; /* attribute list */ + short encoding; /* when set, output encodingStyle */ + short mustUnderstand; /* a mustUnderstand element was parsed or is output */ + short keep_alive; /* connection should be kept open */ + short null; /* parsed XML is xsi:nil */ + short ns; /* when not set, output full xmlns bindings */ + short part; /* parsing state */ + short alloced; + short peeked; + size_t chunksize; + size_t chunkbuflen; + char endpoint[SOAP_TAGLEN]; + char path[SOAP_TAGLEN]; + char host[SOAP_TAGLEN]; + char *action; + char *authrealm; /* HTTP authentication realm */ + char *prolog; /* XML declaration prolog */ + unsigned long ip; /* IP number */ + int port; /* port number */ + unsigned int max_keep_alive; + const char *proxy_http_version;/* HTTP version of proxy "1.0" or "1.1" */ + const char *proxy_host; /* Proxy Server host name */ + int proxy_port; /* Proxy Server port (default = 8080) */ + const char *proxy_userid; /* Proxy Authorization user name */ + const char *proxy_passwd; /* Proxy Authorization password */ + int status; /* -1 when request, else error code to be returned by server */ + int error; + int errmode; + int errnum; +#ifndef WITH_LEANER + struct soap_dom_element *dom; + struct soap_dime dime; + struct soap_mime mime; + struct soap_xlist *xlist; +#endif +#if !defined(WITH_LEAN) || defined(SOAP_DEBUG) + const char *logfile[SOAP_MAXLOGS]; + FILE *fdebug[SOAP_MAXLOGS]; + struct soap_mlist *mht[SOAP_PTRHASH]; +#endif +#ifndef WITH_LEAN + const char *c14ninclude; + const char *c14nexclude; + struct soap_cookie *cookies; + const char *cookie_domain; + const char *cookie_path; + int cookie_max; +#endif +#ifndef WITH_NOIO +#ifdef WITH_IPV6 + struct sockaddr_storage peer; /* IPv6: set by soap_accept and by UDP recv */ +#else + struct sockaddr_in peer; /* IPv4: set by soap_connect/soap_accept and by UDP recv */ +#endif +#endif + size_t peerlen; +#ifdef WITH_OPENSSL + int (*fsslauth)(struct soap*); + int (*fsslverify)(int, X509_STORE_CTX*); + BIO *bio; + SSL *ssl; + SSL_CTX *ctx; + unsigned short ssl_flags; + const char *keyfile; + const char *password; + const char *dhfile; + const char *cafile; + const char *capath; + const char *crlfile; + const char *randfile; + SSL_SESSION *session; + char session_host[SOAP_TAGLEN]; + int session_port; +#endif +#ifdef WITH_ZLIB + short zlib_state; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_INFLATE */ + short zlib_in; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + short zlib_out; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */ + z_stream d_stream; /* decompression stream */ + char z_buf[SOAP_BUFLEN]; /* buffer */ + size_t z_buflen; + unsigned short z_level; /* compression level to be used (0=none, 1=fast to 9=best) */ + uLong z_crc; /* internal gzip crc */ + float z_ratio_in; /* detected compression ratio compressed_length/length of inbound message */ + float z_ratio_out; /* detected compression ratio compressed_length/length of outbound message */ +#endif +#ifdef WMW_RPM_IO + void *rpmreqid; +#endif +#ifndef WITH_LEAN +#ifdef __cplusplus + soap(); + soap(soap_mode); + soap(soap_mode, soap_mode); + soap(struct soap&); + ~soap(); +#endif +#endif +}; + +struct soap_code_map +{ long code; + const char *string; +}; + +/* forwarding list */ +struct soap_flist +{ struct soap_flist *next; + int type; + void *ptr; + unsigned int level; + size_t len; + void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t); +}; + +/* id-ref forwarding list */ +struct soap_ilist +{ struct soap_ilist *next; + int type; + size_t size; + void *link; + void *copy; + struct soap_flist *flist; + void *ptr; + unsigned int level; + char id[1]; /* the actual id string value flows into the allocated region below this struct */ +}; + +struct soap_plugin +{ struct soap_plugin *next; + const char *id; + void *data; + int (*fcopy)(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src); + void (*fdelete)(struct soap *soap, struct soap_plugin *p); /* should delete fields of plugin only and not free(p) */ +}; + +#ifndef WITH_NONAMESPACES +extern SOAP_NMAC struct Namespace namespaces[]; +#endif + +#ifndef WITH_LEAN +# define soap_get0(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx]) +# define soap_get1(soap) (((soap)->bufidx>=(soap)->buflen && soap_recv(soap)) ? EOF : (unsigned char)(soap)->buf[(soap)->bufidx++]) +#else +soap_wchar soap_get0(struct soap*); +soap_wchar soap_get1(struct soap*); +#endif + +#define soap_revget1(soap) ((soap)->bufidx--) +#define soap_unget(soap, c) ((soap)->ahead = c) +#define soap_register_plugin(soap, plugin) soap_register_plugin_arg(soap, plugin, NULL) +#define soap_imode(soap, n) ((soap)->mode = (soap)->imode = (n)) +#define soap_set_imode(soap, n) ((soap)->imode |= (n)) +#define soap_clr_imode(soap, n) ((soap)->imode &= ~(n)) +#define soap_omode(soap, n) ((soap)->mode = (soap)->omode = (n)) +#define soap_set_omode(soap, n) ((soap)->omode |= (n)) +#define soap_clr_omode(soap, n) ((soap)->omode &= ~(n)) +#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n)) +#define soap_clr_mode(soap, n) ((soap)->imode &= ~(n), (soap)->omode &= ~(n)) +#define soap_destroy(soap) soap_delete((soap), NULL) + +#ifdef HAVE_STRRCHR +# define soap_strrchr(s, t) strrchr(s, t) +#else + SOAP_FMAC1 char* SOAP_FMAC2 soap_strrchr(const char *s, int t); +#endif + +#ifdef HAVE_STRTOL +# define soap_strtol(s, t, b) strtol(s, t, b) +#else + SOAP_FMAC1 long SOAP_FMAC2 soap_strtol(const char *s, char **t, int b); +#endif + +#ifdef HAVE_STRTOUL +# define soap_strtoul(s, t, b) strtoul(s, t, b) +#else + SOAP_FMAC1 unsigned long SOAP_FMAC2 soap_strtoul(const char *s, char **t, int b); +#endif + +#if defined(WITH_OPENSSL) +# define soap_random soap_rand() +SOAP_FMAC1 int SOAP_FMAC2 soap_rand(void); +#elif defined(HAVE_RANDOM) +# define soap_random (int)random() +#else +# define soap_random rand() +#endif + +#ifdef WITH_NOIDREF +# define soap_embedded(s, p, t) (0) +# define soap_id_lookup(s, i, p, t, n, k) (p) +# define soap_id_forward(s, h, p, len, st, tt, n, k, fc) (p) +# define soap_reference(s, a, t) (1) +# define soap_array_reference(s, p, a, n, t) (1) +# define soap_embed(s, p, a, n, t, pp) (0) +# define soap_embedded_id(s, i, p, t) (i) +# define soap_is_embedded(s, p) (0) +# define soap_is_single(s, p) (1) +# define soap_lookup_type(s, i) (0) +# define soap_getindependent(s) (0) +# define soap_putindependent(s) (0) +# define soap_getelement(s, n) (n) +# define soap_putelement(s, p, t, i, n) (0) +# define soap_markelement(s, p, n) (0) +#endif + +SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultsubcode(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultstring(struct soap*); +SOAP_FMAC1 const char** SOAP_FMAC2 soap_faultdetail(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializeheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putheader(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getheader(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_serializefault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putfault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getfault(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_ssl_init(void); +SOAP_FMAC1 int SOAP_FMAC2 soap_poll(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect_command(struct soap*, int, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_connect(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_bind(struct soap*, const char*, int, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_accept(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_accept(struct soap*); +SOAP_FMAC1 const char * SOAP_FMAC2 soap_ssl_error(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_server_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_ssl_client_context(struct soap*, unsigned short, const char*, const char*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_puthttphdr(struct soap*, int status, size_t count); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_get_header_attribute(struct soap*, const char*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_key(char*, size_t, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_decode_val(char*, size_t, const char*); + +SOAP_FMAC1 size_t SOAP_FMAC2 soap_hash(const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_endpoint(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_flush(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_get(struct soap*); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getchar(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_tag_cmp(const char*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_sender_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_receiver_fault_subcode(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_sender_error(struct soap*, const char*, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_receiver_error(struct soap*, const char*, const char*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_raw(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_raw(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send2(struct soap*, const char*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_send3(struct soap*, const char*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_pututf8(struct soap*, unsigned long); +SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getutf8(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_putbase64(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_getbase64(struct soap*, int*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_puthex(struct soap*, const unsigned char*, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_gethex(struct soap*, int*); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_xop_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_dime_forward(struct soap*, unsigned char**, int*, char**, char**, char**); +#endif + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup_id(struct soap*, void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup(struct soap*, const void *p, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_enter(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_pointer_lookup(struct soap*, const void *p, const struct soap_array *a, int n, int t, struct soap_plist**); +SOAP_FMAC1 int SOAP_FMAC2 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_lookup(struct soap*, const char*); +SOAP_FMAC1 struct soap_ilist* SOAP_FMAC2 soap_enter(struct soap*, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_resolve(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_embedded(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_reference(struct soap*, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_reference(struct soap*, const void *p, const struct soap_array *a, int n, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_embedded_id(struct soap*, int id, const void *p, int t); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_embedded(struct soap*, struct soap_plist*); +SOAP_FMAC1 int SOAP_FMAC2 soap_is_single(struct soap*, struct soap_plist*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_embedded(struct soap*, struct soap_plist*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_count(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_send(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_send(struct soap*); + +SOAP_FMAC1 const struct soap_code_map* SOAP_FMAC2 soap_code(const struct soap_code_map*, const char*); +SOAP_FMAC1 long SOAP_FMAC2 soap_code_int(const struct soap_code_map*, const char*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_code_str(const struct soap_code_map*, long); +SOAP_FMAC1 long SOAP_FMAC2 soap_code_bits(const struct soap_code_map*, const char*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_code_list(struct soap*, const struct soap_code_map*, long); + +SOAP_FMAC1 int SOAP_FMAC2 soap_getline(struct soap*, char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_begin_recv(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_end_recv(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_malloc(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_dealloc(struct soap*, void*); +SOAP_FMAC1 struct soap_clist * SOAP_FMAC2 soap_link(struct soap*, void*, int, int, void (*fdelete)(struct soap_clist*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_unlink(struct soap*, const void*); +SOAP_FMAC1 void SOAP_FMAC2 soap_free_temp(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_del(struct soap*); + +SOAP_FMAC1 void* SOAP_FMAC2 soap_track_malloc(struct soap*, const char*, int, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_track_free(struct soap*, const char*, int, void*); + +#ifndef WITH_NOIDREF +SOAP_FMAC1 int SOAP_FMAC2 soap_lookup_type(struct soap*, const char *id); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_lookup(struct soap*, const char *id, void **p, int t, size_t n, unsigned int k); +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_forward(struct soap*, const char *id, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void(*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t)); +#endif +SOAP_FMAC1 void* SOAP_FMAC2 soap_id_enter(struct soap*, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*)); +SOAP_FMAC1 void SOAP_FMAC2 soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t, const void *q, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_size(const int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getoffsets(const char *, const int *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsize(const char *, const char *, int *); +SOAP_FMAC1 int SOAP_FMAC2 soap_getsizes(const char *, int *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_getposition(const char *, int *); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsize(struct soap*, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizesoffsets(struct soap*, const char *, const int *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putsizes(struct soap*, const char *, const int *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffset(struct soap*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_putoffsets(struct soap*, const int *, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_closesock(struct soap*); + +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new(void); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new1(soap_mode); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_new2(soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_free(struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy(struct soap*); +SOAP_FMAC1 struct soap *SOAP_FMAC2 soap_copy_context(struct soap*, struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_copy_stream(struct soap*, struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_init1(struct soap*, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_init2(struct soap*, soap_mode, soap_mode); +SOAP_FMAC1 void SOAP_FMAC2 soap_done(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_cleanup(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_begin(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_end(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_delete(struct soap*, void*); + +#ifdef SOAP_DEBUG +SOAP_FMAC1 void SOAP_FMAC2 soap_set_recv_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_sent_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_test_logfile(struct soap*, const char*); +SOAP_FMAC1 void SOAP_FMAC2 soap_close_logfiles(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_open_logfile(struct soap*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_value(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_tag(struct soap*, const char*, const char *); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_array(struct soap*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element(struct soap*, const char*, int, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_out(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_array_begin_out(struct soap*, const char *tag, int id, const char *type, const char *offset); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_ref(struct soap*, const char *tag, int id, int href); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_href(struct soap*, const char *tag, int id, const char *ref, const char *val); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_null(struct soap*, const char *tag, int id, const char *type); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_id(struct soap*, const char *tag, int id, const void *p, const struct soap_array *a, int d, const char *type, int n); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_result(struct soap*, const char *tag); +SOAP_FMAC1 void SOAP_FMAC2 soap_check_result(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_out(struct soap*, const char *tag); +SOAP_FMAC1 int SOAP_FMAC2 soap_element_start_end_out(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_attribute(struct soap*, const char*, const char*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_begin_in(struct soap*, const char *tag, int nillable, const char *type); + +SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_in(struct soap*, const char *tag); + +SOAP_FMAC1 int SOAP_FMAC2 soap_peek_element(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_retry(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_revert(struct soap*); + +SOAP_FMAC1 char* SOAP_FMAC2 soap_strdup(struct soap*, const char*); +SOAP_FMAC1 const char * SOAP_FMAC2 soap_strsearch(const char *big, const char *little); + +SOAP_FMAC1 int SOAP_FMAC2 soap_string_out(struct soap*, const char *s, int flag); +SOAP_FMAC1 char* SOAP_FMAC2 soap_string_in(struct soap*, int, long, long); + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_wstring_out(struct soap*, const wchar_t *s, int flag); +SOAP_FMAC1 wchar_t* SOAP_FMAC2 soap_wstring_in(struct soap*, int, long, long); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_match_namespace(struct soap*, const char *, const char*, int n1, int n2); + +SOAP_FMAC1 int SOAP_FMAC2 soap_set_namespaces(struct soap*, const struct Namespace*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_local_namespaces(struct soap*); + +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_namespace(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_push_namespace(struct soap*, const char *,const char *); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_current_namespace(struct soap *soap, const char *tag); + +SOAP_FMAC1 struct soap_nlist* SOAP_FMAC2 soap_lookup_ns(struct soap *soap, const char *tag, size_t n); + +SOAP_FMAC1 int SOAP_FMAC2 soap_store_lab(struct soap*, const char*, size_t); +SOAP_FMAC1 int SOAP_FMAC2 soap_append_lab(struct soap*, const char*, size_t); + +SOAP_FMAC1 int SOAP_FMAC2 soap_new_block(struct soap*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_push_block(struct soap*, size_t); +SOAP_FMAC1 void SOAP_FMAC2 soap_pop_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_size_block(struct soap*, size_t); +SOAP_FMAC1 char* SOAP_FMAC2 soap_first_block(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_next_block(struct soap*); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_block_size(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_save_block(struct soap*, char*, int); +SOAP_FMAC1 void SOAP_FMAC2 soap_end_block(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_out(struct soap*); +SOAP_FMAC1 int soap_envelope_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_out(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_out(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_body_begin_in(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_body_end_in(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_header(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_response(struct soap*, int); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_empty_response(struct soap*, int status); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_empty_response(struct soap*); + +SOAP_FMAC1 int SOAP_FMAC2 soap_send_fault(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*); + +#ifndef WITH_NOSTDLIB +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault(struct soap*, FILE*); +SOAP_FMAC1 void SOAP_FMAC2 soap_print_fault_location(struct soap*, FILE*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_s2byte(struct soap*, const char*, char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2short(struct soap*, const char*, short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2int(struct soap*, const char*, int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2long(struct soap*, const char*, long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2LONG64(struct soap*, const char*, LONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2float(struct soap*, const char*, float*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2double(struct soap*, const char*, double*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedByte(struct soap*, const char*, unsigned char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedShort(struct soap*, const char*, unsigned short*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedInt(struct soap*, const char*, unsigned int*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2unsignedLong(struct soap*, const char*, unsigned long*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2ULONG64(struct soap*, const char*, ULONG64*); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2string(struct soap*, const char*, char**); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2QName(struct soap*, const char*, char**); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_s2wchar(struct soap*, const char*, wchar_t**); +SOAP_FMAC1 int SOAP_FMAC2 soap_s2dateTime(struct soap*, const char*, time_t*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2base64(struct soap*, const unsigned char*, char*, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_s2hex(struct soap*, const unsigned char*, char*, int); +#endif + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_byte2s(struct soap*, char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_short2s(struct soap*, short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_int2s(struct soap*, int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_long2s(struct soap*, long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_LONG642s(struct soap*, LONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_float2s(struct soap*, float); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_double2s(struct soap*, double); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedByte2s(struct soap*, unsigned char); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedShort2s(struct soap*, unsigned short); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedInt2s(struct soap*, unsigned int); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_unsignedLong2s(struct soap*, unsigned long); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_ULONG642s(struct soap*, ULONG64); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_QName2s(struct soap*, const char*); + +#ifndef WITH_LEAN +SOAP_FMAC1 const char* SOAP_FMAC2 soap_wchar2s(struct soap*, const wchar_t*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_dateTime2s(struct soap*, time_t); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_base642s(struct soap*, const char*, char*, size_t, int*); +SOAP_FMAC1 const char* SOAP_FMAC2 soap_hex2s(struct soap*, const char*, char*, size_t, int*); +#endif + + +SOAP_FMAC1 int* SOAP_FMAC2 soap_inint(struct soap*, const char *tag, int *p, const char *, int); +SOAP_FMAC1 char* SOAP_FMAC2 soap_inbyte(struct soap*, const char *tag, char *p, const char *, int); +SOAP_FMAC1 long* SOAP_FMAC2 soap_inlong(struct soap*, const char *tag, long *p, const char *, int); +SOAP_FMAC1 LONG64* SOAP_FMAC2 soap_inLONG64(struct soap*, const char *tag, LONG64 *p, const char *, int); +SOAP_FMAC1 short* SOAP_FMAC2 soap_inshort(struct soap*, const char *tag, short *p, const char *, int); +SOAP_FMAC1 float* SOAP_FMAC2 soap_infloat(struct soap*, const char *tag, float *p, const char *, int); +SOAP_FMAC1 double* SOAP_FMAC2 soap_indouble(struct soap*, const char *tag, double *p, const char *, int); +SOAP_FMAC1 unsigned char* SOAP_FMAC2 soap_inunsignedByte(struct soap*, const char *tag, unsigned char *p, const char *, int); +SOAP_FMAC1 unsigned short* SOAP_FMAC2 soap_inunsignedShort(struct soap*, const char *tag, unsigned short *p, const char *, int); +SOAP_FMAC1 unsigned int* SOAP_FMAC2 soap_inunsignedInt(struct soap*, const char *tag, unsigned int *p, const char *, int); +SOAP_FMAC1 unsigned long* SOAP_FMAC2 soap_inunsignedLong(struct soap*, const char *tag, unsigned long *p, const char *, int); +SOAP_FMAC1 ULONG64* SOAP_FMAC2 soap_inULONG64(struct soap*, const char *tag, ULONG64 *p, const char *, int); +SOAP_FMAC1 char** SOAP_FMAC2 soap_instring(struct soap*, const char *tag, char **p, const char *, int, int, long, long); +SOAP_FMAC1 char** SOAP_FMAC2 soap_inliteral(struct soap*, const char *tag, char **p); + +#ifndef WITH_LEAN +SOAP_FMAC1 time_t* SOAP_FMAC2 soap_indateTime(struct soap*, const char *tag, time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwstring(struct soap*, const char *tag, wchar_t **p, const char *, int, long, long); +SOAP_FMAC1 wchar_t** SOAP_FMAC2 soap_inwliteral(struct soap*, const char *tag, wchar_t **p); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_outbyte(struct soap*, const char *tag, int id, const char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outshort(struct soap*, const char *tag, int id, const short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outint(struct soap*, const char *tag, int id, const int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outlong(struct soap*, const char *tag, int id, const long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outLONG64(struct soap*, const char *tag, int id, const LONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outfloat(struct soap*, const char *tag, int id, const float *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outdouble(struct soap*, const char *tag, int id, const double *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedByte(struct soap*, const char *tag, int id, const unsigned char *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedShort(struct soap*, const char *tag, int id, const unsigned short *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedInt(struct soap*, const char *tag, int id, const unsigned int *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outunsignedLong(struct soap*, const char *tag, int id, const unsigned long *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outULONG64(struct soap*, const char *tag, int id, const ULONG64 *p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outstring(struct soap*, const char *tag, int id, char *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outliteral(struct soap*, const char *tag, char *const*p, const char *type); + +#ifndef WITH_LEAN +SOAP_FMAC1 int SOAP_FMAC2 soap_outdateTime(struct soap*, const char *tag, int id, const time_t *p, const char *, int); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_outwstring(struct soap*, const char *tag, int id, wchar_t *const*p, const char *, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_outwliteral(struct soap*, const char *tag, wchar_t *const*p, const char *type); +#endif + +#ifndef WITH_LEANER +SOAP_FMAC1 int SOAP_FMAC2 soap_attachment(struct soap *, const char*, int, const void*, const struct soap_array*, const char*, const char*, const char*, int, const char*, int); +SOAP_FMAC1 int SOAP_FMAC2 soap_move(struct soap*, long); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_tell(struct soap*); +SOAP_FMAC1 char* SOAP_FMAC2 soap_dime_option(struct soap*, unsigned short, const char*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putdime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmimehdr(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_getmime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmimehdr(struct soap*, struct soap_multipart*); +SOAP_FMAC1 int SOAP_FMAC2 soap_putmime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_set_mime(struct soap*, const char *boundary, const char *start); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_dime(struct soap*); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_mime(struct soap*); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_dime_attachment(struct soap*, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_mime_attachment(struct soap*, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description); +SOAP_FMAC1 void SOAP_FMAC2 soap_post_check_mime_attachments(struct soap *soap); +SOAP_FMAC1 int SOAP_FMAC2 soap_check_mime_attachments(struct soap *soap); +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_get_mime_attachment(struct soap *soap, void *handle); +SOAP_FMAC1 struct soap_multipart* SOAP_FMAC2 soap_next_multipart(struct soap_multipart*); +SOAP_FMAC1 int SOAP_FMAC2 soap_match_cid(struct soap*, const char*, const char*); +#endif + +SOAP_FMAC1 int SOAP_FMAC2 soap_register_plugin_arg(struct soap*, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void*); +SOAP_FMAC1 void* SOAP_FMAC2 soap_lookup_plugin(struct soap*, const char*); + +SOAP_FMAC1 const char* SOAP_FMAC2 soap_attr_value(struct soap *soap, const char *name, int flag); +SOAP_FMAC1 int SOAP_FMAC2 soap_set_attr(struct soap *soap, const char *name, const char *value); +SOAP_FMAC1 void SOAP_FMAC2 soap_clr_attr(struct soap *soap); + +#ifdef WITH_COOKIES +SOAP_FMAC1 void SOAP_FMAC2 soap_getcookies(struct soap *soap, const char *val); +SOAP_FMAC1 size_t SOAP_FMAC2 soap_encode_cookie(const char*, char*, size_t); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_set_cookie(struct soap*, const char*, const char*, const char*, const char*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern char* SOAP_FMAC2 soap_env_cookie_value(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern time_t SOAP_FMAC2 soap_cookie_expire(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_expire(struct soap*, const char*, long, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_set_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_clr_cookie_session(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_clr_cookie(struct soap*, const char*, const char*, const char*); +SOAP_FMAC1 extern int SOAP_FMAC2 soap_getenv_cookies(struct soap*); +SOAP_FMAC1 extern struct soap_cookie* SOAP_FMAC2 soap_copy_cookies(struct soap*, struct soap*); +SOAP_FMAC1 extern void SOAP_FMAC2 soap_free_cookies(struct soap*); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/org.glite.security.proxyrenewal/.cvsignore b/org.glite.security.proxyrenewal/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.security.proxyrenewal/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.security.proxyrenewal/LICENSE b/org.glite.security.proxyrenewal/LICENSE deleted file mode 100644 index 01b973b..0000000 --- a/org.glite.security.proxyrenewal/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.security.proxyrenewal/Makefile b/org.glite.security.proxyrenewal/Makefile deleted file mode 100644 index 24252c7..0000000 --- a/org.glite.security.proxyrenewal/Makefile +++ /dev/null @@ -1,167 +0,0 @@ -# -# Copyright (c) 2004 on behalf of the EU EGEE Project: -# The European Organization for Nuclear Research (CERN), -# Istituto Nazionale di Fisica Nucleare (INFN), Italy -# Datamat Spa, Italy -# Centre National de la Recherche Scientifique (CNRS), France -# CS Systeme d'Information (CSSI), France -# Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -# Universiteit van Amsterdam (UvA), Netherlands -# University of Helsinki (UH.HIP), Finland -# University of Bergen (UiB), Norway -# Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom -# -# Top Makefile file for the GLite Security Proxyrenewal module -# -# Authors: Ales Krenek -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log -# - -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-security-proxyrenewal -version=0.0.0 -PREFIX=/opt/glite - -glite_location=$PREFIX -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -myproxy_prefix=$globus_prefix - --include Makefile.inc - -VPATH:=${top_srcdir}/src:${top_srcdir}/examples - -GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour} \ - -I${globus_prefix}/include/${nothrflavour}/openssl - -GLOBUSTHRINC:= -I${globus_prefix}/include/${thrflavour} \ - -I${globus_prefix}/include/${thrflavour}/openssl - -MYPROXYINC:= -I${myproxy_prefix}/include/${nothrflavour} -MYPROXYTHRINC:= -I${myproxy_prefix}/include/${thrflavour} - -DEBUG:=-g -O0 - -CFLAGS:= ${DEBUG} \ - ${MYPROXYINC} \ - -I${top_srcdir}/src -I${top_srcdir}/interface \ - -I${glite_location}/include - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lssl_${nothrflavour} - -MYPROXY_LIB_NOTHR :=-L${myproxy_prefix}/lib -lmyproxy_${nothrflavour} -MYPROXY_LIB_THR:=-L${myproxy_prefix}/lib -lmyproxy_${thrflavour} - -offset=1 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -DAEMONOBJ:=renewd.o renew.o common.o commands.o api.o voms.o -LIBOBJ:=api.o common.o -LIB_CORE_OBJS := renewal_core.o voms.o -CLIENTOBJ:=client.o - -THRLIBOBJ:=${LIBOBJ:.o=.thr.o} -LIBLOBJ:=${LIBOBJ:.o=.lo} -THRLIBLOBJ:=${LIBOBJ:.o=.thr.lo} - -LIB_CORE_NOTHR_OBJS := ${LIB_CORE_OBJS} -LIB_CORE_NOTHR_LOBJS := ${LIB_CORE_OBJS:.o=.lo} -LIB_CORE_THR_OBJS := ${LIB_CORE_OBJS:.o=.thr.o} -LIB_CORE_THR_LOBJS := ${LIB_CORE_OBJS:.o=.thr.lo} - -LIB:=libglite_security_proxyrenewal_${nothrflavour}.la -THRLIB:=libglite_security_proxyrenewal_${thrflavour}.la -LIB_CORE_NOTHR := libglite_security_proxyrenewal_core_${nothrflavour}.la -LIB_CORE_THR := libglite_security_proxyrenewal_core_${thrflavour}.la - -VOMS_LIB_NOTHR := -L${glite_location}/lib -lvomsc_${nothrflavour} -VOMS_LIB_THR := -L${glite_location}/lib -lvomsc_${thrflavour} - -DAEMON:=glite-proxy-renewd -CLIENT:=glite-proxy-renew -EXAMPLES := renew_core - -default: all -compile all: ${LIB} ${THRLIB} ${LIB_CORE_NOTHR} ${DAEMON} ${CLIENT} - -${LIB}: ${LIBOBJ} - ${LINK} ${version_info} -o $@ ${LIBLOBJ} -rpath ${glite_location}/lib - -${THRLIB}: ${THRLIBOBJ} - ${LINK} ${version_info} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib - -${LIB_CORE_NOTHR}: ${LIB_CORE_NOTHR_OBJS} - ${LINK} ${version_info} -o $@ ${LIB_CORE_NOTHR_LOBJS} -rpath ${glite_location}/lib ${MYPROXY_LIB_NOTHR} ${VOMS_LIB_NOTHR} - -${LIB_CORE_THR}: ${LIB_CORE_THR_OBJS} - ${LINK} ${version_info} -o $@ ${LIB_CORE_THR_LOBJS} -rpath ${glite_location}/lib ${MYPROXY_LIB_THR} ${VOMS_LIB_THR} - -${DAEMON}: ${DAEMONOBJ} ${LIB_CORE_NOTHR} - ${LINK} -o $@ ${DAEMONOBJ} ${LIB_CORE_NOTHR} - -${CLIENT}: ${CLIENTOBJ} ${LIB} - ${LINK} -o $@ ${CLIENTOBJ} ${LIB} ${GLOBUS_LIBS} - -${THRLIBOBJ} ${LIB_CORE_THR_OBJS}: %.thr.o: %.c - ${COMPILE} ${GLOBUSTHRINC} -o $@ -c $< - -%.o: %.c - ${COMPILE} ${GLOBUSINC} -c $< - -${EXAMPLES}: %: %.o - ${LINK} -o $@ $< ${LIB_CORE_NOTHR} - -stage: compile - $(MAKE) install PREFIX=${stagedir} - -check: - echo No unit tests - -examples: ${EXAMPLES} - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir - cd tmpbuilddir && tar -czf ../${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz * - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/lib ${PREFIX}/include/glite/security/proxyrenewal ${PREFIX}/share/doc/${package}-${version} ${PREFIX}/etc/init.d - ${INSTALL} -m 644 ${LIB} ${THRLIB} ${LIB_CORE_NOTHR} ${PREFIX}/lib - ${INSTALL} -m 755 ${DAEMON} ${CLIENT} ${PREFIX}/bin - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h renewal_core.h ${PREFIX}/include/glite/security/proxyrenewal - - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-proxy-renewald - - -clean: - $(RM) $(LIB) ${THRLIB} ${LIB_CORE_NOTHR} ${LIB_CORE_THR} $(DAEMON) $(CLIENT) $(EXAMPLES) *.o *.lo core - -.PHONY: default all compile examples check stage dist distsrc distbin install clean diff --git a/org.glite.security.proxyrenewal/build.xml b/org.glite.security.proxyrenewal/build.xml deleted file mode 100755 index 2ddf1c0..0000000 --- a/org.glite.security.proxyrenewal/build.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.proxyrenewal/config/startup b/org.glite.security.proxyrenewal/config/startup deleted file mode 100755 index 26ba757..0000000 --- a/org.glite.security.proxyrenewal/config/startup +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/opt/glite/var} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -PROXY_REPOSITORY="$GLITE_LOCATION_VAR/spool/glite-renewd" - -unset creds - -start() -{ - if test -z "$GLITE_USER" ;then - echo 'Error: GLITE_USER is not set' - echo FAILED - return 1 - fi - - [ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] && - creds="-t $GLITE_HOST_CERT -k $GLITE_HOST_KEY" - - if test -z "$creds"; then - if su - $GLITE_USER -c "test -r /etc/grid-security/hostkey.pem -a -r /etc/grid-security/hostcert.pem"; then - echo "$0: WARNING: /etc/grid-security/hostkey.pem readable by $GLITE_USER" - creds="-t /etc/grid-security/hostcert.pem -k /etc/grid-security/hostkey.pem" - fi - fi - - [ -z "$creds" ] && - echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 - - # workaround for VOMS_FindByVO that seems to always require user's own VOMS config file (bug #7511) - user_voms_config=$HOME/.glite/vomses - if [ ! -f "$user_voms_config" ]; then - rm -f /tmp/renewal_vomses - su - $GLITE_USER -c "touch /tmp/renewal_vomses && chmod 644 /tmp/renewal_vomses" - user_voms_config=/tmp/renewal_vomses - fi - - echo -n Starting ProxyRenewal Daemon: glite-proxy-renewd ... - - if [ ! -d "$PROXY_REPOSITORY" ]; then - mkdir -p $PROXY_REPOSITORY || exit 1 - chown $GLITE_USER $PROXY_REPOSITORY - chmod 0700 $PROXY_REPOSITORY - fi - - su - $GLITE_USER -c "VOMS_USERCONF=$user_voms_config \ - $GLITE_LOCATION/bin/glite-proxy-renewd \ - -r $PROXY_REPOSITORY $creds -A" && echo " done" -} - -stop() -{ - echo -n "Stopping ProxyRenewal Daemon: glite-proxy-renewd ..." - killall glite-proxy-renewd - echo " done" -} - -status() -{ - if netstat -an --unix | grep "^unix .* LISTEN.* /tmp/dgpr_renew_" >/dev/null 2>&1 ;then - echo glite-proxy-renewd running - else - echo glite-proxy-renewd not running - return 1 - fi -} - -case x$1 in - xstart) start;; - xstop) stop;; - xrestart) stop; start;; - xstatus) status;; - x*) echo usage: $0 start,stop,restart,status >&2 - exit 1;; -esac diff --git a/org.glite.security.proxyrenewal/examples/renew_core.c b/org.glite.security.proxyrenewal/examples/renew_core.c deleted file mode 100644 index 69518ea..0000000 --- a/org.glite.security.proxyrenewal/examples/renew_core.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include - -static struct option const long_options[] = { - { "server", required_argument, 0, 's' }, - { "proxy", required_argument, 0, 'p' }, - { "help", no_argument, 0, 'h' }, - { NULL, 0, NULL, 0} -}; - -static char short_options[] = "s:p:h"; - -int -main(int argc, char *argv[]) -{ - char *server = NULL; - char *proxy = NULL; - char *new_proxy = NULL; - extern int optind; - char arg; - glite_renewal_core_context ctx = NULL; - int ret; - - while ((arg = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) { - switch(arg) { - case 's': - server = optarg; break; - case 'p': - proxy = optarg; break; - case 'h': - fprintf(stdout, "Usage: %s --server --proxy \n", argv[0]); - exit(1); - } - } - - if (server == NULL || proxy == NULL) { - fprintf(stderr, "both server and proxy parameters must be given\n"); - exit(1); - } - - ret = glite_renewal_core_init_ctx(&ctx); - if (ret) { - fprintf(stderr, "glite_renewal_core_init_ctx() failed\n"); - exit(1); - } - - ctx->log_dst = GLITE_RENEWAL_LOG_NONE; - - ret = glite_renewal_core_renew(ctx, server, 0, proxy, &new_proxy); - if (ret) { - fprintf(stderr, "%s: glite_renewal_core_renew() failed: %s", - argv[0], ctx->err_message); - exit(1); - } - - ret = glite_renewal_core_destroy_ctx(ctx); - - printf("%s\n", new_proxy); - - return 0; -} diff --git a/org.glite.security.proxyrenewal/interface/renewal.h b/org.glite.security.proxyrenewal/interface/renewal.h deleted file mode 100644 index e07a89f..0000000 --- a/org.glite.security.proxyrenewal/interface/renewal.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * \file proxyrenewal/renewal.h - * \author Daniel Kouril - * \author Miroslav Ruda - * \brief API for proxy renewal. - * \version 2.0 - * - * General rules: - * - functions return 0 on success, nonzero on error, errror details can - * be found via edg_wlpr_GetErrorText() - */ - -#ifndef RENEWAL_H -#define RENEWAL_H - -#ident "$Header$" - -#ifdef RENEWAL_HAVE_JOBID -#include "glite/wmsutils/jobid/cjobid.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define EDG_WLPR_FLAG_UNIQUE 1 -#define EDG_WLPR_FLAG_UPDATE 2 - -typedef enum _edg_wlpr_ErrorCode { -/** - * Base for proxy renewal specific code. - * Start sufficently high not to collide with standard errno. */ - /* XXX see common/exception_codes.h */ - EDG_WLPR_ERROR_BASE = 1900, - EDG_WLPR_ERROR_UNEXPECTED_EOF, - EDG_WLPR_ERROR_GENERIC, - EDG_WLPR_ERROR_PROTO_PARSE_ERROR, - EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND, - EDG_WLPR_ERROR_UNKNOWN_COMMAND, - EDG_WLPR_ERROR_SSL, - EDG_WLPR_ERROR_MYPROXY, - EDG_WLPR_PROXY_NOT_REGISTERED, - EDG_WLPR_PROXY_EXPIRED, - EDG_WLPR_ERROR_VOMS, - EDG_WLPR_ERROR_TIMEOUT, - EDG_WLPR_ERROR_ERRNO, -} edg_wlpr_ErrorCode; - -/** - * Return a human readable string containg description of the errorcode - * \retval char* pointer to a error description - */ -const char * -edg_wlpr_GetErrorText(int err_code); - -/** - * This function contacts the renewal daemon and registers the specified proxy - * for periodic renewal. - * \param filename IN: specification of the proxy to register. - * \param jdl IN: JDL of the job owing the proxy. The JDL is looked for a - * myproxy server contact. - * \param flags IN: one of EDG_WLPR_FLAG_UNIQUE or EDG_WLPR_FLAG_UPDATE, or - * their bitwise OR. - * \param repository_filename OUT: filename of registered proxy in repository. - * \retval 0 success - * \retval nonzero on error. Human readable form of the error can be get via - * edg_wlpr_GetErrorText(). - */ -int -edg_wlpr_RegisterProxy( - const char * filename, - const char *jdl, - int flags, - char ** repository_filename -); - -/** - * The same function as edg_wlpr_RegisterProxy() but information about the - * myproxy server and jobid are passed as parameters instead of in JDL. - */ -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_RegisterProxyExt( - const char * filename, - const char * server, - unsigned int port, - edg_wlc_JobId jobid, - int flags, - char ** repository_filename -); -#endif - -int -glite_renewal_RegisterProxy( - const char * filename, - const char * server, - unsigned int port, - const char *jobid, - int flags, - char ** repository_filename -); - -/** - * Unregister proxy from the renewal daemon. - * \param jobid IN: specification of job whose proxy shall be unregistered - * \param filename IN: (optional) specification of the proxy to unregister. - * \retval 0 success - * \retval nonzero on error. Human readable form of the error can be get via - * edg_wlpr_GetErrorText(). - */ -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_UnregisterProxy( - edg_wlc_JobId jobid, - const char * repository_filename -); -#endif - -int -glite_renewal_UnregisterProxy( - const char * jobid, - const char * repository_filename -); - -/** - * Get a list of registered proxies maintained by the renewal daemon. - * \param count OUT: number of proxies - * \param list OUT: a list of filenames separated by '\n' - * specifying the registered proxies. - * \warning The caller is responsible for freeing the data. - * \retval 0 success - * \retval nonzero on error. Human readable form of the error can be get via - * edg_wlpr_GetErrorText(). - */ -int -edg_wlpr_GetList(int *count, char **list); - -/** - * Get a status message about a proxy. - * The function contacts the renewal daemon and retrieve information it - * maintains about the proxy. - * \param filename IN: specification of the proxy to query - * \param info OUT: status message. - * \warning The caller is responsible for freeing the data. - * \retval 0 success - * \retval nonzero on error. Human readable form of the error can be get via - * edg_wlpr_GetErrorText(). - */ -int -edg_wlpr_GetStatus(const char *repository_filename, char **info); - -/** - * For given jobid return registered proxy filename from repository - * \param jobid IN: specification of jobid - * \param repository_filename OUT: proxy regitered for given jobid - * \warning The caller is responsible for freeing the data. - * \retval 0 success - * \retval nonzero on error. Human readable form of the error can be get via - * edg_wlpr_GetErrorText(). - */ -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_GetProxy(edg_wlc_JobId jobid, char **repository_filename); -#endif - -int -glite_renewal_GetProxy( - const char * jobid, - char **repository_filename); - -#ifdef __cplusplus -} -#endif - -#endif /* RENEWAL_H */ diff --git a/org.glite.security.proxyrenewal/interface/renewal_core.h b/org.glite.security.proxyrenewal/interface/renewal_core.h deleted file mode 100644 index 8348963..0000000 --- a/org.glite.security.proxyrenewal/interface/renewal_core.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef RENEWAL_CORE_H -#define RENEWAL_CORE_H - -#ident "$Id$" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - GLITE_RENEWAL_LOG_NONE, - GLITE_RENEWAL_LOG_STDOUT, - GLITE_RENEWAL_LOG_SYSLOG, -} glite_renewal_log_dst; - -typedef struct glite_renewal_core_context_data { - int log_level; - glite_renewal_log_dst log_dst; - char *err_message; - char *voms_conf; -} glite_renewal_core_context_data; - -typedef struct glite_renewal_core_context_data *glite_renewal_core_context; - -/** - * This cal initializes the context and sets default values - */ -int -glite_renewal_core_init_ctx(glite_renewal_core_context *context); - -/** - * This call frees the context and all memory used by the context - */ -int -glite_renewal_core_destroy_ctx(glite_renewal_core_context context); - -/** - * This call tries to renew the proxy certificate using the MyProxy - * repository. If VOMS attributes are present in the proxy they are renewed - * as well. - * \param context IN: context with authentication information - * \param myproxy_server IN: hostname of the myproxy repository - * \param myproxy_port IN: TCP port of the myproxy repository, if 0 the - * default value will be used - * \param current_proxy IN: filename with the proxy to renew - * \param new_proxy OUT: filename with the renewed proxy, the caller is - * responsible for removing the file when it's not needed. - */ -int -glite_renewal_core_renew(glite_renewal_core_context context, - const char *myproxy_server, - unsigned int myproxy_port, - const char *current_proxy, - char **new_proxy); - -#ifdef __cplusplus -} -#endif - -#endif /* RENEWAL_CORE_H */ diff --git a/org.glite.security.proxyrenewal/project/build.number b/org.glite.security.proxyrenewal/project/build.number deleted file mode 100644 index 1936771..0000000 --- a/org.glite.security.proxyrenewal/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=137 diff --git a/org.glite.security.proxyrenewal/project/build.properties b/org.glite.security.proxyrenewal/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.security.proxyrenewal/project/configure.properties.xml b/org.glite.security.proxyrenewal/project/configure.properties.xml deleted file mode 100644 index 3d6914b..0000000 --- a/org.glite.security.proxyrenewal/project/configure.properties.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -myproxy_prefix=${with.myproxy.prefix} - - - diff --git a/org.glite.security.proxyrenewal/project/properties.xml b/org.glite.security.proxyrenewal/project/properties.xml deleted file mode 100755 index f1e51dd..0000000 --- a/org.glite.security.proxyrenewal/project/properties.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.proxyrenewal/project/tar_exclude b/org.glite.security.proxyrenewal/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.security.proxyrenewal/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.security.proxyrenewal/project/taskdefs.xml b/org.glite.security.proxyrenewal/project/taskdefs.xml deleted file mode 100755 index 13e894e..0000000 --- a/org.glite.security.proxyrenewal/project/taskdefs.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/org.glite.security.proxyrenewal/project/version.properties b/org.glite.security.proxyrenewal/project/version.properties deleted file mode 100644 index 1441742..0000000 --- a/org.glite.security.proxyrenewal/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.3.0 -module.age=1 diff --git a/org.glite.security.proxyrenewal/src/api.c b/org.glite.security.proxyrenewal/src/api.c deleted file mode 100644 index a72d692..0000000 --- a/org.glite.security.proxyrenewal/src/api.c +++ /dev/null @@ -1,550 +0,0 @@ -#include "renewal.h" -#include "renewal_locl.h" - -#ident "$Header$" - -#define SEPARATORS "\n" - -/* prototypes of static routines */ -static int -encode_request(edg_wlpr_Request *request, char **msg); - -static int -decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response); - -static int -do_connect(char *socket_name, struct timeval *timeout, int *sock); - -static int -send_request(int sock, struct timeval *timeout, edg_wlpr_Request *request, edg_wlpr_Response *response); - -static int -encode_request(edg_wlpr_Request *request, char **msg) -{ - char *buf; - size_t buf_len; - int ret; - - buf_len = EDG_WLPR_BUF_SIZE; - buf = malloc(buf_len); - if (buf == NULL) - return ENOMEM; - buf[0] = '\0'; - - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_VERSION, - EDG_WLPR_VERSION, SEPARATORS); - if (ret) - goto err; - - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_COMMAND, - edg_wlpr_EncodeInt(request->command), - SEPARATORS); - if (ret) - goto err; - - if (request->myproxy_server) { - char host[1024]; - -#if 0 - snprintf(host, sizeof(host), "%s:%d", request->myproxy_server, - (request->myproxy_port) ? request->myproxy_port : EDG_WLPR_MYPROXY_PORT); /* XXX let server decide ? */ -#else - snprintf(host, sizeof(host), "%s", request->myproxy_server); -#endif - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_MYPROXY_SERVER, - host, SEPARATORS); - if (ret) - goto err; - } - - if (request->proxy_filename) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_PROXY, - request->proxy_filename, SEPARATORS); - if (ret) - goto err; - } - - if (request->jobid) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_JOBID, - request->jobid, SEPARATORS); - if (ret) - goto err; - } - - if (request->entries) { - char **p = request->entries; - while (*p) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_ENTRY, - *p, SEPARATORS); - if (ret) - goto err; - p++; - } - } - - buf[strlen(buf)] = '\0'; - *msg = buf; - return 0; - -err: - free(buf); - *msg = NULL; - return ret; -} - -static int -decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response) -{ - int ret; - char *value = NULL; - /* char *p; */ - int i; - int current_size = 0; - - /* XXX add an ending zero '\0' */ - - assert(msg != NULL); - assert(response != NULL); - - memset(response, 0, sizeof(*response)); - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_VERSION, SEPARATORS, - 0, &response->version); - if (ret) - goto err; - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_RESPONSE, SEPARATORS, - 0, &value); - if (ret) - goto err; - - ret = edg_wlpr_DecodeInt(value, (int *)(&response->response_code)); - free(value); - if (ret) - goto err; - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_MYPROXY_SERVER, - SEPARATORS, 0, &response->myproxy_server); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - -#if 0 - response->myproxy_port = EDG_WLPR_MYPROXY_PORT; /* ??? */ - if (response->myproxy_server && (p = strchr(response->myproxy_server, ':'))) { - int port; - *p = '\0'; - port = atol(p+1); /* XXX */ - response->myproxy_port = port; - } -#endif - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_START_TIME, SEPARATORS, - 0, &value); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - if (ret == 0) { - ret = edg_wlpr_DecodeInt(value, (int *)(&response->start_time)); - free(value); - if (ret) - goto err; - } - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_END_TIME, SEPARATORS, - 0, &value); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - if (ret == 0) { - ret = edg_wlpr_DecodeInt(value, (int *)(&response->end_time)); - free(value); - if (ret) - goto err; - } - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_RENEWAL_TIME, - SEPARATORS, 0, &value); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - if (ret == 0) { - ret = edg_wlpr_DecodeInt(value, (int *)(&response->next_renewal_time)); - free(value); - if (ret) - goto err; - } - - /* XXX Counter */ - - i = 0; - while ((ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_PROXY, - SEPARATORS, i, &value)) == 0) { - if (i >= current_size) { - char **tmp; - - tmp = realloc(response->filenames, - (current_size + 16 + 1) * sizeof(*tmp)); - if (tmp == NULL) { - ret = ENOMEM; - goto err; - } - response->filenames = tmp; - current_size += 16; - } - response->filenames[i] = value; - i++; - } - if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - if (response->filenames) - response->filenames[i] = NULL; - - return 0; - -err: - edg_wlpr_CleanResponse(response); - - return ret; -} - -static int -do_connect(char *socket_name, struct timeval *timeout, int *sock) -{ - struct sockaddr_un my_addr; - int s; - int ret; - struct timeval before,after; - int sock_err; - socklen_t err_len; - - assert(sock != NULL); - memset(&my_addr, 0, sizeof(my_addr)); - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - return errno; - } - - if (timeout) { - int flags = fcntl(s, F_GETFL, 0); - if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) - return errno; - } - - my_addr.sun_family = AF_UNIX; - strncpy(my_addr.sun_path, socket_name, sizeof(my_addr.sun_path)); - - ret = connect(s, (struct sockaddr *) &my_addr, sizeof(my_addr)); - if (ret == -1) { - if (errno == EINPROGRESS) { - struct pollfd pollfds[1]; - - pollfds[0].fd = s; - pollfds[0].events = POLLOUT; - - gettimeofday(&before,NULL); - switch (poll(pollfds, 1, timeout->tv_sec*1000+timeout->tv_usec/1000)) { - case -1: close(s); - return errno; - case 0: close(s); - return EDG_WLPR_ERROR_TIMEOUT; - } - gettimeofday(&after,NULL); - if (edg_wlpr_DecrementTimeout(timeout, before, after)) { - close (s); - return EDG_WLPR_ERROR_TIMEOUT; - } - - err_len = sizeof sock_err; - if (getsockopt(s,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) { - close(s); - return errno; - } - if (sock_err) { - close(s); - errno = sock_err; - return errno; - } - } else { - close(s); - return errno; - } - } - - *sock = s; - return 0; -} - -static int -send_request(int sock, struct timeval *timeout, edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - int ret; - char *buf = NULL; - size_t buf_len; - - /* timeouts ?? */ - - ret = encode_request(request, &buf); - if (ret) - return ret; - - ret = edg_wlpr_Write(sock, timeout, buf, strlen(buf) + 1); - free(buf); - if (ret) - return ret; - - ret = edg_wlpr_Read(sock, timeout, &buf, &buf_len); - if (ret) - return ret; - - ret = decode_response(buf, buf_len, response); - free(buf); - if (ret) - return ret; - - return 0; -} - -int -edg_wlpr_RequestSend(edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - char sockname[1024]; - int ret; - int sock; - struct timeval timeout; - const char *s = NULL; - double d; - - s = getenv("GLITE_PR_TIMEOUT"); - d = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT; - timeout.tv_sec = (long) d; - timeout.tv_usec = (long) ((d-timeout.tv_sec) * 1e6); - - snprintf(sockname, sizeof(sockname), "%s%d", - DGPR_REG_SOCKET_NAME_ROOT, getuid()); - ret = do_connect(sockname, &timeout, &sock); - if (ret) - return ret; - - ret = send_request(sock, &timeout, request, response); - - close(sock); - return ret; -} - -int -glite_renewal_RegisterProxy(const char *filename, const char * server, - unsigned int port, - const char *jobid, int flags, - char **repository_filename) -{ - edg_wlpr_Request request; - edg_wlpr_Response response; - int ret; - - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - if (jobid == NULL) - return EINVAL; - - request.command = EDG_WLPR_COMMAND_REG; - request.myproxy_server = server; - request.proxy_filename = filename; - request.jobid = strdup(jobid); - if (request.jobid == NULL) - return ENOMEM; - - ret = edg_wlpr_RequestSend(&request, &response); - free(request.jobid); - if (ret == 0 && response.response_code == 0 && repository_filename && - response.filenames && response.filenames[0] ) - *repository_filename = strdup(response.filenames[0]); - - if (ret == 0) - ret = response.response_code; - - edg_wlpr_CleanResponse(&response); - - return ret; -} - -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_RegisterProxyExt(const char *filename, const char * server, - unsigned int port, - edg_wlc_JobId jobid, int flags, - char **repository_filename) -{ - char *ji; - int ret; - - ji = edg_wlc_JobIdUnparse(jobid); - if (ji == NULL) - return EINVAL; - - ret = glite_renewal_RegisterProxy(filename, server, port, ji, flags, - repository_filename); - free(ji); - return ret; -} -#endif /* RENEWAL_HAVE_JOBID */ - -#if 0 -int -edg_wlpr_RegisterProxy(const char *filename, const char *jdl, - int flags, char **repository_filename) -{ - char server[1024]; - size_t server_len; - unsigned int port = 0; - char *p, *q; - - memset(server, 0, sizeof(server)); - - /* parse JDL and find information about myproxy server */ - p = strstr(jdl, JDL_MYPROXY); - if (p == NULL) - return 0; /* XXX */ - q = strchr(p, '\n'); /* XXX */ - if (q) - server_len = q - p; - else - server_len = jdl + strlen(jdl) - p; - if (server_len >= sizeof(server)) - return EINVAL; /* XXX */ - strncmp(server, p, sizeof(server)); - - return (edg_wlpr_RegisterProxyExt(filename, server, port, NULL, flags, - repository_filename)); -} -#endif - -int -glite_renewal_UnregisterProxy(const char *jobid, const char *repository_filename) -{ - edg_wlpr_Request request; - edg_wlpr_Response response; - int ret; - - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - if (jobid == NULL) - return EINVAL; - - request.command = EDG_WLPR_COMMAND_UNREG; - request.proxy_filename = repository_filename; - request.jobid = strdup(jobid); - if (request.jobid == NULL) - return ENOMEM; - - ret = edg_wlpr_RequestSend(&request, &response); - free(request.jobid); - - if (ret == 0) - ret = response.response_code; - edg_wlpr_CleanResponse(&response); - - return ret; -} - -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_UnregisterProxy(edg_wlc_JobId jobid, const char *repository_filename) -{ - char *ji; - int ret; - - ji = edg_wlc_JobIdUnparse(jobid); - if (ji == NULL) - return EINVAL; - ret = glite_renewal_UnregisterProxy(ji, repository_filename); - free(ji); - return ret; -} -#endif /* RENEWAL_HAVE_JOBID */ - -int -edg_wlpr_GetList(int *count, char **list) -{ - return ENOSYS; /* XXX */ -} - -int -edg_wlpr_GetStatus(const char *filename, char **info) -{ - return ENOSYS; /* XXX */ -} - -static const char* const errTexts[] = { - "Unexpected EOF from peer", - "Generic error", - "Protocol parse error", - "Compulsory element not found in message", - "Unknown protocol command", - "SSL error", - "Error from Myproxy server", - "Proxy not registered", - "Proxy expired", - "VOMS error", - "Operation timed out", - "System error" -}; - -const char * -edg_wlpr_GetErrorText(int code) -{ - return code ? - (code <= EDG_WLPR_ERROR_BASE ? - strerror(code) : - errTexts[code - EDG_WLPR_ERROR_BASE - 1] - ) : - NULL; -} - -int -glite_renewal_GetProxy(const char *jobid, char **repository_filename) -{ - edg_wlpr_Request request; - edg_wlpr_Response response; - int ret; - - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - if (jobid == NULL) - return EINVAL; - - request.command = EDG_WLPR_COMMAND_GET; - request.jobid = strdup(jobid); - if (request.jobid == NULL) - return ENOMEM; - - ret = edg_wlpr_RequestSend(&request, &response); - free(request.jobid); - - if (ret == 0 && response.response_code == 0 && repository_filename && - response.filenames && response.filenames[0] ) - *repository_filename = strdup(response.filenames[0]); - - if (ret == 0) - ret = response.response_code; - edg_wlpr_CleanResponse(&response); - - return ret; -} - -#ifdef RENEWAL_HAVE_JOBID -int -edg_wlpr_GetProxy(edg_wlc_JobId jobid, char **repository_filename) -{ - char *ji; - int ret; - - ji = edg_wlc_JobIdUnparse(jobid); - if (ji == NULL) - return EINVAL; - - ret = glite_renewal_GetProxy(ji, repository_filename); - free(ji); - return ret; -} -#endif /* RENEWAL_HAVE_JOBID */ diff --git a/org.glite.security.proxyrenewal/src/client.c b/org.glite.security.proxyrenewal/src/client.c deleted file mode 100644 index 87efd78..0000000 --- a/org.glite.security.proxyrenewal/src/client.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include "renewal.h" - -static const char rcsid[] = "$Header$"; - -static struct option const long_options[] = { - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { "server", required_argument, 0, 's' }, - { "port", required_argument, 0, 'p' }, - { "file", required_argument, 0, 'f' }, - { "jobid", required_argument, 0, 'j' }, - { NULL, 0, NULL, 0} -}; - -static char short_options[] = "hvs:p:f:j:"; - -static void -usage(exit_code) -{ - fprintf(stdout, "Usage: edg-wl-renew [option] operation\n" - "\t-s myproxy_server [-p port] -f filename -j jobid start |\n" - "\t-j jobid [-f filename] stop |\n" - "\t-j jobid get\n" - "-h, --help display this help and exit\n" - "-v, --version output version information and exit\n" - "-s, --server address of myproxy server\n" - "-p, --port port of myproxy server\n" - "-f, --file filename with proxy\n" - "-j, --jobid datagrid jobid\n"); - exit(exit_code); -} - -int -main(int argc, char *argv[]) -{ - char *server = NULL; - int port = 0; - char *proxyfile = NULL; - char *jobid_str = NULL; - char *repository_filename = NULL; - int ret; - int arg; - extern int optind; - - while ((arg = getopt_long(argc, argv, - short_options, long_options, (int *) 0)) != EOF) - switch(arg) { - case 'h': - usage(0); break; - case 'v': - fprintf(stdout, "%s:\t%s\n", argv[0], rcsid); exit(0); - case 's': - server = strdup(optarg); break; - case 'p': - port = atoi(optarg); break; - case 'f': - proxyfile = strdup(optarg); break; - case 'j': - jobid_str = strdup(optarg); break; - default: - usage(1); break; - } - - if (optind >= argc) - usage(1); - - if (strcmp(argv[optind], "start") == 0) { - if (proxyfile == NULL || server == NULL || jobid_str == NULL) - usage(1); - ret = glite_renewal_RegisterProxy(proxyfile, server, port, jobid_str, 0, - &repository_filename); - if (ret) { - fprintf(stderr, "Registering proxy failed: %s\n", - edg_wlpr_GetErrorText(ret)); - exit(1); - } - printf("%s\n", repository_filename); - free(repository_filename); - exit(0); - } - else if (strcmp(argv[optind], "stop") == 0) { - if (jobid_str == NULL) - usage(1); - ret = glite_renewal_UnregisterProxy(jobid_str, proxyfile); - if (ret) { - fprintf(stderr, "Unregistering proxy failed: %s\n", - edg_wlpr_GetErrorText(ret)); - exit(1); - } - } - else if (strcmp(argv[optind], "get") == 0) { - if (jobid_str == NULL) - usage(1); - ret = glite_renewal_GetProxy(jobid_str, &proxyfile); - if (ret) { - fprintf(stderr, "GET request failed: %s\n", - edg_wlpr_GetErrorText(ret)); - exit(1); - } - printf("%s\n", proxyfile); - free(proxyfile); - } - else - usage(1); - - return 0; -} diff --git a/org.glite.security.proxyrenewal/src/commands.c b/org.glite.security.proxyrenewal/src/commands.c deleted file mode 100644 index abc4809..0000000 --- a/org.glite.security.proxyrenewal/src/commands.c +++ /dev/null @@ -1,1256 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include "glite/security/voms/voms_apic.h" - -#ident "$Header$" - -#define SEPARATORS ",\n" -#define RENEWAL_START_FRACTION 0.75 /* XXX */ -#define RENEWAL_MIN_LIFETIME (15 * 60) - -extern char *repository; -extern time_t condor_limit; -extern char *cadir; -extern char *vomsdir; -extern int voms_enabled; - -static char * -strmd5(glite_renewal_core_context ctx, const char *s, unsigned char *digest); - -static int -get_record_ext(glite_renewal_core_context ctx, FILE *fd, proxy_record *record, int *last_used_suffix); - -static int -get_record(glite_renewal_core_context ctx, FILE *fd, proxy_record *record); - -static int -store_record(glite_renewal_core_context ctx, char *basename, proxy_record *record); - -static int -copy_file_content(glite_renewal_core_context ctx, FILE *in, FILE *out); - -static int -copy_file(glite_renewal_core_context ctx, char *src, char *dst); - -static int -get_base_filename(glite_renewal_core_context ctx, char *proxy_file, char **basefilename); - -int -decode_record(glite_renewal_core_context ctx, char *line, proxy_record *record); - -int -encode_record(glite_renewal_core_context ctx, proxy_record *record, char **line); - -static int -open_metafile(glite_renewal_core_context ctx, char *proxy_file, FILE **fd); - -void -free_record(glite_renewal_core_context ctx, proxy_record *record); - -static int -realloc_prd_list(glite_renewal_core_context ctx, prd_list *list); - -/* make public: */ -static int -edg_wlpr_GetTokenInt(glite_renewal_core_context ctx, const char *msg, const size_t msg_len, - const char *key, const char *separators, - int req_index, int *value); - -static void -record_to_response(glite_renewal_core_context ctx, int status_code, proxy_record *record, - edg_wlpr_Response *response); - -static int -filename_to_response(glite_renewal_core_context ctx, char *filename, edg_wlpr_Response *response); - - - - -static char * -strmd5(glite_renewal_core_context ctx, const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - static char mbuf[33]; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) - memcpy(digest,d,sizeof(d)); - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return mbuf; -} - -static int -get_base_filename(glite_renewal_core_context ctx, char *proxy_file, char **basefilename) -{ - char *subject = NULL; - char file[FILENAME_MAX]; - int ret; - - assert(basefilename != NULL); - - ret = glite_renewal_get_proxy_base_name(ctx, proxy_file, &subject); - if (ret) - goto end; - - snprintf(file, sizeof(file), "%s/%s", repository, strmd5(ctx, subject, NULL)); - *basefilename = strdup(file); /* XXX test ENOMEM */ - ret = 0; - -end: - if (subject) - free(subject); - return ret; -} - -static int -copy_file_content(glite_renewal_core_context ctx, FILE *in, FILE *out) -{ - char buf[1024]; - size_t num; - int ret; - - while (1) { - num = fread(buf, sizeof(*buf), sizeof(buf), in); - if ((ret = ferror(in))) { - glite_renewal_log(ctx, LOG_ERR, "Reading failed: %s", strerror(errno)); - return ret; - } - num = fwrite(buf, sizeof(*buf), num, out); - if ((ret = ferror(in))) { - glite_renewal_log(ctx, LOG_ERR, "Writing failed: %s", strerror(errno)); - return ret; - } - if (feof(in)) - return 0; - } -} - -/* return the time interval, after which the renewal should be started */ -static time_t -get_delta(glite_renewal_core_context ctx, time_t current_time, time_t start_time, time_t end_time) -{ - time_t remaining_life; - time_t life_to_lose; - time_t limit; - time_t delta; - - if (RENEWAL_MIN_LIFETIME > condor_limit) { - limit = RENEWAL_MIN_LIFETIME; - } else { - limit = condor_limit; - } - - limit += RENEWAL_CLOCK_SKEW; - - if (current_time + limit >= end_time) { - /* if the proxy is too short, renew it as soon as possible */ - - if (current_time + condor_limit > end_time ) { - glite_renewal_log(ctx, LOG_ERR, "Remaining proxy lifetime fell below the value of the Condor limit!"); - } - - return 0; - } - - remaining_life = end_time - current_time; - - /* renewal should gain the jobs an extra lifetime of - RENEWAL_START_FRACTION (default 3/4) of the new proxy's - lifetime. If the time remaining on the current proxy is already - small then the jobs may gain an extra lifetime of more than that. - - In any case, a renewal will be scheduled to happen before the - lifetime limit. - - 'life_to_lose' is the lifetime that will be lost, ie the time that - will still remain on the current proxy when it is renewed - */ - - life_to_lose = (1.0-RENEWAL_START_FRACTION)*60*60*DGPR_RETRIEVE_DEFAULT_HOURS; - - if (life_to_lose < limit) { - life_to_lose = limit; - } - - delta = life_to_lose - limit; - - while( remaining_life < (limit + delta) ) { - delta *= (1.0-RENEWAL_START_FRACTION); - } - - life_to_lose = limit + delta; - - return (remaining_life - life_to_lose); -} - -int -get_times(glite_renewal_core_context ctx, char *proxy_file, proxy_record *record) -{ - FILE *fd; - X509 *cert = NULL; - ASN1_UTCTIME *asn1_time = NULL; - int ret; - time_t current_time, start_time, end_time; - - assert(record != NULL); - assert(proxy_file != NULL); - - fd = fopen(proxy_file, "r"); - if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Opening proxy file %s failed: %s", - proxy_file, strerror(errno)); - return errno; - } - - cert = PEM_read_X509(fd, NULL, NULL, NULL); - if (cert == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot read X.509 certificate from %s", - proxy_file); - ret = -1; /* XXX SSL_ERROR */ - goto end; - } - - asn1_time = ASN1_UTCTIME_new(); - X509_gmtime_adj(asn1_time,0); - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &end_time); - globus_gsi_cert_utils_make_time(X509_get_notBefore(cert), &start_time); - current_time = time(NULL); - ASN1_UTCTIME_free(asn1_time); - /* if (end_time - RENEWAL_CLOCK_SKEW < current_time) { Too short proxy } */ - if (end_time + RENEWAL_CLOCK_SKEW < current_time) { - glite_renewal_log(ctx, LOG_ERR, "Expired proxy in %s", proxy_file); - ret = EDG_WLPR_PROXY_EXPIRED; - goto end; - } - - /* Myproxy seems not to do check on expiration and return expired proxies - if credentials in repository are expired */ - X509_free(cert); - cert = NULL; - while (1) { - time_t tmp_end; - /* see http://www.openssl.org/docs/crypto/pem.html section BUGS */ - cert = PEM_read_X509(fd, NULL, NULL, NULL); - if (cert == NULL) { - if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) { - /* End of file reached. no error */ - ERR_clear_error(); - break; - } - glite_renewal_log(ctx, LOG_ERR, "Cannot read additional certificates from %s", - proxy_file); - ret = -1; /* XXX SSL_ERROR */ - goto end; - } - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &tmp_end); - if (tmp_end + RENEWAL_CLOCK_SKEW < current_time) { - glite_renewal_log(ctx, LOG_ERR, "Expired proxy in %s", proxy_file); - ret = EDG_WLPR_PROXY_EXPIRED; - goto end; - } - X509_free(cert); - cert = NULL; - } - - record->next_renewal = current_time + get_delta(ctx, current_time, start_time, - end_time); - record->end_time = end_time; - ret = 0; - -end: - fclose(fd); - if (cert) - X509_free(cert); - - return ret; -} - -static int -copy_file(glite_renewal_core_context ctx, char *src, char *dst) -{ - FILE *from = NULL; - FILE *tmp_to = NULL; - int tmp_fd; - char tmpfile[FILENAME_MAX]; - int ret; - - if (strcmp(src, dst) == 0) - return 0; - - from = fopen(src, "r"); - if (from == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open file %s for reading (%s)", - src, strerror(errno)); - return errno; - } - - snprintf(tmpfile, sizeof(tmpfile), "%s.XXXXXX", dst); - tmp_fd = mkstemp(tmpfile); - if (tmp_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); - ret = errno; - goto end; - } - - - tmp_to = fdopen(tmp_fd, "w"); - if (tmp_to == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot associate stream with temporary file (%s)", - strerror(errno)); - unlink(tmpfile); - ret = errno; - goto end; - } - - ret = copy_file_content(ctx, from, tmp_to); - fclose(tmp_to); - if (ret) { - goto end; - } - - ret = rename(tmpfile, dst); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Cannot replace repository file %s with temporary file (%s)", - strerror(errno)); - unlink(tmpfile); - ret = errno; - goto end; - } - tmp_to = NULL; - -end: - fclose(from); - close(tmp_fd); - unlink(tmpfile); - - return ret; -} - -void -free_record(glite_renewal_core_context ctx, proxy_record *record) -{ - int i; - - if (record == NULL) - return; - if (record->myproxy_server) - free(record->myproxy_server); - if (record->jobids.val) { - for (i = 0; i < record->jobids.len; i++) - free(record->jobids.val[i]); - free(record->jobids.val); - } - memset(record, 0, sizeof(*record)); -} - -static int -realloc_prd_list(glite_renewal_core_context ctx, prd_list *list) -{ - char **tmp; - - tmp = realloc(list->val, (list->len + 1) * sizeof(*list->val)); - if (tmp == NULL) - return ENOMEM; - list->val = tmp; - list->len++; - return 0; -} - -static int -get_jobids(glite_renewal_core_context ctx, const char *msg, const size_t msg_len, proxy_record *record) -{ - int index = 0; - int ret; - char *value; - char **tmp; - - memset(&record->jobids, 0, sizeof(record->jobids)); - while ((ret = edg_wlpr_GetToken(msg, msg_len, "jobid=", SEPARATORS, - index, &value)) == 0) { - tmp = realloc(record->jobids.val, (record->jobids.len + 1) * sizeof(*tmp)); - if (tmp == NULL) { - ret = ENOMEM; - break; - } - record->jobids.val = tmp; - record->jobids.val[index] = value; - record->jobids.len++; - index++; - } - if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - if (record->jobids.len) - free(record->jobids.val); - record->jobids.len = 0; - record->jobids.val = NULL; - return ret; - } - - return 0; -} - -static int -edg_wlpr_GetTokenInt(glite_renewal_core_context ctx, const char *msg, const size_t msg_len, - const char *key, const char *separators, - int req_index, int *value) -{ - int ret; - char *str_value = NULL; - - ret = edg_wlpr_GetToken(msg, msg_len, key, separators, req_index, &str_value); - if (ret) - return ret; - - ret = edg_wlpr_DecodeInt(str_value, value); - free(str_value); - return ret; -} - -int -decode_record(glite_renewal_core_context ctx, char *line, proxy_record *record) -{ - /* line must be ended with '\0' */ - int ret; - size_t len; - - assert(line != NULL); - assert(record != NULL); - - memset(record, 0, sizeof(*record)); - - len = strlen(line) + 1; - - ret = edg_wlpr_GetTokenInt(ctx, line, len, "suffix=", SEPARATORS, 0, - &record->suffix); - if (ret) - return ret; - -#if 0 - ret = edg_wlpr_GetTokenInt(ctx, line, len, "counter=", SEPARATORS, 0, - &record->counter); - if (ret) - goto end; -#endif - - ret = edg_wlpr_GetTokenInt(ctx, line, len, "unique=", SEPARATORS, 0, - &record->unique); - if (ret) - goto end; - - ret = edg_wlpr_GetTokenInt(ctx, line, len, "voms_exts=", SEPARATORS, 0, - &record->voms_exts); - - ret = edg_wlpr_GetToken(line, len, "server=", SEPARATORS, 0, - &record->myproxy_server); - if (ret) - goto end; - - ret = edg_wlpr_GetTokenInt(ctx, line, len, "next_renewal=", SEPARATORS, 0, - (int *)&record->next_renewal); - if (ret) - goto end; - - ret = edg_wlpr_GetTokenInt(ctx, line, len, "end_time=", SEPARATORS, 0, - (int *)&record->end_time); - if (ret) - goto end; - - ret = get_jobids(ctx, line, len, record); - if (ret) - goto end; - -end: - if (ret) - free_record(ctx, record); - - return ret; -} - -int -encode_record(glite_renewal_core_context ctx, proxy_record *record, char **line) -{ - char tmp_line[1024]; - size_t jobids_len = 0; - int i; - - snprintf(tmp_line, sizeof(tmp_line), "suffix=%d, unique=%d, voms_exts=%d, server=%s, next_renewal=%ld, end_time=%ld", - record->suffix, record->unique, record->voms_exts, - (record->myproxy_server) ? record->myproxy_server : "", - record->next_renewal, record->end_time); - for (i = 0; i < record->jobids.len; i++) - /* alloc space for string ", jobid=" */ - jobids_len += 2 + strlen("jobid=") + strlen(record->jobids.val[i]); - - *line = calloc(1, strlen(tmp_line) + jobids_len + 1); - if (*line == NULL) - return ENOMEM; - - strcat(*line, tmp_line); - memset(tmp_line, 0, sizeof(tmp_line)); - - for (i = 0; i < record->jobids.len; i++) { - snprintf(tmp_line, sizeof(tmp_line), ", jobid=%s", record->jobids.val[i]); - strcat(*line, tmp_line); - } - - return 0; -} - -/* Get proxy record from the index file. If no suffix is defined return a free - record with the smallest index */ -static int -get_record_ext(glite_renewal_core_context ctx, FILE *fd, proxy_record *record, int *last_used_suffix) -{ - char line[1024]; - int last_suffix = -1; - int ret; - char *p; - proxy_record tmp_record; - time_t current_time; - int line_num = 0; - - assert(record != NULL); - memset(&tmp_record, 0, sizeof(tmp_record)); - - current_time = time(NULL); - while (fgets(line, sizeof(line), fd) != NULL) { - line_num++; - free_record(ctx, &tmp_record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(ctx, line, &tmp_record); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Skipping invalid entry at line %d", line_num); - continue; - } - if (record->suffix >= 0) { - if (record->suffix == tmp_record.suffix) { - record->suffix = tmp_record.suffix; - record->jobids.len = tmp_record.jobids.len; - record->jobids.val = tmp_record.jobids.val; - record->unique = tmp_record.unique; - record->voms_exts = tmp_record.voms_exts; - if (record->myproxy_server) - free(record->myproxy_server); - record->myproxy_server = tmp_record.myproxy_server; - record->end_time = tmp_record.end_time; - record->next_renewal = tmp_record.next_renewal; - return 0; - } else - continue; - } - if (tmp_record.suffix > last_suffix) - last_suffix = tmp_record.suffix; - - /* if no particular suffix was specified get the first free record - available */ - if (tmp_record.jobids.len >= MAX_PROXIES || tmp_record.unique || - tmp_record.voms_exts) - continue; - - if (tmp_record.jobids.len == 0) { - /* no jobs registered for this record, so use it initialized with the - * parameters (currently myproxy location) provided by user */ - record->suffix = tmp_record.suffix; - record->next_renewal = record->end_time = 0; - free_record(ctx, &tmp_record); - return 0; - } - - /* Proxies with VOMS attributes require a separate record, which is not - * shared with another proxies. The same applies it the unique flag was - * set by the caller */ - if (record->voms_exts || record->unique) - continue; - - if (tmp_record.jobids.len > 0 && record->myproxy_server && - strcmp(record->myproxy_server, tmp_record.myproxy_server) != 0) - continue; - - if (tmp_record.jobids.len > 0 && - current_time + condor_limit + RENEWAL_CLOCK_SKEW > tmp_record.end_time) { - - /* skip expired proxy (or ones that are going to expire soon), - leaving it untouched (it will be removed after next run of the - renewal process) */ - - continue; - } - - record->suffix = tmp_record.suffix; - record->jobids.len = tmp_record.jobids.len; - record->jobids.val = tmp_record.jobids.val; - record->unique = tmp_record.unique; - record->voms_exts = tmp_record.voms_exts; - if (record->myproxy_server) - free(record->myproxy_server); - record->myproxy_server = tmp_record.myproxy_server; - record->end_time = tmp_record.end_time; - record->next_renewal = tmp_record.next_renewal; - return 0; - } - - if (last_used_suffix) - *last_used_suffix = last_suffix; - - if (record->suffix >= 0) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested suffix %d not found in meta file", - record->suffix); - } - - free_record(ctx, &tmp_record); - - return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND; -} - -static int -get_record(glite_renewal_core_context ctx, FILE *fd, proxy_record *record) -{ - return get_record_ext(ctx, fd, record, NULL); -} - -static int -store_record(glite_renewal_core_context ctx, char *basename, proxy_record *record) -{ - int stored = 0; - FILE *fd = NULL; - int temp; - char line[1024]; - char *new_line = NULL; - int ret, i; - char *p; - proxy_record tmp_record; - char tmp_file[FILENAME_MAX]; - char meta_file[FILENAME_MAX]; - int line_num = 0; - - assert (record != NULL); - - memset(&tmp_record, 0, sizeof(tmp_record)); - - snprintf(meta_file, sizeof(meta_file), "%s.data", basename); - snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", meta_file); - - temp = mkstemp(tmp_file); - if (temp < 0) - return errno; - - fd = fopen(meta_file, "r"); - if (fd == NULL) { - ret = errno; - goto end; - } - while (fgets(line, sizeof(line), fd) != NULL) { - line_num++; - free_record(ctx, &tmp_record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(ctx, line, &tmp_record); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Removing invalid entry at line %d in %s", line_num, basename); - continue; - } - if (record->suffix == tmp_record.suffix && - record->unique == tmp_record.unique) { - tmp_record.next_renewal = record->next_renewal; - tmp_record.end_time = record->end_time; - tmp_record.voms_exts = record->voms_exts; - if (tmp_record.myproxy_server != NULL) - free(tmp_record.myproxy_server); - tmp_record.myproxy_server = strdup(record->myproxy_server); - if (tmp_record.jobids.val) { - for (i = 0; i < tmp_record.jobids.len; i++) - free(tmp_record.jobids.val[i]); - free(tmp_record.jobids.val); - } - tmp_record.jobids.len = 0; - tmp_record.jobids.val = NULL; - for (i = 0; i < record->jobids.len; i++) { - realloc_prd_list(ctx, &tmp_record.jobids); - tmp_record.jobids.val[tmp_record.jobids.len - 1] = - strdup(record->jobids.val[i]); - } - stored = 1; - } - ret = encode_record(ctx, &tmp_record, &new_line); - if (ret) - goto end; - dprintf(temp, "%s\n", new_line); - free(new_line); - new_line = NULL; - } - if (! stored) { - ret = encode_record(ctx, record, &new_line); - if (ret) - goto end; - ret = dprintf(temp, "%s\n", new_line); - free(new_line); - new_line = NULL; - } - fclose(fd); fd = NULL; - close(temp); - - ret = rename(tmp_file, meta_file); - if (ret) - ret = errno; - -end: - free_record(ctx, &tmp_record); - if (fd) - fclose(fd); - close(temp); - return ret; -} - -static int -open_metafile(glite_renewal_core_context ctx, char *basename, FILE **fd) -{ - FILE *meta_fd; - char meta_filename[FILENAME_MAX]; - - snprintf(meta_filename, sizeof(meta_filename), "%s.data", basename); - meta_fd = fopen(meta_filename, "a+"); - if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Opening meta file %s failed (%s)", - meta_filename, strerror(errno)); - return errno; - } - rewind(meta_fd); - *fd = meta_fd; - glite_renewal_log(ctx, LOG_DEBUG, "Using meta file %s", meta_filename); - return 0; -} - -static int -filename_to_response(glite_renewal_core_context ctx, char *filename, edg_wlpr_Response *response) -{ - response->filenames = malloc(2 * sizeof(*response->filenames)); - if (response->filenames == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Not enough memory"); - return errno; - } - response->filenames[0] = strdup(filename); - if (response->filenames[0] == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Not enough memory"); - free(response->filenames); - return errno; - } - response->filenames[1] = NULL; - return 0; -} - -static void -record_to_response(glite_renewal_core_context ctx, int status_code, proxy_record *record, - edg_wlpr_Response *response) -{ - /* XXX Neni struktrura proxy_record zbytecna? Mohla by se pouzivat primo - edg_wlpr_Response? */ - response->response_code = status_code; /* XXX chyba parsovatelna pres API */ - if (status_code) - return; - - if (response->myproxy_server) { - response->myproxy_server = strdup(record->myproxy_server); - if (response->myproxy_server == NULL) { - response->response_code = ENOMEM; /* XXX */ - return; - } - } - response->end_time = record->end_time; - response->next_renewal_time = record->next_renewal; - /* XXX use jobid response->counter = record->counter; */ -} - -int -check_proxyname(glite_renewal_core_context ctx, char *datafile, char *jobid, char **filename) -{ - proxy_record record; - FILE *meta_fd = NULL; - char line[1024]; - char proxy[FILENAME_MAX]; - char *p; - int ret, i; - - memset(&record, 0, sizeof(record)); - - meta_fd = fopen(datafile, "r"); - if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", - datafile, strerror(errno)); - return errno; - } - - while (fgets(line, sizeof(line), meta_fd) != NULL) { - free_record(ctx, &record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(ctx, line, &record); - if (ret) - continue; /* XXX exit? */ - for (i = 0; i < record.jobids.len; i++) { - if (strcmp(jobid, record.jobids.val[i]) == 0) { - snprintf(proxy, sizeof(proxy), "%s/%s", repository, datafile); - p = strrchr(proxy, '.'); - sprintf(p, ".%d", record.suffix); - *filename = strdup(proxy); - free_record(ctx, &record); - fclose(meta_fd); - return 0; - } - } - } - free_record(ctx, &record); - fclose(meta_fd); - return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND; -} - -int -find_proxyname(glite_renewal_core_context ctx, char *jobid, char **filename) -{ - DIR *dir = NULL; - struct dirent *file; - int ret; - - chdir(repository); - - dir = opendir(repository); - if (dir == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open repository directory %s (%s)", - repository, strerror(errno)); - return errno; - } - - while ((file = readdir(dir))) { - /* read files of format `md5sum`.data, where md5sum() is of fixed length - 32 chars */ - if (file->d_name == NULL || strlen(file->d_name) != 37 || - strcmp(file->d_name + 32, ".data") != 0) - continue; - ret = check_proxyname(ctx, file->d_name, jobid, filename); - if (ret == 0) { - closedir(dir); - return 0; - } - } - closedir(dir); - glite_renewal_log(ctx, LOG_ERR, "Requested proxy is not registered"); - return EDG_WLPR_PROXY_NOT_REGISTERED; -} - -#ifdef NOVOMS -int -find_voms_cert(glite_renewal_core_context ctx, char *file, int *present) -{ - *present = 0; - return 0; -} - -#else -int -find_voms_cert(glite_renewal_core_context ctx, char *file, int *present) -{ - struct vomsdata *voms_info = NULL; - STACK_OF(X509) *chain = NULL; - EVP_PKEY *privkey = NULL; - X509 *cert = NULL; - int ret, err; - - *present = 0; - - voms_info = VOMS_Init(vomsdir, cadir); - if (voms_info == NULL) { - glite_renewal_log(ctx, LOG_ERR, "check_voms_cert(): Cannot initialize VOMS context (VOMS_Init() failed, probably voms dir was not specified)"); - return EDG_WLPR_ERROR_VOMS; - } - - ret = glite_renewal_load_proxy(ctx, file, &cert, &privkey, &chain, NULL); - if (ret) { - VOMS_Destroy(voms_info); - return ret; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err); - if (ret == 1) { - *present = 1; - } - - VOMS_Destroy(voms_info); - X509_free(cert); - EVP_PKEY_free(privkey); - sk_X509_pop_free(chain, X509_free); - return 0; -} -#endif - -void -register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - proxy_record record; - int ret; - FILE *meta_fd = NULL; - int last_suffix; - char *basename = NULL; - char filename[FILENAME_MAX]; - - assert(request != NULL); - assert(response != NULL); - - memset(&record, 0, sizeof(record)); - memset(response, 0, sizeof(*response)); - glite_renewal_log(ctx, LOG_DEBUG, "Registration request for %s", request->proxy_filename); - - if (request->proxy_filename == NULL || request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Registration request doesn't contain registration information"); - return; /* EINVAL; */ - } - umask(0177); - - ret = get_base_filename(ctx, request->proxy_filename, &basename); - if (ret) - goto end; - - ret = open_metafile(ctx, basename, &meta_fd); - if (ret) - goto end; - - if (voms_enabled) - ret = find_voms_cert(ctx, request->proxy_filename, &record.voms_exts); - /* ignore VOMS related error */ - - /* Find first free record */ - record.suffix = -1; - record.myproxy_server = strdup(request->myproxy_server); - ret = get_record_ext(ctx, meta_fd, &record, &last_suffix); - fclose(meta_fd); meta_fd = NULL; - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto end; - - if (ret == EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND || record.jobids.len == 0 || request->unique || record.voms_exts) { - /* create a new proxy file in the repository */ - int suffix; - - suffix = (record.jobids.len == 0 && record.suffix >= 0) ? - record.suffix : last_suffix + 1; - snprintf(filename, sizeof(filename), "%s.%d", basename, suffix); - ret = copy_file(ctx, request->proxy_filename, filename); - if (ret) - goto end; - ret = get_times(ctx, filename, &record); - if (ret) - goto end; - record.suffix = suffix; - ret = realloc_prd_list(ctx, &record.jobids); - if (ret) - goto end; - record.jobids.val[record.jobids.len - 1] = strdup(request->jobid); - record.unique = request->unique; - glite_renewal_log(ctx, LOG_DEBUG, "Created a new proxy file in repository (%s)", - filename); - } else { - ret = realloc_prd_list(ctx, &record.jobids); - if (ret) - goto end; - record.jobids.val[record.jobids.len - 1] = strdup(request->jobid); - snprintf(filename, sizeof(filename), "%s.%d", basename, record.suffix); - glite_renewal_log(ctx, LOG_DEBUG, "Inremented counter on %s", filename); - } - - ret = store_record(ctx, basename, &record); - -end: - if (meta_fd) { - fclose(meta_fd); - } - - if (basename) - free(basename); - - if (ret == 0) - ret = filename_to_response(ctx, filename, response); - record_to_response(ctx, ret, &record, response); - free_record(ctx, &record); -} - -void -unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - proxy_record record; - int ret, i, index; - FILE *meta_fd = NULL; - char *basename = NULL; - char *p; - struct stat stat_buf; - - memset(&record, 0, sizeof(record)); - glite_renewal_log(ctx, LOG_DEBUG, "Unregistration request for %s", request->jobid); - - if (request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Unregistration request doesn't contain needed information"); - ret = EINVAL; - goto end; - } - - if (request->proxy_filename == NULL) { - ret = find_proxyname(ctx, request->jobid, &request->proxy_filename); - if (ret) - goto end; - } - - ret = get_base_filename(ctx, request->proxy_filename, &basename); - if (ret) { - goto end; - } - - if (strncmp(request->proxy_filename, basename, strlen(basename) != 0)) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", - request->proxy_filename); - ret = EDG_WLPR_PROXY_NOT_REGISTERED; - goto end; - } - - p = strrchr(request->proxy_filename, '.'); - if (p == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", - request->proxy_filename); - ret = EDG_WLPR_PROXY_NOT_REGISTERED; - goto end; - } - - ret = edg_wlpr_DecodeInt(p+1, &record.suffix); - if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", - request->proxy_filename); - ret = EDG_WLPR_PROXY_NOT_REGISTERED; - goto end; - } - - ret = open_metafile(ctx, basename, &meta_fd); - if (ret) { - /* fill in error response */ - return; - } - - ret = get_record(ctx, meta_fd, &record); - if (ret) - goto end; - - ret = EDG_WLPR_PROXY_NOT_REGISTERED; - for (i = 0; i < record.jobids.len; i++) - if (strcmp(request->jobid, record.jobids.val[i]) == 0) { - ret = 0; - break; - } - if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not registered", - request->proxy_filename); - goto end; - } - - /* remove jobid from the list */ - index = i; - free(record.jobids.val[i]); - record.jobids.len--; - for (i = index; i < record.jobids.len; i++) - record.jobids.val[i] = record.jobids.val[i+1]; - - if (record.jobids.len == 0) { - record.unique = 0; - record.voms_exts = 0; - record.end_time = 0; - record.next_renewal = 0; - } - - ret = stat(request->proxy_filename, &stat_buf); - if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Cannot stat file %s: (%s)", - request->proxy_filename, strerror(errno)); - ret = errno; - goto end; - } - - ret = store_record(ctx, basename, &record); - if (ret) - goto end; - - if (record.jobids.len == 0) - unlink(request->proxy_filename); - -end: - if (meta_fd) { - fclose(meta_fd); - } - if (basename) - free(basename); - - if (ret == 0) - ret = filename_to_response(ctx, request->proxy_filename, response); - record_to_response(ctx, ret, &record, response); - free_record(ctx, &record); -} - -void -get_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - char *filename = NULL; - int ret; - - memset(response, 0, sizeof(*response)); - - glite_renewal_log(ctx, LOG_DEBUG, "GET request for %s", request->jobid); - - if (request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "GET request doesn't contain jobid specification"); - ret = EINVAL; - goto end; - } - - ret = find_proxyname(ctx, request->jobid, &filename); - -end: - if (ret == 0) - ret = filename_to_response(ctx, filename, response); - if (filename) - free(filename); - response->response_code = ret; -} - -void -update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response) -{ - FILE *fd = NULL; - int tmp_fd = -1; - int suffix = -1; - char tmp_file[FILENAME_MAX]; - char cur_proxy[FILENAME_MAX]; - char datafile[FILENAME_MAX]; - char line[1024]; - char *new_line = NULL; - char *basename, *proxy = NULL; - char **entry; - proxy_record record; - int ret; - char *p; - time_t current_time; - - memset(&record, 0, sizeof(record)); - - glite_renewal_log(ctx, LOG_DEBUG, "UPDATE_DB request for %s", request->proxy_filename); - - chdir(repository); - basename = request->proxy_filename; - - snprintf(datafile, sizeof(datafile), "%s.data", basename); - fd = fopen(datafile, "r"); - if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", - datafile, strerror(errno)); - ret = errno; - return; - } - - snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", datafile); - tmp_fd = mkstemp(tmp_file); - if (tmp_fd < 0) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); - ret = errno; - goto end; - } - - entry = request->entries; - if (entry) { - p = strchr(*entry, ':'); - *p = '\0'; - suffix = atoi(*entry); - proxy = p+1; - } - - current_time = time(NULL); - - while (fgets(line, sizeof(line), fd) != NULL) { - free_record(ctx, &record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(ctx, line, &record); - if (ret) - goto end; - - if (record.suffix > suffix && entry && *entry) { - do { - entry++; - if (entry == NULL || *entry == NULL) { - suffix = -1; - break; - } - - p = strchr(*entry, ':'); - suffix = atoi(*entry); - proxy = p+1; - } while (record.suffix > suffix); - } - - if (record.suffix == suffix) { - snprintf(cur_proxy, sizeof(cur_proxy), "%s.%d", basename, suffix); - if (proxy == NULL || *proxy == '\0') { - /* if proxy isn't specified use file registered currently and - * reschedule renewal */ - if (record.end_time < current_time) { - char *server; - /* remove file with expired proxy and clean the record in db */ - unlink(cur_proxy); - server = strdup(record.myproxy_server); - free_record(ctx, &record); - record.suffix = suffix; - record.myproxy_server = server; - glite_renewal_log(ctx, LOG_WARNING, "Removed expired proxy %s", cur_proxy); - } else - get_times(ctx, cur_proxy, &record); - } else { - ret = get_times(ctx, proxy, &record); - (ret == 0) ? rename(proxy, cur_proxy) : unlink(proxy); - } - } - - ret = encode_record(ctx, &record, &new_line); - if (ret) - goto end; - - dprintf(tmp_fd, "%s\n", new_line); - free(new_line); - new_line = NULL; - } - free_record(ctx, &record); - - close(tmp_fd); - fclose(fd); - - rename(tmp_file, datafile); - - return; - -end: - if (fd) - fclose(fd); - unlink(tmp_file); - if (tmp_fd > 0) - close(tmp_fd); - free_record(ctx, &record); - - return; -} diff --git a/org.glite.security.proxyrenewal/src/common.c b/org.glite.security.proxyrenewal/src/common.c deleted file mode 100644 index 206bc2f..0000000 --- a/org.glite.security.proxyrenewal/src/common.c +++ /dev/null @@ -1,322 +0,0 @@ -#include "renewal_locl.h" - -#ident "$Header$" - -/* nread() and nwrite() never return partial data */ -static int -nread(int sock, struct timeval *to, char *buf, size_t buf_len, size_t *read_len) -{ - int count; - size_t remain = buf_len; - char *cbuf = buf; - struct pollfd pollfds[1]; - struct timeval before,after; - int ret; - - if (to) { - gettimeofday(&before,NULL); - } - - while (remain > 0) { - pollfds[0].fd = sock; - pollfds[0].events = POLLIN; - switch (poll(pollfds, 1, to ? (to->tv_sec*1000+to->tv_usec/1000) : INFTIM)) { - case 0: - ret = EDG_WLPR_ERROR_TIMEOUT; - goto end; - case -1: - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - - count = read(sock, cbuf, remain); - if (count < 0) { - if (errno == EINTR) - continue; - else { - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - } else - if (count == 0) { - *read_len = 0; - return 0; - } - cbuf += count; - remain -= count; - } - *read_len = buf_len; - ret = 0; - -end: - if (to) { - gettimeofday(&after,NULL); - edg_wlpr_DecrementTimeout(to, before, after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - return ret; -} - -static int -nwrite(int sock, struct timeval *to, const char *buf, size_t buf_len) -{ - const char *cbuf = buf; - int count; - size_t remain = buf_len; - struct pollfd pollfds[1]; - struct timeval before,after; - int ret; - - if (to) { - gettimeofday(&before,NULL); - } - - while (remain > 0) { - pollfds[0].fd = sock; - pollfds[0].events = POLLOUT; - switch (poll(pollfds, 1, to ? (to->tv_sec*1000+to->tv_usec/1000) : INFTIM)) { - case 0: ret = EDG_WLPR_ERROR_TIMEOUT; - goto end; - case -1: ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - - count = write(sock, cbuf, remain); - if (count < 0) { - if (errno == EINTR) - continue; - else { - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - } - cbuf += count; - remain -= count; - } - ret = 0; - -end: - if (to) { - gettimeofday(&after,NULL); - edg_wlpr_DecrementTimeout(to, before, after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - return ret; -} - -int -edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len) -{ - int ret; - unsigned char length[4]; - size_t len; - - ret = nread(sock, timeout, length, 4, &len); - if (ret) { - *buf_len = 0; - return ret; - } - if (len != 4) { - *buf_len = 0; - return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX vraci i kdyz peer spadne a zavre trubku */ - } - *buf_len = (length[0] << 24) | - (length[1] << 16) | - (length[2] << 8 ) | - (length[3] << 0); - - *buf = malloc(*buf_len); - if (*buf == NULL) - return ENOMEM; - - ret = nread(sock, timeout, *buf, *buf_len, &len); - if (ret) - return ret; - - if (len != *buf_len) { - free(*buf); - *buf_len = 0; - return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX */ - } - - return 0; -} - -int -edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len) -{ - unsigned char length[4]; - int ret; - - length[0] = (buf_len >> 24) & 0xFF; - length[1] = (buf_len >> 16) & 0xFF; - length[2] = (buf_len >> 8) & 0xFF; - length[3] = (buf_len >> 0) & 0xFF; - - if ((ret = nwrite(sock, timeout, length, 4)) != 0 || - (ret = nwrite(sock, timeout, buf, buf_len)) != 0) - return ret; - - return 0; -} - -int -edg_wlpr_GetToken(const char *msg, const size_t msg_len, - const char *key, const char *separators, - int req_index, char **value) -{ - char *p; - size_t len; - int index; - - assert(separators != NULL); - - /* Add ending zero ? */ - - index = 0; - p = (char *)msg; - while (p && (p = strstr(p, key))) { - if (index == req_index) - break; - index++; - p += strlen(key); - } - if (p == NULL) - return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND; - - p = strchr(p, '='); - if (p == NULL) - return EDG_WLPR_ERROR_PROTO_PARSE_ERROR; - - len = strcspn(p+1, separators); - if (len == 0) - return EDG_WLPR_ERROR_PROTO_PARSE_ERROR; - - *value = malloc(len + 1); - if (*value == NULL) - return ENOMEM; - - memcpy(*value, p+1, len); - (*value)[len] = '\0'; - - return 0; -} - -int -edg_wlpr_StoreToken(char **buf, size_t *buf_len, char *command, - char *value, const char *separator) -{ - char line[2048]; - char *tmp; - - assert(buf != NULL); - assert(separator != NULL); - - if (strlen(command) + 1 + strlen(value) + 2 > sizeof(line)) - return ERANGE; /* XXX */ - - snprintf(line, sizeof(line), "%s%s%s", command, value, separator); - - while (strlen(*buf) + strlen(line) + 1 > *buf_len) { - tmp = realloc(*buf, *buf_len + EDG_WLPR_BUF_SIZE); - if (tmp == NULL) - return ENOMEM; - *buf = tmp; - *buf_len += EDG_WLPR_BUF_SIZE; - } - strcat(*buf, line); - - return 0; -} - -void -edg_wlpr_CleanRequest(edg_wlpr_Request *request) -{ - assert(request != NULL); - if (request->version) - free(request->version); - if (request->proxy_filename) - free(request->proxy_filename); - if (request->myproxy_server) - free(request->myproxy_server); - if (request->jobid) - free(request->jobid); - if (request->entries) { - char **p = request->entries; - char **next; - while (*p) { - next = p+1; - free(*p); - p = next; - } - free(request->entries); - } - - memset(request, 0, sizeof(request)); -} - -void -edg_wlpr_CleanResponse(edg_wlpr_Response *response) -{ - assert(response != NULL); - if (response->version) - free(response->version); - if (response->myproxy_server) - free(response->myproxy_server); - if (response->filenames) { - char **p = response->filenames; - char **next; - - while (*p) { - next = p+1; - free(*p); - p = next; - } - free(response->filenames); - } - memset(response, 0, sizeof(*response)); -} - -const char * -edg_wlpr_GetErrorString(int code) -{ - return (code == 0) ? "OK" : "Error"; -} - -char * -edg_wlpr_EncodeInt(int num) /* long? time */ -{ - static char ret[64]; - - snprintf(ret, sizeof(ret), "%d", num); - return ret; -} - -int -edg_wlpr_DecodeInt(char *str, int *num) -{ - *num = atol(str); /* XXX */ - return 0; -} - -int -edg_wlpr_DecrementTimeout(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); -} diff --git a/org.glite.security.proxyrenewal/src/renew.c b/org.glite.security.proxyrenewal/src/renew.c deleted file mode 100644 index 29105d2..0000000 --- a/org.glite.security.proxyrenewal/src/renew.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include "glite/security/voms/voms_apic.h" - -#ident "$Header$" - -#define RENEWAL_COUNTS_MAX 1000 /* the slave daemon exits after that many attemtps */ - -extern char *repository; -extern char *cadir; -extern char *vomsdir; -extern int voms_enabled; -static int received_signal = -1, die = 0; - -static void -check_renewal(glite_renewal_core_context ctx, char *datafile, int force_renew, int *num_renewed); - -static int -renew_proxy(glite_renewal_core_context ctx, proxy_record *record, char *basename, char **new_proxy); - -static void -register_signal(int signal); - -static void -register_signal(int signal) -{ - received_signal = signal; - switch ((received_signal = signal)) { - case SIGINT: - case SIGTERM: - case SIGQUIT: - die = signal; - break; - default: - break; - } -} - -static int -renew_proxy(glite_renewal_core_context ctx, proxy_record *record, char *basename, char **new_proxy) -{ - char repository_file[FILENAME_MAX]; - int ret = -1; - char *p = NULL; - char *server = NULL; - unsigned int port = 0; - - snprintf(repository_file, sizeof(repository_file),"%s.%d", - basename, record->suffix); - - if (record->myproxy_server) - server = strdup(record->myproxy_server); - - if (server && (p = strchr(server, ':'))) { - *p++ = '\0'; - ret = edg_wlpr_DecodeInt(p, &port); - } - - ret = glite_renewal_core_renew(ctx, server, port, repository_file, new_proxy); - if (ret) - goto end; - - ret = 0; - -end: - if (server) - free(server); - - return ret; -} - -static void -check_renewal(glite_renewal_core_context ctx, char *datafile, int force_renew, int *num_renewed) -{ - char line[1024]; - proxy_record record; - char *p; - int ret, i; - time_t current_time; - FILE *meta_fd = NULL; - char basename[FILENAME_MAX]; - edg_wlpr_Request request; - edg_wlpr_Response response; - char *new_proxy = NULL; - char *entry = NULL; - char **tmp; - int num = 0; - - assert(datafile != NULL); - - *num_renewed = 0; - - memset(&record, 0, sizeof(record)); - memset(basename, 0, sizeof(basename)); - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - strncpy(basename, datafile, sizeof(basename) - 1); - p = basename + strlen(basename) - strlen(".data"); - if (strcmp(p, ".data") != 0) { - glite_renewal_log(ctx, LOG_ERR, "Meta filename doesn't end with '.data'"); - return; - } - *p = '\0'; - - request.command = EDG_WLPR_COMMAND_UPDATE_DB; - request.proxy_filename = strdup(basename); - - meta_fd = fopen(datafile, "r"); - if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", - datafile, strerror(errno)); - return; - } - - current_time = time(NULL); - glite_renewal_log(ctx, LOG_DEBUG, "Reading metafile %s", datafile); - - while (fgets(line, sizeof(line), meta_fd) != NULL) { - free_record(ctx, &record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(ctx, line, &record); - if (ret) - continue; /* XXX exit? */ - if (record.jobids.len == 0) /* no jobid registered for this proxy */ - continue; - if (current_time + RENEWAL_CLOCK_SKEW >= record.end_time || - record.next_renewal <= current_time || - force_renew) { - ret = EDG_WLPR_PROXY_EXPIRED; - if ( record.end_time + RENEWAL_CLOCK_SKEW >= current_time) { - /* only try renewal if the proxy hasn't already expired */ - ret = renew_proxy(ctx, &record, basename, &new_proxy); - } - - /* if the proxy wasn't renewed have the daemon planned another renewal */ - asprintf(&entry, "%d:%s", record.suffix, (ret == 0) ? new_proxy : ""); - if (new_proxy) { - free(new_proxy); new_proxy = NULL; - } - - tmp = realloc(request.entries, (num + 2) * sizeof(*tmp)); - if (tmp == NULL) { - free_record(ctx, &record); - return; - } - request.entries = tmp; - request.entries[num] = entry; - request.entries[num+1] = NULL; - num++; - } - } - free_record(ctx, &record); - - if (num > 0) { - ret = edg_wlpr_RequestSend(&request, &response); - if (ret != 0) - glite_renewal_log(ctx, LOG_ERR, - "Failed to send update request to master (%d)", ret); - else if (response.response_code != 0) - glite_renewal_log(ctx, LOG_ERR, - "Master failed to update database (%d)", response.response_code); - - /* delete all tmp proxy files which may survive */ - for (i = 0; i < num; i++) { - p = strchr(request.entries[i], ':'); - if (p+1) - unlink(p+1); - } - } - fclose(meta_fd); - - edg_wlpr_CleanResponse(&response); - edg_wlpr_CleanRequest(&request); - - *num_renewed = num; - - return; -} - -int renewal(glite_renewal_core_context ctx, int force_renew, int *num_renewed) -{ - DIR *dir = NULL; - struct dirent *file; - FILE *fd; - int num = 0; - - glite_renewal_log(ctx, LOG_DEBUG, "Starting renewal process"); - - *num_renewed = 0; - - if (chdir(repository)) { - glite_renewal_log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", - repository, strerror(errno)); - return errno; - } - - dir = opendir(repository); - if (dir == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open repository directory %s (%s)", - repository, strerror(errno)); - return errno; - } - - while ((file = readdir(dir))) { - /* read files of format `md5sum`.data, where md5sum() is of fixed length - 32 chars */ - if (file->d_name == NULL || strlen(file->d_name) != 37 || - strcmp(file->d_name + 32, ".data") != 0) - continue; - fd = fopen(file->d_name, "r"); - if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", - file->d_name, strerror(errno)); - continue; - } - check_renewal(ctx, file->d_name, force_renew, &num); - *num_renewed += num; - fclose(fd); - } - closedir(dir); - glite_renewal_log(ctx, LOG_DEBUG, "Finishing renewal process"); - return 0; -} - -void -watchdog_start(glite_renewal_core_context ctx) -{ - struct sigaction sa; - int force_renewal; - int count = 0, num; - - memset(&sa,0,sizeof(sa)); - sa.sa_handler = register_signal; - sigaction(SIGUSR1, &sa, NULL); - sigaction(SIGINT,&sa,NULL); - sigaction(SIGQUIT,&sa,NULL); - sigaction(SIGTERM,&sa,NULL); - sigaction(SIGPIPE,&sa,NULL); - - while (count < RENEWAL_COUNTS_MAX && !die) { - received_signal = -1; - sleep(60 * 5); - force_renewal = (received_signal == SIGUSR1) ? 1 : 0; - if (die) - break; - /* XXX uninstall signal handler ? */ - renewal(ctx, force_renewal, &num); - count += num; - } - glite_renewal_log(ctx, LOG_DEBUG, "Terminating after %d renewal attempts", count); - exit(0); -} diff --git a/org.glite.security.proxyrenewal/src/renewal_core.c b/org.glite.security.proxyrenewal/src/renewal_core.c deleted file mode 100644 index 3bd2d1d..0000000 --- a/org.glite.security.proxyrenewal/src/renewal_core.c +++ /dev/null @@ -1,283 +0,0 @@ -#include -#include - -#include "renewal_core.h" -#include "renewal_locl.h" -#include "renewd_locl.h" - -static const char rcsid[] = "$Id$"; - -int -glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *cur_file, X509 **cert, EVP_PKEY **priv_key, - STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy) -{ - globus_result_t result; - globus_gsi_cred_handle_t proxy = NULL; - int ret; - - result = globus_gsi_cred_handle_init(&proxy, NULL); - if (result) { - fprintf(stderr, "globus_gsi_cred_handle_init() failed\n"); - goto end; - } - - result = globus_gsi_cred_read_proxy(proxy, (char *) cur_file); - if (result) { - fprintf(stderr, "globus_gsi_cred_read_proxy() failed\n"); - goto end; - } - - if (cert) { - result = globus_gsi_cred_get_cert(proxy, cert); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert() failed\n"); - goto end; - } - } - - if (priv_key) { - result = globus_gsi_cred_get_key(proxy, priv_key); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_key() failed\n"); - goto end; - } - } - - if (chain) { - result = globus_gsi_cred_get_cert_chain(proxy, chain); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert_chain() failed\n"); - goto end; - } - } - - if (cur_proxy) { - *cur_proxy = proxy; - proxy = NULL; - } - - ret = 0; - -end: - if (proxy) - globus_gsi_cred_handle_destroy(proxy); - if (result) - ret = EDG_WLPR_ERROR_GENERIC; - - return ret; -} - -int -glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **name) -{ - X509 *cert = NULL; - EVP_PKEY *key = NULL; - STACK_OF(X509) *chain = NULL; - X509_NAME *subject = NULL; - int ret; - globus_result_t result; - - ret = glite_renewal_load_proxy(ctx, file, &cert, &key, &chain, NULL); - if (ret) - return ret; - - subject = X509_NAME_dup(X509_get_subject_name(cert)); - - sk_X509_insert(chain, cert, 0); - cert = NULL; - - result = globus_gsi_cert_utils_get_base_name(subject, chain); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "Cannot get subject name from proxy %s", file); - ret = EDG_WLPR_ERROR_SSL; /* XXX ??? */ - goto end; - } - - *name = X509_NAME_oneline(subject, NULL, 0); - ret = 0; - -end: - if (cert) - X509_free(cert); - if (key) - EVP_PKEY_free(key); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (subject) - X509_NAME_free(subject); - - return ret; -} - -int -glite_renewal_core_renew(glite_renewal_core_context ctx, - const char * myproxy_server, - unsigned int myproxy_port, - const char *current_proxy, - char **new_proxy) -{ - char tmp_proxy[FILENAME_MAX]; - int tmp_fd; - int ret = -1; - char *p; - const char *server = NULL; - myproxy_socket_attrs_t *socket_attrs; - myproxy_request_t *client_request; - myproxy_response_t *server_response; - char *renewed_proxy; - int voms_exts; - - socket_attrs = malloc(sizeof(*socket_attrs)); - memset(socket_attrs, 0, sizeof(*socket_attrs)); - - client_request = malloc(sizeof(*client_request)); - memset(client_request, 0, sizeof(*client_request)); - - server_response = malloc(sizeof(*server_response)); - memset(server_response, 0, sizeof(*server_response)); - - myproxy_set_delegation_defaults(socket_attrs, client_request); - - glite_renewal_log(ctx, LOG_DEBUG, "Trying to renew proxy in %s", current_proxy); - - snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.myproxy.XXXXXX", current_proxy); - tmp_fd = mkstemp(tmp_proxy); - if (tmp_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); - return errno; - } - - ret = glite_renewal_get_proxy_base_name(ctx, current_proxy, &client_request->username); - if (ret) - goto end; - - voms_exts = glite_renewal_check_voms_attrs(ctx, current_proxy); - - client_request->proxy_lifetime = 60 * 60 * DGPR_RETRIEVE_DEFAULT_HOURS; - - server = (myproxy_server) ? myproxy_server : socket_attrs->pshost; - if (server == NULL) { - glite_renewal_log(ctx, LOG_ERR, "No myproxy server specified"); - ret = EINVAL; - goto end; - } - socket_attrs->pshost = strdup(server); - - socket_attrs->psport = (myproxy_port) ? myproxy_port : MYPROXY_SERVER_PORT; - - verror_clear(); - ret = myproxy_get_delegation(socket_attrs, client_request, (char *) current_proxy, - server_response, tmp_proxy); - if (ret == 1) { - ret = EDG_WLPR_ERROR_MYPROXY; - glite_renewal_log(ctx, LOG_ERR, "Error contacting MyProxy server for proxy %s: %s", - current_proxy, verror_get_string()); - verror_clear(); - goto end; - } - - renewed_proxy = tmp_proxy; - - if (voms_exts) { - char tmp_voms_proxy[FILENAME_MAX]; - int tmp_voms_fd; - - snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.voms.XXXXXX", - current_proxy); - tmp_voms_fd = mkstemp(tmp_voms_proxy); - if (tmp_voms_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); - ret = errno; - goto end; - } - - ret = glite_renewal_renew_voms_creds(ctx, current_proxy, renewed_proxy, tmp_voms_proxy); - close(tmp_voms_fd); - if (ret) { - unlink(tmp_voms_proxy); - goto end; - } - - renewed_proxy = tmp_voms_proxy; - unlink(tmp_proxy); - } - - if (new_proxy) - *new_proxy = strdup(renewed_proxy); - - ret = 0; - -end: - if (socket_attrs->socket_fd) - close(socket_attrs->socket_fd); - close(tmp_fd); - if (ret) - unlink(tmp_proxy); - myproxy_free(socket_attrs, client_request, server_response); - - return ret; -} - -int -glite_renewal_core_init_ctx(glite_renewal_core_context *context) -{ - glite_renewal_core_context p = NULL; - - *context = NULL; - - p = calloc(1, sizeof(*p)); - if (p == NULL) - return ENOMEM; - - p->log_level = LOG_ERR; - p->log_dst = GLITE_RENEWAL_LOG_SYSLOG; - - *context = p; - return 0; -} - -int -glite_renewal_core_destroy_ctx(glite_renewal_core_context context) -{ - if (context == NULL) - return 0; - if (context->err_message); - free(context->err_message); - free(context); - return 0; -} - -void -glite_renewal_log(glite_renewal_core_context context, int dbg_level, const char *format, ...) -{ - va_list ap; - - if (context->err_message) { - free(context->err_message); - context->err_message = NULL; - } - - /* cannot handle the %m format argument specific for syslog() */ - va_start(ap, format); - vasprintf(&context->err_message, format, ap); - va_end(ap); - - if (dbg_level > context->log_level) - return; - - switch (context->log_dst) { - case GLITE_RENEWAL_LOG_STDOUT: - printf("%s\n", context->err_message); - break; - case GLITE_RENEWAL_LOG_SYSLOG: - syslog(dbg_level, "%s", context->err_message); - break; - case GLITE_RENEWAL_LOG_NONE: - default: - break; - } - - return; -} diff --git a/org.glite.security.proxyrenewal/src/renewal_locl.h b/org.glite.security.proxyrenewal/src/renewal_locl.h deleted file mode 100644 index 256eb26..0000000 --- a/org.glite.security.proxyrenewal/src/renewal_locl.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef RENEWAL_LOCL_H -#define RENEWAL_LOCL_H - -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef INFTIM -#define INFTIM (-1) -#endif - -#include -#include -#include -#include - -#include "renewal.h" - -#define JDL_MYPROXY "Myproxy_server=" - -typedef enum { - EDG_WLPR_COMMAND_NONE = 0, - EDG_WLPR_COMMAND_REG = 1, - EDG_WLPR_COMMAND_UNREG, - EDG_WLPR_COMMAND_GET, - EDG_WLPR_COMMAND_LIST, - EDG_WLPR_COMMAND_STATUS, - EDG_WLPR_COMMAND_UPDATE_DB, -} edg_wlpr_Command; - -/* prefix neni nutny */ -#define EDG_WLPR_PROTO_VERSION "Version=" -#define EDG_WLPR_PROTO_COMMAND "Command=" -#define EDG_WLPR_PROTO_MYPROXY_SERVER "Myproxy_server=" -#define EDG_WLPR_PROTO_PROXY "Proxy_name=" -#define EDG_WLPR_PROTO_UNIQUE_PROXY "Unique=" /* XXX */ -#define EDG_WLPR_PROTO_JOBID "Jobid=" -#define EDG_WLPR_PROTO_ENTRY "Entry=" - -#define EDG_WLPR_PROTO_RESPONSE "Response=" /* XXX result ?? */ -#define EDG_WLPR_PROTO_START_TIME "Start_time=" -#define EDG_WLPR_PROTO_END_TIME "End_time=" -#define EDG_WLPR_PROTO_RENEWAL_TIME "Renewal_time=" /* XXX Next renewal ?? */ - -#define EDG_WLPR_MYPROXY_PORT 7512 - -#define EDG_WLPR_REPOSITORY_ROOT "/var/spool/edg-wl-renewd" - -#define EDG_WLPR_BUF_SIZE 4096 - -#define EDG_WLPR_VERSION "EDG Proxy Renewal 1.0" - -#define MAX_PROXIES 4 /* max. number of jobids sharing one proxy */ - -#define RENEWAL_CLOCK_SKEW (5 * 60) - -#define DGPR_RETRIEVE_DEFAULT_HOURS 10 - -#define GLITE_PR_TIMEOUT_DEFAULT 120 - -typedef struct { - char *version; - edg_wlpr_Command command; - char *myproxy_server; - char *proxy_filename; - int unique; - char *jobid; - char **entries; /* for updates from the renewal part (renew.c) */ -} edg_wlpr_Request; - -typedef struct { - char *version; - int response_code; - time_t start_time; - time_t end_time; - time_t next_renewal_time; - int counter; - char *myproxy_server; - char **filenames; -} edg_wlpr_Response; - -#define DGPR_REG_SOCKET_NAME_ROOT "/tmp/dgpr_renew_" - -#if 0 -/* Errors: */ -/* XXX enum */ -#define EDG_WLPR_ERROR_EOF 1 -#define EDG_WLPR_ERROR_PARSE_NOT_FOUND 2 -#define EDG_WLPR_ERROR_PARSE_ERROR 3 -#define EDG_WLPR_ERROR_UNKNOWN_COMMAND 4 -#define EDG_WLPR_ERROR_NOTFOUND 5 -#endif - -int -edg_wlpr_GetToken(const char *msg, const size_t msg_len, - const char *key, const char *separators, - int req_index, char **value); - -int -edg_wlpr_StoreToken(char **buf, size_t *buf_len, char *command, - char *value, const char *separator); - -int -edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len); - -int -edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len); - -void -edg_wlpr_CleanRequest(edg_wlpr_Request *request); - -void -edg_wlpr_CleanResponse(edg_wlpr_Response *response); - -const char * -edg_wlpr_GetErrorString(int err); - -char * -edg_wlpr_EncodeInt(int num); /* long? time */ - -int -edg_wlpr_DecodeInt(char *str, int *num); - -int -edg_wlpr_RequestSend(edg_wlpr_Request *request, edg_wlpr_Response *response); - -int -edg_wlpr_DecrementTimeout(struct timeval *timeout, struct timeval before, struct timeval after); - -#endif /* RENEWAL_LOCL_H */ diff --git a/org.glite.security.proxyrenewal/src/renewd.c b/org.glite.security.proxyrenewal/src/renewd.c deleted file mode 100644 index 3c8512c..0000000 --- a/org.glite.security.proxyrenewal/src/renewd.c +++ /dev/null @@ -1,609 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -static const char rcsid[] = "$Header$"; - -#define SEPARATORS "\n" -/* GRIDMANAGER_CHECKPROXY_INTERVAL + GRIDMANAGER_MINIMUM_PROXY_TIME */ -#define CONDOR_MINIMUM_PROXY_TIME (1800) - -int debug = 0; -char *repository = NULL; -time_t condor_limit = CONDOR_MINIMUM_PROXY_TIME; -char *cadir = NULL; -char *vomsdir = NULL; -int voms_enabled = 0; -char *cert = NULL; -char *key = NULL; -char *vomsconf = NULL; - -static volatile int die = 0, child_died = 0; -double default_timeout = 0; - -static struct option opts[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' }, - { "debug", no_argument, NULL, 'd' }, - { "repository", required_argument, NULL, 'r' }, - { "condor-limit", required_argument, NULL, 'c' }, - { "CAdir", required_argument, NULL, 'C' }, - { "VOMSdir", required_argument, NULL, 'V' }, - { "enable-voms", no_argument, NULL, 'A' }, - { "voms-config", required_argument, NULL, 'G' }, - { "cert", required_argument, NULL, 't' }, - { "key", required_argument, NULL, 'k' }, - { NULL, 0, NULL, 0 } -}; - -typedef struct { - edg_wlpr_Command code; - void (*handler) (glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response); -} command_table; - -static command_table commands[] = { - { EDG_WLPR_COMMAND_REG, register_proxy, }, - { EDG_WLPR_COMMAND_UNREG, unregister_proxy, }, - { EDG_WLPR_COMMAND_GET, get_proxy, }, -#if 0 - { EDG_WLPR_COMMAND_LIST, list_proxies, }, - { EDG_WLPR_COMMAND_STATUS, status_proxy, }, -#endif - { EDG_WLPR_COMMAND_UPDATE_DB, update_db, }, - { 0, NULL }, -}; - -/* static prototypes */ -static void -usage(glite_renewal_core_context ctx, char *progname); - -static int -do_listen(glite_renewal_core_context ctx, char *socket_name, int *sock); - -static int -encode_response(glite_renewal_core_context ctx, edg_wlpr_Response *response, char **msg); - -static command_table * -find_command(glite_renewal_core_context ctx, edg_wlpr_Command code); - -static int -proto(glite_renewal_core_context ctx, int sock); - -static int -doit(glite_renewal_core_context ctx, int sock); - -static int -decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg_len, edg_wlpr_Request *request); - -int -start_watchdog(glite_renewal_core_context ctx, pid_t *pid); - -static void -catchsig(int sig) -{ - switch (sig) { - case SIGINT: - case SIGTERM: - case SIGQUIT: - die = sig; - break; - case SIGCHLD: - child_died = 1; - break; - default: - break; - } -} - -static command_table * -find_command(glite_renewal_core_context ctx, edg_wlpr_Command code) -{ - command_table *c; - - for (c = commands; c->code; c++) { - if (c->code == code) - return c; - } - return NULL; -} - -static int -proto(glite_renewal_core_context ctx, int sock) -{ - char *buf = NULL; - size_t buf_len; - int ret; - edg_wlpr_Response response; - edg_wlpr_Request request; - command_table *command; - struct timeval timeout; - - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - timeout.tv_sec = (long) default_timeout; - timeout.tv_usec = (long) ((default_timeout - timeout.tv_sec) * 1e6); - - ret = edg_wlpr_Read(sock, &timeout, &buf, &buf_len); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Error reading from client: %s", - edg_wlpr_GetErrorString(ret)); - return ret; - } - - ret = decode_request(ctx, buf, buf_len, &request); - free(buf); - if (ret) - goto end; - - /* XXX check request (protocol version, ...) */ - - command = find_command(ctx, request.command); - if (command == NULL) { - ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND; - glite_renewal_log(ctx, LOG_ERR, "Received unknown command (%d)", request.command); - goto end; - } - - glite_renewal_log(ctx, LOG_INFO, "Received command code %d for proxy %s and jobid %s", - request.command, - request.proxy_filename ? request.proxy_filename : "(unspecified)", - request.jobid ? request.jobid : "(unspecified)"); - - command->handler(ctx, &request, &response); - - ret = encode_response(ctx, &response, &buf); - if (ret) - goto end; - - ret = edg_wlpr_Write(sock, &timeout, buf, strlen(buf) + 1); - free(buf); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Error sending response to client: %s", - edg_wlpr_GetErrorString(ret)); - goto end; - } - -end: - edg_wlpr_CleanRequest(&request); - edg_wlpr_CleanResponse(&response); - - return ret; -} - -static int -doit(glite_renewal_core_context ctx, int sock) -{ - int newsock; - struct sockaddr_un client_addr; - int client_addr_len = sizeof(client_addr); - int flags; - - while (!die) { - - if (child_died) { - int pid, newpid, ret; - - while ((pid=waitpid(-1,NULL,WNOHANG))>0) - ; - ret = start_watchdog(ctx, &newpid); - if (ret) - return ret; - glite_renewal_log(ctx, LOG_DEBUG, "Renewal slave process re-started"); - child_died = 0; - continue; - } - - newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len); - if (newsock == -1) { - if (errno != EINTR) - glite_renewal_log(ctx, LOG_ERR, "accept() failed"); - continue; - } - glite_renewal_log(ctx, LOG_DEBUG, "Got connection"); - - flags = fcntl(newsock, F_GETFL, 0); - if (fcntl(newsock, F_SETFL, flags | O_NONBLOCK) < 0) { - glite_renewal_log(ctx, LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n", - strerror(errno)); - close(newsock); - continue; - } - - proto(ctx, newsock); - - glite_renewal_log(ctx, LOG_DEBUG, "Connection closed"); - close(newsock); - } - glite_renewal_log(ctx, LOG_DEBUG, "Terminating on signal %d\n",die); - return 0; -} - -static int -decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg_len, edg_wlpr_Request *request) -{ - char *value = NULL; -#if 0 - char *p; - int port; -#endif - int ret; - int index; - - /* XXX add an ending zero '\0' */ - - assert(msg != NULL); - assert(request != NULL); - - memset(request, 0, sizeof(*request)); - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_VERSION, SEPARATORS, - 0, &request->version); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading protocol specification: %s", - edg_wlpr_GetErrorString(ret)); - return ret; - } - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_COMMAND, SEPARATORS, - 0, &value); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading command specification: %s", - edg_wlpr_GetErrorString(ret)); - goto err; - } - - ret = edg_wlpr_DecodeInt(value, (int *)(&request->command)); - if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Received non-numeric command specification (%s)", - value); - free(value); - goto err; - } - free(value); - - if (find_command(ctx, request->command) == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Received unknown command (%d)", request->command); - ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND; - goto err; - } - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_MYPROXY_SERVER, - SEPARATORS, 0, &request->myproxy_server); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading myproxy server specification: %s", - edg_wlpr_GetErrorString(ret)); - goto err; - } - -#if 0 - request->myproxy_port = EDG_WLPR_MYPROXY_PORT; /* ??? */ - if (request->myproxy_server && (p = strchr(request->myproxy_server, ':'))) { - *p = '\0'; - port = atol(p+1); /* XXX see myproxy for err check */ - request->myproxy_port = port; - } -#endif - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_PROXY, SEPARATORS, - 0, &request->proxy_filename); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading proxy specification: %s", - edg_wlpr_GetErrorString(ret)); - goto err; - } - -#if 0 - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_UNIQUE_PROXY, - SEPARATORS, 0, &value); - if (ret && ret != EDG_WLPR_ERROR_PARSE_NOT_FOUND) - goto err; - if (ret == 0 && strcasecmp(value, "yes") == 0) - request->unique = 1; - free(value); -#endif - - ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_JOBID, SEPARATORS, - 0, &request->jobid); - if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading JobId : %s", - edg_wlpr_GetErrorString(ret)); - goto err; - } - - index = 0; - while ((ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_ENTRY, - SEPARATORS, index, &value)) == 0) { - char **tmp; - - tmp = realloc(request->entries, (index + 2) * sizeof(*tmp)); - if (tmp == NULL) { - ret = ENOMEM; - goto err; - } - request->entries = tmp; - request->entries[index] = value; - index++; - } - if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) - goto err; - if (request->entries) - request->entries[index] = NULL; - - return 0; - -err: - edg_wlpr_CleanRequest(request); - return ret; -} - -static int -encode_response(glite_renewal_core_context ctx, edg_wlpr_Response *response, char **msg) -{ - char *buf; - size_t buf_len; - int ret; - - buf_len = EDG_WLPR_BUF_SIZE; - buf = malloc(buf_len); - if (buf == NULL) - return ENOMEM; - buf[0] = '\0'; - - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_VERSION, - EDG_WLPR_VERSION, SEPARATORS); - if (ret) - goto err; - - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_RESPONSE, - edg_wlpr_EncodeInt(response->response_code), - SEPARATORS); - if (ret) - goto err; - - if (response->myproxy_server) { - char host[1024]; - -#if 0 - snprintf(host, sizeof(host), "%s:%d", response->myproxy_server, - (response->myproxy_port) ? response->myproxy_port : EDG_WLPR_MYPROXY_PORT); -#endif - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_MYPROXY_SERVER, - host, SEPARATORS); - if (ret) - goto err; - } - - if (response->start_time) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_START_TIME, - edg_wlpr_EncodeInt(response->start_time), - SEPARATORS); - if (ret) - goto err; - } - - if (response->end_time) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_END_TIME, - edg_wlpr_EncodeInt(response->end_time), - SEPARATORS); - if (ret) - goto err; - } - - if (response->next_renewal_time) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_RENEWAL_TIME, - edg_wlpr_EncodeInt(response->next_renewal_time), - SEPARATORS); - if (ret) - goto err; - } - - if (response->filenames) { - char **p = response->filenames; - while (*p) { - ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_PROXY, *p, - SEPARATORS); - if (ret) - goto err; - p++; - } - } - - buf[strlen(buf)] = '\0'; - *msg = buf; - return 0; - -err: - free(buf); - *msg = NULL; - return ret; -} - - -static void -usage(glite_renewal_core_context ctx, char *progname) -{ - fprintf(stderr,"usage: %s [option]\n" - "\t-h, --help display this help and exit\n" - "\t-v, --version output version information and exit\n" - "\t-d, --debug don't fork, print out debugging information\n" - "\t-r, --repository repository directory\n" - "\t-c, --condor-limit how long before expiration the proxy must be renewed\n" - "\t-C, --CAdir trusted certificates directory\n" - "\t-V, --VOMSdir trusted VOMS servers certificates directory\n" - "\t-A, --enable-voms renew also VOMS certificates in proxies\n" - "\t-G, --voms-config location of the vomses configuration file\n", - progname); -} - -static int -do_listen(glite_renewal_core_context ctx, char *socket_name, int *sock) -{ - struct sockaddr_un my_addr; - int s; - int ret; - - assert(sock != NULL); - - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sun_family = AF_UNIX; - strncpy(my_addr.sun_path, socket_name, sizeof(my_addr.sun_path)); - unlink(socket_name); - umask(0177); - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - glite_renewal_log(ctx, LOG_ERR, "socket(): %s", strerror(errno)); - return errno; - } - - ret = bind(s, (struct sockaddr *)&my_addr, sizeof(my_addr)); - if (ret == -1) { - glite_renewal_log(ctx, LOG_ERR, "bind(): %s", strerror(errno)); - close(s); - return errno; - } - - ret = listen(s, 50); - if (ret == -1) { - glite_renewal_log(ctx, LOG_ERR, "listen(): %s", strerror(errno)); - close(s); - return errno; - } - - *sock = s; - return 0; -} - -int -start_watchdog(glite_renewal_core_context ctx, pid_t *pid) -{ - pid_t p; - - switch ((p = fork())) { - case -1: - glite_renewal_log(ctx, LOG_ERR, "fork() failed: %s", - strerror(errno)); - return errno; - case 0: - watchdog_start(ctx); - exit(0); - break; - default: - *pid = p; - return 0; - } - /* not reachable */ - exit(0); -} - -int main(int argc, char *argv[]) -{ - int sock; - char *progname; - int opt; - int fd; - char sockname[PATH_MAX]; - int ret; - pid_t pid; - struct sigaction sa; - const char *s = NULL; - glite_renewal_core_context ctx = NULL; - - progname = strrchr(argv[0],'/'); - if (progname) progname++; - else progname = argv[0]; - - repository = EDG_WLPR_REPOSITORY_ROOT; - debug = 0; - - while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:t:k:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(ctx, progname); exit(0); - case 'v': fprintf(stdout, "%s:\t%s\n", progname, rcsid); exit(0); - case 'd': debug = 1; break; - case 'r': repository = optarg; break; - case 'c': condor_limit = atoi(optarg); break; - case 'C': cadir = optarg; break; - case 'V': vomsdir = optarg; break; - case 'A': voms_enabled = 1; break; - case 'G': vomsconf = optarg; break; - case 't': cert = optarg; break; - case 'k': key = optarg; break; - case '?': usage(ctx, progname); return 1; - } - - if (optind < argc) { - usage(ctx, progname); - exit(1); - } - - ret = glite_renewal_core_init_ctx(&ctx); - if (ret) { - fprintf(stderr, "Cannot initialize context\n"); - exit(1); - } - if (debug) { - ctx->log_level = LOG_DEBUG; - ctx->log_dst = GLITE_RENEWAL_LOG_STDOUT; - } - ctx->voms_conf = vomsconf; - - if (chdir(repository)) { - glite_renewal_log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", - repository, strerror(errno)); - exit(1); - } - - globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE); - globus_module_activate(GLOBUS_GSI_PROXY_MODULE); - - if (!debug) - for (fd = 3; fd < OPEN_MAX; fd++) close(fd); - - if (!debug) { - /* chdir ? */ - if (daemon(1,0) == -1) { - perror("deamon()"); - exit(1); - } - openlog(progname, LOG_PID, LOG_DAEMON); - } - - if (cert) - setenv("X509_USER_CERT", cert, 1); - - if (key) - setenv("X509_USER_KEY", key, 1); - - if (cadir) - setenv("X509_CERT_DIR", cadir, 1); - - s = getenv("GLITE_PR_TIMEOUT"); - default_timeout = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT; - - memset(&sa,0,sizeof(sa)); - sa.sa_handler = catchsig; - sigaction(SIGINT,&sa,NULL); - sigaction(SIGQUIT,&sa,NULL); - sigaction(SIGTERM,&sa,NULL); - sigaction(SIGCHLD,&sa,NULL); - sigaction(SIGPIPE,&sa,NULL); - - ret = start_watchdog(ctx, &pid); - if (ret) - return 1; - - umask(0177); - snprintf(sockname, sizeof(sockname), "%s%d", - DGPR_REG_SOCKET_NAME_ROOT, getuid()); - /* XXX check that the socket is not already active */ - ret = do_listen(ctx, sockname, &sock); - if (ret) - return 1; - glite_renewal_log(ctx, LOG_DEBUG, "Listening at %s", sockname); - - ret = doit(ctx, sock); - - close(sock); - return ret; -} diff --git a/org.glite.security.proxyrenewal/src/renewd_locl.h b/org.glite.security.proxyrenewal/src/renewd_locl.h deleted file mode 100644 index 489e909..0000000 --- a/org.glite.security.proxyrenewal/src/renewd_locl.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef RENEWALD_LOCL_H -#define RENEWALD_LOCL_H - -#ident "$Header$" - -#include -#include -#include - -#include "renewal.h" -#include "renewal_core.h" - -#ifdef HAVE_DMALLOC_H -#include -#endif - -/* XXX */ -#if 0 -#define EDG_WLPR_ERROR_PARSE_NOT_FOUND EDG_WLPR_ERROR_PROTO_PARSE_ERROR -#define EDG_WLPR_ERROR_NOTFOUND EDG_WLPR_PROXY_NOT_REGISTERED -#endif - -typedef struct { - unsigned int len; - char **val; -} prd_list; - -typedef struct { - int suffix; - prd_list jobids; - int unique; - int voms_exts; - char *myproxy_server; - time_t end_time; - time_t next_renewal; -} proxy_record; - -/* commands */ -void -register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response); - -void -unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response); - -void -get_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response); - -void -update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response); - -int -get_times(glite_renewal_core_context ctx, char *proxy_file, proxy_record *record); - -void -watchdog_start(glite_renewal_core_context ctx); - -void -glite_renewal_log(glite_renewal_core_context ctx, int dbg_level, const char *format, ...); - -int -decode_record(glite_renewal_core_context ctx, char *line, proxy_record *record); - -int -encode_record(glite_renewal_core_context ctx, proxy_record *record, char **line); - -void -free_record(glite_renewal_core_context ctx, proxy_record *record); - -int -glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *filename, X509 **cert, EVP_PKEY **privkey, - STACK_OF(X509) **chain, globus_gsi_cred_handle_t *proxy); - -int -glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **subject); - -int -glite_renewal_renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file); - -int -glite_renewal_check_voms_attrs(glite_renewal_core_context ctx, const char *proxy); - -#endif /* RENEWALD_LOCL_H */ diff --git a/org.glite.security.proxyrenewal/src/voms.c b/org.glite.security.proxyrenewal/src/voms.c deleted file mode 100644 index 687d93b..0000000 --- a/org.glite.security.proxyrenewal/src/voms.c +++ /dev/null @@ -1,356 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include -#include - -#include "glite/security/voms/voms_apic.h" - -#include "glite/security/voms/newformat.h" - -char * Decode(const char *, int, int *); -char **listadd(char **, char *, int); - -static int -generate_proxy(glite_renewal_core_context ctx, globus_gsi_cred_handle_t cur_proxy, - X509_EXTENSION *voms_extension, const char *new_file) -{ - globus_result_t result; - globus_gsi_proxy_handle_t proxy_handle = NULL; - globus_gsi_cred_handle_t proxy = NULL; - EVP_PKEY *cur_proxy_priv_key = NULL; - X509 *new_cert = NULL; - X509 *voms_cert = NULL; - globus_gsi_cert_utils_cert_type_t proxy_type; - - result = globus_gsi_proxy_handle_init(&proxy_handle, NULL); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); - goto end; - } - - result = globus_gsi_cred_get_key(cur_proxy, &cur_proxy_priv_key); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_key() failed\n"); - goto end; - } - - /* Create and sign a new proxy */ - result = globus_gsi_cred_get_cert_type(cur_proxy, &proxy_type); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_cert_type() failed\n"); - goto end; - } - - result = globus_gsi_proxy_handle_set_type(proxy_handle, proxy_type); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_set_type() failed\n"); - goto end; - } - - result = globus_gsi_proxy_create_signed(proxy_handle, cur_proxy, &proxy); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); - goto end; - } - - /* Get the new proxy */ - result = globus_gsi_cred_get_cert(proxy, &new_cert); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_cert() failed\n"); - goto end; - } - - /* The Globus API doesn't allow to store custom X.509 extensions */ - voms_cert = X509_dup(new_cert); - if (voms_cert->cert_info->extensions == NULL) - voms_cert->cert_info->extensions = sk_X509_EXTENSION_new_null(); - sk_X509_EXTENSION_push(voms_cert->cert_info->extensions, voms_extension); - - /* Openssl ensures that memory containing old signature structures is unallocated */ -#if 0 - X509_sign(voms_cert, cur_proxy_priv_key, proxy_handle->attrs->signing_algorithm); -#else - X509_sign(voms_cert, cur_proxy_priv_key, EVP_md5()); -#endif - - /* And put the cert back, older one is unallocated by the function */ - result = globus_gsi_cred_set_cert(proxy, voms_cert); - if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_set_cert() failed\n"); - goto end; - } - - result = globus_gsi_cred_write_proxy(proxy, (char *)new_file); - -end: - - return 0; -} - -static int -my_VOMS_Export(glite_renewal_core_context ctx, void *buf, int buf_len, X509_EXTENSION **extension) -{ - AC *ac = NULL; - unsigned char *p, *pp; - AC **voms_attrs = NULL; - - p = pp = buf; - ac = d2i_AC(NULL, &p, buf_len+1); - if (ac == NULL) { - glite_renewal_log(ctx, LOG_ERR, "d2i_AC() failed\n"); - return 1; - } - - voms_attrs = (AC **)listadd((char **)voms_attrs, (char *)ac, sizeof(AC *)); - - *extension = X509V3_EXT_conf_nid(NULL, NULL, OBJ_txt2nid("acseq"), - (char*)voms_attrs); - return 0; -} - -static int -create_voms_command(glite_renewal_core_context ctx, struct vomsdata *vd, struct voms **voms_cert, char **command) -{ - int voms_error, ret; - struct data **attribs; - -#if 0 - VOMS_ResetOrder(vd, &voms_error); - for (i = 2; i < argc; i++) { - ret = VOMS_Ordering(argv[i], vd, &voms_error); - if (ret == 0) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Ordering() failed\n"); - return 1; - } - } -#endif - - if (voms_cert == NULL || *voms_cert == NULL || (*voms_cert)->std == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Invalid VOMS certificate\n"); - return 1; - } - - attribs = (*voms_cert)->std; - - if (strcmp (attribs[0]->role, "NULL") == 0 ) - ret = asprintf(command, "G%s", attribs[0]->group); - else - ret = asprintf(command, "B%s:%s", attribs[0]->group, attribs[0]->role); - -end: - - return 0; -} - -static int -renew_voms_cert(glite_renewal_core_context ctx, struct vomsdata *vd, struct voms **voms_cert, - char **buf, size_t *buf_len) -{ - int voms_error = 0, i, ret, voms_version; - struct contactdata **voms_contacts = NULL; - char *command = NULL; - - voms_contacts = VOMS_FindByVO(vd, (*voms_cert)->voname, ctx->voms_conf, NULL, &voms_error); - - if (voms_contacts == NULL) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_FindByVO() failed\n"); - return 1; - } - - ret = create_voms_command(ctx, vd, voms_cert, &command); - - /* XXX the lifetime should be taken from the older proxy */ - ret = VOMS_SetLifetime(60*60*12, vd, &voms_error); - - /* XXX iterate over all servers on the list on errors */ - ret = VOMS_ContactRaw(voms_contacts[0]->host, voms_contacts[0]->port, - voms_contacts[0]->contact, command, - (void**) buf, buf_len, &voms_version, - vd, &voms_error); - if (ret == 0) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Contact() failed\n"); - return 1; - } - - VOMS_DeleteContacts(voms_contacts); - - if (command) - free(command); - - return 0; -} - -static int -renew_voms_certs(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file) -{ - globus_gsi_cred_handle_t cur_proxy = NULL; - globus_gsi_cred_handle_t new_proxy = NULL; - struct vomsdata *vd = NULL; - struct voms **voms_cert = NULL; - int voms_err, ret; - X509 *cert = NULL; - STACK_OF(X509) *chain = NULL; - char *buf = NULL; - size_t buf_len = 0; - X509_EXTENSION *extension = NULL; - char *old_env_proxy = getenv("X509_USER_PROXY"); - char *old_env_cert = getenv("X509_USER_CERT"); - char *old_env_key = getenv("X509_USER_KEY"); - - setenv("X509_USER_PROXY", cur_file, 1); - setenv("X509_USER_CERT", renewed_file, 1); - setenv("X509_USER_KEY", renewed_file, 1); - - ret = glite_renewal_load_proxy(ctx, cur_file, &cert, NULL, &chain, &cur_proxy); - if (ret) - goto end; - - vd = VOMS_Init(NULL, NULL); - if (vd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Init() failed\n"); - return 1; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); - if (ret == 0) { - if (voms_err == VERR_NOEXT) { - /* no VOMS cred, no problem; continue */ - /* XXX this part shouldn't be reachable, this call is only called - * if the proxy does contain VOMS attributes */ - glite_renewal_log(ctx, LOG_ERR, "No VOMS attributes found in proxy %s\n", cur_file); - ret = 0; - goto end; - } else { - glite_renewal_log(ctx, LOG_ERR, "Cannot get VOMS certificate(s) from proxy"); - ret = 1; - goto end; - } - } - - /* XXX make sure this loop can really work for multiple voms certificates - * embedded in the proxy */ - for (voms_cert = vd->data; voms_cert && *voms_cert; voms_cert++) { - char *tmp, *ptr; - size_t tmp_len; - - ret = renew_voms_cert(ctx, vd, voms_cert, &tmp, &tmp_len); - if (ret) - goto end; - ptr = realloc(buf, buf_len + tmp_len); - if (ptr == NULL) { - ret = ENOMEM; - goto end; - } - buf = ptr; - memcpy(buf + buf_len, tmp, tmp_len); - buf_len += tmp_len; - } - - if (buf == NULL) { - /* no extension renewed, return */ - ret = 0; - goto end; - } - - ret = my_VOMS_Export(ctx, buf, buf_len, &extension); - if (ret) - goto end; - - ret = glite_renewal_load_proxy(ctx, renewed_file, NULL, NULL, NULL, &new_proxy); - if (ret) - goto end; - - ret = generate_proxy(ctx, new_proxy, extension, new_file); - -end: - (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) : - unsetenv("X509_USER_PROXY"); - (old_env_cert) ? setenv("X509_USER_CERT", old_env_cert, 1) : - unsetenv("X509_USER_CERT"); - (old_env_key) ? setenv("X509_USER_KEY", old_env_key, 1) : - unsetenv("X509_USER_KEY"); - - if (cert) - X509_free(cert); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (vd) - VOMS_Destroy(vd); - if (cur_proxy) - globus_gsi_cred_handle_destroy(cur_proxy); - if (new_proxy) - globus_gsi_cred_handle_destroy(new_proxy); - if (buf) - free(buf); - - return ret; -} - -int -glite_renewal_renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file) -{ - return renew_voms_certs(ctx, cur_file, renewed_file, new_file); -} - -int -glite_renewal_check_voms_attrs(glite_renewal_core_context ctx, const char *proxy) -{ - int ret, voms_err, present; - X509 *cert = NULL; - STACK_OF(X509) *chain = NULL; - struct vomsdata *vd = NULL; - - ret = glite_renewal_load_proxy(ctx, proxy, &cert, NULL, &chain, NULL); - if (ret) - return 0; - - vd = VOMS_Init(NULL, NULL); - if (vd == NULL) { - present = 0; - goto end; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); - if (ret == 0) { - present = 0; - goto end; - } - - present = 1; - -end: - if (cert) - X509_free(cert); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (vd) - VOMS_Destroy(vd); - - return present; -} - -#if 0 -int -main(int argc, char *argv[]) -{ - int ret; - const char *current_proxy = "/tmp/x509up_u11930"; - const char *renewed_proxy = "/tmp/proxy"; - - if (argc > 1) - current_proxy = argv[1]; - if (argc > 2) - renewed_proxy = argv[2]; - - if (globus_module_activate(GLOBUS_GSI_PROXY_MODULE) != GLOBUS_SUCCESS || - globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE) != GLOBUS_SUCCESS) { - glite_renewal_log(ctx, LOG_ERR, "[%d]: Unable to initialize Globus modules\n", getpid()); - return 1; - } - - ret = renew_voms_certs(current_proxy, renewed_proxy); - - return 0; -} -#endif diff --git a/org.glite.testsuites.ctb/LB/Makefile b/org.glite.testsuites.ctb/LB/Makefile deleted file mode 100644 index 34295c1..0000000 --- a/org.glite.testsuites.ctb/LB/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC=gcc -CFLAGS= -EXEC=testSocket - -all: $(EXEC) - -testSocket: testSocket.c - $(CC) -o $@ $< $(CFLAGS) - -clean: - rm -rf *.o - -mrproper: clean - rm -rf $(EXEC) diff --git a/org.glite.testsuites.ctb/LB/lb-l1.sh b/org.glite.testsuites.ctb/LB/lb-l1.sh deleted file mode 100755 index e60f40b..0000000 --- a/org.glite.testsuites.ctb/LB/lb-l1.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/bin/bash -########################################################################################## -# Script for testing of LB services -# Basic test: PING -# check LB binaries -# check running services with sockets -##################################################################################### -# # -# Returned values: # -# # -# Exit TEST_OK: Test Passed # -# Exit TEST_ERROR: Test Failed # -# Exit 2: Wrong Input # -# # -# Authors: Shkelzen Rugovac, Frederic Munster, Othmane Bouhali # -################################################################ - -## -# defining variables -########################" -PATH=/opt/glite/examples:$PATH -#echo $PATH -LBLOGEV=${LBLOGEV:-glite-lb-logevent} -LBJOBLOG=${LBJOBLOG:-glite-lb-job_log} -LBJOBREG=${LBJOBREG:-glite-lb-job_reg} -LBUSERJOBS=${LBUSERJOBS:-glite-lb-user_jobs} -LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status} -LBPURGE=${LBPURGE:-glite-lb-purge} -LBCHANGEACL=${LBCHANGEACL:-glite-lb-change_acl} -LBMON=${LBMON:-glite-lb-lbmon} -LB_INTERLOGD=glite-lb-interlogd -LB_LOGD=glite-lb-logd -DEBUG=2 -## -# show help and usage -######################" -showHelp() -{ - echo "Usage: $0 [OPTIONS] " - echo "Options:" - echo " -h | --help Show this help message." - echo " -m | --m lb_host hostName or IPV4 adress " - echo " -g | --log 'logfile' Redirect all output to the 'logfile'." - echo "" -# echo "For proper operation check your grid-proxy-info" -# grid-proxy-info -} -if [ -z "$1" ]; then - showHelp - exit 2 -fi -logfile=output.log -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-m" | "--bkserver") shift ; LB_HOST=$1 ;; - "-g" | "--log") shift ; logfile=$1 flag=1 ;; - - *) echo "Unrecognized option $1 try -h for help"; exit 2 ;; - - esac - shift -done - - -## -# Ping the LB_HOST -###################### - -function ping_host -{ - echo " Testing ping to $LB_HOST" >> $logfile - result=`ping -c 5 $LB_HOST 2>/dev/null | grep "0% packet loss"| wc -l` - if [ $result -gt 0 ]; then - echo "Pinging $LB_HOST OK " >> $logfile - else - echo "" >> $logfile - echo "Ping failed: The $LB_HOST is not accessible! " >> $logfile - echo "" >> $logfile - echo " LB Basic Test: Failed. " >> $logfile - exit $TEST_ERROR - fi -# echo " - OK " -} - -check_exec() -{ - [ $DEBUG -gt 0 ] && [ -n "$2" ] && echo -n -e "$2\t" >> $logfile || echo -n -e "$1\t" >> $logfile - eval $1 - RV=$? - [ $DEBUG -gt 0 ] && [ $RV -eq 0 ] && echo "OK" >> $logfile || echo "FAILED" >> $logfile - return $RV -} - -# -# check the binaries -######################### -check_binaries() -{ - check_exec 'LBJOBREG=`which $LBJOBREG`' "Checking binary $LBJOBREG ? " || exit 1 - check_exec 'LBJOBLOG=`which $LBJOBLOG`' "Checking binary $LBJOBLOG ? " || exit 1 - check_exec 'LBLOGEV=`which $LBLOGEV`' "Checking binary $LBLOGEV ?" || exit 1 - check_exec 'LBUSERJOBS=`which $LBUSERJOBS`' "Checking binary $LBUSERJOBS ?" || exit 1 - check_exec 'LBJOBSTAT=`which $LBJOBSTAT`' "Checking binary $LBJOBSTAT ? " || exit 1 - check_exec 'LBCHANGEACL=`which $LBCHANGEACL`' "Checking binary $LBCHANGEACL ?" || exit 1 - check_exec 'LBMON=`which $LBMON`' "Checking binary $LBMON " || exit 1 -} -# -# check the services -##################" -check_services() -{ -echo "Listening to locallogger port (9002)" >> $logfile -./testSocket $LB_HOST 9002 >> $logfile -if [ $? -eq 0 ]; then - echo "logd running ? - [OK]" >> $logfile - else - echo "logd running ? - [FAILED]" >> $logfile - exit $TEST_ERROR - fi -echo "Listening to interlogger ports (9000-9001-9003)" >> $logfile -./testSocket $LB_HOST 9000 >> $logfile && -./testSocket $LB_HOST 9001 >> $logfile && -./testSocket $LB_HOST 9003 >> $logfile -if [ $? -eq 0 ]; then - echo "Inetrlogd running ? - [OK]" >> $logfile - else - echo "interlogd running ? - [FAILED]" >> $logfile - exit $TEST_ERROR - fi -} - -##################### -# Starting the test -##################### -ping_host -check_binaries -check_services -if [ $flag -ne 1 ];then - cat $logfile - rm $logfile -fi - diff --git a/org.glite.testsuites.ctb/LB/lb-l2.sh b/org.glite.testsuites.ctb/LB/lb-l2.sh deleted file mode 100755 index 69f6a25..0000000 --- a/org.glite.testsuites.ctb/LB/lb-l2.sh +++ /dev/null @@ -1,253 +0,0 @@ -#!/bin/bash -#3.1.4 et 3.2.1: Normal event delivery and Normal Job States - -#Prerequisities: All services running - -#Actions: -#Registers jobs with glite-lb-job-reg prferably pointing to remote LB Server -#Check of the job status -#Logs sequences of events with glite-lb-logevent -#Checks with glite-lb-job_log that the events got delivered aftewards -#Checks with glite-lb-job_status that the status of the jobs are correct - - -PATH=/opt/glite/examples:$PATH -#echo $PATH -LBJOBREG=${LBJOBREG:-glite-lb-job_reg} -LBLOGEVENT=${LBLOGEVENT:-glite-lb-logevent} -LBJOBSTATUS=${LBJOBSTATUS:-glite-lb-job_status} -LBJOBLOG=${LBJOBLOG:-glite-lb-job_log} -LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status} -LBPURGE=${PURGE:-glite-lb-purge} - -BKSERVER="pc900.iihe.ac.be" -STATES="aborted cancelled done ready running scheduled waiting submitted " -SOURCES="NetworkServer WorkloadManager BigHelper JobController LogMonitor LRMS Application UserInterface" - -stest=1 -i=0 -JOBS_ARRAY_SIZE=10 -INTERVAL=2 - -init() -{ -export EDG_WL_QUERY_SERVER="$BKSERVER:9000" -export EDG_WL_LOG_DESTINATION="$BKSERVER:9002" -BKSERVER_HOST="$BKSERVER:9000" -BKSERVER_OPT="-m $BKSERVER" -} - - -getJobId() -{ -cat jobreg |grep "EDG_JOBID" |cut -c12- > jobList2 -res=`cat jobList2 |wc -c` -res=$[$res-2] -cat jobList2 |cut -c1-`echo $res` > jobreg -rm jobList2 -} - -#registrating a job -job_reg() -{ -eval $LBJOBREG -m pc900.iihe.ac.be:9000 -s userInterface > jobreg -getJobId -job=`cat jobreg` -rm jobreg -} - -#registering a list of jobs which jobid's are placed in an array -array_job_reg() -{ -echo "Registering $JOBS_ARRAY_SIZE jobs...................." -job_id=0 -st_count=`echo $SOURCES | wc -w` -while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - tmp=`echo $RANDOM % $st_count + 1 | bc` - jsource=`echo $SOURCES | cut -d " " -f $tmp | tr A-Z a-z` - job_reg $jsource - echo $job - SAMPLE_JOBS_ARRAY[$job_id]=$job - job_id=$[$job_id+1] - done -} - -#Event delivery test -testLB() -{ -echo "Checking the Events............................................." -echo -job_id=0 -while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - #sleep 2 - dtest=0 - #out is the list of events sent, we count the number of events and then we extract the job status - nbEvents=`cat out[$job_id] |grep glite-lb-logevent | wc -l` - nbEvents=$[$nbEvents+1] - cat out[$job_id] |gawk -F"-e " '{ print $2 }' > eventsTemp - echo "UserTag"> events - echo "RegJob">> events - cat eventsTemp|gawk -F" --" '{ print $1 }'>> events - rm eventsTemp - events3="blank" - i=0 - cmp -s events events3 - while [ $? -ne 0 ] && [ $i -lt $INTERVAL ] ; do - - - #we use glite-lb-job_log and apply the same treatment as above to the output - eval $LBJOBLOG -r $INTERVAL -d 2 ${SAMPLE_JOBS_ARRAY[$job_id]} > joblog2 - nbevents=`cat joblog2 | grep DATE | wc -l` - cat joblog2|gawk -F"DG.EVNT=\"" '{ print $2 }' > eventsTemp2 - cat eventsTemp2|gawk -F"\"" '{ print $1 }'> events2 - cat events2|sed /^$/d > events3 - rm eventsTemp2 events2 joblog2 - #Comparison of the outputs and intermediary printout - echo "Events Sent....." >> LoggedEvents.log - cat -n events >> LoggedEvents.log -# cat -n events - echo "Events recorded in the LB server....." >> LoggedEvents.log - cat -n events3 >> LoggedEvents.log -# cat -n events3 - i=$[$i+1] - cmp -s events events3 - done - cmp -s events events3 - if [ $? -eq 0 ]; then - dtest=1 - echo "Job $job_id ....................[OK]" - i=0 - - else - echo "Job $job_id.....................[FAILED]" - fi - rm events events3 out[$job_id] - job_id=$[$job_id+1] -done -echo -echo "A detailed list of events logged has been printed to LoggedEvents.log" -echo -} - -#job status test -testLB2() -{ -echo "Checking the Jobs Status........................................" -echo -job_id=0 - while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - #sleep 1 - eval $LBJOBSTATUS ${SAMPLE_JOBS_ARRAY[$job_id]} > status - testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l` - i=0 - while [ $testStatus -ne 1 ] && [ $i -lt $INTERVAL ] ; do - bkserver_state=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}` - testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l` - i=$[$i+1] - done - if [$testStatus -eq 1 ] ; then - echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[OK]" - else - echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[FAILED]" - cat status > errorStatus.tmp - echo "Detailed status has been copied to errorStatus.tmp" - echo - dtest=0 - fi - rm status -job_id=$[$job_id+1] -done -} -showHelp() -{ - echo "Usage: $0 [OPTIONS] " - echo "Options:" - echo " -h | --help Show this help message." - echo " -r | --retries Number of test retries (2 by default)" - echo " -n | --nbjobs Number of jobs (10 by default)" - echo " -m | --bkserver Host address of the BKServer ex:pc900.iihe.ac.be " - echo " -s | --states List of states in which could tested jobs fall." - echo " -l | --large-stress 'size' Do a large stress logging ('size' random data added to the messages." - echo "" - -# echo "For proper operation check your grid-proxy-info" -# grid-proxy-info -} - -#logging events to the jobs. Events are selected randomly from a list. -logEvents() -{ -echo "Logging events to the $JOBS_ARRAY_SIZE jobs...................................." -echo -job_id2=0 -st_count=`echo $STATES | wc -w` - while [ $job_id2 -lt $JOBS_ARRAY_SIZE ] ; do - tmp=`echo $RANDOM % $st_count + 1 | bc` - state=`echo $STATES | cut -d " " -f $tmp | tr A-Z a-z` - SAMPLE_JOBS_STATES[$job_id2]=$state - echo > LoggedEvents.log - echo "Submitting events to the job: ${SAMPLE_JOBS_ARRAY[$job_id2]} " >> LoggedEvents.log - echo >> LoggedEvents.log - - echo "event submitted.......................................[$state]" >> LoggedEvents.log - eval glite-lb-$state.sh $LARGE_STRESS -j ${SAMPLE_JOBS_ARRAY[$job_id2]} 2>out[$job_id2] - job_id2=$(($job_id2 + 1)) -done -} - -#logging tags to the jobs -logTags() -{ -echo "Logging tags to the $JOBS_ARRAY_SIZE jobs...................................." -echo - -job_id=0 -while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - eval $LBLOGEVENT -s Application -e UserTag -j ${SAMPLE_JOBS_ARRAY[$job_id]} -name testTag -value 12345 >> LoggedEvents.log -job_id=$[$job_id+1] -done -} - - - -#input -if [ -z "$1" ]; then - showHelp - exit 2 -fi -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-r" | "--retries") shift ; INTERVAL=$1 ;; - "-n" | "--nbjobs") shift ; JOBS_ARRAY_SIZE=$1 ;; - "-m" | "--bkserver") shift ; BKSERVER=$1 ;; - "-s" | "--states") shift; STATES="$1" ;; - "-l" | "--large-stress") shift ; LARGE_STRESS="-l $1" ;; -# "-g" | "--log") shift ; logfile=$1 ;; - - *) echo "Unrecognized option $1 try -h for help"; exit 2 ;; - - esac - shift -done -echo - - -#main.................................................................. -init -array_job_reg -logEvents -logTags -testLB -testLB2 -#testProxy -#eval $LBPURGE -h -echo -if [ $stest -eq 1 ];then - echo "Final test result .........................................[OK]" - exit 1 -else echo "Final test result .........................................[FAILED]" - exit 0 - fi -echo diff --git a/org.glite.testsuites.ctb/LB/lb-l2Stat.sh b/org.glite.testsuites.ctb/LB/lb-l2Stat.sh deleted file mode 100755 index 1e5d9e2..0000000 --- a/org.glite.testsuites.ctb/LB/lb-l2Stat.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/bash -# Normal event delivery and Normal Job States with internal BKsrever performance - -#Prerequisities: All services running -#Actions: -#Registers jobs with glite-lb-job-reg prferably pointing to remote LB Server -#Check of the job status -#Logs sequences of events with glite-lb-logevent -#Check with glite-lb-job_status that the status of the jobs are correct and mesures how long it took to get results - - -PATH=/opt/glite/examples:$PATH -#echo $PATH -LBJOBREG=${LBJOBREG:-glite-lb-job_reg} -LBLOGEVENT=${LBLOGEVENT:-glite-lb-logevent} -LBJOBSTATUS=${LBJOBSTATUS:-glite-lb-job_status} -LBJOBLOG=${LBJOBLOG:-glite-lb-job_log} -LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status} -LBPURGE=${PURGE:-glite-lb-purge} - -# -m host -BKSERVER="pc900.iihe.ac.be" -STATES="aborted cancelled done ready running scheduled waiting submitted " -SOURCES="NetworkServer WorkloadManager BigHelper JobController LogMonitor LRMS Application UserInterface" - -stest=1 -i=0 -JOBS_ARRAY_SIZE=10 -# timeouts for polling the bkserver -timeout=10 -maxtimeout=300 -NB_TAGS=50 -INTERVAL=2 - -init() -{ -export EDG_WL_QUERY_SERVER="$BKSERVER:9000" -export EDG_WL_LOG_DESTINATION="$BKSERVER:9002" -BKSERVER_HOST="$BKSERVER:9000" -BKSERVER_OPT="-m $BKSERVER" -} - -get_time() -{ - sec=`date +%s` - nsec=`date +%N` - time=`echo "1000000000*$sec + $nsec"|bc` -# time=$sec - return 0 -} - -getJobId() -{ -cat jobreg |grep "EDG_JOBID" |cut -c12- > jobList2 -res=`cat jobList2 |wc -c` -res=$[$res-2] -cat jobList2 |cut -c1-`echo $res` > jobreg -rm jobList2 -} - -#registrating a job -job_reg() -{ -eval $LBJOBREG -m pc900.iihe.ac.be:9000 -s userInterface > jobreg -getJobId -job=`cat jobreg` -rm jobreg -} - -array_job_reg() -{ -echo "Registering $JOBS_ARRAY_SIZE jobs...................." -job_id=0 -st_count=`echo $SOURCES | wc -w` -while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - tmp=`echo $RANDOM % $st_count + 1 | bc` - jsource=`echo $SOURCES | cut -d " " -f $tmp | tr A-Z a-z` - job_reg $jsource - echo $job - SAMPLE_JOBS_ARRAY[$job_id]=$job - job_id=$[$job_id+1] - done -} - -#job status test -testLBP() -{ -echo "Checking the Events............................................." -echo -job_id=0 -while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do - get_time - start=$time - logEvent $job_id - logTag $job_id - - - eval $LBJOBSTATUS ${SAMPLE_JOBS_ARRAY[$job_id]} > status - testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l` - response=0 - while [ $testStatus -ne 1 ];do - bkserver_state=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}` - testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l` - echo "**Retrying**" - sleep $timeout - response=$(($response + $timeout )) - if test $response -gt $maxtimeout ; then - echo -e "ERROR\n\tstatus of job ${SAMPLE_JOBS_ARRAY[$job_id]} as queried from bkserver ($bkserver_state) has not become ${SAMPLE_JOBS_STATES[$job_id]} for more than $response seconds!" - echo "Detailed status has been copied to errorStatus.tmp" - echo - dtest=0 - exit 1; - fi - done - get_time - response=`echo "scale=9; ($time - $start)/1000000000"|bc` - SAMPLE_JOBS_RESPONSES[$job_id]=$response - echo "Job: $job_id ....[`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`].......[OK]" - echo - rm status - job_id=$[$job_id+1] - done - j=0 - total=0 - echo "Sending events took for individual jobs the following time" - while [ $j -lt $JOBS_ARRAY_SIZE ] ; do - total=`echo "scale=9; $total + ${SAMPLE_JOBS_RESPONSES[$j]}" |bc` - echo -e "${SAMPLE_JOBS_ARRAY[$j]} \t${SAMPLE_JOBS_RESPONSES[$j]} seconds" - j=$(($j + 1)) - done - echo -e "Total time for $JOBS_ARRAY_SIZE jobs: \t$total" - echo -e -n "Average time for event: \t" - echo "scale=9; $total / $JOBS_ARRAY_SIZE "|bc - echo -e -n "Average time for event and tags: \t" - echo "scale=9; $total / $JOBS_ARRAY_SIZE / $NB_TAGS"|bc - echo -e -n "Event throughput (events/sec): \t" - echo "scale=9; $NB_TAGS * $JOBS_ARRAY_SIZE / $total"|bc - echo - echo "A detailed list of events logged has been printed to LoggedEvents.log" - echo -} - -showHelp() -{ - echo "Usage: $0 [OPTIONS] " - echo "Options:" - echo " -h | --help Show this help message." - echo " -n | --nbjobs Number of jobs" - echo " -s | --states List of states in which could tested jobs fall." - echo " -m | --bkserver Host address of the BKServer " - echo " -t | --tags Number of user tags to load to each job." - echo " -l | --large-stress 'size' Do a large stress logging ('size' rand om data added to the messages." - echo "" - -# echo "For proper operation check your grid-proxy-info" -# grid-proxy-info -} - -logEvent() -#ARG1: Number of the job considered in the jobs array -{ -st_count=`echo $STATES | wc -w` -tmp=`echo $RANDOM % $st_count + 1 | bc` -state=`echo $STATES | cut -d " " -f $tmp | tr A-Z a-z` -SAMPLE_JOBS_STATES[$1]=$state -echo "Logging event to the job($1).........................[$state]" -echo > LoggedEvents.log -echo "Submitting events to the job: ${SAMPLE_JOBS_ARRAY[$1]} " >> LoggedEvents.log -echo >> LoggedEvents.log -echo "event submitted.......................................[$state]" >> LoggedEvents.log -eval glite-lb-$state.sh $LARGE_STRESS -j ${SAMPLE_JOBS_ARRAY[$1]} 2>out -} -logTag() -{ -i=0 -echo "Logging $NB_TAGS tags to the job................" -eval $LBLOGEVENT -s Application -n $NB_TAGS -e UserTag -j ${SAMPLE_JOBS_ARRAY[$1]} -name testTag -value 12345 >> LoggedEvents.log -} - - - -#input -if [ -z "$1" ]; then - showHelp - exit 2 -fi -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-n" | "--nbjobs") shift ; JOBS_ARRAY_SIZE=$1 ;; - "-s" | "--states") shift; STATES="$1" ;; - "-m" | "--bkserver") shift ; BKSERVER_HOST=$1 ;; - "-t" | "--tags") shift ; NB_TAGS=$1 ;; - "-l" | "--large-stress") shift ; LARGE_STRESS="-l $1" ;; -# "-g" | "--log") shift ; logfile=$1 ;; - - *) echo "Unrecognized option $1 try -h for help"; exit 2 ;; - - esac - shift -done - -echo "Test of job status with several jobs " -echo "***********************************" -echo -init -array_job_reg -testLBP -echo -if [ $stest -eq 1 ];then - echo "Final test result .........................................[OK]" - exit 1 -else echo "Final test result .........................................[FAILED]" - exit 0 - fi -echo diff --git a/org.glite.testsuites.ctb/LB/testSocket.c b/org.glite.testsuites.ctb/LB/testSocket.c deleted file mode 100755 index cf1adc8..0000000 --- a/org.glite.testsuites.ctb/LB/testSocket.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFFSIZE 32 -void Die(char *mess) { -perror(mess); -exit(1); } -int main(int argc, char *argv[]) { -int sock; -struct hostent *hip; -char *adrIPp; -struct in_addr adrIP; -struct sockaddr_in echoserver; -char buffer[BUFFSIZE]; -unsigned int echolen; -int received = 0; -if (argc != 3) { - fprintf(stderr, "USAGE: TCPecho \n"); - exit(1); - } -//conversion from DNS to IPv4 -if((hip=gethostbyname(argv[1]))==NULL) -{ -printf("Erreur avec gethostbyname\n"); -// exit(1); -} -adrIP.s_addr=*(int *)hip->h_addr; -adrIPp =(char *)inet_ntoa(adrIP); -/* Create the TCP socket */ -if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - Die("Failed to create socket"); - } -/* Construct the server sockaddr_in structure */ -memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */ -echoserver.sin_family = AF_INET; /* Internet/IP */ -echoserver.sin_addr.s_addr = inet_addr(adrIPp); /* IP address */ -echoserver.sin_port = htons(atoi(argv[2])); /* server port */ -printf("Connecting a socket with : %s,%s", adrIPp,argv[2]); -/* Establish connection */ -if (connect(sock, - (struct sockaddr *) &echoserver, - sizeof(echoserver)) < 0) { - Die("Failed to connect with server"); - } -else - { - shutdown(sock,2); - printf(" [OK]\n"); - exit(0); - } -} diff --git a/org.glite.wms-utils.exception/.cvsignore b/org.glite.wms-utils.exception/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.glite.wms-utils.exception/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.glite.wms-utils.exception/LICENSE b/org.glite.wms-utils.exception/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.exception/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.wms-utils.exception/Makefile.am b/org.glite.wms-utils.exception/Makefile.am deleted file mode 100755 index b66c2bb..0000000 --- a/org.glite.wms-utils.exception/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Process this file with automake to produce Makefile.in -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE -## Subdirectories list -SUBDIRS = interface src - -## Default flags to run aclocal -ACLOCAL_AMFLAGS = -I project - -stage: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - prefix_arg="@prefix@"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail" - -distsrc: dist - mv $(distdir).tar.gz $(DISTTAR)/$(distdir)_src.tar.gz - -distbin: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - tmpdistbin="$(WORKDIR)/dist_bin"; \ - prefix_arg="prefix=$$tmpdistbin"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail"; \ - pushd $$tmpdistbin; \ - $(AMTAR) -zcf $(DISTTAR)/$(distdir)_bin.tar.gz .; \ - popd; \ - rm -rf $$tmpdistbin - diff --git a/org.glite.wms-utils.exception/bootstrap b/org.glite.wms-utils.exception/bootstrap deleted file mode 100755 index ceeb099..0000000 --- a/org.glite.wms-utils.exception/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -mkdir -p src/autogen -set -x -aclocal -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf diff --git a/org.glite.wms-utils.exception/build.xml b/org.glite.wms-utils.exception/build.xml deleted file mode 100755 index d12e8c2..0000000 --- a/org.glite.wms-utils.exception/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/configure.ac b/org.glite.wms-utils.exception/configure.ac deleted file mode 100755 index 398817a..0000000 --- a/org.glite.wms-utils.exception/configure.ac +++ /dev/null @@ -1,127 +0,0 @@ -# -# Copyright (c) 2004 on behalf of the EU EGEE Project: -# The European Organization for Nuclear Research (CERN), -# Istituto Nazionale di Fisica Nucleare (INFN), Italy -# Datamat Spa, Italy -# Centre National de la Recherche Scientifique (CNRS), France -# CS Systeme d'Information (CSSI), France -# Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -# Universiteit van Amsterdam (UvA), Netherlands -# University of Helsinki (UH.HIP), Finland -# University of Bergen (UiB), Norway -# Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom -# -# Common configure.ac file for the GLite WMS Common module -# -# Authors: Alberto Di Meglio -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log$ -# Revision 1.13 2006/03/20 15:29:52 eronchie -# Increased version -# -# Revision 1.12 2005/10/15 07:54:17 eronchie -# Increased version -# -# Revision 1.11 2005/09/20 10:20:52 eronchie -# Started merged with 1.4 -# -# Revision 1.10 2004/12/10 07:31:35 eronchie -# Increased version -# -# Revision 1.9 2004/11/16 15:31:13 eronchie -# Increased version -# -# Revision 1.8 2004/09/22 00:25:17 glbuild -# Fixed missing parenthesis -# -# Revision 1.7 2004/09/21 19:21:57 glbuild -# modified module.version -# -# Revision 1.6 2004/08/17 10:41:47 eronchie -# Added optimize option -# -# Revision 1.5 2004/07/23 08:02:09 eronchie -# Updated configure.ac -# -# Revision 1.4 2004/07/21 18:49:26 eronchie -# Added AC_GLITE -# -# Revision 1.3 2004/07/21 18:47:49 eronchie -# Removed obsolete things -# -# Revision 1.2 2004/07/21 18:44:22 eronchie -# Updated header file -# -# Revision 1.1.1.1 2004/07/21 18:16:57 eronchie -# Moved out exception from org.glite.wms.common/src/utilitiesY -# -# -# - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([GLite WMS Utils Exception], [3.1.1]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/Exception.cpp]) - -# Notices. -AC_COPYRIGHT([Copyright (c) 2004 The EU EGEE Project -See LICENCE file for details -]) -AC_REVISION([$Revision$]) - -#Environment. -WORKDIR=`pwd` -AC_SUBST(WORKDIR) - -# Checks for programs. -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_CXXCPP -AM_PROG_CC_C_O -AC_PROG_LIBTOOL - -# Checks for libraries. - -# Checks for header files. -AC_CHECK_HEADERS([fcntl.h mntent.h sys/vfs.h syslog.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_CHECK_MEMBERS([struct stat.st_rdev]) -AC_TYPE_UID_T -AC_CHECK_TYPES([ptrdiff_t]) - -# Checks for library functions. -AC_HEADER_STDC -AC_FUNC_ERROR_AT_LINE -AC_FUNC_GETMNTENT -AC_FUNC_MEMCMP -AC_FUNC_STAT -AC_FUNC_STRFTIME -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([bzero endpwent ftruncate getmntent memset mkdir pow strerror strtol]) - -AC_GLITE - -AC_OPTIMIZE - -# Configuration items -AC_PREFIX_DEFAULT([/opt/glite]) -AM_CONFIG_HEADER([src/autogen/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([src/Makefile]) -AC_CONFIG_FILES([interface/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.exception/interface/Makefile.am b/org.glite.wms-utils.exception/interface/Makefile.am deleted file mode 100755 index 3c4ccb7..0000000 --- a/org.glite.wms-utils.exception/interface/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -exceptiondir = $(includedir) -nobase_exception_HEADERS = \ - glite/wmsutils/exception/exception_codes.h \ - glite/wmsutils/exception/Exception.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h deleted file mode 100644 index 19ca7c7..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H -#define GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H - -/* - * Exception.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * Contributors are mentioned in the code where appropriate. - */ - -#include -#include -//#include -#include // For logging exceptions to log file -#include // list the exception codes -#include -#include -#include // base ancestor stl::exception - - -namespace glite { - namespace wmsutils { - namespace exception { - -extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog) -#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try { -#define GLITE_STACK_CATCH() } catch (glite::wmsutils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; } catch (std::exception &ex){ glite::wmsutils::exception::Exception exc( __FILE__ , LINE, METHOD, 0, "Standard exception: " + std::string(ex.what()) ); throw exc; } - -/** - * The Exception base classe contains attributes into which are placed exception information and provides - * constructor that beyond the error code take parameters specifying the source file and line number - * (e.g. through __FILE__ and __LINE__) where the error has been generated and string messages, - * allowing an easy way of storing the origin of the exception. - * Moreover it provides methods for getting all the exception information and for logging them either - * in a log file or to the syslog daemon. - * Each of the derived types may contain its private attributes describing the actual error instance in detail. - * Moreover each exception has an attribute representing the exception identifier that is set by the - * class constructor and allows the identification of the original exception. - * - * @version 0.1 - * @date 22 July 2004 - * @author Alessandro Maraschini -*/ - -class Exception : public std::exception{ - public: - /** - * Constructor Update all mandatory fields - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) - * @param exc the previous exception as in the stack trace */ - Exception ( const std::string& source, const std::string& method, Exception *exc); - /** - * Constructor Update all mandatory fields - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) */ - Exception ( const std::string& source, const std::string& method, int code, const std::string& exception); - - /** - * Constructor Update all mandatory fields - * @param source the path of the file that raised the exception - * @param line_number the number of the line in the file that raised the exception - * @param method the name of the method that raised the exception - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception */ - Exception (const std::string& source, int line_number, const std::string& method, int code, const std::string& exception); - /** - * Default Destructor - */ - virtual ~Exception() throw (); - /** - * Return a string debug message containing information about Exception thrown - * Debug message contains all the attributes stored in an exception instance such as the method, the file and the line - * that threw the exception. - *@return the debug message string representation - */ - virtual std::string dbgMessage(); - /** - * Return the error code - * @return The integer representing the code of the error that generated the exception - */ - virtual int getCode(); - - /** - * return the Error Message associated to the Exception - * @return The Exception string message representation - */ - virtual const char* what() const throw (); - - /** - * Print Exception error information into a log file - * @param logfile the file where to log exception information - */ - virtual void log(const std::string& logfile = ""); - /** - * Retrieve the Exception name - * @return the name of the Exception thrown - */ - virtual std::string getExceptionName(); - - /** - * Retrieve the Stack of the exception as a list of previous generated exceptions - *@return the string representation of the stack trace: each line correspond to an exception message - */ - virtual std::string printStackTrace() ; - /** - * Return the list of methods that caused the Exception - */ - virtual std::vector getStackTrace() ; - /** - * Update stack information - */ - virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ; - protected: - /** Empty constructor*/ - Exception(); - /** integer error code representing the cause of the error */ - int error_code; - /** string exception message representation*/ - std::string error_message ; - /** line number where the exception was raised */ - int line; - /** The name of the file where the exception was raised */ - std::string source_file; - /** the name of the exception */ - std::string exception_name; - /** the name of the method where the expceiton was raised */ - std::string method_name ; - /** a string representation of the stacktrace */ - std::string stack; - /** the actual internal stacktrace representation */ - std::vector< std::string> stack_strings ; - /** the name of the ancestor exception */ - std::string ancestor ; -}; //End Exception Class -}}} // Closing namespace -#endif diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h deleted file mode 100755 index fce99aa..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef GLITE_WMSUTILS_EXCEPTION_CODES_H -#define GLITE_WMSUTILS_EXCEPTION_CODES_H -// pure C-style code (needed by some libraries) -#define GLITE_WMS_COMMON_ERROR_BASE 900 -#define GLITE_WMS_USERINTERFACE_ERROR_BASE 1000 -#define GLITE_WMS_NETWORKSERVER_ERROR_BASE 1200 -#define GLITE_WMS_SOCKET_ERROR_BASE 1300 -#define GLITE_WMS_LDAP_ERROR_BASE 1350 -#define GLITE_WMS_LOGGING_ERROR_BASE 1400 -#define GLITE_WMS_REQUESTAD_ERROR_BASE 1500 -#define GLITE_WMS_CHECKPOINT_ERROR_BASE 1600 -#define GLITE_WMS_CONFIGURATION_ERROR_BASE 1800 -#ifdef __cplusplus -namespace glite { -namespace wmsutils { -namespace exception { - /** - * The Error Code - */ - enum { - WMS_COMMON_BASE = GLITE_WMS_COMMON_ERROR_BASE, - THREAD_INIT , // pthread_attr_init method failed - THREAD_DETACH , // pthread_attr_setdetachstate method failed - THREAD_CREATE , // pthread_create method failed - THREAD_JOIN, - THREAD_SSL, - WMS_FATAL_ERROR, - WMS_UI_ERROR_BASE = GLITE_WMS_USERINTERFACE_ERROR_BASE, - WMS_NS_ERROR_BASE = GLITE_WMS_NETWORKSERVER_ERROR_BASE, - WMS_SOCKET_ERROR_BASE = GLITE_WMS_SOCKET_ERROR_BASE, - WMS_LDAP_ERROR_BASE = GLITE_WMS_LDAP_ERROR_BASE, - WMS_LB_ERROR_BASE = GLITE_WMS_LOGGING_ERROR_BASE , - WMS_REQUESTAD_ERROR_BASE = GLITE_WMS_REQUESTAD_ERROR_BASE, - WMS_CHKPT_ERROR_BASE = GLITE_WMS_CHECKPOINT_ERROR_BASE, - WMS_CONFIGURATION_ERROR_BASE = GLITE_WMS_CONFIGURATION_ERROR_BASE - }; -} // exception namespace -} // wmsutils namespace -} // glite namespace -#endif //ifdef c++ -#endif diff --git a/org.glite.wms-utils.exception/project/build.number b/org.glite.wms-utils.exception/project/build.number deleted file mode 100644 index 95bc38e..0000000 --- a/org.glite.wms-utils.exception/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 02:08:14 CEST 2005 -module.build=154 diff --git a/org.glite.wms-utils.exception/project/build.properties b/org.glite.wms-utils.exception/project/build.properties deleted file mode 100755 index f4aef51..0000000 --- a/org.glite.wms-utils.exception/project/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -build.package.summary="files for gLite wms utils exception" -build.package.description="exception api" diff --git a/org.glite.wms-utils.exception/project/configure.properties.xml b/org.glite.wms-utils.exception/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.exception/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.exception/project/properties.xml b/org.glite.wms-utils.exception/project/properties.xml deleted file mode 100755 index 1e49af0..0000000 --- a/org.glite.wms-utils.exception/project/properties.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/project/version.properties b/org.glite.wms-utils.exception/project/version.properties deleted file mode 100755 index 40c3916..0000000 --- a/org.glite.wms-utils.exception/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=3.1.1 -module.age=1 diff --git a/org.glite.wms-utils.exception/src/Exception.cpp b/org.glite.wms-utils.exception/src/Exception.cpp deleted file mode 100644 index 546f253..0000000 --- a/org.glite.wms-utils.exception/src/Exception.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* ************************************************************************** -* filename : Exceptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/exception/Exception.h" -#include "glite/wmsutils/exception/exception_codes.h" - -namespace glite { -namespace wmsutils{ -namespace exception { -using namespace std ; -pthread_mutex_t METHOD_MUTEX ; // This mutex is used in order to lock the file for writing log infornation - -/* ********************************* -* Exception Class Implementation -************************************/ -//Constructor/Destructor - -Exception::Exception () { - line = 0; -}; - -Exception::~Exception() throw(){ } - -/** -* Exception chainig -*/ -void Exception::push_back (const string& source, int line_number, const string& method){ - stack_strings.push_back (dbgMessage()); - ancestor = what(); - source_file = source; - line = line_number; - method_name = method; - error_message = ""; - exception_name = ""; -} - -Exception::Exception( const std::string& file, int line_number, const std::string& method, int code, const std::string& name) - : error_code(code), exception_name(name){ - source_file = file; - line = line_number; - method_name = method; -}; - -Exception::Exception (const string& source, const string& method, int code, const string& exception) - : error_code(code), exception_name(exception){ - source_file = source; - method_name = method; - // stack= ""; - line = 0; -}; - -int Exception::getCode(){ - if (error_code != 0) return error_code; - else - return WMS_COMMON_BASE; -}; - -const char* Exception::what() const throw(){ - if (!ancestor.empty()) return ancestor.c_str(); - - return error_message.c_str(); -}; - -string Exception::getExceptionName(){ - return exception_name; -}; - -void Exception::log(const std::string& logfile) -{ - if (logfile == "") - syslog (LOG_PERROR, (char *)(dbgMessage()).c_str()); - else{ - pthread_mutex_lock( &METHOD_MUTEX); // LOCK - //TBD : test if file exist-->>Create HEADER ?? - ofstream fout ((char *) logfile.c_str() , ios::app ); //Open the file for writing (if it doesn't exist then it will be created) - fout << "\n" << dbgMessage() ; //write (append) the message - fout.close(); //close the file - pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK - } -}; - -string Exception::printStackTrace(){ - string stack = "" ; - for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){ - stack+=stack_strings[i] +"\n" ; - } - return stack +dbgMessage(); -}; - -vector Exception::getStackTrace(){ - // make a copy of the stack - vector stack = stack_strings ; - stack.push_back(dbgMessage()) ; - return stack; -}; - -string Exception::dbgMessage(){ - string result ; - //Adding exception Name - result = exception_name; - - //Adding error msg - if (error_message!="") result +=": " + string(what()); - - if (result != "") result+="\n"; - - //Adding Source - result +="\tat " + method_name +"[" +source_file; - - //Adding line number - if (line!=0){ - char buffer [1024] ; - sprintf (buffer, "%i" , line) ; - result += ":" + string ( buffer ); - } - result +="]" ; - return result; -} - -}}} // Closing namespace - diff --git a/org.glite.wms-utils.exception/src/Makefile.am b/org.glite.wms-utils.exception/src/Makefile.am deleted file mode 100755 index 0c5caac..0000000 --- a/org.glite.wms-utils.exception/src/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -lib_LTLIBRARIES = libglite_wmsutils_exception.la - -libglite_wmsutils_exception_la_SOURCES = \ - Exception.cpp - -AM_CPPFLAGS = -I$(top_srcdir)/interface \ - -I$(top_srcdir)/src - -MAINTAINERCLEANFILES = Makefile.in *.*~ diff --git a/org.glite.wms-utils.exception/test/Makefile.am b/org.glite.wms-utils.exception/test/Makefile.am deleted file mode 100755 index a972450..0000000 --- a/org.glite.wms-utils.exception/test/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -EXCEPTION_LIBS = $(top_builddir)/src/libglite_wmsutils_exception.la - -TESTS = glite-wmsutils-exception - -check_PROGRAMS = $(TESTS) - -glite_wmsutils_exception_SOURCES = exception_cu_suite.cpp \ - exception_cu_suite.h \ - exception_cu_main.cpp - -glite_wmsutils_exception_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(EXCEPTION_LIBS) \ - $(CPPUNIT_LIBS) - -AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/test \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - $(CPPUNIT_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.exception/test/exception_cu_main.cpp b/org.glite.wms-utils.exception/test/exception_cu_main.cpp deleted file mode 100644 index 182df4c..0000000 --- a/org.glite.wms-utils.exception/test/exception_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "exception_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Exception_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.exception/test/exception_cu_suite.cpp b/org.glite.wms-utils.exception/test/exception_cu_suite.cpp deleted file mode 100644 index f749af9..0000000 --- a/org.glite.wms-utils.exception/test/exception_cu_suite.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "exception_cu_suite.h" -#include "glite/wmsutils/exception/Exception.h" -#include -#include - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::exception; - -void Exception_test::setUp() -{} - -void Exception_test::tearDown() -{} - - -void Exception_test::constructor_case() -{ - - //constructor class name, line number, method name, code, exception name - glite::wmsutils::exception::Exception exc_5("TEST_Class", 3, "test_method", 1, "exception_test"); - - //constructor class name, method name, code, exception name - glite::wmsutils::exception::Exception exc_4("TEST_Class", "test_method", 1, "exception_test"); - - CPPUNIT_ASSERT(exc_5.getExceptionName() == "exception_test"); - CPPUNIT_ASSERT(exc_5.getCode() == 1); -} - -void Exception_test::tostring_case() -{ - cout<<"TEST TO STRING METHODS"< msgvec = exc_5.getStackTrace(); - - for (int i=0; i -#include -#include - -#include - - -class Exception_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Exception_test); - CPPUNIT_TEST(constructor_case); - CPPUNIT_TEST(tostring_case); - CPPUNIT_TEST(stackTrace_case); - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void constructor_case(); - void tostring_case(); - void stackTrace_case(); - -}; - - - diff --git a/org.glite.wms-utils.jobid/.cvsignore b/org.glite.wms-utils.jobid/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.wms-utils.jobid/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.wms-utils.jobid/LICENSE b/org.glite.wms-utils.jobid/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.jobid/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.wms-utils.jobid/Makefile.am b/org.glite.wms-utils.jobid/Makefile.am deleted file mode 100755 index bf956e1..0000000 --- a/org.glite.wms-utils.jobid/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE - -## Subdirectories list -SUBDIRS = interface src examples - -## Default flags to run aclocal -ACLOCAL_AMFLAGS = -I project - -stage: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - prefix_arg="@prefix@"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail" - -distsrc: dist - mv $(distdir).tar.gz $(DISTTAR)/$(distdir)_src.tar.gz - -distbin: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - tmpdistbin="$(WORKDIR)/dist_bin"; \ - prefix_arg="prefix=$$tmpdistbin"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail"; \ - pushd $$tmpdistbin; \ - $(AMTAR) -zcf $(DISTTAR)/$(distdir)_bin.tar.gz .; \ - popd; \ - rm -rf $$tmpdistbin - diff --git a/org.glite.wms-utils.jobid/bootstrap b/org.glite.wms-utils.jobid/bootstrap deleted file mode 100755 index ceeb099..0000000 --- a/org.glite.wms-utils.jobid/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -mkdir -p src/autogen -set -x -aclocal -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf diff --git a/org.glite.wms-utils.jobid/build.xml b/org.glite.wms-utils.jobid/build.xml deleted file mode 100755 index 44c110c..0000000 --- a/org.glite.wms-utils.jobid/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/configure.ac b/org.glite.wms-utils.jobid/configure.ac deleted file mode 100755 index e255849..0000000 --- a/org.glite.wms-utils.jobid/configure.ac +++ /dev/null @@ -1,147 +0,0 @@ -# -# Copyright (c) 2004 on behalf of the EU EGEE Project: -# The European Organization for Nuclear Research (CERN), -# Istituto Nazionale di Fisica Nucleare (INFN), Italy -# Datamat Spa, Italy -# Centre National de la Recherche Scientifique (CNRS), France -# CS Systeme d'Information (CSSI), France -# Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -# Universiteit van Amsterdam (UvA), Netherlands -# University of Helsinki (UH.HIP), Finland -# University of Bergen (UiB), Norway -# Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom -# -# Common configure.ac file for the GLite WMS Common module -# -# Authors: Alberto Di Meglio -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log$ -# Revision 1.19 2006/03/20 15:30:43 eronchie -# Increased version -# -# Revision 1.18 2005/10/15 07:55:00 eronchie -# Increased version -# -# Revision 1.17 2005/09/20 10:41:49 eronchie -# Started merging with rc1.4 -# -# Revision 1.16 2004/12/10 07:33:42 eronchie -# Increased version -# -# Revision 1.15 2004/11/16 15:35:22 eronchie -# Increased version -# -# Revision 1.14 2004/11/16 15:15:45 eronchie -# Increased version -# -# Revision 1.13 2004/09/22 00:25:17 glbuild -# Fixed missing parenthesis -# -# Revision 1.12 2004/09/21 19:22:09 glbuild -# modified module.version -# -# Revision 1.11 2004/08/17 13:46:28 eronchie -# Added interface -# -# Revision 1.10 2004/08/17 13:41:20 eronchie -# Moved out JobIdExceptions.h cjobid.h JobId.h -# Put in interface/glite/wmsutils/jobid -# -# Revision 1.9 2004/08/17 10:40:34 eronchie -# Added optimize option -# -# Revision 1.8 2004/07/27 09:14:19 eronchie -# Removed AC_WMSUTILS_EXCEPTION and AC_GLOBUS_SSL_UTILS checks -# Set directly exception library macro -# -# Revision 1.7 2004/07/21 17:53:36 eronchie -# Moved out org.glite.wms.jobid from org.glite.wms and put in org.glite.wms-utils -# -# -# - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([GLite WMS Utils Jobid], [3.1.1]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/jobid/strmd5.h]) - -# Notices. -AC_COPYRIGHT([Copyright (c) 2004 The EU EGEE Project -See LICENCE file for details -]) -AC_REVISION([$Revision$]) - -#Environment. -WORKDIR=`pwd` -AC_SUBST(WORKDIR) - -# Checks for programs. -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_CXXCPP -AM_PROG_CC_C_O -AC_PROG_LIBTOOL - -# Checks for libraries. - -# Checks for header files. -AC_CHECK_HEADERS([fcntl.h mntent.h sys/vfs.h syslog.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_CHECK_MEMBERS([struct stat.st_rdev]) -AC_TYPE_UID_T -AC_CHECK_TYPES([ptrdiff_t]) - -# Checks for library functions. -AC_HEADER_STDC -AC_FUNC_ERROR_AT_LINE -AC_FUNC_GETMNTENT -AC_FUNC_MEMCMP -AC_FUNC_STAT -AC_FUNC_STRFTIME -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([bzero endpwent ftruncate getmntent memset mkdir pow strerror strtol]) - -have_globus=no - -AC_GLOBUS([], have_globus=yes, have_globus=no) -AC_MSG_RESULT(["GLOBUS found $have_globus"]) - -if test "$have_globus" = "no"; then - AC_MSG_RESULT(["Please verify GLOBUS package"]) -fi - -if test "$have_globus" = "no"; then - AC_MSG_ERROR([Cannot continue building]) -fi -AC_GLITE - -GLITE_WMSUTILS_EXCEPTION_LIBS="-L$GLITE_LOCATION/lib -lglite_wmsutils_exception" - -AC_SUBST(GLITE_WMSUTILS_EXCEPTION_LIBS) - -AC_OPTIMIZE - -# Configuration items -AC_PREFIX_DEFAULT([/opt/glite]) -AM_CONFIG_HEADER([src/autogen/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([examples/Makefile]) -AC_CONFIG_FILES([interface/Makefile]) -AC_CONFIG_FILES([src/Makefile]) -AC_CONFIG_FILES([src/jobid/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.jobid/examples/Makefile.am b/org.glite.wms-utils.jobid/examples/Makefile.am deleted file mode 100755 index fa9a407..0000000 --- a/org.glite.wms-utils.jobid/examples/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -STDCPP = -lstdc++ - -JOBID = $(top_builddir)/src/jobid/libglite_wmsutils_cjobid.la - -check_PROGRAMS = testjobid - -testjobid_SOURCES = testjobid.c -testjobid_LDADD = \ - $(JOBID) \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_SSL_THR_LIBS) \ - $(STDCPP) - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.jobid/examples/testjobid.c b/org.glite.wms-utils.jobid/examples/testjobid.c deleted file mode 100755 index 56f6cba..0000000 --- a/org.glite.wms-utils.jobid/examples/testjobid.c +++ /dev/null @@ -1,33 +0,0 @@ -/* test code for jobid routines */ - -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" - -int main(int argc, char* argv[]) -{ - char* ju; - char* bkserver = "ujsa.uhjs"; - - edg_wlc_JobId ji = 0; - edg_wlc_JobId ji2 = 0; - - int r = edg_wlc_JobIdCreate(bkserver, 0, &ji); - printf("Create: %d\n", r); - - ju = edg_wlc_JobIdUnparse(ji); - printf("Unparse: %s\n", ju); - - edg_wlc_JobIdParse(ju, &ji2); - free(ju); - - ju = edg_wlc_JobIdUnparse(ji); - printf("Unparse2: %s\n", ju); - free(ju); - - edg_wlc_JobIdFree(ji); - edg_wlc_JobIdFree(ji2); - - return 0; -} diff --git a/org.glite.wms-utils.jobid/interface/Makefile.am b/org.glite.wms-utils.jobid/interface/Makefile.am deleted file mode 100755 index 8737f19..0000000 --- a/org.glite.wms-utils.jobid/interface/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -jobiddir = $(includedir) -nobase_jobid_HEADERS = \ - glite/wmsutils/jobid/cjobid.h \ - glite/wmsutils/jobid/manipulation.h \ - glite/wmsutils/jobid/JobIdExceptions.h \ - glite/wmsutils/jobid/JobId.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h deleted file mode 100755 index 8d0b7b4..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_JOBID_H -#define GLITE_WMSUTILS_JOBID_JOBID_H - -/* - * JobId.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * - */ - -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" - -typedef struct _edg_wlc_jobid_s* edg_wlc_jobid_t; - -namespace glite { -namespace wmsutils { -namespace jobid { - -/** - * Managing Identification, checking, retreiving info from a job - * File name: JobId.h - * The JobId class provides a representation of the Datagrid job identifier - * (dg_jobId) and the methods for manipulating it. - * We remind that the format of the dg_jobId is as follows: - * :/ - * - * @ingroup common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini */ - -class JobId { -public: - /**@name Constructors/Destructor */ - //@{ - /** Instantiates an empty JobId object */ - JobId() ; - /** - * Instantiates a JobId object from the passed dg_jobId in string format. - * @param job_id_string a string representig a classAd expression - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const std::string& job_id_string); - JobId(const JobId&); - JobId(const edg_wlc_JobId&); - /** - * Destructor - * Destroy the Job Id instance - */ - ~JobId() ; - //@} - - /**@name Miscellaneous */ - //@{ - /** Unsets the JobId instance. Clear all it's memebers */ - void clear() ; - /** - * Check wheater the jobId has been already created (true) or not (false) - *@return true (jobId created) or false (jobId not yet created) - */ - bool isSet() { return ( m_JobId != 0 ) ; } - /** - * Set the JobId instance according to the LB and RB server addresses and the unique string passed as input parameters. - * @param lb_server Loggin and Bookkeeping server address - * @param port Loggin and Bookkeeping port ( dafault value is 9000 ) - * @param unique A Unique identification ( automatically generatad by md5 protocol ) - * @throws WrongIdException When one parameter has been passed in a wrong format */ - void setJobId(const std::string& lb_server, int port = 0, const std::string& unique = ""); - //@} - /**@name Get Methods */ - //@{ - /** @return the LB address into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getServer() const; - /** @return the Unique string into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getUnique() const; - //@} - /** This method sets the JobId instance from the JobId in string format given - * as input. - * @param dg_JobId the string representing the job - * @throws WrongIdException When a string is passed in a wrong format */ - void fromString ( const std::string& dg_JobId ); - /** Converts the jobId into a string - @return the string representation of a JobId*/ - std::string toString() const; - /** casting operator */ - operator const edg_wlc_JobId() const { return m_JobId; } - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(JobId const &); - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(const edg_wlc_JobId &); - /** Retrieve the internal id reference - *@return the JobId internal reference used by some LB methods */ - edg_wlc_JobId getId() const ; -private: - // This Variable stores the Job unique identification String - edg_wlc_JobId m_JobId; - mutable char* m_pStr; - mutable char* m_pBkserver; - mutable char* m_pUnique; - /** Operator "<"*/ - friend bool operator<(JobId const& lhs, JobId const& rhs); - /** Operator "=="*/ - friend bool operator==(JobId const& lhs, JobId const& rhs); -}; - -inline bool operator<(JobId const& lhs, JobId const& rhs) -{ - return strcmp ( lhs.m_pStr , rhs.m_pStr ) <0 ; -} - -inline bool operator==(JobId const& lhs, JobId const& rhs) -{ -return strcmp ( lhs.m_pStr , rhs.m_pStr ) ==0 ; -} - -std::ostream& operator<<(std::ostream& os, JobId const& id); - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_JOBID_H diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h deleted file mode 100755 index 42cbdf4..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_EXCEPTIONS_H -#define GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - -/* - * JobIdExceptions.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - */ - -#include "glite/wmsutils/exception/Exception.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -/** - * JobIdException - Exception thrown by JobId Class - * @ingroup Common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini -*/ - -class JobIdException : public glite::wmsutils::exception::Exception { -public: - /** - * Update all mandatory Exception Information - */ - JobIdException (const std::string& file, - int line, - const std::string& method, - int code, - const std::string& exception_name) ; -};//End CLass JobIdException - -/** -* WrongIdFieldException -* This Exception is thrown when a Job Id syntax error is found -* A valid Job Identification string should be made as follows: -* :/ */ -class WrongIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The wrong expression catched */ - WrongIdException(const std::string& file, - int line, - const std::string& method, - int code ); -}; //End CLass WrongIdException -/** -* EmptyIdException -* This Exception is thrown when the user tries to get information from a JobId -* which has not been initialized yet, i.e tries to use the get Methods -*/ -class EmptyIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The Empty filed requested for */ - EmptyIdException::EmptyIdException(const std::string& file, - int line, - const std::string& method, - int code , - const std::string& field ); -}; //End CLass EmptyIdException - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h deleted file mode 100755 index e8f84f5..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _GLITE_JOBID_H -#define _GLITE_JOBID_H - -/*! - * \file cjobid.h - * \brief L&B consumer API - */ - -#ident "$Header$" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _edg_wlc_JobId *edg_wlc_JobId; - -#define GLITE_WMSC_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */ -#define GLITE_WMSC_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */ - - -/* All the pointer functions return malloc'ed objects (or NULL on error) */ - -/** - * Create a Job ID. - * See the lb_draft document for details on its construction and components - * \param bkserver book keeping server hostname - * \param port port for the bk service - * \param jobid new created job id - * \ret al 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdCreate(const char * bkserver, int port, edg_wlc_JobId * jobid); - -/** - * Recreate a Job ID - * \param bkserver bookkeeping server hostname - * \param port port for the bk service - * \param unique string which represent created jobid (if NULL then new - * one is created) - * \param jobid new created job id - * \retval 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdRecreate(const char *bkserver, int port, const char * unique, edg_wlc_JobId * jobid); - -/** - * Create copy of Job ID - * \param in jobid for duplication - * \param jobid duplicated jobid - * \retval 0 for success - * \retval EINVAL invalid jobid - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId * jobid); - -/* - * Free jobid structure - * \param jobid for dealocation - */ -void edg_wlc_JobIdFree(edg_wlc_JobId jobid); - -/** - * Parse Job ID string and creates jobid structure - * \param jobidstr string representation of jobid - * \param jobid parsed job id - * \retval 0 for success - * \retval EINVAL jobidstr can't be parsed - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdParse(const char* jobidstr, edg_wlc_JobId * jobid); - -/** - * Unparse Job ID (produce the string form of JobId). - * \param jobid to be converted to string - * \return allocated string which represents jobid - */ -char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid); - -/** - * Extract bookkeeping server address (address:port) - * \param jobid from which the bkserver address should be extracted - * \retval pointer to allocated string with bkserver address - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid); - -#ifdef __cplusplus -} -#endif - -#endif /* _GLITE_JOBID_H */ diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h deleted file mode 100755 index 9f862ae..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_MANIPULATION_H -#define GLITE_WMSUTILS_JOBID_MANIPULATION_H - -#include - -namespace glite { -namespace wmsutils { -namespace jobid { - -class JobId; - -std::string get_reduced_part( const JobId &id, int level = 0 ); -std::string to_filename( const JobId &id ); -JobId from_filename( const std::string &filename ); - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif /* GLITE_WMSUTILS_JOBID_MANIPULATION_H */ - -// Local Variables: -// mode: c++ -// End: diff --git a/org.glite.wms-utils.jobid/project/build.number b/org.glite.wms-utils.jobid/project/build.number deleted file mode 100644 index 1acc27a..0000000 --- a/org.glite.wms-utils.jobid/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 02:12:40 CEST 2005 -module.build=152 diff --git a/org.glite.wms-utils.jobid/project/build.properties b/org.glite.wms-utils.jobid/project/build.properties deleted file mode 100755 index f5a9095..0000000 --- a/org.glite.wms-utils.jobid/project/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -build.package.summary="files for gLite wms utils jobid" -build.package.description="jobid api" diff --git a/org.glite.wms-utils.jobid/project/configure.properties.xml b/org.glite.wms-utils.jobid/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.jobid/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.jobid/project/properties.xml b/org.glite.wms-utils.jobid/project/properties.xml deleted file mode 100755 index 9662658..0000000 --- a/org.glite.wms-utils.jobid/project/properties.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/project/version.properties b/org.glite.wms-utils.jobid/project/version.properties deleted file mode 100755 index 40c3916..0000000 --- a/org.glite.wms-utils.jobid/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=3.1.1 -module.age=1 diff --git a/org.glite.wms-utils.jobid/src/Makefile.am b/org.glite.wms-utils.jobid/src/Makefile.am deleted file mode 100755 index 5225c64..0000000 --- a/org.glite.wms-utils.jobid/src/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Subdirectories list -SUBDIRS = jobid - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp b/org.glite.wms-utils.jobid/src/jobid/JobId.cpp deleted file mode 100755 index 273f9f9..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* ************************************************************************** - * filename : JobId.cpp - * author : Alessandro Maraschini - * copyright : (C) 2002 by DATAMAT - ***************************************************************************/ - -#include "glite/wmsutils/jobid/JobId.h" - -#include - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -using namespace std ; - -/****************************************************************** - Constructor / Destructor - *******************************************************************/ -JobId::JobId() : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 ) -{ -} - -JobId::JobId(const std::string& job_id_string ) - : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 ) -{ - fromString( job_id_string ) ; -} - -JobId::JobId(const JobId &old) -{ - edg_wlc_JobIdDup(old.m_JobId,&m_JobId); - m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0; - m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0; - m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0; -} - -JobId & JobId::operator=(JobId const &old) -{ - clear(); - edg_wlc_JobIdDup(old.m_JobId,&m_JobId); - m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0; - m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0; - m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0; - - return *this; -} - - -JobId::JobId(const edg_wlc_JobId &old) - : m_pStr(0), m_pBkserver(0), m_pUnique(0) -{ - edg_wlc_JobIdDup(old,&m_JobId); -} - - -JobId & JobId::operator=(const edg_wlc_JobId &old) -{ - clear(); - edg_wlc_JobIdDup(old,&m_JobId); - m_pStr = 0; - m_pBkserver = 0; - m_pUnique = 0; - return(*this); -} - -JobId::~JobId() -{ - clear(); -} - -/****************************************************************** - method : clear - unsets the JobId instance. - *******************************************************************/ -void JobId::clear() -{ - if ( m_JobId ) - { - edg_wlc_JobIdFree( m_JobId ); - m_JobId = 0; - if (m_pStr) - free(m_pStr); - if (m_pBkserver) - free(m_pBkserver); - if (m_pUnique) - free(m_pUnique); - m_pStr = m_pBkserver = m_pUnique = NULL; - } -} - - -/****************************************************************** - method : setJobId - sets the JobId instance according to the LB and RB - server addresses and the unique string passed as input parameters. - *******************************************************************/ -void JobId::setJobId(const string& bkserver, int port, const string& unique) -{ - int code = edg_wlc_JobIdRecreate(bkserver.c_str(), port, unique.size() ? unique.c_str() : NULL, &m_JobId) ; - if ( code != 0 ) - throw WrongIdException(__FILE__ , __LINE__ , "setJobId(const string& bkserver, int port, const string& unique)" , code ) ; -} - - -/****************************************************************** - Protected method : fromString - sets the JobId instance from the dg_jobId in string format given as input. - *******************************************************************/ -void JobId::fromString (const string& dg_JobId) -{ - clear(); - int code = edg_wlc_JobIdParse(dg_JobId.c_str(), &m_JobId) ; - if ( code != 0 ) - throw WrongIdException(__FILE__ , __LINE__ , "fromString (const string& dg_JobId)" , code ) ; -} - -/****************************************************************** - method : ToString - converts the JobId instance into its string format. - and put it in the dg_jobId output variable - *******************************************************************/ -std::string JobId::toString() const -{ - if ( m_JobId && !m_pStr ) - m_pStr = edg_wlc_JobIdUnparse(m_JobId) ; - if ( !m_pStr ) - throw EmptyIdException (__FILE__ , __LINE__ ,"toString()" ,ENOENT , "JobId") ; - return m_pStr; -} - -/****************************************************************** - method : getServer - return a string containing the LB server address, - *******************************************************************/ -std::string JobId::getServer() const -{ - if ( m_JobId && !m_pBkserver ) - m_pBkserver = edg_wlc_JobIdGetServer( m_JobId ) ; - - if ( !m_pBkserver ) - throw EmptyIdException (__FILE__ , __LINE__ , "getServer()", ENOENT , "LB server Address") ; - - return m_pBkserver; -} - -/****************************************************************** - method : getUnique - return a string containing unique jobid string - *******************************************************************/ -std::string JobId::getUnique() const -{ - if ( m_JobId && !m_pUnique ) - m_pUnique = edg_wlc_JobIdGetUnique( m_JobId ) ; - - if ( !m_pUnique ) - throw EmptyIdException (__FILE__ , __LINE__ , "getUnique()" , ENOENT , "Unique") ; - - return m_pUnique; -} -/****************************************************************** - method : getId - return the c JobId struct representing this instance - *******************************************************************/ -edg_wlc_JobId JobId::getId() const -{ - edg_wlc_JobId out ; - if ( edg_wlc_JobIdDup(m_JobId, &out) ) - throw EmptyIdException (__FILE__ , __LINE__ , "getId()" , ENOENT , "JobId") ; - return out ; -} - -std::ostream& -operator<<(std::ostream& os, JobId const& id) -{ - return os << id.toString(); -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp b/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp deleted file mode 100755 index 6be40b7..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* ************************************************************************** -* filename : JobIdExecptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -using namespace std; -using namespace glite::wmsutils::exception; - -/***************************** -* JobIdException -*****************************/ -JobIdException::JobIdException (const string& file, - int line, - const string& method, - int code, - const string& exception_name) - : Exception(file, line, method, code, exception_name) -{ -} - -/***************************** -* WrongIdException -*****************************/ -WrongIdException::WrongIdException(const string& file, - int line, - const string& method, - int code ) - : JobIdException(file, line, method, code, - "WrongIdException") -{ - error_message = "Wrong Field caught while parsing Job Id" ; -} - -/***************************** -* EmptyIdException -*****************************/ -EmptyIdException::EmptyIdException(const string& file, - int line, - const string& method, - int code , - const string& field ) - : JobIdException(file, line, method, code, - "EmptyIdException") -{ - error_message = "Unable to retrieve " + field + ": the instance has not been initialized yet"; -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - diff --git a/org.glite.wms-utils.jobid/src/jobid/Makefile.am b/org.glite.wms-utils.jobid/src/jobid/Makefile.am deleted file mode 100755 index 7a23118..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -lib_LTLIBRARIES = libglite_wmsutils_jobid.la libglite_wmsutils_cjobid.la - -libglite_wmsutils_jobid_la_SOURCES = \ - JobId.cpp \ - JobIdExceptions.cpp \ - manipulation.cpp - -libglite_wmsutils_cjobid_la_SOURCES = \ - cjobid.c \ - strmd5.c - -jobidincludedir = $(includedir)/glite/wmsutils/jobid -jobidinclude_HEADERS = \ - strmd5.h - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - -D_GNU_SOURCE - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/src/jobid/cjobid.c b/org.glite.wms-utils.jobid/src/jobid/cjobid.c deleted file mode 100755 index 2fa0010..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/cjobid.c +++ /dev/null @@ -1,258 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" -#include "strmd5.h" - -struct _edg_wlc_JobId { - char *id; /* unique job identification */ - /* additional information */ - char *BShost;/* bookkeeping server hostname */ - unsigned int BSport; /* bookkeeping server port */ - char *info; /* additional information (after ? in URI) */ -}; - -int edg_wlc_JobIdCreate(const char *bkserver, int port, edg_wlc_JobId *jobId) -{ - return edg_wlc_JobIdRecreate(bkserver, port, NULL, jobId); -} - - -int edg_wlc_JobIdRecreate(const char* bkserver, int port, const char *unique, edg_wlc_JobId *jobId) -{ - edg_wlc_JobId out; - char hostname[200]; /* used to hold string for encrypt */ - struct timeval tv; - int skip; - char* portbeg; - - struct hostent* he; - - if (!bkserver) - return EINVAL; - - if (unique == NULL) { - gethostname(hostname, 100); - he = gethostbyname(hostname); - assert(he->h_length > 0); - gettimeofday(&tv, NULL); - srandom(tv.tv_usec); - - skip = strlen(hostname); - skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d", - *((int*)he->h_addr_list[0]), getpid(), (int)random(), - (int)tv.tv_sec, (int)tv.tv_usec); - } - - *jobId = NULL; - out = (edg_wlc_JobId) malloc (sizeof(*out)); - if (!out) - return ENOMEM; - - memset(out, 0, sizeof(*out)); - - /* check if it begins with prefix */ - /* unsupported */ - if (strncmp(bkserver, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX)-1) == 0) - return EINVAL; - - out->BShost = strdup(bkserver); - portbeg = strchr(out->BShost, ':'); - if (portbeg) { - *portbeg = 0; - /* try to get port number */ - if (port == 0) - port = atoi(portbeg + 1); - } - - if (port == 0) - port = GLITE_WMSC_JOBID_DEFAULT_PORT; - - out->BSport = port; - - out->id = (unique) ? strdup(unique) : str2md5base64(hostname); - //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id); - - if (!out->id || !out->BShost) { - edg_wlc_JobIdFree(out); - return ENOMEM; - } - - *jobId = out; - return 0; -} - - -int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId *out) -{ - edg_wlc_JobId jid; - *out = NULL; - if (in == NULL) - return 0; - - jid = malloc(sizeof(*jid)); - if (!jid) - return ENOMEM; - - memset(jid, 0,sizeof(*jid)); - jid->BShost = strdup(in->BShost); - jid->id = strdup(in->id); - if (in->info) - jid->info = strdup(in->info); - - if (jid->BShost == NULL || jid->id == NULL) { - edg_wlc_JobIdFree(jid); - return ENOMEM; - } - - jid->BSport = in->BSport; - *out = jid; - return 0; -} - - -// XXX -// use recreate -// parse name, port, unique -int edg_wlc_JobIdParse(const char *idString, edg_wlc_JobId *jobId) -{ - char *pom, *pom1, *pom2; - edg_wlc_JobId out; - - *jobId = NULL; - - out = (edg_wlc_JobId) malloc (sizeof(*out)); - if (out == NULL ) - return ENOMEM; - - memset(out,0,sizeof(*out)); - - if (strncmp(idString, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1)) { - out->BShost = (char *) NULL; - out->BSport = 0; - - free(out); - return EINVAL; - } - - pom = strdup(idString + sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1); - pom1 = strchr(pom, '/'); - pom2 = strchr(pom, ':'); - - if (!pom1) { free(pom); free(out); return EINVAL; } - - if ( pom2 && (pom1 > pom2)) { - pom[pom2-pom] = '\0'; - out->BShost = strdup(pom); - pom[pom1-pom] = '\0'; - out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10); - } else { - pom[pom1-pom] = '\0'; - out->BShost = strdup(pom); - out->BSport = GLITE_WMSC_JOBID_DEFAULT_PORT; - } - - /* XXX: localhost not supported in jobid - if (!strncmp(out->BShost,"localhost",9) { - free(pom); - free(out->BShost); - free(out); - return EINVAL; - } - */ - - /* additional info from URI */ - pom2 = strchr(pom1+1,'?'); - if (pom2) { - *pom2 = 0; - out->info = strdup(pom2+1); - } - - /* extract the unique part */ - out->id = strdup(pom1+1); - - for (pom1 = out->BShost; *pom1; pom1++) - if (isspace(*pom1)) break; - - for (pom2 = out->id; *pom2; pom2++) - if (isspace(*pom2)) break; - - if (*pom1 || *pom2) { - free(pom); - edg_wlc_JobIdFree(out); - return EINVAL; - } - - free(pom); - *jobId = out; - return 0; -} - - -void edg_wlc_JobIdFree(edg_wlc_JobId job) -{ - if (job) { - free(job->id); - free(job->BShost); - free(job->info); - free(job); - } -} - - -char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid) -{ - char *out, port[40]; - - if (!jobid) - return NULL; - - if (jobid->BSport) - sprintf(port,":%d",jobid->BSport); - else - *port = 0; - - asprintf(&out, GLITE_WMSC_JOBID_PROTO_PREFIX"%s%s/%s%s%s", - jobid->BShost,port, - jobid->id, - (jobid->info ? "?" : ""), - (jobid->info ? jobid->info : "")); - - return out; -} - - -char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid) -{ - char *bs = NULL; - - if (jobid) - asprintf(&bs, "%s:%u", jobid->BShost, - jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT); - - return bs; -} - - -void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = strdup(jobid->BShost); - *srvPort = jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT; - } -} - - -char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid) -{ - return jobid ? strdup(jobid->id) : NULL; -} diff --git a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp b/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp deleted file mode 100755 index cf3a710..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include - -#include -#include - -#include "glite/wmsutils/jobid/JobId.h" - -using namespace std; - -namespace glite { -namespace wmsutils { -namespace jobid { - -namespace { - -class HexInt { -public: - HexInt( unsigned int i = 0 ); - HexInt( const string &str ); - HexInt( string::const_iterator begin, string::const_iterator end ); - ~HexInt( void ); - - inline operator unsigned int( void ) const { return this->hi_int; } - inline operator const string &( void ) const { return this->hi_str; } - - static unsigned int least( void ) { return hi_s_least; } - static void least( unsigned int least ) { hi_s_least = least; } - -private: - void parseString( void ); - - unsigned int hi_int; - string hi_str; - - static unsigned int hi_s_least; - static const char *hi_s_map; -}; - -class BadChar { -public: - BadChar( void ); - ~BadChar( void ); - - inline bool operator()( char c ) - { return( !(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || - (c == '.') || (c == '-') || (c == ' ')) ); } -}; - -unsigned int HexInt::hi_s_least = 2; -const char *HexInt::hi_s_map = "0123456789abcdef"; - -HexInt::HexInt( unsigned int ui ) : hi_int( ui ), hi_str( hi_s_least, '0' ) -{ - int n; - string::reverse_iterator pos = this->hi_str.rbegin(); - - while( ui != 0 ) { - n = ui % 16; - if( pos != this->hi_str.rend() ) { - *pos = hi_s_map[n]; - pos += 1; - } - else this->hi_str.insert( this->hi_str.begin(), hi_s_map[n] ); - - ui /= 16; - } - - if( this->hi_str.length() < hi_s_least ) - this->hi_str.insert( this->hi_str.begin(), (hi_s_least - this->hi_str.length()), '0' ); -} - -HexInt::HexInt( const string &str ) : hi_int( 0 ), hi_str( str ) -{ - this->parseString(); -} - -HexInt::HexInt( string::const_iterator begin, string::const_iterator end ) : hi_int( 0 ), hi_str( begin, end ) -{ - this->parseString(); -} - -void HexInt::parseString( void ) -{ - int hexbase; - char *pos, *end = (char *) hi_s_map + 16; - string::reverse_iterator it; - - for( it = this->hi_str.rbegin(), hexbase = 1; it != this->hi_str.rend(); ++it, hexbase *= 16 ) { - pos = find( (char *) hi_s_map, end, (char) tolower(*it) ); - - if( pos != end ) this->hi_int += hexbase * (pos - hi_s_map); - else { - this->hi_int = 0; - break; - } - } - - return; -} - -HexInt::~HexInt( void ) {} - -BadChar::BadChar( void ) {} - -BadChar::~BadChar( void ) {} - -/* - Helper function for the get_reduced_part(...) -*/ -string get_reduced_part_internal( const string &unique, int level ) -{ - string::size_type length = unique.length(); - string piece( unique.substr(0, 2) ), answer; - - if( (level == 0) || (length <= 2) ) answer.assign( piece ); - else if( length != 0 ) { - answer.assign( piece ); - answer.append( 1, '/' ); - answer.append( get_reduced_part_internal(unique.substr(2, length - 2), level - 1) ); - } - - return answer; -} - -}; // Unnamed namespace - -string get_reduced_part( const JobId &id, int level ) -{ - return get_reduced_part_internal( id.getUnique(), level ); -} - -string to_filename( const JobId &id ) -{ - string sid( id.toString() ), coded; - string::iterator last, next; - - last = sid.begin(); - do { - next = find_if( last, sid.end(), BadChar() ); - - if( next != sid.end() ) { - if( last != next ) coded.append( last, next ); - coded.append( 1, '_' ); - coded.append( HexInt(*next) ); - - last = next + 1; - } - else coded.append( last, sid.end() ); - } while( next != sid.end() ); - - return coded; -} - -JobId from_filename( const string &filename ) -{ - char c; - string decoded; - string::const_iterator last, next; - - last = filename.begin(); - do { - next = find( last, filename.end(), '_' ); - - if( next != filename.end() ) { - c = HexInt( next + 1, next + 3 ); - - if( last != next ) decoded.append( last, next ); - decoded.append( 1, c ); - - last = next + 3; - } - else decoded.append( last, filename.end() ); - } while( next != filename.end() ); - - return JobId( decoded ); -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.c b/org.glite.wms-utils.jobid/src/jobid/strmd5.c deleted file mode 100755 index 0433f55..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.c +++ /dev/null @@ -1,118 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "jobid/strmd5.h" - -#warning Thread unsafe! -static char mbuf[33]; - -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - unsigned char* enc_buf = (unsigned char*)enc; - int out_size = 0; - unsigned int bits = 0; - unsigned int shift = 0; - - while ( out_size < out_max_size ) { - if ( enc_size>0 ) { - // Shift in byte - bits <<= 8; - bits |= *enc_buf; - shift += 8; - // Next byte - enc_buf++; - enc_size--; - } else if ( shift>0 ) { - // Pad last bits to 6 bits - will end next loop - bits <<= 6 - shift; - shift = 6; - } else { - // Terminate with Mime style '=' - *out = '='; - out_size++; - - return out_size; - } - - // Encode 6 bit segments - while ( shift>=6 ) { - shift -= 6; - *out = b64[ (bits >> shift) & 0x3F ]; - out++; - out_size++; - } - } - - // Output overflow - return -1; -} - -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.h b/org.glite.wms-utils.jobid/src/jobid/strmd5.h deleted file mode 100755 index c5d76b6..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ident "$Header$" - -/* Compute MD5 sum of the first argument. - * The sum is returned in the 16-byte array pointed to by 2nd argument - * (if not NULL) - * - * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f] - * (pointer to static area, changed by subsequent calls) - */ - -char *strmd5(const char *src, unsigned char *dst); - -/** - * Returns: allocated 32bytes long ASCII string with md5 sum - * of the first argument - */ -char *str2md5(const char *src); - -/** - * Returns: allocated 22bytes long ASCII string with md5 sum in base64 - * format of the source argument - */ -char *str2md5base64(const char *src); - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.wms-utils.jobid/test/Makefile.am b/org.glite.wms-utils.jobid/test/Makefile.am deleted file mode 100755 index 5111c30..0000000 --- a/org.glite.wms-utils.jobid/test/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -JOBID_LIBS = $(top_builddir)/src/jobid/libglite_wmsutils_jobid.la -CJOBID_LIBS = $(top_builddir)/src/jobid/libglite_wmsutils_cjobid.la - -TESTS = glite-wmsutils-jobid \ - glite-wmsutils-manipulation - -check_PROGRAMS = $(TESTS) - -glite_wmsutils_jobid_SOURCES = jobid_cu_suite.cpp \ - jobid_cu_suite.h \ - jobid_cu_main.cpp - -glite_wmsutils_jobid_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(CPPUNIT_LIBS) \ - $(JOBID_LIBS) \ - $(CJOBID_LIBS) - -glite_wmsutils_manipulation_SOURCES = manipulation_cu_suite.cpp \ - manipulation_cu_suite.h \ - manipulation_cu_main.cpp - -glite_wmsutils_manipulation_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(CPPUNIT_LIBS) \ - $(JOBID_LIBS) \ - $(CJOBID_LIBS) - - -AM_CPPFLAGS = -I$(top_srcdir)/interface \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/test \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - $(CPPUNIT_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp b/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp deleted file mode 100644 index 770e306..0000000 --- a/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "jobid_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Jobid_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp b/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp deleted file mode 100644 index ebe04da..0000000 --- a/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "jobid_cu_suite.h" - - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::jobid; - - -void Jobid_test::setUp() -{} - -void Jobid_test::tearDown() -{} - -void Jobid_test::Constructor_case() -{ - //EMPTY CONSTRUCTOR - JobId empty; - - CPPUNIT_ASSERT(empty.isSet()==false); - - //create a string with cjobid - string bkserver="grid012g.cnaf.infn.it"; - edg_wlc_JobId jobid; - int bkport=6000; - int ok=edg_wlc_JobIdCreate(bkserver.c_str(), bkport, &jobid); - CPPUNIT_ASSERT(ok == 0); - if (ok==0) - { - string jobstring=edg_wlc_JobIdUnparse(jobid); - - //STRING CONSTRUCTOR - JobId stringCons(jobstring); - - //EDG_WLC CONSTRUCTOR - JobId edg_wlc_Cons(jobid); - - //test copy constructor - JobId copycon(stringCons); - - CPPUNIT_ASSERT(stringCons.isSet()); - CPPUNIT_ASSERT(edg_wlc_Cons.isSet()); - CPPUNIT_ASSERT(copycon.isSet()); - - //test = - JobId testequal; - testequal=stringCons; - CPPUNIT_ASSERT(testequal.isSet()); - - JobId testoperator; - testoperator=jobid; - CPPUNIT_ASSERT(testoperator.isSet()); - - edg_wlc_JobId testget = edg_wlc_Cons.getId(); - char *server; - unsigned int port; - edg_wlc_JobIdGetServerParts(testget, &server, &port); - string serverstring = server; - CPPUNIT_ASSERT(port==bkport); - CPPUNIT_ASSERT(serverstring==bkserver); - } - - CPPUNIT_ASSERT_THROW( JobId stringwrong("grid012"), WrongIdException); -} - -void Jobid_test::Clear_case() -{ - JobId *element; - string jobstring="https://grid012g.cnaf.infn.it:6000/qaKyEoV3G144rmoyXeW6QA"; - CPPUNIT_ASSERT_NO_THROW(element= new JobId(jobstring)); - - CPPUNIT_ASSERT(element->isSet()); - element->clear(); - CPPUNIT_ASSERT(element->isSet()==false); - delete element; -} - -void Jobid_test::SetandGet_case() -{ - JobId element; - string lbserver="grid012g.cnaf.infn.it"; - int port=6000; - string unique ="qaKyEoV3G144rmoyXeW6QA"; - element.setJobId(lbserver, port, unique); - - string server=element.getServer(); - lbserver=lbserver+":6000"; - - CPPUNIT_ASSERT(server==lbserver); - string lonely=element.getUnique(); - CPPUNIT_ASSERT(lonely==unique); - - string descr=element.toString(); - cout << "!!! BEGIN TEST toString() METHOD!!!"<< endl; - cout << descr < -#include -#include - -#include - -#include "glite/wmsutils/jobid/JobId.h" -#include "glite/wmsutils/jobid/cjobid.h" -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -class Jobid_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Jobid_test); - - CPPUNIT_TEST(Constructor_case); - CPPUNIT_TEST(Clear_case); - CPPUNIT_TEST(SetandGet_case); - - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void Constructor_case(); - void Clear_case(); - void SetandGet_case(); - -}; - - - diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp b/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp deleted file mode 100644 index 07d2914..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "manipulation_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Manipulation_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp b/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp deleted file mode 100644 index a6a69d8..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "manipulation_cu_suite.h" - - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::jobid; - - -void Manipulation_test::setUp() -{} - -void Manipulation_test::tearDown() -{} - -void Manipulation_test::to_fromfile_case() -{ - JobId element; - - string lbserver="grid012g.cnaf.infn.it"; - int port=6000; - string unique ="qaKyEoV3G144rmoyXeW6QA"; - element.setJobId(lbserver, port, unique); - - string filename=to_filename(element); - - JobId newelement = from_filename(filename); - - string reduced = get_reduced_part(element, 7); - - string newreduced = get_reduced_part(newelement, 7); - - CPPUNIT_ASSERT(reduced==newreduced); -} - diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h b/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h deleted file mode 100644 index 287b902..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -#include - -#include "glite/wmsutils/jobid/JobId.h" -#include "glite/wmsutils/jobid/manipulation.h" - -class Manipulation_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Manipulation_test); - - CPPUNIT_TEST(to_fromfile_case); - - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void to_fromfile_case(); - -}; - - - diff --git a/org.gridsite.core/.cvsignore b/org.gridsite.core/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.gridsite.core/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES deleted file mode 100644 index f5c895b..0000000 --- a/org.gridsite.core/CHANGES +++ /dev/null @@ -1,364 +0,0 @@ -* Fri Feb 16 2007 Andrew McNab -- ==== GridSite version 1.5.0 ==== -* Fri Feb 16 2007 Andrew McNab -- ==== GridSite version 1.4.0 ==== -* Thu Feb 15 2007 Andrew McNab -- Final preparations for 1.4.x -* Fri Sep 22 2006 Andrew McNab -- Transfer htproxyinfo utility functions into - grst_x509.c (GRSTx509ChainLoadCheck etc) -* Wed Aug 6 2006 Andrew McNab -- ==== GridSite version 1.3.4 ==== -* Mon Jul 17 2006 Andrew McNab -- Add Shibboleth handling from Joseph Dada's branch to - mod_gridsite in main GridSite tree. -* Tue Jun 27 2006 Andrew McNab -- Merge delegation services back into core. -- Add OCSP options -* Thu Jun 22 2006 Andrew McNab -- Lots of additions to SiteCast/SlashGrid, including - /grid/local/ filesystem with DNs from gridmapdir -- GridSiteCastAlias now allows any URL scheme (gsiftp, - xrootd, ...) not just HTTP(S). -- Replace static gridsite.spec with make-gridsite-spec -* Fri Jun 9 2006 Andrew McNab -- Add patch from Jan Pospisil to - Makefile, to allow standalone building of libraries. -- Include code for June 2006 version of delegation - protocol (ie userproxy.pem rather than usercert.pem - and userkey.pem) -* Thu Jun 8 2006 Andrew McNab -- SiteCast support in SlashGrid -* Mon Jun 5 2006 Andrew McNab -- ==== GridSite version 1.3.1 ==== -* Sun May 26 2006 Andrew McNab -- Include SlashGrid code, and in gridsite.spec etc -- Add sample fuse.spec to docs for use with SlashGrid -* Fri May 26 2006 Andrew McNab -- ==== GridSite version 1.3.0 ==== -* Mon Apr 24 2006 Andrew McNab -- Reworked SSL session caching: passcodes directory now - because /var/www/sessions by default, and also used - to cache credentials according to SSL Session ID. -* Mon Apr 10 2006 Andrew McNab -- Patch from Alberto di Meglio - to allow use of relocated httpd include files. -* Mon Apr 3 2006 Andrew McNab -- Use dist for building tar balls -* Mon Apr 3 2006 Andrew McNab -- ==== GridSite version 1.1.19 ==== -* Fri Mar 31 2006 Andrew McNab -- Final tidy up for gLite 3.1 -* Fri Mar 31 2006 Andrew McNab -- ==== GridSite version 1.1.18 ==== -* Wed Mar 29 2006 Andrew McNab -- New proxy destroy and time functions. -* Tue Mar 28 2006 Shiv Kaushal -- Fixed bug in GACL admin interface that would cause - internal server erorr sometimes when adding new - entries to and ACL. -* Sat Mar 25 2006 Shiv Kaushal -- Change delegation header to Proxy-Delegation-Service - instead of Grst- -* Wed Mar 22 2006 Andrew McNab -- Add GRSTx509MakeDelegationID() to grst_x509.c -- Include code for new style delegation proxy storage -* Fri Mar 17 2006 Andrew McNab -- Associate ldconfig %post in spec with -shared RPM -* Thu Mar 16 2006 Andrew McNab -- Fixes for 200/201 error pages produced by Apache -- Fixes for onetime passcode non-removal if HTTPS -- Include new multi-RPM spec file: gridsite-shared, - gridsite-devel, gridsite-apache, gridsite-commands - (replacing htcp) and gridsite-gsexec -* Fri Mar 03 2006 Shiv Kaushal -- Modify GridSiteDelegationURI directive to insert HTTP - headers instead of modifying HTML -* Mon Feb 6 2006 Shiv Kaushal -- Add GridSiteDelegationURI directive to mod_gridsite - to allow Firefox extension to locate delegation service -* ==== GridSite version 1.1.17 ==== -* Thu Jan 12 2005 Andrew McNab -- Add 5 minute window for VOMS attributes valid slightly - in the future. -- Include Content-Range PUT support in mod_gridsite, - adapted from mod_dav by David O Callaghan -- Return 201 Created when PUT creates a file -* Mon Dec 5 2005 Andrew McNab -- Change GRIDHTTP_ONETIME to GRIDHTTP_PASSCODE -- Remove onetime=yes default from mod_gridsite -- Update gridsite.spec and Makefile for gridsite-copy.cgi -* Wed Nov 16 2005 Andrew McNab -- ==== GridSite version 1.1.16 ==== -* Wed Nov 16 2005 Andrew McNab -- Add -fPIC option to Makefile for IA64, as suggested - by Andreas Unterkircher. -* Wed Oct 12 2005 Andrew McNab -- ==== GridSite version 1.1.15 ==== -* Wed Oct 12 2005 Andrew McNab -- Fix for older OpenSSL to grst_x509.c from - Zoltan.Farkas -* Wed Oct 12 2005 Andrew McNab -- ==== GridSite version 1.1.14 ==== -* Tue Oct 11 2005 Andrew McNab -- Modify VOMS AC parsing to handle multiple ACs inside - the same X.509 AC extension. -* Mon Oct 10 2005 Andrew McNab -- ==== GridSite version 1.1.13 ==== -* Mon Oct 10 2005 Andrew McNab -- Add target_gname patch to gsexec from - Gerben Venekamp -* Thu Oct 6 2005 Andrew McNab -- Fix session reuse with Shared-Memory SSL Session - Cache bug #8856 in mod_gridsite. -- Add SiteCast support to file copying in htcp. -* Tue Oct 4 2005 Andrew McNab -- Move User, Config, Admin and Install guides from - doc directory into GridSite Wiki. -- Create/update man pages for htcp, mod_gridsite and - gsexec to be distributed with source/binaries. -* Mon Oct 3 2005 Andrew McNab -- Fix to gsexec GRST_CRED_0/SSL_CLIENT_S_DN bug found - by Ian Stokes-Rees -* Fri Sep 30 2005 Andrew McNab -- Add SiteCast ping (NOP) support to htcp -* Thu Sep 29 2005 Andrew McNab -- Add SiteCast support to mod_gridsite (file location - discovery via UDP multicast of HTCP messages.) -* Wed Sep 21 2005 Andrew McNab -- Add ports 777 and 488 to example httpd.conf files in - docs. See http://www.gridsite.org/wiki/IP_Ports -* Tue Sep 13 2005 Andrew McNab -- ==== GridSite version 1.1.12 ==== -* Tue Sep 13 2005 Andrew McNab -- Fix bug #10031 submitted by Fabrizio Pacini - (invalid free in - GRSTgaclAclLoadFile if ACL format not valid.) -* Mon Sep 12 2005 Andrew McNab -- Accept GRIDHTTP_ONETIME when passed in HTTP query - (still overridden by a GRIDHTTP_ONETIME in a cookie.) -* Sat Sep 10 2005 Andrew McNab -- Fix problem with attempted upgrades to GridHTTP when - already on the HTTP virtual server. -* Fri Sep 9 2005 Andrew McNab -- GRST_DESTINATION_TRANSLATED and GRST_DESTINATION_PERM - environment variables, for use with CGI-based COPY. -- Rework GridHTTP (ex-Downgrade) code to store method - and URI with permission, rather than credentials. -- Restrict use of GridSiteOnetimesDir to main server. -* Fri Aug 26 2005 Andrew McNab -- Fix for HTTP PUT lack-of-truncation bug found by - Mike Jones, and support for HTTP/WebDAV MOVE. -- Add MOVE support to htcp and update htcp manpage. -- Unset CURLOPT_SSL_VERIFYPEER in htcp etc when using - --noverify option. -* Fri Jun 10 2005 Andrew McNab -- ==== GridSite version 1.1.11 ==== -* Fri Jun 10 2005 Andrew McNab -- Tidy up gsexec vs GridSiteDiskMode -* Fri Jun 10 2005 Andrew McNab -- ==== GridSite version 1.1.10 ==== -* Wed Jun 8 2005 Andrew McNab -- Add GridSiteDiskMode Apache directive to set file - permissions. -- Add GridSiteExecMethod and GridSiteUserGroup to - configure suexec or extended gsexec functionality. -* Thu Jun 2 2005 Andrew McNab -- HTML improvements for Bug #4083 -- Note that GridSite currently doesn't work with SHM - SSL session cache, in httpd-*.conf and config guide. -- Add GridSiteExecMethod for use with gsexec -* Thu May 26 2005 Andrew McNab -- Include gsexec, a drop-in replacement for suexec, - which can do suexec execution of CGI programs or - pool-account mapping based on client DN. -* Tue May 24 2005 Shiv Kaushal -- Add XACML support to GACL code in libgridsite. -* Tue May 24 2005 Andrew McNab -- ==== GridSite version 1.1.9 ==== -* Mon Apr 25 2005 Andrew McNab -- Avoid build problems when using pre-0.9.7 OpenSSL - (ie with Globus compatibility.) -* Mon Apr 25 2005 Andrew McNab -- ==== GridSite version 1.1.8 ==== -* Mon Feb 28 2005 Andrew McNab -- Fix to GRSTgaclUndenyPerm in gridsite.h (bug #7135) - from Marco Sottilaro -* Mon Feb 28 2005 Andrew McNab -- ==== GridSite version 1.1.7 ==== -* Thu Feb 24 2005 Andrew McNab -- Add more sanity checking (signatures, dates, issuer,) - holder) to VOMS attribute parser. -* Mon Feb 21 2005 Andrew McNab -- Add bugfix for Bug #6357 from Fabrizio Pacini - to fix delegation proxy - cache names in OpenSSL 0.9.7. -* Sun Feb 20 2005 Andrew McNab -- Add basic VOMS support (signature checking not yet - in) for X.509 Attribute Certificates. -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.6 ==== -* Tue Feb 8 2005 Andrew McNab -- Include GRSTx509MakeProxyFileName() and - GRSTx509StringToChain() (code to used hashes in cached - proxy file names.) Bug #6357 -- Change ordering of output proxy file produced by - GRSTx509CacheProxy so proxy private key is the 2nd PEM - encoded block (rather than at the end.) Bug #6365 -- Add libgridsite_globus[.so|.a] in preparation for - separate Globus OpenSSL and system OpenSSL versions -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.5 ==== -* Tue Dec 14 2004 Andrew McNab -- Patch from Daniel Kouril to allow - switching Globus vs system OpenSSL libraries/headers. -* Tue Dec 14 2004 Andrew McNab -- ==== GridSite version 1.1.4 ==== -* Mon Nov 15 2004 Andrew McNab -- Back out of (most of) redone VOMS support for committing - to JRA1 CVS. -* Thu Oct 19 2004 Andrew McNab -- ==== GridSite version 1.1.3 ==== -* Thu Oct 19 2004 Andrew McNab -- Fix Bug #5203 from Martijn Steenbakkers - by fixing GACLparseEntry in gridsite-gacl.h -- Change to C style comments (mostly) in gridsite.h and - gridsite-gacl.h (fixes part of Bug #4222 from - ) -- Fix Bug #4225 from in - GRSTgaclCredsFree() -- Add GRSTx509CachedProxyFind() and findproxyfile - command to allow proxies to be found in proxy cache -- Change GRSTx509StoreProxy() to GRSTx509CacheProxy() for - consistency with this and GRSTx509CachedProxyKeyFind() -* Wed Oct 18 2004 Andrew McNab -- ==== GridSite version 1.1.2 ==== -* Tue Oct 19 2004 Andrew McNab -- Copy code from delegation prototype into grst_x509.c - and include htproxyput.c and grst-delegation.c - optional targets (which depend on gSOAP.) -* Wed Oct 13 2004 Andrew McNab -- Include per-file patch to GRSTgaclFileFindAclname: - .gacl:FILENAME controls FILENAME if it exists. -* Tue Jul 27 2004 Andrew McNab -- ==== GridSite version 1.1.1 ==== -* Tue Jul 27 2004 Andrew McNab -- Include HTTP Downgrade support in htcp -* Sat Jul 24 2004 Andrew McNab -- Include HTTP Downgrade support in mod_gridsite. -* Thu Jul 22 2004 Andrew McNab -- Begin development version 1.1.x -* Thu Jul 22 2004 Andrew McNab -- ==== GridSite version 1.1.0 ==== -* Mon Jul 19 2004 Andrew McNab -- Changes in line with EGEE SCM - most importantly - the top level directory becomes org.gridsite.core -* Mon Jul 19 2004 Andrew McNab -- ==== GridSite version 1.0.3 ==== -* Mon Jun 28 2004 Andrew McNab -- In GRSTx509CheckChain() and GRSTx509CompactCreds() - we now accept the first cert in a chain as a CA - even if it is X509v3 but without the CA bits set. - (On the basis that the first chain is from the - administrator-installed CA files store.) -* Sun Jun 27 2004 Andrew McNab -- ==== GridSite version 1.0.2 ==== -* Sun Jun 27 2004 Andrew McNab -- Fix for Bug #2860 (so can now read DN Lists over - HTTPS when have no user certificate if relevant - .gacl gives permission but not ) -- Include gridsite-gacl.h mods from Daniel Kouril - to fix faulty definitions - of GACLnewEntry() and GACLnewAcl() and to make - a legacy non-static GACLparseEntry() wrapper. -* Thu Jun 17 2004 Andrew McNab -- Changes to mod_gridsite.h for Fedora Core 2 / - Apache 2.0.49+ mod_ssl changes (mod_ssl-private.h) -* Wed Jun 9 2004 Andrew McNab -- Incorporate EGEE CVS layout changes in production - branch. -* Wed Jun 9 2004 Andrew McNab -- ==== GridSite version 1.0.1 ==== -* Sun Dec 14 2003 Andrew McNab -- 1.0.0 is first full production release - (development now in 1.1.x branch) -* Sun Dec 14 2003 Andrew McNab -- ==== GridSite version 1.0.0 ==== -* Sat Dec 13 2003 Andrew McNab -- Remove need for modified mod_ssl-gridsite: now - mod_gridsite intercepts callbacks with wrappers. -- Add GRSTx509NameCmp() which compares string reps of - DNs across OpenSSL version changes (ie Email=) -* Fri Dec 12 2003 Andrew McNab -- ==== GridSite version 0.9.11 ==== -* Thu Dec 11 2003 Andrew McNab -- Simplify checking of cert/proxy chain in - mod_ssl-gridsite: rely on mod_ssl/OpenSSL more. -* Wed Dec 2 2003 Andrew McNab -- ==== GridSite version 0.9.10 ==== -* Tue Dec 1 2003 Andrew McNab -- GACL ignores leading/trailing spaces in values. -* Sat Nov 29 2003 Andrew McNab -- Better directory listing in htcp. -- htcp now built as separate binary RPM. -- gridsite-admin.cgi upload now redirects to same - directory after upload (Bug #1939); allows - optional new name for file (Request / Bug #1940); - and has better checking of ../dir/file attacks. -* Sat Nov 29 2003 Andrew McNab -- ==== GridSite version 0.9.8 ==== -* Thu Nov 27 2003 Andrew McNab -- Shiv's updated GACL editor, with redirects. -* Wed Nov 26 2003 Andrew McNab -- Include Daniel Stenberg's roffit script to make - HTML man pages for htcp and urlencode. -- Various fixes found when installing GridPP WWW. -* Wed Nov 26 2003 Andrew McNab -- ==== GridSite version 0.9.7 ==== -* Thu Nov 20 2003 Andrew McNab -- Major updates to htcp (htrm/htls/htll) -- GACL now recurses subdirectories when examining - the DN List directories path. -* Sat Nov 15 2003 Andrew McNab -- ==== GridSite version 0.9.6 ==== -* Fri Nov 14 2003 Andrew McNab -- Function call fixes in grst-admin.cgi -* Thu Nov 13 2003 Andrew McNab -- Add htcp (curl-url-get reborn) -* Thu Nov 13 2003 Andrew McNab -- ==== GridSite version 0.9.5 ==== -* Thu Nov 13 2003 Andrew McNab -- More grst-admin.cgi GACL updates from Shiv. -- .gacl security improvements to grst-admin.cgi from - Shiv Kaushal and Peter Moore. -* Tue Nov 11 2003 Andrew McNab -- One RPM instead of three, with version from VERSION -- Textarea for HTML/Text editing now 80 columns -* Mon Nov 10 2003 Andrew McNab -- Add delegation level and GridSiteGSIProxyLimit - support. -- Add GridSiteAdminList handling to mod_gridsite - and real-gridsite-admin.cgi -* Sun Nov 9 2003 Andrew McNab -- Add directory create/delete, and file/dir rename. -- Add ZIP listing/unzipping via external unzip - utility from http://www.info-zip.org/pub/infozip/ -* Mon Nov 3 2003 Andrew McNab -- Include next version of Shiv's GACL editor. -- Add rpm-usr target to Makefile, to make RPMs - out-of-the-box compatible with RH9 and its Apache2 -- Use REMOTE_DOUBLE_REV for GACL hostname creds in - mod_gridsite.c/mod_gridsite_perm_handler() -* Sun Oct 26 2003 Andrew McNab -- Include GACL editor in real-gridsite-admin.cgi - from Shiv Kaushal -* Sun Oct 26 2003 Andrew McNab -- Reorganise into a single build tree, including - Apache 2.0 .h files to remove circular dependency. -* Sun Oct 26 2003 Andrew McNab -- ==== GridSite version 0.9.4 ==== -* Sun Oct 19 2003 Andrew McNab -- Include many pieces of GridSite code from 0.3.x (CGI) - fileGridSite and mod_gridsite 0.9.0 -* Sun Oct 19 2003 Andrew McNab -- ==== GridSite version 0.9.3 ==== diff --git a/org.gridsite.core/INSTALL b/org.gridsite.core/INSTALL deleted file mode 100644 index 4943047..0000000 --- a/org.gridsite.core/INSTALL +++ /dev/null @@ -1,37 +0,0 @@ -BUILDING/INSTALLING GRIDSITE -============================ - -For more detailed instructions, see the Installation and Build -pages in the GridSite Wiki http://www.gridsite.org/wiki/ - -GridSite is currently only supported on Linux, but should be -trivially portable to other Unix platforms where the GNU build -tools are available. - -When building from source, two routes are available: building -with Make or with RPM. - -BUILDING WITH MAKE -================== - -make -make install - -will build all components and install them all under the default -locations of /usr/local/[lib|bin|include|sbin] The default prefix -/usr/local is set by the prefix variable in the top level Makefile - -BUILDING WITH RPM -================= - -For RedHat Linux and derivatives, building with RPM is recommended. -The command - -make rpm - -will build the gridsite and htcp binary RPMs in the directory -../RPMTMP/RPMS/i386 relative to the working directory. A SRPM is -put into ../RPMTMP/SRPMS - -Building with RPM uses the default prefix /usr, although the -resulting RPMs are relocatable to other hierarchies. diff --git a/org.gridsite.core/LICENSE b/org.gridsite.core/LICENSE deleted file mode 100644 index befd74b..0000000 --- a/org.gridsite.core/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright (c) 2002-5, Andrew McNab and Shiv Kaushal, -University of Manchester. All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -Clearly marked portions of the published GridSite source code -are derived from Apache httpd or its modules, and are covered -by the Apache Software License: - -Copyright 2001-2005 The Apache Software Foundation - -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. diff --git a/org.gridsite.core/README b/org.gridsite.core/README deleted file mode 100644 index df81f32..0000000 --- a/org.gridsite.core/README +++ /dev/null @@ -1,6 +0,0 @@ -See INSTALL for build and installation instructions, and the -man pages for reference information. - -The GridSite Wiki at http://www.gridsite.org/wiki/ has guides -( http://www.gridsite.org/wiki/Category:Guides ) and cookbook -examples ( http://www.gridsite.org/wiki/Category:Cookbooks ) diff --git a/org.gridsite.core/VERSION b/org.gridsite.core/VERSION deleted file mode 100644 index 31ecb41..0000000 --- a/org.gridsite.core/VERSION +++ /dev/null @@ -1,4 +0,0 @@ -MAJOR_VERSION=1 -MINOR_VERSION=1.5 -PATCH_VERSION=1.5.0 -VERSION=$(PATCH_VERSION) diff --git a/org.gridsite.core/build.xml b/org.gridsite.core/build.xml deleted file mode 100644 index 0f47b59..0000000 --- a/org.gridsite.core/build.xml +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - Ant build file to build the Gridsite Core Component - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${global.prefix} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/doc/README.htcp-bin b/org.gridsite.core/doc/README.htcp-bin deleted file mode 100644 index ac546fc..0000000 --- a/org.gridsite.core/doc/README.htcp-bin +++ /dev/null @@ -1,13 +0,0 @@ -Binaries (and links) are in ./bin; man pages are in ./man/man1 - -Install by copying binaries/links onto your path, or by copying htcp -and making symbolic links to htcp from htls, htll, htrm and htmkdir. - -All the .1 man pages should be copied to a suitable ./man/man1 -directory on your man path. - -If you just want to install htcp in /usr/local, then unpacking this -tgz file in /usr/local should do the trick. (Delete this README when -you're finished!) - -For more about htcp see http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/build-apache2.sh b/org.gridsite.core/doc/build-apache2.sh deleted file mode 100644 index 507be31..0000000 --- a/org.gridsite.core/doc/build-apache2.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2002-3, Andrew McNab, University of Manchester -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# o Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# o Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -#--------------------------------------------------------------- -# For more information about GridSite: http://www.gridsite.org/ -#--------------------------------------------------------------- -# -# This script takes an Apache .tar.gz as the single command line argument, -# unpacks the file, modifies the httpd.spec it contains to work without -# the "-C" option to configure (which RedHat 7.3 doesnt like) and -# outputs source and binary RPMs in SRPMS and RPMS/i386 - -if [ "$1" = "" ] ; then - echo Must give a tar.gz file name - exit -fi - -export MYTOPDIR=`pwd` - -if [ -x /usr/bin/rpmbuild ] ; then - export RPMCMD=rpmbuild -else - export RPMCMD=rpm -fi - -echo "$1" | grep '\.tar\.gz$' >/dev/null 2>&1 -if [ $? = 0 ] ; then # a gzipped source tar ball - - rm -Rf $MYTOPDIR/BUILD $MYTOPDIR/BUILDROOT $MYTOPDIR/SOURCES - mkdir -p $MYTOPDIR/SOURCES $MYTOPDIR/SPECS $MYTOPDIR/BUILD \ - $MYTOPDIR/SRPMS $MYTOPDIR/RPMS/i386 $MYTOPDIR/BUILDROOT - - shortname=`echo $1 | sed 's:^.*/::' | sed 's:\.tar\.gz$::'` - - cp -f $1 SOURCES - - tar zxvf SOURCES/$shortname.tar.gz $shortname/httpd.spec - cp -f $shortname/httpd.spec SPECS - - sed -e 's/configure -C /configure /' \ - SPECS/httpd.spec >SPECS/httpd-2.spec - - $RPMCMD --define "_topdir $MYTOPDIR" \ - -ba --buildroot $MYTOPDIR/BUILDROOT SPECS/httpd-2.spec - - exit -fi - -echo I dont recognise the file type (must be .tar.gz) - -exit diff --git a/org.gridsite.core/doc/delegation-1.1.0.wsdl b/org.gridsite.core/doc/delegation-1.1.0.wsdl deleted file mode 100644 index df7e1f2..0000000 --- a/org.gridsite.core/doc/delegation-1.1.0.wsdl +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - - - - The cause of the delegation exception on the server side. - - - - - - - - - - New proxy certificate request, containing the certificate - request and a generated delegation ID. - - - - - - - The new RFC 3280 style proxy certificate request - in PEM format with Base64 encoding. - - - - - - - The ID associated with the new delegation session. - - - - - - - - - - - - The ID of the new delegation session, specified by the client. - The ID can be empty. - - - - - - - The new RFC 3280 style proxy certificate request - in PEM format with Base64 encoding. - - - - - - - - The ID of an already existing delegation session, - initiated by getProxyReq() or getNewProxyReq(). - - - - - RFC 3280 style proxy certificate, signed by the - client, in PEM format with Base64 encoding. - - - - - - - - - The ID of an already existing delegation session, - where the client wants to renew the delegated - credential. - - - - - - - The new RFC 3280 style proxy certificate request, - which is to replace the existing one, - in PEM format with Base64 encoding. - - - - - - - - - The server side generated ID of the new delegation - session and the new RFC 3280 style proxy certificate - request in PEM format with Base64 encoding. - - - - - - - - The ID of an already existing delegation session to be queried. - - - - - - - The date and time when the delegated credentials will expire. - - - - - - - - The ID of an already existing delegation session to be destroyed. - - - - - - - - - - - - Delegation interface. - - - - - - Starts the delegation procedure by asking for a certificate - signing request from the server. The server answers with a - certificate signing request which includes the public key - for the new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Check if a delegation ID was provided. If not, generate a delegation - id by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does - (a credential renewal is happening), check - existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new proxy certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - The client's DN and VOMS attributes do not match the stored ones, - i.e. the client is not authorized. - - - - - - - - Starts the delegation procedure by asking for a certificate - signing request from the server. The server answers with a - certificate signing request which includes the public key - for the new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Generate a delegation - ID by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does, check - existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match, because then this is - the rare case of hash collision, i.e. two different clients - are mapped to the same delegation ID. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - There were already credentials associated to the delegation ID. - - - - - - - - Finishes the delegation procedure by sending the signed - proxy certificate to the server. - - - - Check if a delegation ID was provided. If not, generate a - delegation id by hashing the client DN and client VOMS - attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does, check - existing info (DN and VOMS attributes) against client info. - Throw exception if it does not match. - - - Check, if client information matches proxy information. - - - Check given proxy against private key of delegation ID in - storage-cache-area. If they do not - match, throw exception. - - - Store proxy in storage-area - and clean up the storage-cache-area. - - - - - - - - - There were no cached credentials associated to the delegation ID - (neither - getNewProxyReq() nor - - renewProxyReq() was called previously), - or the client's DN and VOMS attributes do not match the stored ones, - i.e. the client is not authorized. - - - - - - - - - Restarts the delegation procedure by asking for a certificate - signing request from the server for an already existing delegation ID. - The server answers with a certificate signing request which includes - the public key for new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Check if a delegation ID was provided. If not, generate a delegation - id by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does - not, then throw an exception. - - - Check if the existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - Returns the termination (expiration) date and time of the credential, - associated with the given delegaion ID. If there was no delegation ID, - then generate one by hashing the client DN and client VOMS attributes. - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - - Destroys the delegated credentials associated with the - given delegation ID immediately. If there was no delegation ID, - then generate one by hashing the client DN and client VOMS attributes. - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/doc/findproxyfile.1 b/org.gridsite.core/doc/findproxyfile.1 deleted file mode 100644 index 9de4d47..0000000 --- a/org.gridsite.core/doc/findproxyfile.1 +++ /dev/null @@ -1,63 +0,0 @@ -.TH findproxyfile 1 "October 2004" "findproxyfile" "GridSite Manual" -.SH NAME -.B findproxyfile -\- returns full path to GSI Proxy file -.SH SYNOPSIS -.B findproxyfile -[--proxycache=PATH] [--delegation-id=ID] [--user-dn=DN] [--outsidecache] -.SH DESCRIPTION -.B findproxyfile -returns full path to a GSI Proxy file, either in the proxy cache maintained -by the GridSite G-HTTPS and delegation portType functions, or in other -standard places. - -If a User DN is given -.B findproxyfile -uses the value of the -.B --proxycache -argument, the GRST_PROXY_PATH or the -compile time default to detemine the location of the proxy cache directory. -The directory is searched for a proxy having the given User DN and -Delegation ID. (If no Delegation ID is specificed, then the default value is -used.) - -If -.B findproxyfile -does not find a proxy or if a User DN is not given, but -.B --outsidecache -was given, then the environment variable X509_USER_PROXY and the standard -location /tmp/x509up_uUID are searched as well. - -.SH OPTIONS - -.IP "--proxycache=PATH" -Give the path of the proxy cache directory explicitly, overriding the -default and the GRST_PROXY_PATH environment variable if present. - -.IP "--delegation-id=ID" -The optional delegation ID is search for in the proxy cache in addition to -the User DN. If absent, the default Delegation ID value is searched for. - -.IP "--user-dn=DN" -The DN of the full user certificate associated with the proxy to be searched -for in the proxy cache. (This is not the DN of any proxy earlier in the -chain: it is a the DN of a certificate issued by a recognised CA.) - -.IP "--outsidecache" -If a User DN is not given, or a proxy not found in the cache, then search -for a proxy using X509_USER_PROXY environment variable and file name of -form /tmp/x509up_uUID as well. - -.SH RETURN VALUE -If a proxy is found, its full path is output on standard out. - -.SH EXIT CODES -0 is returned on succcess. Non-zero otherwise. - -.SH BUGS -In this version, no attempt is made to verify or validate the proxies. - -.SH AUTHOR -Andrew McNab - -findproxyfile is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/fuse.spec b/org.gridsite.core/doc/fuse.spec deleted file mode 100644 index ac785a2..0000000 --- a/org.gridsite.core/doc/fuse.spec +++ /dev/null @@ -1,139 +0,0 @@ -# -# You should be able to build your own FUSE RPMs for use with SlashGrid -# by fetching an up-to-date stable FUSE tar file from SourceForge, -# putting it in /usr/src/redhat/SOURCES, updating the Version: header in -# this file, and then executing rpmbuild -ba fuse.spec -# -Name: fuse -Version: 2.5.3 -URL: http://fuse.sourceforge.net -Source: %{name}-%{version}.tar.gz -Release: 3%(sed 's/^\([A-Z]\)[^ ]* \([A-Z]\)[^0-9]*\([0-9][^ ]*\).*/\1\2\3/g' /etc/redhat-release | sed 's/[^A-Z,a-z,0-9]//g')_%(uname -r | sed 's/-/_/g') -Summary: File System in Userspace (FUSE) utilities -Group: System Environment/Base -License: GPL -Packager: Andrew McNab -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -%description -With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains the FUSE userspace tools to -mount a FUSE filesystem. - -(This version is designed for use with the SlashGrid daemon: - http://www.gridsite.org/slashgrid/ ) - -%package libs -Summary: File System in Userspace (FUSE) libraries -Group: System Environment/Libraries -License: LGPL - -%description libs -Devel With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains the FUSE libraries. - -%package devel -Summary: File System in Userspace (FUSE) devel files -Group: Development/Libraries -Requires: %{name}-libs = %{version}-%{release} -Requires: pkgconfig -License: LGPL - -%description devel -With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains development files (headers, -pgk-config) to develop FUSE based applications/filesystems. - -%prep -%setup -q -#disable device creation during build/install -sed -i 's|mknod|echo Disabled: mknod |g' util/Makefile.in -sed -i 's|install-data-local | |g' util/Makefile.in -sed -i 's| install-data-local| |g' util/Makefile.in - -%build -%configure --disable-static -make %{?_smp_mflags} - -%install -rm -rf $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -type f -name "*.la" -exec rm -f {} ';' - -# change from 4755 to 0755 to allow stripping (setuid not needed by SlashGrid) -chmod 0755 $RPM_BUILD_ROOT/%{_bindir}/fusermount - -%clean -rm -rf $RPM_BUILD_ROOT - -%post -mknod --mode=0660 /dev/fuse c 10 229 -chown root.root /dev/fuse -depmod - -%postun - -%post libs -p /sbin/ldconfig - -%postun libs -p /sbin/ldconfig - -%files -%doc AUTHORS ChangeLog COPYING FAQ Filesystems NEWS README README.NFS -/sbin/mount.fuse -%attr(0755,root,root) %{_bindir}/fusermount -/lib/modules/%(uname -r)/kernel/fs/fuse/fuse.*o - -%files libs -%doc COPYING.LIB -%{_libdir}/libfuse.so.* - -%files devel -%defattr(-,root,root,-) -%{_libdir}/libfuse.so -%{_libdir}/pkgconfig/*.pc -%{_includedir}/fuse.h -%{_includedir}/fuse - -%changelog - -* Sun May 28 2006 Andrew McNab 2.5.3-3 -- Simplify for use with SlashGrid daemon (which only runs as root) on - Scientific Linux 3.*/4.* too - -* Wed May 03 2006 Peter Lemenkov 2.5.3-1%{?dist} -- Update to 2.5.3 - -* Thu Mar 30 2006 Peter Lemenkov 2.5.2-4%{?dist} -- rebuild - -* Mon Feb 13 2006 Peter Lemenkov - 2.5.2-3 -- Proper udev rule - -* Mon Feb 13 2006 Peter Lemenkov - 2.5.2-2 -- Added missing requires - -* Tue Feb 07 2006 Peter Lemenkov - 2.5.2-1 -- Update to 2.5.2 -- Dropped fuse-mount.fuse.patch - -* Wed Nov 23 2005 Thorsten Leemhuis - 2.4.2-1 -- Use dist - -* Wed Nov 23 2005 Thorsten Leemhuis - 2.4.2-1 -- Update to 2.4.2 (solves CVE-2005-3531) -- Update README.fedora - -* Sat Nov 12 2005 Thorsten Leemhuis - 2.4.1-3 -- Add README.fedora -- Add hint to README.fedora and that you have to be member of the group "fuse" - in the description -- Use groupadd instead of fedora-groupadd - -* Fri Nov 04 2005 Thorsten Leemhuis - 2.4.1-2 -- Rename packages a bit -- use makedev.d/40-fuse.nodes -- fix /sbin/mount.fuse -- Use a fuse group to restict access to fuse-filesystems - -* Fri Oct 28 2005 Thorsten Leemhuis - 2.4.1-1 -- Initial RPM release. diff --git a/org.gridsite.core/doc/gridsite-delegation.8 b/org.gridsite.core/doc/gridsite-delegation.8 deleted file mode 100644 index 41ce1e3..0000000 --- a/org.gridsite.core/doc/gridsite-delegation.8 +++ /dev/null @@ -1,19 +0,0 @@ -.TH gridsite-delegation 8 "March 2006" "gridsite-delegation" "GridSite Manual" -.SH NAME -.B gridsite-delegation.cgi -\- CGI implementation of GridSite/gLite GSI delegation Web Service -.SH SYNOPSIS -.B gridsite-delegation.cgi - -.SH DESCRIPTION -.B gridsite-delegation.cgi -is a server-side implementation of the GridSite/gLite GSI delegation Web -Service - -.SH AUTHOR -Andrew McNab - -gridsite-delegation.cgi is part of GridSite: http://www.gridsite.org/ - -.SH "SEE ALSO" -.BR htproxyput(1) diff --git a/org.gridsite.core/doc/gsexec.8 b/org.gridsite.core/doc/gsexec.8 deleted file mode 100644 index e229663..0000000 --- a/org.gridsite.core/doc/gsexec.8 +++ /dev/null @@ -1,134 +0,0 @@ -.TH GSEXEC 8 "October 2005" "gsexec" "GridSite Manual" -.SH NAME -.B gsexec -\- Switch user before executing external programs - -.SH "SYNOPSIS" - -.BR gsexec -[-V] - -.SH "SUMMARY" - -gsexec is used by the Apache HTTP Server to switch to another user before -executing CGI programs\&. In order to achieve this, it must run as root\&. -Since the HTTP daemon normally doesn't run as root, the gsexec executable -needs the setuid bit set and must be owned by root\&. It should never be -writable for any other person than root\&. - -gsexec is based on Apache's suexec, and its behaviour is controlled with -the Apache configuration file directives -.BR GridSiteExecMethod -and -.BR GridSiteUserGroup -added to Apache by -.BR mod_gridsite(8) -Four execution methods are supported: nosetuid, suexec, X509DN and directory, -and these may be set on a per-directory basis within the Apache configuration -file. - -.SH "NOSETUID METHOD" - -This is the default behaviour, but can also be produced by giving -.BR "GridSiteExecMethod nosetuid" - -CGI programs will then be executed without using gsexec, and will -run as the Unix user given by the User and Group Apache directives (normally -apache.apache on Red Hat derived systems.) - -.SH "SUEXEC METHOD" - -If -.BR "GridSiteExecMethod suexec" -is given for this virtual host or directory, then CGI programs will be -executed using the user and group given by the -.BR "GridSiteUserGroup user group" -directive, which may also be set on a per-directory basis (unlike suexec's -.BR SuexecUserGroup -which is per-server only.) The CGI program must either be owned by root, -the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the user and group given with the -.BR GridSiteUserGroup -directive. - -.SH "X509DN METHOD" - -If -.BR "GridSiteExecMethod X509DN" -is given, then the CGI program runs as a pool user, detemined using lock -files in the exec mapping directory chosen as build time of gsexec. -The pool user is chosen according -to the client's full certificate X.509 DN (ie with any trailing GSI proxy -name components stripped off.) Subsequent requests by the same X.509 -identity will be mapped to the same pool user. The CGI program must either be -owned by root, the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the pool user selected. - -.SH "DIRECTORY METHOD" - -If -.BR "GridSiteExecMethod directory" -is given, then the CGI program runs as a pool user chosen according -to the directory in which the CGI is located: all CGIs in that directory -run as the same pool user. The CGI program must either be -owned by root, the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the pool user selected. - - -.SH "EXECMAPDIR" - -The default exec mapping directory is /var/www/execmapdir and this is fixed -when the gsexec executable is built. The exec mapping directory and all -of its lock files must be owned and only writable by root. To initialise the -lock files, create an empty lock file for each pool user, with the pool -username as the filename (eg user0001, user0002, ...) As the pool users are -leased to X.509 identities or directories, they will become hard linked to -lock files with the URL-encoded X.509 DN or full directory path. - -You can recycle pool users by removing the corresponding URL-encoded -hard link. -.BR stat(1) -and -.BR "ls(1)" -with option -.BR "-i" -can be used to print the inodes of lock files to match up the hard links. - -.BR "However, you must ensure that all files and processes owned by the pool" -.BR "user are deleted before recycling!" - -.SH "OPTIONS" - -.TP --V -If you are root, this option displays the compile options of gsexec\&. -For security reasons all configuration options are changeable only at -compile time\&. - -.SH "MORE INFORMATION" -For further information about the concepts and the security model of -the original Apache suexec -please refer to the suexec documentation: - -http://httpd\&.apache\&.org/docs-2\&.0/suexec\&.html - -For examples using the gsexec extensions, please see the GridSite gsexec -page: - -http://www.gridsite.org/wiki/Gsexec - -.SH AUTHORS - -Apache project, for original suexec - -Andrew McNab for gsexec modifications. - -gsexec is part of GridSite: http://www.gridsite.org/ - -.SH "SEE ALSO" -.BR httpd(8), -.BR suexec(8), -.BR mod_gridsite(8) diff --git a/org.gridsite.core/doc/gsoap-devel.spec b/org.gridsite.core/doc/gsoap-devel.spec deleted file mode 100644 index 1eb61f0..0000000 --- a/org.gridsite.core/doc/gsoap-devel.spec +++ /dev/null @@ -1,52 +0,0 @@ -# -# You can use this spec file and the gSOAP source tar file from sourceforge -# to build a binary development RPM of gSOAP, suitable for building the -# gridsite-ws components. Installing the resulting RPM puts the gSOAP files -# directory in /usr, where the gridsite-ws Makefile expects them by default. -# -# See http://www.gridsite.org/wiki/GSOAP for more about GridSite and gSOAP -# -Name: gsoap-devel -Version: %(echo ${MYVERSION:-2.7.6b}) -Release: 1%(sed 's/^\([A-Z]\)[^ ]* \([A-Z]\)[^0-9]*\([0-9][^ ]*\).*/\1\2\3/g' /etc/redhat-release | sed 's/[^A-Z,a-z,0-9]//g') -Summary: gSOAP development compilers/libraries/headers -License: Modified BSD -Group: Development/Libraries -Source: gsoap_%{version}.tar.gz -Prefix: %(echo ${MYPREFIX:-/usr}) -URL: http://www.cs.fsu.edu/~engelen/soap.html -Packager: Andrew McNab - -%description -Enough of gSOAP to build clients and servers based on gSOAP, using its headers -and static libraries. -By default, everything is installed in /usr/lib|bin|include/ - -%prep - -%setup -n gsoap-2.7 - -%build - -./configure --prefix=$RPM_BUILD_ROOT/%{prefix} -make - -%install -make install - -%files -%attr(-, root, root) %{prefix}/bin/soapcpp2 -%attr(-, root, root) %{prefix}/bin/wsdl2h -%attr(-, root, root) %{prefix}/include/stdsoap2.h -%attr(-, root, root) %{prefix}/lib/libgsoap++.a -%attr(-, root, root) %{prefix}/lib/libgsoap.a -%attr(-, root, root) %{prefix}/lib/libgsoapck++.a -%attr(-, root, root) %{prefix}/lib/libgsoapck.a -%attr(-, root, root) %{prefix}/lib/libgsoapssl++.a -%attr(-, root, root) %{prefix}/lib/libgsoapssl.a -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoap++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoap.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapck++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapck.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapssl++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapssl.pc diff --git a/org.gridsite.core/doc/htcp.1 b/org.gridsite.core/doc/htcp.1 deleted file mode 100644 index 0731d33..0000000 --- a/org.gridsite.core/doc/htcp.1 +++ /dev/null @@ -1,200 +0,0 @@ -.TH HTCP 1 "October 2005" "htcp" "GridSite Manual" -.SH NAME -.B htcp, htmv, htrm, htls, htll, htmkdir, htfind, htping -\- file transfers and queries via HTTP/HTTPS/SiteCast -.SH SYNOPSIS -.B htcp, htmv -[options] Source-URL[s] Destination-URL - -.B htrm, htls, htll, htmkir, htfind -[options] Target-URL[s] - -.B htping -[options] -.SH DESCRIPTION -.B htcp -is a client to fetch files or directory listings from remote servers using -HTTP or HTTPS, or to put or delete files or directories onto remote servers -using HTTPS. htcp is similar to scp(1), but uses HTTP/HTTPS rather than ssh -as its transfer protocol. htcp can also use the HTCP protocol to query -HTTP(S) fileservers via SiteCast. - -When talking to a fileserver with HTTPS, htcp can run "anonymously", with a -standard X.509 user certificate and key, or with a GSI Proxy. This makes -htcp very useful in Grid environments where many users have certificates -and where jobs and users have access to GSI proxies. - -.SH URLs -htcp supports the file:, http: and https: URL schemes as sources and -destinations. If no scheme is given, the URL scheme is assumed to be file: -and relative to the current directory if not an absolute path. - -If multiple sources are given during a copy, they will be used in turn and -the destination must be a directory (directories are indicated by a trailing -/) However, source and destination cannot both refer to remote servers. - -.SH OPTIONS -.IP "-v/--verbose" -Turn on debugging information. Used once, this option will enable htcp's -messages to stderr. Used twice, will also enable the underlying libcurl -messages. - -.IP "--delete" -Instead of copying files, delete all the URLs given on the command line. -Calling the program as htrm has the same effect. - -.IP "--list" -Instead of copying files, output lists of files located in the URL-directories -given on the command line. Calling the program as htls has the same effect. - -.IP "--long-list" -Instead of copying files, output long listings of files located in the -URL-directories given on the command line. If available, the size in bytes -and modification time of each file is given. Calling the program as -htll has the same effect. - -.IP "--mkdir" -Instead of copying files, attempt to create a directory on a remote server -with HTTP PUT. The server must support the convention that PUT to a URL with -a trailing slash means create a directory. No file body is sent. Calling the -program as htmkdir has the same effect. - -.IP "--move" -Move/rename files on a single remote server, given the two, absolute URLs -of the remote file names. Server must support HTTP/WebDAV MOVE. Calling the -program as htmv has the same effect. - -.IP "--ping" -Query specified multicast groups with the HTCP NOP ("No Operation") code. -SiteCast enabled servers will respond immediately with a NOP reply, and all -of the responses will be listed, with the round trip time in milliseconds. -Any waiting times specified in the --groups option will be ignored. Calling -the program as htping has the same effect. -(--groups must be used for this option to work.) - -.IP "--find" -Query specified multicast groups with the HTCP TST code. SiteCast enabled -servers will respond with TST replies if they have the files corresponding -to the given SiteCast target URL(s). All of the transfer URLs returned -will be listed. Waiting times specified in the --groups option will be used -to space out the multicast queries, but the program listens for responses -continuously. Calling the program as htfind has the same effect. -(--groups must be used for this option to work.) - -.IP "--groups " -IP multicast groups to use for SiteCast queries. IP Groups is a comma -separated list of groups, in the format: nnn.nnn.nnn.nnn:port[:ttl[:seconds]] -The IP number and port must be specified. The IP time-to-live, ttl, controls -how many networks the multicast packets may pass through - the default, 1, -limits packets to the local network. Multiple groups may be specified, -separated by commas. If multiple groups are specified, then seconds is the -time to wait before making the next multicast - 1 second is the default. - -.IP "--timeout " -A request timeout used for multicast ping. - -.IP "--anon" -Do not attempt to use X.509 user certificates or GSI proxies to authenticate -to the remote HTTPS server. This means you are "anonymous", but the server's -identity may still be verified and the connection is still encrypted. - -.IP "--cert and --key " -Path to the PEM-encoded -X.509 or GSI Proxy user certificate and key to use for HTTPS -connections, intead of "anonymous mode." If only one of --key or --cert -is given, then that will be tried for both. If neither is given, then the -following order of precedence is used: -the file name held by the variable X509_USER_PROXY; the file -/tmp/x509up_uID (with Unix UID equal to ID); the file names held by -X509_USER_CERT / X509_USER_KEY; the files ~/.globus/usercert.pem and -~/.globus/userkey.pem (where ~/ is the home directory of the user.) - -.IP "--capath " -Path to the PEM-encoded CA root certificates to use when -verifying remote servers' host certificates in HTTPS connections. Ideally -this should be a directory of hash.0 files as described in the OpenSSL -verify(1) man page, but a file may be used instead. If --capath is not -given, the value of the environment variable X509_CERT_DIR will be tried. -If this is not valid, then /etc/grid-security/certificates will be used. - -.IP "--no-verify" -Do not use CA root certificates to verify remote servers' host certificates. -This is useful for testing sites before their certificate is set up properly, -but leaves you vulnerable to "man in the middle" attacks by hostile servers -masquerading as your target. - -.IP "--grid-http" -Try to use GridHTTP redirection for HTTPS URLs. Compatible servers will perform -authentication and authorization on the HTTPS connection and then redirect -to HTTP for the GET or PUT file transfer. htcp makes the HTTP request using -the GRID_AUTH_PASSCODE single-use passcode obtained via HTTPS. The --grid-http -option will be ignored for directory operations or HTTP URLs. If a redirected -transfer isn't possible, a normal HTTPS data transfer will be attempted. - -.IP "--sitecast" -Try to use SiteCast to locate remote files which are to be copied (currently -only for the -.BR fetching -of remote files.) If no location is found via SiteCast, then a direct request -for the given URL is tried. (--groups must be used for this option to work.) - -.IP "--domain " -Try to use SiteCast to locate remote files which are to be copied (currently -only for the -.BR fetching -of remote files) -.BR "if the domain component of the URL matches" -the SiteCast domain given. -If no location is found via SiteCast, then a direct request -for the given URL is tried. (--groups must be used for this option to work.) - -.SH FILES -.IP /tmp/x509up_uID -Default GSI Proxy file for Unix UID equal to ID. - -.IP /etc/grid-security/certificates -Default location for trusted Certification Authority root certificates to use -when checking server certificates. - -.IP /tmp/.ca-roots-XXXXXX -Prior to 7.9.8, the underlying curl library did not support the CA root -certificates directory. -If built with an old version of libcurl, htcp will concatenate the -certificates in the CA roots directory into a unique temporary file and use -that. - -.SH ENVIRONMENT - -.IP X509_CERT_DIR -Holds directory to search for Certification Authority root certificates when -verifying server certificates. (Tried if --capath is not given on the -command line.) - -.IP X509_USER_PROXY -Holds file name of a GSI Proxy to use as user certificate. (Tried if --cert or ---key are not given on the command line.) - -.IP "X509_USER_CERT and X509_USER_KEY" -Holds file name of X.509 user certificate and key. (Tried if X509_USER_PROXY -is not valid.) - -.SH EXIT CODES -0 is returned on complete success. Curl error codes are returned when -reported by the underlying curl library, and CURLE_HTTP_RETURNED_ERROR (22) -is returned when the HTTP(S) server returns a code outside the range 200-299. -The manpage libcurl-errors(3) lists all the curl error codes. - -.SH TO DO -Recursive copying. Server-side wildcards. Parallel streams. Better error -recovery. - -.SH AUTHOR -Andrew McNab - -htcp is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR scp(1), -.BR curl(1), -.BR wget(1), -.BR verify(1), -.BR libcurl-errors(3) diff --git a/org.gridsite.core/doc/htfind.1 b/org.gridsite.core/doc/htfind.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htfind.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htll.1 b/org.gridsite.core/doc/htll.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htll.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htls.1 b/org.gridsite.core/doc/htls.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htls.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htmkdir.1 b/org.gridsite.core/doc/htmkdir.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htmkdir.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htmv.1 b/org.gridsite.core/doc/htmv.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htmv.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htping.1 b/org.gridsite.core/doc/htping.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htping.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htproxydestroy.1 b/org.gridsite.core/doc/htproxydestroy.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxydestroy.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyinfo.1 b/org.gridsite.core/doc/htproxyinfo.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyinfo.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyput.1 b/org.gridsite.core/doc/htproxyput.1 deleted file mode 100644 index a917054..0000000 --- a/org.gridsite.core/doc/htproxyput.1 +++ /dev/null @@ -1,121 +0,0 @@ -.TH HTPROXYPUT 1 "March 2006" "htproxyput" "GridSite Manual" -.SH NAME -.B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew -\- GSI proxy delegations and querying, using GridSite/gLite delegation API -.SH SYNOPSIS -.B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew -[options] Service-URL - -.B htproxyinfo -[options] - -.SH DESCRIPTION -.B htproxyput -is a client to perform GSI proxy delegations using the GridSite/gLite -delegation Web Service portType. The gridsite-delegation(8) CGI program is -the complementary server-side implementation. - -.B htproxyinfo -examines a local copy of a GSI proxy, and outputs a summary of its X.509 and -VOMS contents. - -.SH OPTIONS -.IP "-v/--verbose" -Turn on debugging information. - -.IP "--delegation-id " -Explicitly specify the Delegation ID to use. - -.IP "--destroy" -Instead of delegating a proxy, delete the proxy from the service's proxy -cache. Calling the program as htproxydestroy has the same effect. - -.IP "--time" -Instead of delegating a proxy, report the expiration time of the proxy, -in the local time of the client. Calling the program as htproxytime has the -same effect. - -.IP "--unixtime" -Instead of delegating a proxy, report the expiration time of the proxy, as -the number of seconds since 00:00:00 1970-01-01 UTC. Calling the program as -htproxyunixtime has the same effect. - -.IP "--renew" -Delegate an updated version of an existing proxy. The Delegation ID -.B must -be given when using this option. Calling the program as htproxyrenew has the -same effect. - -.IP "--info" -Examine a local proxy file, and output a summary of the X.509 certificates -and VOMS attributes it contains. Calling the program as htproxyinfo has the -same effect. - -.IP "--cert and --key " -Path to the PEM-encoded -X.509 or GSI Proxy user certificate and key to use for HTTPS -connections, intead of "anonymous mode." If only one of --key or --cert -is given, then that will be tried for both. If neither is given, then the -following order of precedence is used: -the file name held by the variable X509_USER_PROXY; the file -/tmp/x509up_uID (with Unix UID equal to ID); the file names held by -X509_USER_CERT / X509_USER_KEY; the files ~/.globus/usercert.pem and -~/.globus/userkey.pem (where ~/ is the home directory of the user.) - -.IP "--capath " -Path to the PEM-encoded CA root certificates to use when -verifying remote servers' host certificates in HTTPS connections. Ideally -this should be a directory of hash.0 files as described in the OpenSSL -verify(1) man page, but a file may be used instead. If --capath is not -given, the value of the environment variable X509_CERT_DIR will be tried. -If this is not valid, then /etc/grid-security/certificates will be used. - -.IP "--no-verify" -Do not use CA root certificates to verify remote servers' host certificates. -This is useful for testing sites before their certificate is set up properly, -but leaves you vulnerable to "man in the middle" attacks by hostile servers -masquerading as your target. - -.SH FILES -.IP /tmp/x509up_uID -Default GSI Proxy file for Unix UID equal to ID. - -.IP /etc/grid-security/certificates -Default location for trusted Certification Authority root certificates to use -when checking server certificates. - -.IP /tmp/.ca-roots-XXXXXX -Prior to 7.9.8, the underlying curl library did not support the CA root -certificates directory. -If built with an old version of libcurl, htproxyput will concatenate the -certificates in the CA roots directory into a unique temporary file and use -that. - -.SH ENVIRONMENT - -.IP X509_CERT_DIR -Holds directory to search for Certification Authority root certificates when -verifying server certificates. (Tried if --capath is not given on the -command line.) - -.IP X509_USER_PROXY -Holds file name of a GSI Proxy to use as user certificate. (Tried if --cert or ---key are not given on the command line.) - -.IP "X509_USER_CERT and X509_USER_KEY" -Holds file name of X.509 user certificate and key. (Tried if X509_USER_PROXY -is not valid.) - -.SH EXIT CODES -0 is returned on complete success, and non-zero on error. - -.SH TO DO -Better error recovery. - -.SH AUTHOR -Andrew McNab - -htproxyput is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR htcp(1), -.BR gridsite-delegation(8) diff --git a/org.gridsite.core/doc/htproxyrenew.1 b/org.gridsite.core/doc/htproxyrenew.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyrenew.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxytime.1 b/org.gridsite.core/doc/htproxytime.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxytime.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyunixtime.1 b/org.gridsite.core/doc/htproxyunixtime.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyunixtime.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htrm.1 b/org.gridsite.core/doc/htrm.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htrm.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/httpd-fileserver.conf b/org.gridsite.core/doc/httpd-fileserver.conf deleted file mode 100644 index fbc170c..0000000 --- a/org.gridsite.core/doc/httpd-fileserver.conf +++ /dev/null @@ -1,155 +0,0 @@ -############################################################################## -## GridSite httpd-fileserver.conf - Andrew McNab -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## Example configuration file for GridSite as an HTTP(S) fileserver, -## listening on ports 80/777 (HTTP) and 443/488 (HTTPS) -## -## (777/488 is to allow firewalls to distinguish between Grid and -## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. -## -## You do not need to install the GridSite mod_ssl.so module if you -## do not wish to use Globus Proxies or VOMS attributes, but you must -## have the mod_gridsite.so in /usr/lib/httpd/modules -## -## We're assuming you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from https://datagrid.in2p3.fr/distribution/datagrid/security/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ -## -## To start serving files, make a directory /var/www/htdocs owned by -## apache.apache, including the file .gacl containing: -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE MOVE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -## -############################################################################## - -ServerRoot "/etc/httpd" - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 15 - -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User apache -Group apache - -DocumentRoot "/var/www/htdocs" - - - AllowOverride None - - -LogLevel debug -LogFormat "%h \"%{SSL_CLIENT_S_DN}x\" %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -###################################################################### -# Plain unauthenticated HTTP on ports 80 and 777 -###################################################################### - -Listen 80 -Listen 777 - - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on ports 443 and 488 -###################################################################### -Listen 443 -Listen 488 -SSLSessionCacheTimeout 300 -SSLSessionCache shm:/var/cache/mod_ssl/shm_cache - - - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - GridSiteGSIProxyLimit 0 -# GridSiteMethods GET PUT DELETE MOVE - - - diff --git a/org.gridsite.core/doc/httpd-webserver.conf b/org.gridsite.core/doc/httpd-webserver.conf deleted file mode 100644 index 710bb12..0000000 --- a/org.gridsite.core/doc/httpd-webserver.conf +++ /dev/null @@ -1,226 +0,0 @@ -############################################################################## -## GridSite httpd-webserver.conf - Andrew McNab -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## Example configuration file for GridSite as a Web Server -## (that is, primarily for interactive use with a browser.) -## Listening is on ports 80/777 (HTTP) and 443/488 (HTTPS). -## -## (777/488 is to allow firewalls to distinguish between Grid and -## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a webserver. -## -## You do not need to install the GridSite mod_ssl.so module if you -## do not wish to use Globus Proxies or VOMS attributes, but you must -## have the mod_gridsite.so in /usr/lib/httpd/modules -## -## We're assuming you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from https://datagrid.in2p3.fr/distribution/datagrid/security/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ or /var/www/htdocs/dn-lists/ -## (Lists in /etc/grid-security/dn-lists/ override lists elsewhere.) -## -## To start serving files, make a directory /var/www/htdocs owned by -## apache.apache, including the file .gacl containing: -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE MOVE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -############################################################################## - -ServerRoot "/etc/httpd" - -## You MUST put your server's fully qualified domain name here -## This, the DOMAIN part of the https://DOMAIN/... URLs you want -ServerName FULL.SERVER.NAME - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 15 - -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so -LoadModule alias_module /usr/lib/httpd/modules/mod_alias.so -LoadModule cgi_module /usr/lib/httpd/modules/mod_cgi.so - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User apache -Group apache - -DocumentRoot "/var/www/htdocs" - - - AllowOverride None - - -LogLevel debug -LogFormat "%h \"%{SSL_CLIENT_S_DN}x\" %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -###################################################################### -# Plain unauthenticated HTTP on ports 80 and 777 -###################################################################### - -Listen 80 -Listen 777 - - -## This is used to serve the Manage Directory links in footers, -## and to allow you to edit files and ACLs via your browser. -ScriptAlias /real-gridsite-admin.cgi /usr/sbin/real-gridsite-admin.cgi - - - ## This sets up GACL authorization for this server. - GridSiteAuth on - - ## This exports various bits of info into the CGI environment - ## variables (and is needed for gridsite-admin.cgi to work.) - GridSiteEnvs on - - ## Nice GridSite directory listings (without truncating file names!) - GridSiteIndexes on - - ## If this is on, GridSite will look for gridsitehead.txt and - ## gridsitefoot.txt in the current directory or its parents, and - ## use them to replace the and tags in .html files. - GridSiteHtmlFormat on - - ## These directives (and the ScriptAlias above) allow authorized - ## people to manage files, ACLs and DN Lists through their web - ## browsers. Via HTTP, this just means extended directory listings - ## and History pages. - GridSiteAdminURI /real-gridsite-admin.cgi - GridSiteAdminFile gridsite-admin.cgi - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on ports 443 and 488 -###################################################################### -Listen 443 -Listen 488 -SSLSessionCacheTimeout 300 -SSLSessionCache shm:/var/cache/mod_ssl/shm_cache - - - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - -## This is used to serve the Manage Directory links in footers, -## and to allow you to edit files and ACLs via your browser. -ScriptAlias /real-gridsite-admin.cgi /usr/sbin/real-gridsite-admin.cgi - - - ## This sets up GACL authorization for this server. - GridSiteAuth on - - ## This exports various bits of info into the CGI environment - ## variables (and is needed for gridsite-admin.cgi to work.) - GridSiteEnvs on - - ## Nice GridSite directory listings (without truncating file names!) - GridSiteIndexes on - - ## If this is on, GridSite will look for gridsitehead.txt and - ## gridsitefoot.txt in the current directory or its parents, and - ## use them to replace the and tags in .html files. - GridSiteHtmlFormat on - - ## This is the path of directories (and all their subdirectories) for - ## GACL to search when it encounters a dn-list credential. The DN List - ## files are plain text, one DN per line, and must have the full url - ## as the file name, but URL Encoded - eg with urlencode(1) - GridSiteDNlists /etc/grid-security/dn-lists/:/var/www/htdocs/dn-lists/ - - ## This is used to form the URL at which DN Lists "owned" by this - ## server are exported. https://FULL.SERVER.NAME/dn-lists/file - ## ALL FILES WITH URLs ON THIS SERVER WILL BE EXPORTED IRRESPECTIVE - ## OF WHERE THEY ARE FOUND ON THE DN-LISTS PATH!! - GridSiteDNlistsURI /dn-lists/ - - ## If this is greater than zero, we will accept GSI Proxies for clients - ## (full client certificates - eg inside web browsers - are always ok) - GridSiteGSIProxyLimit 0 - - ## This directive allows authorized people to write/delete files - ## from non-browser clients - eg with htcp(1) - GridSiteMethods GET PUT DELETE MOVE - - ## These directives (and the ScriptAlias above) allow authorized - ## people to manage files, ACLs and DN Lists through their web - ## browsers via HTTPS. The value of GridSiteAdminFile appears to - ## exist in every directory, but is internally redirected by - ## mod_gridsite to the value of GridSiteAdminURI (the ScriptAlias - ## then maps that onto the real-gridsite-admin.cgi executable.) - GridSiteAdminURI /real-gridsite-admin.cgi - GridSiteAdminFile gridsite-admin.cgi - - - diff --git a/org.gridsite.core/doc/index.html b/org.gridsite.core/doc/index.html deleted file mode 100644 index 46c147b..0000000 --- a/org.gridsite.core/doc/index.html +++ /dev/null @@ -1,82 +0,0 @@ -GridSite 1.5.x Documentation - -

GridSite 1.5.x Documentation

- -

-GridSite -is a set of extensions to the Apache 2.0 webserver, which support -Grid security based on X.509 certificates. Since GridSite applies access -control within Apache itself, via mod_gridsite, Grid authorization and -the associated verified credentials are available to all technologies -supported by Apache, including static file serving, SSI, CGI, PHP, JSP and -mod_perl. - -

-The GridSite Wiki includes -guides and cookbook examples about using GridSite, along with up to date -information about the APIs. - -

Reference

- -

-The following reference documents and man pages are put in -/usr/share/doc/gridsite-VERSION when GridSite is installed. - -

-

- -
htcp(1) -
A command line tool for copying files to or from HTTP(S) servers. -

- -

mod_gridsite(8) -
An Apache 2.0 module which enforces access control via Grid Access - Control Lists, and X.509, GSI or VOMS credentials. mod_gridsite also - gives Apache built-in support for the HTTP PUT and DELETE methods, and - formatting of HTML pages with standard headers and footers. -

- -

gsexec(8) -
A modified version of suexec(8), for use with mod_gridsite(8). gsexec - allows CGI programs to be run as pool users, depending on the client's - X.509 identity or the directory in which the CGI is located. -

- -

httpd-fileserver.conf and - httpd-webserver.conf -
Example configuration files for simple HTTP(S) fileservers and - webservers, with explanatory comments. -

- -

urlencode(1) -
A command for URL-encoding strings. -

- -

findproxyfile(1) -
The findproxyfile command returns full path to a GSI Proxy file, - either in the proxy cache maintained by the GridSite G-HTTPS and - delegation portType functions, or in other standard places. -

- - - -

fuse.spec -
An RPM SPEC file which can be used to build the - FUSE kernel module, - library and commands on Linux 2.4.x and 2.6.x systems, for use with - SlashGrid. -

- -

gridsite.h API reference -
A detailed description of the C API provided by libgridsite, generated - from the sources by doxygen. -

- -

- - diff --git a/org.gridsite.core/doc/mod_gridsite.8 b/org.gridsite.core/doc/mod_gridsite.8 deleted file mode 100644 index fc8c3bb..0000000 --- a/org.gridsite.core/doc/mod_gridsite.8 +++ /dev/null @@ -1,325 +0,0 @@ -.TH MOD_GRIDSITE 8 "October 2005" "mod_gridsite" "GridSite Manual" -.SH NAME -.B mod_gridsite -\- Grid extensions to Apache httpd -.SH SYNOPSIS -.B LoadModule gridsite_module mod_gridsite.so -.SH DESCRIPTION -.B mod_gridsite -is an Apache 2.0 module which enforces access control via Grid -Access Control Lists, and X.509, GSI or VOMS credentials. mod_gridsite also -gives Apache built-in support for the HTTP PUT and DELETE methods, and -formatting of HTML pages with standard headers and footers. - -Since mod_gridsite access -control within Apache itself, Grid authorization and -the associated verified credentials are available to all technologies -supported by Apache, including static file serving, SSI, CGI, PHP, mod_perl -and Java servlets via a connector to Tomcat. - -Operation of mod_gridsite can be configured using runtime directives -in Apache's standard httpd.conf configuration file. The module must first be -loaded with a LoadModule directive: - -LoadModule gridsite_module /PATH/TO/MODULES/mod_gridsite.so - -The module's behaviour is then controlled by GridSite... directives within -Apache sections, allowing different directories to use -GridSite features in different ways. - -.SH DIRECTIVES - -.IP "GridSiteIndexes on|off" -Determines whether GridSite generates HTML directory listings. These -have some advantages over standard Apache directory listings (eg the -displayed filenames are never truncated) and will include standard -headers and footers if GridSiteHtmlFormat is on. -(Default: GridSiteIndexes off) - -.IP "GridSiteIndexHeader file" -If the named file is found in the directory being listed, the file -is included verbatim at the top of the listing and excluded from -the file-by-file listing. The file can either be HTML or plain text (in -which case browsers will be treat it as one HTML paragraph.) -(Default: none) - -.IP "GridSiteHtmlFormat on|off" -Determines where HTML pages receive additional formatting before being -sent to the client. This includes the "Last modified", -"View page history", "Switch to HTTP(S)", -"Print View" and "Built with GridSite" footer -elements. If header and footer files are found, they will be used too. -(Default: GridSiteHtmlFormat off) - -.IP "GridSiteHeadFile file" -.IP "GridSiteFootFile file" -Set the filenames to be searched for as standard headers and footers -for HTML pages. For each HTML page, the directory of that page is tried -first, and then parent directories in ascending order until a header / -footer file is found. Header files are inserted in place of HTML - tags; footer files in place of . (These -standard files should each include the appropriate body tag as a -replacement.) -(Defaults: GridSiteHeadFile gridsitehead.txt, -GridSiteFootFile gridsitefoot.txt) - -.IP "GridSiteAuth on|off" -Enables GridSite access control features, using -GACL files. The files are named .gacl and are -per-directory. The current directory is tried and then parent -directories in ascending order until a .gacl file is found. -(Default: GridSiteAuth off) - -.IP "GridSiteAdminList uri" -All members of the DN List with name "uri" receive the full set -of permissions, irrespective of per-directory .gacl files. People in -this group have full control over the whole site. -(Default: none) - -.IP "GridSiteGSIProxyLimit limit" -When using GSI Proxy credentials, -proxies with delegation depth greater than "limit" will -be ignored by mod_gridsite authorization decisions. A limit of zero -implies only full X.509 -certificates (and no proxies) will be accepted. A limit of 1 implies -that only the initial proxy, usually created on the user's own machine, -is acceptable. Higher levels lead to proxies on remote machines, eg -used by running jobs, being accepted. -(Default: GridSiteGSIProxyLimit 1) - -.IP "GridSiteMethods [GET] [PUT] [DELETE] [MOVE]" -Specifies which HTTP methods are supported by GridSite. GET (and HEAD) -are always supported. PUT and DELETE support is turned on by this -directive, subject to a positive statement that write permission is -allowed for the directory in question, by a GACL file. -(Default: GridSite GET) - -.IP "GridSiteDNlists directory1[:directory2[:directory3]...]" -Sets up the DN List path used by GACL for -evaluating credentials. If this directive is not used, -then GACL will use the GRST_DN_LISTS variable from Apache's own -environment. If that is not set either, then /etc/grid-security/dn-lists -is searched. -(Default: none) - -.IP "GridSiteDNlistsURI uri" -If GridSiteDNlistsURI is used, then the URI given appears to be -populated with all the DN lists on the current DN lists path which -match the current server. That is, for server https://example.org/ -with DN lists URI /dn-lists/, all DN lists with URLs starting -https://example.org/dn-lists/ will appear to be present in /dn-lists/, -irrespective of where in the path they are stored. -(Default: none) -

- -.IP "GridSiteAdminURI uri" -GridSiteAdminURI gives the absolute URI on the server of the GridSite -Admin CGI program, which is used for file management, HTML and GACL -editing. This should be used in conjunction with the standard Apache -directive ScriptAlias to map that URI to the real-gridsite-admin.cgi -executable. For example: - -ScriptAlias /real-gridsite-admin.cgi /PATH/TO/real-gridsite-admin.cgi - -This URI is always reached by an internal redirection from the value -set by GridSiteAdminFile, and is never visible to users. -(Default: none) - -.IP "GridSiteAdminFile cgifilename" -If GridSiteAdminURI is set, then the cgifilename of GridSiteAdminFile -appears to be present in all directories when explicitly -requested (it does not appear in directory listings.) Requests for these -ghost CGI URIs are internally redirected to the value set by -GridSiteAdminURI. (Default: GridSiteAdminFile gridsite-admin.cgi) - -.IP "GridSiteEnvs on|off" -This makes mod_gridsite export several variables into the environment -of CGI programs and other dynamic content systems. The variable names -are listed below. For gridsite-admin.cgi mechanism to work, this switch -must be left in its default state of on. -(Default: GridSiteEnvs on) - -.IP "GridSiteEditable [ext1 [ext2 [ext3] ...]]]" -A space-separated list of file extensions which can safely be edited -by the GridSite Text/HTML editor. The extensions are given without the -initial dot. This directive must apply to the gridsite-admin.cgi -executable, rather than just to the files it manages. This is most -easily achieved by placing GridSiteEditable in the main section of -the virtual host, outside any Directory or Location containers. -(Default: GridSiteEditable txt shtml html htm css js php jsp) - -.IP "GridSiteHelpURI uri" -If set, gives the URI to use for "Website Help" links in HTML -page footers. (Default: none) - -.IP "GridSiteLink on|off" -Turns off the link in the HTML page footers which gives credit to GridSite. -(Default: GridSiteLink on) - -.IP "GridSiteUnzip path" -If "path" is set by this directive, then real-gridsite-admin.cgi -will offer to list the contents of .zip archives on the server. -Users with write access are able to unpack the contents into the same -directory as the .zip file. The value of "path" must point -to the location of the unzip binary. (Default: none) - -.IP "GridSiteGridHTTP on|off" -Enable GridHTTP for this server, virtual server or directory: -HTTPS requests made with the header -.BR "Upgrade: GridHTTP/1.0" -will be redirected to an HTTP version of the file. (Default: off) - -.IP "GridSiteGridHTTPport port" -Sets the port to use for the unencrypted HTTP component of GridHTTP -HTTPS->HTTP transfers. The same setting will be used for all virtual hosts -which support GridHTTP. (Default: 777) - -.IP "GridSiteSessionsDir path" -Location of authentication cookies and SSL session credentials directory, -relative to ServerRoot. Used by GridHTTP to record the credentials obtained -via HTTPS, and available to the corresponding HTTP request or subsequent -HTTPS requests following a session restart. -(Default: /var/www/sessions) - -.IP "GridSiteACLFormat GACL|XACML" -Format to use when writing .gacl files. (Both formats are automatically -recognised when reading.) (Default: GACL) - -.IP "GridSiteACLPath path" -Specify the absolute or relative (to ServerRoot) path of the ACL file -governing this section of the server's URL space. This can be applied to -virtual URL spaces provided by other modules, such as DAV or SVN, using -the Apache container. If the path contains %0, it is replaced -by this virtual server's hostname. If it contains %1, %2, ... it is replaced -with the 1st, 2nd, ... component of the request's URI, separated by slashes -and counting from immediately after the initial slash. - -.IP "GridSiteExecMethod nosetuid|suexec|X509DN|directory" -Execution strategy for CGI scripts and executables. For options other -than nosetuid, suexec (or gsexec renamed suexec) must installed. For -X509DN and directory, gsexec must be installed, as suexec. See -.BR "gsexec(8)" -for an explanation of the different execution strategies. -(Default: nosetuid) - -.IP "GridSiteUserGroup user group" -Unix user and group when using suexec (or gsexec as suexec.) This -is equivalent to the suexec SuexecUserGroup directive, but can be -specified on a per-directory basis. (Default: none) - -.IP "GridSiteDiskMode GroupNone|GroupRead|GroupWrite WorldNone|WorldRead" -The file creation permissions mode, taking two arguments to specify -the group and other permissions. The mode always includes read and write -permission for the CGI user itself. -(Default: GroupNone WorldNone) - -.IP "GridSiteCastUniPort port" -The -.BR UDP -unicast port to listen on for HTCP queries, and from which to -send replies to HTCP unicast and multicast queries. Ideally, this should be -a privileged port below 1024. This directive may not appear within a virtual -server. (Default: 777) - -.IP "GridSiteCastGroup group[:port]" -A UDP multicast group on which to listen for HTCP queries, plus an optional -port. If no port is given, then 777 is used. Multiple GridSiteCastGroup -directives can be given to cause the UDP responder to listen to more than -one multicast group. This directive may not appear within a virtual server. - -.IP "GridSiteCastAlias URL-prefix path-prefix" -Maps SiteCast generic URLs to the local filesystem. When processing -HTCP queries, matching SiteCast URLs will have URL-prefix stripped off -and the remaining portion of the URL added to path-prefix to construct a -local path and filename. If a file is found with that name, a SiteCast HTCP -response will be returned to the querying host. Otherwise the queries are -ignored. -This directive may appear within virtual servers, and the virtual server's -servername and first port will determine the host and port name used to -construct the transfer URL. - -.SH ENVIRONMENT - -The following variables are present in the environment of CGI programs and -other dynamic content systems if the -.BR "GridSiteEnvs on" -directive is in effect. - -.IP GRST_PERM -Numerical value of the permission bit-map obtained by comparing the -user with the GACL in force. (These should be tested using the -GRSTgaclPermHasXXXX functions from GACL.) - -.IP GRST_ADMIN_LIST -URI of the DN List, listing people with full admin and write access -to the whole site. - -.IP GRST_GSIPROXY_LIMIT -Maximum valid delegation level for GSI Proxies. - -.IP GRST_DIR_PATH -Absolute path in the local filesystem to the directory holding the -file being requested. - -.IP GRST_DESTINATION_TRANSLATED -Present if a WebDAV -.BR "Destination:" -header was given in the request with a local URL. Contains the translation of -the URL given into an absolute path in the local filesystem. - -.IP GRST_HELP_URI -URI of website help pages set by GridSiteHelpURI directive. - -.IP GRST_ADMIN_FILE -Filename of per-directory ghost gridsite-admin.cgi program. (This is -used by real-gridsite-admin.cgi to construct links in its pages.) - -.IP GRST_EDITABLE -Space-separated list of extensions which can safely be edited with a -Text/HTML editor. - -.IP "GRST_HEAD_FILE and GRST_FOOT_FILE" -Filenames of standard header and footer files. - -.IP GRST_DN_LISTS -DN lists search path. - -.IP GRST_DN_LISTS_URI -Directory of virtual URIs used to publish this site's DN Lists. - -.IP GRST_UNZIP -Full path to the -.BR "unzip(1)" -binary, used to list and unpack .zip files. - -.IP GRST_NO_LINK -If set, do not include credit links to GridSite in page footers. - -.IP GRST_ACL_FORMAT -Format to use when writing .gacl files: either GACL or XACML. - -.IP GRST_EXEC_METHOD -Specified by -.BR GridSiteExecMethod -either suexec, X509DN or directory. - -.IP GRST_EXEC_DIRECTORY -The directory containing the CGI script or executable (used by gsexec -to determine which pool account to use in directory mapping mode.) - -.IP GRST_DISK_MODE -The -.BR Apache -disk permission modes bit pattern, in hexadecimal, starting with 0x. -(Similar to the Unix bit pattern, except with hexadecimal rather than -octal values: eg 0x600 [Apache] vs 0600 [Unix] -are both read/write for user only.) - -.SH AUTHOR -Andrew McNab - -mod_gridsite is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR htcp(1), -.BR httpd(8), -.BR gsexec(8) diff --git a/org.gridsite.core/doc/slashgrid.8 b/org.gridsite.core/doc/slashgrid.8 deleted file mode 100644 index 64f058f..0000000 --- a/org.gridsite.core/doc/slashgrid.8 +++ /dev/null @@ -1,67 +0,0 @@ -.TH SLASHGRID 28 "September 2006" "slashgrid" "GridSite Manual" -.SH NAME -.B slashgrid -\- Local and remote virtual filesystems using grid credentials - -.SH "SYNOPSIS" - -.BR slashgrid -[--debug] [--domain DOMAIN --groups GROUPS] [--local-root PATH --local-user USER] [--gridmapdir PATH] [--foreground] - -.SH "SUMMARY" - -SlashGrid provides remote virtual filesystems under /grid ("slash grid") -using HTTP/HTTPS as a transport protocol, and a local filesystem under -/grid/local which can give access to the DocumentRoot area of a webserver -on the same machine. In both local and remote cases, X.509, GSI Proxy -and VOMS credentials can be used as the basis of authorization decisions. - -.SH "REMOTE HTTP(S) SERVERS" - -SlashGrid maps URLs of the form https://d.n.s:port/path/file into virtual paths -of the form /grid/https/d.n.s:port/path/file (with /grid/http/ for -HTTP URLs.) - -SlashGrid attempts to obtain a user credential in the form of a GSI Proxy -file, either indicated by the variable X509_USER_PROXY in the environment -of the user's process, or a file of the form /tmp/x509up_uUID, where UID is -their Unix user ID. If none is found, an authenticated HTTPS request is made. - -.SH "SITECAST DOMAINS" - -If the slashgrid daemon is started with the option --domain, then URLs -with DNS component matching the given domain will be located using SiteCast -requests. SlashGrid will attempt to use UDP multicast queries to find a -transfer URL of a copy of the file requested. The option --groups must also -be used to specify a comma-separted list of one or more UDP multicast groups, -which will be searched in order. - -The SiteCast area of the virtual filesystem is read-only (to prevent -corruption of replicas.) - -.SH "LOCAL FILESYSTEM" - -This filesystem is intended for use with GridSite/Apache webservers, which -control access via .gacl policy files in each directory hierarchy. SlashGrid -can interpret these files internally, and this allows other services, such -as GridFTP running in chroot mode, to be share access to a common file store. - -.SH "OPTIONS" - -.TP ---debug -Turn on debugging. - -.SH "MORE INFORMATION" - -http://www.gridsite.org/wiki/SlashGrid - -.SH AUTHORS - -Andrew McNab - -SlashGrid is part of GridSite: http://www.gridsite.org/ - -.SH "SEE ALSO" -.BR htcp(1), -.BR mod_gridsite(8) diff --git a/org.gridsite.core/doc/urlencode.1 b/org.gridsite.core/doc/urlencode.1 deleted file mode 100644 index 7cdfbc3..0000000 --- a/org.gridsite.core/doc/urlencode.1 +++ /dev/null @@ -1,43 +0,0 @@ -.TH URLENCODE 1 "November 2003" "urlencode" "GridSite Manual" -.SH NAME -.B urlencode -\- convert strings to or from URL-encoded form -.SH SYNOPSIS -.B urlencode -[-m|-d] -.I string [string ...] -.SH DESCRIPTION -.B urlencode -encodes strings according to RFC 1738. - -That is, characters A-Z a-z 0-9 . _ -and - are passed through unmodified, but all other characters are -represented as %HH, where HH is their two-digit upper-case hexadecimal ASCII -representation. -For example, the URL http://www.gridpp.ac.uk/ becomes -http%3A%2F%2Fwww.gridpp.ac.uk%2F - -.B urlencode -converts each character in all the strings given on the command line. If -multiple strings are given, they are concatenated with separating spaces -before conversion. - -.SH OPTIONS -.IP "-m" -Instead of full conversion, do GridSite "mild URL encoding" in which A-Z a-z -0-9 . = - _ @ and / are passed through unmodified. This results in slightly -more human-readable strings but the application must be prepared to create -or simulate the directories implied by any slashes. - -.IP "-d" -Do URL-decoding rather than encoding, according to RFC 1738. %HH and %hh -strings are converted and other characters are passed through unmodified, -with the exception that + is converted to space. - -.SH EXIT CODES -0 is always returned. - -.SH AUTHOR -Andrew McNab - -urlencode is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/interface/gridsite-gacl.h b/org.gridsite.core/interface/gridsite-gacl.h deleted file mode 100644 index f739c00..0000000 --- a/org.gridsite.core/interface/gridsite-gacl.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef HEADER_GACL_H -#define HEADER_GACL_H -#endif - -#ifndef GACL_LIB_VERSION -#define GACL_LIB_VERSION "x.x.x" -#endif - -typedef GRSTgaclCred GACLcred; - -typedef int GACLaction; -typedef unsigned int GACLperm; - -typedef GRSTgaclEntry GACLentry; - -typedef GRSTgaclAcl GACLacl; - -typedef GRSTgaclUser GACLuser; - -extern char *gacl_perm_syms[]; -extern GACLperm gacl_perm_vals[]; - -#define GACL_PERM_NONE GRST_PERM_NONE -#define GACL_PERM_READ GRST_PERM_READ -#define GACL_PERM_LIST GRST_PERM_LIST -#define GACL_PERM_WRITE GRST_PERM_WRITE -#define GACL_PERM_ADMIN GRST_PERM_ADMIN - -#define GACLhasNone(perm) (perm == 0) -#define GACLhasRead(perm) ((perm & GRST_PERM_READ) != 0) -#define GACLhasList(perm) ((perm & GRST_PERM_LIST) != 0) -#define GACLhasWrite(perm) ((perm & GRST_PERM_WRITE) != 0) -#define GACLhasAdmin(perm) ((perm & GRST_PERM_ADMIN) != 0) - -#define GACL_ACTION_ALLOW GRST_ACTION_ALLOW -#define GACL_ACTION_DENY GRST_ACTION_DENY - -#define GACL_ACL_FILE GRST_ACL_FILE -#define GACL_DN_LISTS GRST_DN_LISTS - -#define GACLinit() GRSTgaclInit() - -#define GACLnewCred(x) GRSTgaclCredNew((x)) -/* GACLcred *GACLnewCred(char *); */ - -#define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) -/* int GACLaddToCred(GACLcred *, char *, char *); */ - -#define GACLfreeCred(x) GRSTgaclCredFree((x)) -/* int GACLfreeCred(GACLcred *); */ - -#define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) -/* int GACLaddCred(GACLentry *, GACLcred *); */ - -#define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) -/* int GACLdelCred(GACLentry *, GACLcred *); */ - -#define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) -/* int GACLprintCred(GACLcred *, FILE *); */ - - -#define GACLnewEntry() GRSTgaclEntryNew() -/* GACLentry *GACLnewEntry(void); */ - -#define GACLfreeEntry(x) GRSTgaclEntryFree((x)) -/* int GACLfreeEntry(GACLentry *); */ - -#define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) -/* int GACLaddEntry(GACLacl *, GACLentry *); */ - -#define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) -/* int GACLprintEntry(GACLentry *, FILE *); */ - - -#define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) -/* int GACLprintPerm(GACLperm, FILE *); */ - -#define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) -/* int GACLallowPerm(GACLentry *, GACLperm); */ - -#define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) -/* int GACLunallowPerm(GACLentry *, GACLperm); */ - -#define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) -/* int GACLdenyPerm(GACLentry *, GACLperm); */ - -#define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) -/* int GACLundenyPerm(GACLentry *, GACLperm); */ - -#define GACLpermToChar(x) GRSTgaclPermToChar((x)) -/* char *GACLpermToChar(GACLperm); */ - -#define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) -/* GACLperm GACLcharToPerm(char *); */ - -#define GACLnewAcl() GRSTgaclAclNew() -/* GACLacl *GACLnewAcl(void); */ - -#define GACLfreeAcl(x) GRSTgaclAclFree((x)) -/* int GACLfreeAcl(GACLacl *); */ - -#define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) -/* int GACLprintAcl(GACLacl *, FILE *); */ - -#define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) -/* int GACLsaveAcl(char *, GACLacl *); */ - -#define GACLloadAcl(x) GRSTgaclAclLoadFile((x)) -/* GACLacl *GACLloadAcl(char *); */ - -#define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) -/* char *GACLfindAclForFile(char *); */ - -#define GACLloadAclForFile(x) GRSTgaclAclLoadforFile((x)) -/* GACLacl *GACLloadAclForFile(char *); */ - -#define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) -/* int GACLisAclFile(char *); */ - - -#define GACLnewUser(x) GRSTgaclUserNew((x)) -/* GACLuser *GACLnewUser(GACLcred *); */ - -#define GACLfreeUser(x) GRSTgaclUserFree((x)) -/* int GACLfreeUser(GACLuser *); */ - -#define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) -/* int GACLuserAddCred(GACLuser *, GACLcred *); */ - -#define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) -/* int GACLuserHasCred(GACLuser *, GACLcred *); */ - -#define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) -/* GACLcred *GACLuserFindCredType(GACLuser *, char *); */ - -#define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) -/* int GACLtestDnList(char *, GACLuser *); */ - -#define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) -/* GACLperm GACLtestUserAcl(GACLacl *, GACLuser *); */ - -#define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) -/* GACLperm GACLtestExclAcl(GACLacl *, GACLuser *); */ - - -#define GACLurlEncode(x) GRSThttpUrlEncode((x)) -/* char *GACLurlEncode(char *); */ - -#define GACLmildUrlEncode(x) GRSThttpUrlMildencode((x)) -/* char *GACLmildUrlEncode(char *); */ - -GACLentry *GRSTgaclEntryParse(xmlNodePtr cur); -/* special function for legacy EDG LB service */ diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h deleted file mode 100644 index 961bd89..0000000 --- a/org.gridsite.core/interface/gridsite.h +++ /dev/null @@ -1,379 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef HEADER_SSL_H -#include -#endif - -#ifndef HEADER_CRYPTO_H -#include -#endif - -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -/// Everything ok (= OpenSSL X509_V_OK) -#define GRST_RET_OK 0 - -/// Failed for unspecified reason -#define GRST_RET_FAILED 1000 - -/// Failed to find certificate in some cert store / directory -#define GRST_RET_CERT_NOT_FOUND 1001 - -/// Bad signature -#define GRST_RET_BAD_SIGNATURE 1002 - -/// No such file or directory -#define GRST_RET_NO_SUCH_FILE 1003 - - -// #define GRSTerrorLog(GRSTerrorLevel, GRSTerrorFmt, ...) if (GRSTerrorLogFunc != NULL) (GRSTerrorLogFunc)(__FILE__, __LINE__, GRSTerrorLevel, GRSTerrorFmt, __VA_ARGS__) - -#define GRSTerrorLog(GRSTerrorLevel, ...) if (GRSTerrorLogFunc != NULL) (GRSTerrorLogFunc)(__FILE__, __LINE__, GRSTerrorLevel, __VA_ARGS__) - -void (*GRSTerrorLogFunc)(char *, int, int, char *, ...); - -/* these levels are the same as Unix syslog() and Apache ap_log_error() */ - -#define GRST_LOG_EMERG 0 -#define GRST_LOG_ALERT 1 -#define GRST_LOG_CRIT 2 -#define GRST_LOG_ERR 3 -#define GRST_LOG_WARNING 4 -#define GRST_LOG_NOTICE 5 -#define GRST_LOG_INFO 6 -#define GRST_LOG_DEBUG 7 - -typedef struct { char *name; - char *value; - void *next; } GRSTgaclNamevalue; - -typedef struct { char *type; - int delegation; - GRSTgaclNamevalue *firstname; - void *next; } GRSTgaclCred; - -typedef int GRSTgaclAction; -typedef unsigned int GRSTgaclPerm; - -typedef struct { GRSTgaclCred *firstcred; - GRSTgaclPerm allowed; - GRSTgaclPerm denied; - void *next; } GRSTgaclEntry; - -typedef struct { GRSTgaclEntry *firstentry; } GRSTgaclAcl; - -typedef struct { GRSTgaclCred *firstcred; - char *dnlists; } GRSTgaclUser; - -#define GRST_PERM_NONE 0 -#define GRST_PERM_READ 1 -#define GRST_PERM_EXEC 2 -#define GRST_PERM_LIST 4 -#define GRST_PERM_WRITE 8 -#define GRST_PERM_ADMIN 16 -#define GRST_PERM_ALL 31 - -/* DO NOT USE PermIsNone!! */ -#define GRSTgaclPermIsNone(perm) ((perm) == 0) - -#define GRSTgaclPermHasNone(perm) ((perm) == 0) -#define GRSTgaclPermHasRead(perm) (((perm) & GRST_PERM_READ ) != 0) -#define GRSTgaclPermHasExec(perm) (((perm) & GRST_PERM_EXEC ) != 0) -#define GRSTgaclPermHasList(perm) (((perm) & GRST_PERM_LIST ) != 0) -#define GRSTgaclPermHasWrite(perm) (((perm) & GRST_PERM_WRITE) != 0) -#define GRSTgaclPermHasAdmin(perm) (((perm) & GRST_PERM_ADMIN) != 0) - -#define GRST_ACTION_ALLOW 0 -#define GRST_ACTION_DENY 1 - -#define GRST_HIST_PREFIX ".grsthist" -#define GRST_ACL_FILE ".gacl" -#define GRST_DN_LISTS "/etc/grid-security/dn-lists" -#define GRST_RECURS_LIMIT 9 - -#define GRST_PROXYCERTINFO_OID "1.3.6.1.4.1.3536.1.222" -#define GRST_VOMS_OID "1.3.6.1.4.1.8005.100.100.5" -#define GRST_VOMS_DIR "/etc/grid-security/vomsdir" - -#define GRST_ASN1_MAXCOORDLEN 50 -#define GRST_ASN1_MAXTAGS 500 - -struct GRSTasn1TagList { char treecoords[GRST_ASN1_MAXCOORDLEN+1]; - int start; - int headerlength; - int length; - int tag; } ; - -typedef struct { int type; /* CA, user, proxy, VOMS, ... */ - int errors; /* unchecked, bad sig, bad time */ - char *issuer; /* Cert CA DN, EEC of PC, or VOMS DN */ - char *dn; /* Cert DN, or VOMS AC holder DN */ - char *value; /* VOMS FQAN or NULL */ - time_t start; - time_t finish; - int serial; - char *ocsp; /* accessLocation field */ - void *raw; /* X509 or VOMS Extension object */ - void *next; } GRSTx509Cert; - -#define GRST_CERT_BAD_FORMAT 1 -#define GRST_CERT_BAD_CHAIN 2 -#define GRST_CERT_BAD_SIG 4 -#define GRST_CERT_BAD_TIME 8 -#define GRST_CERT_BAD_OCSP 16 - -#define GRST_CERT_TYPE_CA 1 -#define GRST_CERT_TYPE_EEC 2 -#define GRST_CERT_TYPE_PROXY 3 -#define GRST_CERT_TYPE_VOMS 4 - -/* a chain of certs, starting from the first CA */ -typedef struct { GRSTx509Cert *firstcert; } GRSTx509Chain; - -int GRSTx509CertLoad(GRSTx509Cert *, X509 *); -int GRSTx509ChainLoadCheck(GRSTx509Chain **, STACK_OF(X509) *, X509 *, char *, char *); -int GRSTx509ChainFree(GRSTx509Chain *); - -#define GRST_HTTP_PORT 777 -#define GRST_HTTPS_PORT 488 -#define GRST_HTCP_PORT 777 -#define GRST_GSIFTP_PORT 2811 - -#define GRSThtcpNOPop 0 -#define GRSThtcpTSTop 1 - -typedef struct { unsigned char length_msb; - unsigned char length_lsb; - char text[1]; } GRSThtcpCountstr; - -#define GRSThtcpCountstrLen(string) (256*((string)->length_msb) + (string)->length_lsb) - -typedef struct { unsigned char total_length_msb; - unsigned char total_length_lsb; - unsigned char version_msb; - unsigned char version_lsb; - unsigned char data_length_msb; - unsigned char data_length_lsb; - unsigned int response : 4; - unsigned int opcode : 4; - unsigned int rr : 1; - unsigned int f1 : 1; - unsigned int reserved : 6; - unsigned int trans_id; /* must be 4 bytes */ - GRSThtcpCountstr *method; - GRSThtcpCountstr *uri; - GRSThtcpCountstr *version; - GRSThtcpCountstr *req_hdrs; - GRSThtcpCountstr *resp_hdrs; - GRSThtcpCountstr *entity_hdrs; - GRSThtcpCountstr *cache_hdrs; } GRSThtcpMessage; - -int GRSTgaclInit(void); - -/* #define GACLnewCred(x) GRSTgaclCredNew((x)) */ -GRSTgaclCred *GRSTgaclCredNew(char *); - -/* #define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) */ -int GRSTgaclCredAddValue(GRSTgaclCred *, char *, char *); - -#define GRSTgaclCredSetDelegation(cred, level) ((cred)->delegation = (level)) -#define GRSTgaclCredGetDelegation(cred) ((cred)->delegation) - -/* #define GACLfreeCred(x) GRSTgaclCredFree((x)) */ -int GRSTgaclCredFree(GRSTgaclCred *); - -/* #define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) */ -int GRSTgaclEntryAddCred(GRSTgaclEntry *, GRSTgaclCred *); - -/* #define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) */ -int GRSTgaclEntryDelCred(GRSTgaclEntry *, GRSTgaclCred *); - -/* #define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) */ -int GRSTgaclCredCredPrint(GRSTgaclCred *, FILE *); - - -/* #define GACLnewEntry(x) GRSTgaclEntryNew((x)) */ -GRSTgaclEntry *GRSTgaclEntryNew(void); - -/* #define GACLfreeEntry(x) GRSTgaclEntryFree((x)) */ -int GRSTgaclEntryFree(GRSTgaclEntry *); - -/* #define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) */ -int GRSTgaclAclAddEntry(GRSTgaclAcl *, GRSTgaclEntry *); - -/* #define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) */ -int GRSTgaclEntryPrint(GRSTgaclEntry *, FILE *); - - -/* #define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) */ -int GRSTgaclPermPrint(GRSTgaclPerm, FILE *); - -/* #define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) */ -int GRSTgaclEntryAllowPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) */ -int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) */ -int GRSTgaclEntryDenyPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) */ -int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLpermToChar(x) GRSTgaclPermToChar((x)) */ -char *GRSTgaclPermToChar(GRSTgaclPerm); - -/* #define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) */ -GRSTgaclPerm GRSTgaclPermFromChar(char *); - -/* #define GACLnewAcl(x) GRSTgaclAclNew((x)) */ -GRSTgaclAcl *GRSTgaclAclNew(void); - -/* #define GACLfreeAcl(x) GRSTgaclAclFree((x)) */ -int GRSTgaclAclFree(GRSTgaclAcl *); - -/* #define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) */ -int GRSTgaclAclPrint(GRSTgaclAcl *, FILE *); - -/* #define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) */ -int GRSTgaclAclSave(GRSTgaclAcl *, char *); - -/* #define GACLloadAcl(x) GRSTgaclFileLoadAcl((x)) */ -GRSTgaclAcl *GRSTgaclAclLoadFile(char *); - -/* #define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) */ -char *GRSTgaclFileFindAclname(char *); - -/* #define GACLloadAclForFile(x) GRSTgaclFileLoadAcl((x)) */ -GRSTgaclAcl *GRSTgaclAclLoadforFile(char *); - -/* #define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) */ -int GRSTgaclFileIsAcl(char *); - - -/* #define GACLnewUser(x) GRSTgaclUserNew((x)) */ -GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *); - -/* #define GACLfreeUser(x) GRSTgaclUserFree((x)) */ -int GRSTgaclUserFree(GRSTgaclUser *); - -/* #define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) */ -int GRSTgaclUserAddCred(GRSTgaclUser *, GRSTgaclCred *); - -/* #define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) */ -int GRSTgaclUserHasCred(GRSTgaclUser *, GRSTgaclCred *); - -int GRSTgaclUserSetDNlists(GRSTgaclUser *, char *); - -/* #define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) */ -GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *, char *); - -/* #define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) */ -int GRSTgaclDNlistHasUser(char *, GRSTgaclUser *); - -/* #define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) */ -GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *, GRSTgaclUser *); - -/* #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) */ -GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *, GRSTgaclUser *); - -char *GRSThttpUrlDecode(char *); - -/* #define GACLurlEncode(x) GRSThttpUrlEncode((x)) */ -char *GRSThttpUrlEncode(char *); - -/* #define GACLmildUrlEncode(x) GRSThttpMildUrlEncode((x)) */ -char *GRSThttpUrlMildencode(char *); - -int GRSTx509NameCmp(char *, char *); - -int GRSTx509KnownCriticalExts(X509 *); - -int GRSTx509IsCA(X509 *); -int GRSTx509CheckChain(int *, X509_STORE_CTX *); -int GRSTx509VerifyCallback(int, X509_STORE_CTX *); - -int GRSTx509GetVomsCreds(int *, int, size_t, char *, X509 *, STACK_OF(X509) *, char *); -GRSTgaclCred *GRSTx509CompactToCred(char *); -int GRSTx509CompactCreds(int *, int, size_t, char *, STACK_OF(X509) *, char *, X509 *); -char *GRSTx509CachedProxyFind(char *, char *, char *); -char *GRSTx509FindProxyFileName(void); -int GRSTx509MakeProxyCert(char **, FILE *, char *, char *, char *, int); -char *GRSTx509CachedProxyKeyFind(char *, char *, char *); -int GRSTx509ProxyDestroy(char *, char *, char *); -int GRSTx509ProxyGetTimes(char *, char *, char *, time_t *, time_t *); -int GRSTx509CreateProxyRequest(char **, char **, char *); -int GRSTx509MakeProxyRequest(char **, char *, char *, char *); -int GRSTx509StringToChain(STACK_OF(X509) **, char *); -char *GRSTx509MakeDelegationID(void); -char *GRSTx509MakeProxyFileName(char *, STACK_OF(X509) *); -int GRSTx509CacheProxy(char *, char *, char *, char *); - -#define GRST_HEADFILE "gridsitehead.txt" -#define GRST_FOOTFILE "gridsitefoot.txt" -#define GRST_ADMIN_FILE "gridsite-admin.cgi" - -typedef struct { char *text; - void *next; } GRSThttpCharsList; - -typedef struct { size_t size; - GRSThttpCharsList *first; - GRSThttpCharsList *last; } GRSThttpBody; - -void GRSThttpBodyInit(GRSThttpBody *); -void GRSThttpPrintf(GRSThttpBody *, char *, ...); -int GRSThttpCopy(GRSThttpBody *, char *); -void GRSThttpWriteOut(GRSThttpBody *); -int GRSThttpPrintHeaderFooter(GRSThttpBody *, char *, char *); -char *GRSThttpGetCGI(char *); - -time_t GRSTasn1TimeToTimeT(char *, size_t); -int GRSTasn1SearchTaglist(struct GRSTasn1TagList taglist[], int, char *); -int GRSTasn1ParseDump(BIO *, unsigned char *, long, - struct GRSTasn1TagList taglist[], int, int *); -int GRSTasn1GetX509Name(char *, int, char *, char *, - struct GRSTasn1TagList taglist[], int); - -int GRSThtcpNOPrequestMake(char **, int *, unsigned int); -int GRSThtcpNOPresponseMake(char **, int *, unsigned int); -int GRSThtcpTSTrequestMake(char **, int *, unsigned int, char *, char *, char *); -int GRSThtcpTSTresponseMake(char **, int *, unsigned int, char *, char *, char *); -int GRSThtcpMessageParse(GRSThtcpMessage *, char *, int); diff --git a/org.gridsite.core/project/build.number b/org.gridsite.core/project/build.number deleted file mode 100644 index e3c0104..0000000 --- a/org.gridsite.core/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Feb 23 03:19:54 CET 2005 -module.build=141 diff --git a/org.gridsite.core/project/build.properties b/org.gridsite.core/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.gridsite.core/project/configure.properties.xml b/org.gridsite.core/project/configure.properties.xml deleted file mode 100644 index c4067ab..0000000 --- a/org.gridsite.core/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.gridsite.core/project/dependencies.properties b/org.gridsite.core/project/dependencies.properties deleted file mode 100644 index 2a7383b..0000000 --- a/org.gridsite.core/project/dependencies.properties +++ /dev/null @@ -1,9 +0,0 @@ -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.core.version = HEAD - -# Component dependencies tag = do not remove this line = - diff --git a/org.gridsite.core/project/gridsite.core.csf.xml b/org.gridsite.core/project/gridsite.core.csf.xml deleted file mode 100644 index 7ca38dc..0000000 --- a/org.gridsite.core/project/gridsite.core.csf.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.gridsite.core modules have been updated, please rerun the configuration file - - - - The org.glite and org.gridsite.core modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/project/properties.xml b/org.gridsite.core/project/properties.xml deleted file mode 100644 index 74f88dc..0000000 --- a/org.gridsite.core/project/properties.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/project/taskdefs.xml b/org.gridsite.core/project/taskdefs.xml deleted file mode 100644 index 9c35cef..0000000 --- a/org.gridsite.core/project/taskdefs.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.gridsite.core/project/version.properties b/org.gridsite.core/project/version.properties deleted file mode 100644 index 788eead..0000000 --- a/org.gridsite.core/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.5.0 -module.age=1 diff --git a/org.gridsite.core/src/Doxyfile b/org.gridsite.core/src/Doxyfile deleted file mode 100644 index 14f88e0..0000000 --- a/org.gridsite.core/src/Doxyfile +++ /dev/null @@ -1,993 +0,0 @@ -# Doxyfile 1.2.18 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en -# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, -# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these class will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of -# the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. - -STRIP_FROM_PATH = - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower case letters. If set to YES upper case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are adviced to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. - -INHERIT_DOCS = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consist of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . ../interface - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp -# *.h++ *.idl *.odl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories -# that are symbolic links (a Unix filesystem feature) are excluded from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = doxygen - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet - -HTML_STYLESHEET = doxygen.css - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output dir. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non empty doxygen will try to run -# the html help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the Html help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = YES - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, -# or Internet explorer 4.0+). Note that for large projects the tree generation -# can take a very long time. In such cases it is better to disable this feature. -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_XML = NO - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = NO - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse the -# parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superceded by the HAVE_DOT option below. This is only a fallback. It is -# recommended to install and use dot, since it yield more powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermedate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = /usr/local/bin/ - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile deleted file mode 100644 index 3c5de82..0000000 --- a/org.gridsite.core/src/Makefile +++ /dev/null @@ -1,494 +0,0 @@ -# -# Andrew McNab and Shiv Kaushal, University of Manchester. -# Copyright (c) 2002-6. All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# o Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# o Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -#--------------------------------------------------------------- -# For more information about GridSite: http://www.gridsite.org/ -#--------------------------------------------------------------- - -include ../VERSION - -RPMCMD=$(shell if [ -x /usr/bin/rpmbuild ] ; then echo /usr/bin/rpmbuild; else echo rpm; fi) - -ifndef MYRPMDIR -export MYRPMDIR=$(shell pwd)/../RPMTMP -endif - -ifndef prefix -export prefix=/usr/local -endif - -ifndef MYCFLAGS -export MYCFLAGS=-I. -I../interface $(HTTPD_FLAGS) -I/usr/include/httpd -I/usr/include/apr-0 -I/opt/glite/include -fPIC -endif - -ifndef MYLDFLAGS -export MYLDFLAGS=-L. -endif - - - -# -# Build -# - -build: apidoc build-lib \ - htcp gridsite-copy.cgi mod_gridsite.so \ - urlencode findproxyfile real-gridsite-admin.cgi gsexec - -build-lib: libgridsite_globus.so.$(VERSION) libgridsite_globus.a \ - libgridsite.so.$(VERSION) libgridsite.a - -# First, normal versions using system OpenSSL rather than Globus OpenSSL - -libgridsite.so.$(VERSION): grst_err.o grst_x509.o grst_gacl.o grst_xacml.o \ - grst_http.o grst_asn1.o grst_htcp.o - gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ - -o libgridsite.so.$(PATCH_VERSION) -lcrypto `xml2-config --libs` \ - grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o \ - grst_asn1.o grst_htcp.o - ln -sf libgridsite.so.$(VERSION) libgridsite.so - ln -sf libgridsite.so.$(VERSION) libgridsite.so.$(MINOR_VERSION) - -libgridsite.a: grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o - ar src libgridsite.a grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o - -grst_err.o: grst_err.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include \ - -c grst_err.c - -grst_x509.o: grst_x509.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_x509.c - -grst_gacl.o: grst_gacl.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c - -grst_xacml.o: grst_xacml.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c - -grst_http.o: grst_http.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_http.c - -grst_asn1.o: grst_asn1.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_asn1.c - -grst_htcp.o: grst_htcp.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_htcp.c - -# Then build versions using Globus OpenSSL if configured - -ifdef OPENSSL_GLOBUS_LIBS - -libgridsite_globus.so.$(VERSION): grst_err_globus.o \ - grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o \ - grst_asn1_globus.o grst_xacml_globus.o grst_htcp_globus.o - gcc -shared -Wl,-soname,libgridsite_globus.so.$(MINOR_VERSION) \ - -o libgridsite_globus.so.$(PATCH_VERSION) \ - grst_err_globus.o grst_x509_globus.o grst_gacl_globus.o grst_xacml_globus.o \ - grst_http_globus.o grst_asn1_globus.o - ln -sf libgridsite_globus.so.$(VERSION) libgridsite_globus.so - -libgridsite_globus.a: grst_err_globus.o grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o - ar src libgridsite_globus.a \ - grst_err_globus.o grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o - -grst_err_globus.o: grst_err.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include \ - -c grst_err.c \ - -o grst_err_globus.o - -grst_x509_globus.o: grst_x509.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_x509.c \ - -o grst_x509_globus.o - -grst_gacl_globus.o: grst_gacl.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c \ - -o grst_gacl_globus.o - -grst_xacml_globus.o: grst_xacml.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c \ - -o grst_xacml_globus.o - -grst_http_globus.o: grst_http.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_http.c \ - -o grst_http_globus.o - -grst_asn1_globus.o: grst_asn1.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_asn1.c \ - -o grst_asn1_globus.o - -grst_htcp_globus.o: grst_htcp.c ../interface/gridsite.h - gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_htcp.c \ - -o grst_htcp_globus.o - -else - -libgridsite_globus.so.$(VERSION): libgridsite.so.$(VERSION) - cp -f libgridsite.so.$(VERSION) libgridsite_globus.so.$(VERSION) - -libgridsite_globus.a: libgridsite.a - cp -f libgridsite.a libgridsite_globus.a - -endif - -gsexec: gsexec.c gsexec.h - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ - -o gsexec gsexec.c - -urlencode: urlencode.c libgridsite.so.$(VERSION) - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ - -o urlencode urlencode.c -L. \ - -I/usr/kerberos/include \ - -lgridsite - -htcp: htcp.c libgridsite.so.$(VERSION) - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ - -o htcp htcp.c -L. \ - -I/usr/kerberos/include \ - `curl-config --cflags` `curl-config --libs` \ - -lgridsite - -gridsite-copy.cgi: gridsite-copy.c libgridsite.so.$(VERSION) - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ - -o gridsite-copy.cgi gridsite-copy.c -L. \ - -I/usr/kerberos/include \ - `curl-config --cflags` `curl-config --libs` \ - $(MYFCGILIBS) -lgridsite - -mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.so.$(VERSION) - gcc -g $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ - -I/usr/kerberos/include \ - -I/usr/include/libxml2 \ - -DVERSION=\"$(VERSION)\" -o mod_gridsite.so \ - mod_gridsite.c $(MYLDFLAGS) -lxml2 -lm -lz -lgridsite - -real-gridsite-admin.cgi: grst_admin_main.c grst_admin_gacl.c \ - grst_admin_file.c grst_admin.h - gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o real-gridsite-admin.cgi \ - grst_admin_main.c \ - grst_admin_gacl.c \ - grst_admin_file.c \ - -I/usr/kerberos/include \ - -DVERSION=\"$(VERSION)\" -lgridsite -lssl -lcrypto -lxml2 -lz -lm - -findproxyfile: findproxyfile.c libgridsite.so.$(VERSION) - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ - -o findproxyfile findproxyfile.c -L. \ - -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm - -showx509exts: showx509exts.c libgridsite.so.$(VERSION) - gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ - -o showx509exts showx509exts.c -L. \ - -I/usr/kerberos/include \ - -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm - -slashgrid: slashgrid.c libgridsite.so.$(VERSION) - gcc -g -o slashgrid -lfuse -lpthread slashgrid.c \ - $(MYCFLAGS) $(MYLDFLAGS) `xml2-config --cflags` \ - -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22 \ - -I/usr/kerberos/include `curl-config --cflags` \ - -L. `curl-config --libs` -lgridsite - -# This target is used by make-gridsite-spec to test for FUSE include+libs -fuse-test: fuse-test.c - gcc -g -lfuse fuse-test.c \ - $(MYCFLAGS) $(MYLDFLAGS) `xml2-config --cflags` \ - -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22 - -apidoc: - date - doxygen Doxyfile - mkdir -p ../doc/doxygen - cp -f doxygen/*.html doxygen/*.css doxygen/*.png ../doc/doxygen - cd ../doc ; for i in *.1 *.8 ; do ../src/roffit < $$i \ - > $$i.html ; done - -gaclexample: gaclexample.c libgridsite.a - gcc -g -o gaclexample gaclexample.c -I. -L. \ - -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm - -xacmlexample: xacmlexample.c libgridsite.a - gcc -g -o xacmlexample xacmlexample.c -I. -L. \ - -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm -# -# Delegation machinery, including SOAP delegation portType. To build this -# you either need to use the gLite build environment and set REPOSITORY -# or install gSOAP and set GSOAPDIR to the directory containing -# soapcpp2 and stdsoap2.h (unless GSOAPDIR is set already) -# - -ifndef GSOAPDIR - export GSOAPDIR=/usr -endif - -ifndef GRIDSITEDIR - export GRIDSITEDIR=/usr -endif - - -DelegationService.wsdl: delegation.h - $(GSOAPDIR)/bin/soapcpp2 -c delegation.h - -gridsite-delegation.cgi: grst-delegation.c delegation.h \ - DelegationService.wsdl libgridsite.so.$(VERSION) - gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ - grst-delegation.c \ - -I/usr/kerberos/include -I. -I$(GSOAPDIR)/include \ - -I$(GRIDSITEDIR)/include \ - -DVERSION=\"$(VERSION)\" -L. -L$(GSOAPDIR)/lib \ - -L$(GRIDSITEDIR)/lib \ - soapC.c soapServer.c -lgsoap \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -htproxyput: htproxyput.c delegation.h DelegationService.wsdl libgridsite.so.$(VERSION) - gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ - htproxyput.c \ - -I/usr/kerberos/include -I. \ - -g -DVERSION=\"$(VERSION)\" \ - -I$(GSOAPDIR)/include \ - -I$(GRIDSITEDIR)/include \ - -DWITH_OPENSSL -L. -L$(GSOAPDIR)/lib \ - $(STDSOAP2) \ - soapC.c soapClient.c -lgsoapssl \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -# This target is used by make-gridsite-spec to test for gSOAP include+libs -gsoap-test: gsoap-test.c - gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gsoap-test \ - gsoap-test.c \ - -I/usr/kerberos/include -I. \ - -g -DVERSION=\"$(VERSION)\" \ - -I$(GSOAPDIR)/include \ - -I$(GRIDSITEDIR)/include \ - -DWITH_OPENSSL -L$(GSOAPDIR)/lib \ - $(STDSOAP2) -L$(GRIDSITEDIR)/lib \ - -lgsoapssl -lz -lssl -lcrypto -lxml2 -lm - -gridsite-srm.cgi: gridsite-srm.c libgridsite.so.$(VERSION) - gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-srm.cgi \ - gridsite-srm.c \ - -I/usr/kerberos/include -I.\ - -I$(GRIDSITEDIR)/include \ - -DVERSION=\"$(VERSION)\" -L. \ - -L$(GRIDSITEDIR)/lib \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -clean: - -# -# Install -# - -install: apidoc install-lib - mkdir -p $(prefix)/include \ - $(prefix)/lib \ - $(prefix)/bin \ - $(prefix)/sbin \ - $(prefix)/share/man/man1 \ - $(prefix)/share/man/man8 \ - $(prefix)/lib/httpd/modules \ - $(prefix)/share/doc/gridsite-$(MINOR_VERSION) - cp -f ../interface/gridsite.h $(prefix)/include - cp -f ../interface/gridsite-gacl.h $(prefix)/include - cp -f urlencode $(prefix)/bin - cp -f findproxyfile $(prefix)/bin - cp -f real-gridsite-admin.cgi $(prefix)/sbin - cp -f gridsite-copy.cgi $(prefix)/sbin - cp -f ../CHANGES ../README ../INSTALL ../LICENSE ../VERSION \ - $(prefix)/share/doc/gridsite-$(MINOR_VERSION) - cp -f ../doc/index.html ../doc/*.conf ../doc/*.sh ../doc/*.spec \ - $(prefix)/share/doc/gridsite-$(MINOR_VERSION) - for i in htcp.1 htfind.1 htll.1 htls.1 htmkdir.1 htmv.1 htping.1 \ - htrm.1 urlencode.1 findproxyfile.1 ; do \ - cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/man/man1 ; \ - gzip -f $(prefix)/share/man/man1/$$i ; done - for i in mod_gridsite.8 gsexec.8 ; do \ - cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/man/man8 ; \ - gzip -f $(prefix)/share/man/man8/$$i ; done - cp -f htcp $(prefix)/bin - ln -sf htcp $(prefix)/bin/htls - ln -sf htcp $(prefix)/bin/htll - ln -sf htcp $(prefix)/bin/htrm - ln -sf htcp $(prefix)/bin/htmkdir - ln -sf htcp $(prefix)/bin/htmv - ln -sf htcp $(prefix)/bin/htping - ln -sf htcp $(prefix)/bin/htfind - cp -f gsexec $(prefix)/sbin - cp -f mod_gridsite.so $(prefix)/lib/httpd/modules - -install-lib: - mkdir -p $(prefix)/lib - cp -f libgridsite.a $(prefix)/lib - cp -f libgridsite.so.$(PATCH_VERSION) $(prefix)/lib - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so.$(MAJOR_VERSION) - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so.$(MINOR_VERSION) - cp -f libgridsite_globus.a $(prefix)/lib - cp -f libgridsite_globus.so.$(PATCH_VERSION) $(prefix)/lib - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so.$(MAJOR_VERSION) - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so.$(MINOR_VERSION) - -install-slashgrid: slashgrid - cp -f slashgrid $(prefix)/sbin - cp -f slashgrid.init $(RPM_BUILD_ROOT)/etc/rc.d/init.d/slashgrid - cp -f ../doc/slashgrid.8.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/slashgrid.8 $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/slashgrid.8 $(prefix)/share/man/man8 - gzip -f $(prefix)/share/man/man8/slashgrid.8 - mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/headers - mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/blocks - mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/tmp - -install-ws: gridsite-delegation.cgi htproxyput - mkdir -p $(prefix)/include \ - $(prefix)/lib \ - $(prefix)/bin \ - $(prefix)/sbin \ - $(prefix)/share/man/man1 \ - $(prefix)/share/man/man8 \ - $(prefix)/share/doc/gridsite-$(MINOR_VERSION) - cp -f ../doc/*.wsdl $(prefix)/share/doc/gridsite-$(MINOR_VERSION) - for i in htproxyput.1 htproxytime.1 htproxyrenew.1 htproxydestroy.1 \ - htproxyunixtime.1 htproxyinfo.1 ; do \ - cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/man/man1 ; \ - gzip -f $(prefix)/share/man/man1/$$i ; done - for i in gridsite-delegation.8 ; do \ - cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ - cp -f ../doc/$$i $(prefix)/share/man/man8 ; \ - gzip -f $(prefix)/share/man/man8/$$i ; done - cp -f htproxyput $(prefix)/bin - ln -sf htproxyput $(prefix)/bin/htproxydestroy - ln -sf htproxyput $(prefix)/bin/htproxytime - ln -sf htproxyput $(prefix)/bin/htproxyunixtime - ln -sf htproxyput $(prefix)/bin/htproxyrenew - ln -sf htproxyput $(prefix)/bin/htproxyinfo - cp -f gridsite-delegation.cgi $(prefix)/sbin - -# -# Distributions -# - -# source files tarball -dist: - mkdir -p ../dist/gridsite-$(PATCH_VERSION)/src \ - ../dist/gridsite-$(PATCH_VERSION)/doc \ - ../dist/gridsite-$(PATCH_VERSION)/interface - cp -f ../VERSION ../README ../LICENSE ../CHANGES ../INSTALL \ - ../dist/gridsite-$(PATCH_VERSION) - cp -f Makefile grst*.c htcp.c slashgrid.c slashgrid.init \ - urlencode.c findproxyfile.c gaclexample.c mod_gridsite.c \ - htproxyput.c grst_admin.h mod_ssl-private.h \ - gsexec.c gsexec.h gridsite-copy.c delegation.h \ - roffit make-gridsite-spec \ - Doxyfile doxygen.css doxyheader.html \ - ../dist/gridsite-$(PATCH_VERSION)/src - cp -f ../doc/*.html ../doc/*.1 ../doc/*.8 ../doc/*.conf ../doc/*.sh \ - ../doc/*.spec ../doc/*.wsdl \ - ../dist/gridsite-$(PATCH_VERSION)/doc - cp -f ../interface/*.h \ - ../dist/gridsite-$(PATCH_VERSION)/interface - cd ../dist ; tar zcvf ../gridsite-$(PATCH_VERSION).src.tar.gz \ - gridsite-$(PATCH_VERSION) - rm -Rf ../dist/gridsite-$(PATCH_VERSION) - - -# binary tarball distribution for htcp users -htcp-bin: htcp - mkdir -p ../htcp-bin-$(PATCH_VERSION)/bin \ - ../htcp-bin-$(PATCH_VERSION)/man/man1 - cp -f ../doc/README.htcp-bin ../htcp-bin-$(PATCH_VERSION) - cp -f htcp ../htcp-bin-$(PATCH_VERSION)/bin - cp -f ../doc/htcp.1 ../doc/htrm.1 ../doc/htls.1 ../doc/htmkdir.1 \ - ../doc/htll.1 ../doc/htmv.1 ../doc/htping.1 ../doc/htfind.1 \ - ../htcp-bin-$(PATCH_VERSION)/man/man1 - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htls - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htll - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htrm - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htmkdir - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htmv - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htping - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htfind - cd ../htcp-bin-$(VERSION) ; tar zcvf ../htcp-$(VERSION).bin.tar.gz . - rm -Rf ../htcp-bin-$(PATCH_VERSION) - -# RPM targets: build and RPMs go into subdirectories of ../RPMTMP/ -rpm: dist - export PATCH_VERSION=$(PATCH_VERSION) ; \ - export MINOR_VERSION=$(MINOR_VERSION) ; \ - export MYPREFIX=/usr ; \ - ./make-gridsite-spec - rm -Rf $(MYRPMDIR)/BUILDROOT $(MYRPMDIR)/BUILD - mkdir -p $(MYRPMDIR)/SOURCES $(MYRPMDIR)/SPECS $(MYRPMDIR)/BUILD \ - $(MYRPMDIR)/SRPMS $(MYRPMDIR)/RPMS/i386 $(MYRPMDIR)/BUILDROOT - cp -f ../gridsite-$(PATCH_VERSION).src.tar.gz $(MYRPMDIR)/SOURCES - cp -f gridsite.spec $(MYRPMDIR)/SPECS - $(RPMCMD) --define "_topdir $(MYRPMDIR)" \ - -ba --buildroot $(MYRPMDIR)/BUILDROOT gridsite.spec - - -wtf: - pwd - printenv - ls -l - ls -lR /usr/local/ - ls -lR $(GSOAPDIR) - - diff --git a/org.gridsite.core/src/delegation.h b/org.gridsite.core/src/delegation.h deleted file mode 100644 index 01b462f..0000000 --- a/org.gridsite.core/src/delegation.h +++ /dev/null @@ -1,86 +0,0 @@ -//gsoap ns schema namespace: http://www.gridsite.org/namespaces/delegation-1 - -struct ns__DelegationExceptionType -{ - char *message; //nillable -}; - -struct ns__NewProxyReq -{ - char *proxyRequest; //nillable - char *delegationID; //nillable -}; - -struct _DelegationException -{ - struct ns__DelegationExceptionType *ns__DelegationException; -}; - -//gsoap ns service name: DelegationSoapBinding -//gsoap ns service type: Delegation -//gsoap ns service port: https://localhost/gridsite-delegation.cgi -//gsoap ns service namespace: http://www.gridsite.org/namespaces/delegation-1 - -/* *** getProxyReq method *** */ - -//gsoap ns service method-style: rpc -//gsoap ns service method-encoding: literal -//gsoap ns service method-action: "" -//gsoap ns service method-fault: getProxyReq _DelegationException - -int ns__getProxyReq(char *_delegationID, - struct ns__getProxyReqResponse { - char *getProxyReqReturn; } *); - -/* *** getNewProxyReq method *** */ - -//gsoap ns service method-style: getNewProxyReq rpc -//gsoap ns service method-encoding: getNewProxyReq literal -//gsoap ns service method-action: getNewProxyReq "" -//gsoap ns service method-fault: getNewProxyReq _DelegationException - -int ns__getNewProxyReq(struct ns__getNewProxyReqResponse { - struct ns__NewProxyReq *getNewProxyReqReturn; } *); - -/* *** renewProxyReq method *** */ - -//gsoap ns service method-style: renewProxyReq rpc -//gsoap ns service method-encoding: renewProxyReq literal -//gsoap ns service method-action: renewProxyReq "" -//gsoap ns service method-fault: renewProxyReq _DelegationException - -int ns__renewProxyReq(char *_delegationID, - struct ns__renewProxyReqResponse { - char *_renewProxyReqReturn; } *); - -/* *** putProxy method *** */ - -//gsoap ns service method-style: putProxy rpc -//gsoap ns service method-encoding: putProxy literal -//gsoap ns service method-action: putProxy "" -//gsoap ns service method-fault: putProxy _DelegationException - -int ns__putProxy(char *_delegationID, - char *_proxy, - struct ns__putProxyResponse { } *); - -/* *** getTerminationTime method *** */ - -//gsoap ns service method-style: getTerminationTime rpc -//gsoap ns service method-encoding: getTerminationTime literal -//gsoap ns service method-action: getTerminationTime "" -//gsoap ns service method-fault: getTerminationTime _DelegationException - -int ns__getTerminationTime(char *_delegationID, - struct ns__getTerminationTimeResponse { - time_t _getTerminationTimeReturn; } *); - -/* *** destroy method *** */ - -//gsoap ns service method-style: destroy rpc -//gsoap ns service method-encoding: destroy literal -//gsoap ns service method-action: destroy "" -//gsoap ns service method-fault: destroy _DelegationException - -int ns__destroy(char *_delegationID, - struct ns__destroyResponse { } *); diff --git a/org.gridsite.core/src/doxygen.css b/org.gridsite.core/src/doxygen.css deleted file mode 100644 index 97ebc25..0000000 --- a/org.gridsite.core/src/doxygen.css +++ /dev/null @@ -1,49 +0,0 @@ -H1 { text-align: center; } -CAPTION { font-weight: bold } -A.qindex {} -A.qindexRef {} -A.el { text-decoration: none; font-weight: bold } -A.elRef { font-weight: bold } -A.code { text-decoration: none; font-weight: normal; color: #4444ee } -A.codeRef { font-weight: normal; color: #4444ee } -A:hover { text-decoration: none; background-color: #f2f2ff } -DL.el { margin-left: -1cm } -DIV.fragment { width: 100%; border: none; background-color: #eeeeee } -DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } -TD.md { background-color: #f2f2ff; font-weight: bold; } -TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } -TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } -DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } -DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } -XXBODY { background: white } -TD.indexkey { - background-color: #eeeeff; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -TD.indexvalue { - background-color: #eeeeff; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/org.gridsite.core/src/doxyheader.html b/org.gridsite.core/src/doxyheader.html deleted file mode 100644 index af78b52..0000000 --- a/org.gridsite.core/src/doxyheader.html +++ /dev/null @@ -1 +0,0 @@ -

GridSite Version 1.1.x diff --git a/org.gridsite.core/src/findproxyfile.c b/org.gridsite.core/src/findproxyfile.c deleted file mode 100644 index 423ffa2..0000000 --- a/org.gridsite.core/src/findproxyfile.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include - -#include - -#include "gridsite.h" - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [--outsidecache] [--proxycache=PATH] " - "[--delegation-id=DELEGATION-ID] [--user-dn=USER-DN]\n" - "(Version: %s)\n", p, VERSION); -} - -#define GRST_PROXY_CACHE "/var/www/proxycache" - -int main(int argc, char *argv[]) -{ - char *delegation_id = "_", *proxycache = "", *user_dn = "", - *proxyfile = NULL; - int c, outsidecache = 0, verbose = 0, option_index; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"outsidecache", 0, 0, 0}, - {"proxycache", 1, 0, 0}, - {"delegation-id", 1, 0, 0}, - {"user-dn", 1, 0, 0}, - {0, 0, 0, 0} }; - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 1) outsidecache = 1; - else if (option_index == 2) proxycache = optarg; - else if (option_index == 3) delegation_id = optarg; - else if (option_index == 4) user_dn = optarg; - } - else if (c == 'v') ++verbose; - } - - if (*user_dn != '\0') /* try to find in proxy cache */ - { - if ((proxycache == NULL) || (*proxycache == '\0')) - proxycache = getenv("GRST_PROXY_CACHE"); - - if ((proxycache == NULL) || (*proxycache == '\0')) - proxycache = GRST_PROXY_CACHE; - - proxyfile = GRSTx509CachedProxyFind(proxycache, delegation_id, user_dn); - } - - if (((proxyfile == NULL) || (*proxyfile == '\0')) && outsidecache) - { - proxyfile = GRSTx509FindProxyFileName(); - } - - if ((proxyfile != NULL) && (*proxyfile != '\0')) - { - puts(proxyfile); - return 0; - } - - fputs("No proxy file found\n", stderr); - - return 1; -} diff --git a/org.gridsite.core/src/gaclexample.c b/org.gridsite.core/src/gaclexample.c deleted file mode 100644 index 5ad29b7..0000000 --- a/org.gridsite.core/src/gaclexample.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -/* - Example program using GACL - - Build with: - - gcc -o gaclexample gaclexample.c -L. -I. -lgridsite -lxml2 -lz -lm -*/ - -#include -#include -#include -#include - -int main() -{ - GRSTgaclCred *cred, *usercred; - GRSTgaclEntry *entry; - GRSTgaclAcl *acl1, *acl2; - GRSTgaclUser *user; - GRSTgaclPerm perm0, perm1, perm2; - FILE *fp; - - /* must initialise GACL before using it */ - - GRSTgaclInit(); - - /* build up an ACL, starting with a credential */ - - cred = GRSTgaclCredNew("person"); - - GRSTgaclCredAddValue(cred, "dn", "/O=Grid/CN=Mr Grid Person"); - - /* create an entry to put it in */ - - entry = GRSTgaclEntryNew(); - - /* add the credential to it */ - - GRSTgaclEntryAddCred(entry, cred); - - /* add another credential */ - - cred = GRSTgaclCredNew("dn-list"); - GRSTgaclCredAddValue(cred, "url", "example-dn-list"); - GRSTgaclEntryAddCred(entry, cred); - - fp = fopen("example-dn-list", "w"); - fputs("/O=Grid/CN=Mr Grid Person\n", fp); - fclose(fp); - - /* associate some permissions and denials to the credential */ - - GRSTgaclEntryAllowPerm( entry, GRST_PERM_READ); - GRSTgaclEntryAllowPerm( entry, GRST_PERM_WRITE); - GRSTgaclEntryAllowPerm( entry, GRST_PERM_ADMIN); - GRSTgaclEntryDenyPerm( entry, GRST_PERM_ADMIN); - GRSTgaclEntryDenyPerm( entry, GRST_PERM_LIST); - - perm0 = GRST_PERM_READ | GRST_PERM_WRITE; - - printf("test perm should be %d\n", perm0); - - /* create a new ACL and add the entry to it */ - - acl1 = GRSTgaclAclNew(); - - GRSTgaclAclAddEntry(acl1, entry); - - /* create a GRSTgaclUser to compare with the ACL */ - - usercred = GRSTgaclCredNew("person"); - - GRSTgaclCredAddValue(usercred, "dn", "/O=Grid/CN=Mr Grid Person"); - - user = GRSTgaclUserNew(usercred); - - GRSTgaclUserSetDNlists(user, getcwd(NULL, 0)); - printf("DN Lists dir %s\n", getcwd(NULL, 0)); - -// putenv("GRST_DN_LISTS=."); - - perm1 = GRSTgaclAclTestUser(acl1, user); - - printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm1); - - /* print and save the whole ACL */ - - GRSTgaclAclPrint(acl1, stdout); - - GRSTgaclAclSave(acl1, "example.gacl"); - - puts("gridacl.out saved"); - - puts(""); - - /* load the ACL back off the disk, print and test it */ - - acl2 = GRSTgaclAclLoadFile("example.gacl"); - - puts("gridacl.out loaded"); - - if (acl2 != NULL) GRSTgaclAclPrint(acl2, stdout); else puts("acl2 is NULL"); - - perm2 = GRSTgaclAclTestUser(acl2, user); - - printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm2); - - if (perm1 != perm0) return 1; - if (perm2 != perm0) return 2; - - return 0; -} diff --git a/org.gridsite.core/src/gridsite-copy.c b/org.gridsite.core/src/gridsite-copy.c deleted file mode 100644 index 7eb4578..0000000 --- a/org.gridsite.core/src/gridsite-copy.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (c) 2005, Yibiao Li, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/////////////////////////////////////////////////////////////////// -// -// compile: gcc -lcurl gridsite-copy.c -o gridsite-copy.cgi -// usage: cp gridsite-copy.cgi to the cgi-bin directory -// and map the COPY method to gridsite-copy.cgi -// by adding a line in httpd.conf: -// script COPY /cgi-bin/gridsite-copy.cgi -// -/////////////////////////////////////////////////////////////////// -#ifdef GRST_USE_FASTCGI -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -extern char **environ; - -size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) -{ - int written = fwrite(ptr, size, nmemb, (FILE *)stream); - return written; -} - -int gridsite_copy() -{ - char *getenv(); - - CURL *curl; - CURLcode res; - struct tms s_time, e_time; - FILE *fout; - - char *requestURI; - int grstPerm, srcsecure; - char passcode[100]; - char destination[500], destDir[400], destName[100]; - char *ptr, *ptr1; - - times(&s_time); - passcode[0]='\0'; - char *capath="/etc/grid-security/certificates"; - - printf("Content-type: text/html\n\n"); - printf("HTTP COPY\n"); - printf("

HTTP FILE COPY

\n"); - - curl = curl_easy_init(); - printf("Server: Initialized!\n"); - if(curl) { - //get the request URI - requestURI = curl_getenv("REQUEST_URI"); - if( strncmp( requestURI, "https://", 8 )==0 )srcsecure=1; - else srcsecure=0; - printf("The request URL is %s\n", requestURI); - - //get the destination directory and file name - strcpy(destination, getenv("HTTP_DESTINATION")); - ptr=destination; - ptr1 = strrchr(ptr, '/'); - ptr1+=1; - strcpy( destName, ptr1 ); - *ptr1 = '\0'; - strcpy( destDir, ptr ); - - // get the one time passcode from cookie string. - // the segmenty of code is tested on 19th sep. 2005 - if( (ptr=curl_getenv("HTTP_COOKIE")) != NULL) - { - ptr += 20; - strcpy( passcode, ptr ); - } - - //get permision attributes - grstPerm = atoi(curl_getenv("GRST_DESTINATION_PERM")); - - if( grstPerm & 8 ) // write right - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); - - if( srcsecure == 1 ) - { - curl_easy_setopt(curl, CURLOPT_COOKIE, passcode ); - curl_easy_setopt(curl, CURLOPT_CAPATH, capath ); - } - - curl_easy_setopt(curl, CURLOPT_URL, requestURI ); - - strcpy( destination, getenv("GRST_DESTINATION_TRANSLATED")); - fout = fopen( destination, "w" ); - if( fout == NULL ){ - printf("cannot open file to write,"); - printf(" maybe you have no right to write in the directory.\n"); - exit(-1); - } - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fout ); - res = curl_easy_perform(curl); - if( res!=0 ) - { - printf("Server: There are some things wrong with OPT parameters.%d \n", res); - } - else printf("Server: The file has been successfully copied.\n"); - fclose(fout); - } - else - { - printf("You have no permission to write in the destination directory.\n"); - } - - curl_easy_cleanup(curl); - } - else{ - printf("Server: cannot initialize CURL!\n"); - } - - curl_global_cleanup(); - - times(&e_time); - printf("Server: copying time %ld seconds\n", e_time.tms_utime-s_time.tms_utime); - printf("\n"); - return 0; -} - -int main( void ) -{ -#ifdef GRST_USE_FASTCGI - while(FCGI_Accept() >= 0) -#endif - { - gridsite_copy(); - } -} diff --git a/org.gridsite.core/src/grst-delegation.c b/org.gridsite.core/src/grst-delegation.c deleted file mode 100644 index 87f2278..0000000 --- a/org.gridsite.core/src/grst-delegation.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/authz/gridsite/ * - *---------------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "0.0.1" -#endif - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "soapH.h" -#include "DelegationSoapBinding.nsmap" - -#define GRST_PROXYCACHE "/../proxycache/" - -int main(int argn, char *argv[]) -{ - char *docroot, *method, *request, *p, *client_dn, *user_dn, - *delegation_id, *reqtxt, *proxydir; - struct soap soap; - - method = getenv("REQUEST_METHOD"); - if (strcmp(method, "POST") == 0) - { - soap_init(&soap); - soap_serve(&soap); /* CGI application */ - return 0; - } - - puts("Status: 501 Method Not Implemented\n"); - return 0; -} - -char *get_dn(void) -{ - int i; - char *p, *s, *dn; - GRSTgaclCred *cred = NULL; - - for (i=0; ; ++i) - { - asprintf(&p, "GRST_CRED_%d", i); - s = getenv(p); - free(p); - - if (s == NULL) break; - - if ((cred = GRSTx509CompactToCred(s)) == NULL) break; - - if ((strcmp(cred->type, "person") == 0) && - (cred->firstname != NULL) && - (cred->firstname->name != NULL) && - (strcmp(cred->firstname->name, "dn") == 0) && - (cred->firstname->value != NULL)) - { - dn = strdup(cred->firstname->value); - GRSTgaclCredFree(cred); - return dn; - } - - GRSTgaclCredFree(cred); - } - - return NULL; -} - -int ns__getProxyReq(struct soap *soap, - char *delegation_id, - struct ns__getProxyReqResponse *response) -{ - int i; - char *p, *user_dn, *docroot, *proxydir, *request; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = GRSTx509MakeDelegationID(); - else for (i=0; delegation_id[i] != '\0'; ++i) - { - if (!isalnum(delegation_id[i]) && - (delegation_id[i] != '.') && - (delegation_id[i] != ',') && - (delegation_id[i] != '_')) - { - delegation_id = NULL; - break; - } - } - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn != NULL) && - (user_dn[0] != '\0') && - (delegation_id != NULL) && - (GRSTx509MakeProxyRequest(&request, proxydir, - delegation_id, user_dn) == 0)) - { - response->getProxyReqReturn = request; - - free(user_dn); - return SOAP_OK; - } - - free(user_dn); - return SOAP_ERR; -} - -int ns__getNewProxyReq(struct soap *soap, - struct ns__getNewProxyReqResponse *response) -{ - char *p, *user_dn, *docroot, *proxydir, *request, *delegation_id; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - delegation_id = GRSTx509MakeDelegationID(); - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn != NULL) && - (user_dn[0] != '\0') && - (delegation_id != NULL) && - (GRSTx509MakeProxyRequest(&request, proxydir, - delegation_id, user_dn) == 0)) - { - response->getNewProxyReqReturn = malloc(sizeof(struct ns__NewProxyReq)); - response->getNewProxyReqReturn->proxyRequest = request; - response->getNewProxyReqReturn->delegationID = delegation_id; - - free(user_dn); - return SOAP_OK; - } - - free(user_dn); - return SOAP_ERR; -} - -int ns__putProxy(struct soap *soap, char *delegation_id, - char *proxy, - struct ns__putProxyResponse *response) -{ - int fd, c, len = 0, i; - char *docroot, *proxydir, *p, *user_dn; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = GRSTx509MakeDelegationID(); - else for (i=0; delegation_id[i] != '\0'; ++i) - { - if (!isalnum(delegation_id[i]) && - (delegation_id[i] != '.') && - (delegation_id[i] != ',') && - (delegation_id[i] != '_')) - { - delegation_id = NULL; - break; - } - } - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn == NULL) || - (user_dn[0] == '\0') || - (delegation_id == NULL) || - (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxy) - != GRST_RET_OK)) - { - free(proxydir); - free(user_dn); - return SOAP_ERR; - } - - free(proxydir); - free(user_dn); - return SOAP_OK; -} - -int ns__renewProxyReq(struct soap *soap, - char *delegation_id, - struct ns__renewProxyReqResponse *response) -{ - int i; - char *p, *user_dn, *docroot, *proxydir, *request; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - if (delegation_id == NULL) - { - free(user_dn); - return SOAP_ERR; - } - - for (i=0; delegation_id[i] != '\0'; ++i) - { - if (!isalnum(delegation_id[i]) && - (delegation_id[i] != '.') && - (delegation_id[i] != ',') && - (delegation_id[i] != '_')) - { - delegation_id = NULL; - break; - } - } - - if (*delegation_id == '\0') - { - free(user_dn); - return SOAP_ERR; - } - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn != NULL) && - (user_dn[0] != '\0') && - (delegation_id != NULL) && - (GRSTx509MakeProxyRequest(&request, proxydir, - delegation_id, user_dn) == 0)) - { - response->_renewProxyReqReturn = request; - - free(user_dn); - return SOAP_OK; - } - - free(user_dn); - return SOAP_ERR; -} - -int ns__getTerminationTime(struct soap *soap, - char *delegation_id, - struct ns__getTerminationTimeResponse *response) -{ - char *p, *user_dn, *docroot, *proxydir; - time_t start, finish; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - delegation_id = GRSTx509MakeDelegationID(); - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn != NULL) && - (user_dn[0] != '\0') && - (delegation_id != NULL) && - (GRSTx509ProxyGetTimes(proxydir, delegation_id, user_dn, - &start, &finish) == 0)) - { - response->_getTerminationTimeReturn = finish; - - free(user_dn); - return SOAP_OK; - } - - free(user_dn); - return SOAP_ERR; -} - -int ns__destroy(struct soap *soap, - char *delegation_id, - struct ns__destroyResponse *response) -{ - int fd, c, len = 0, i; - char *docroot, *proxydir, *p, *client_dn, *user_dn; - - if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - - if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = GRSTx509MakeDelegationID(); - else for (i=0; delegation_id[i] != '\0'; ++i) - { - if (!isalnum(delegation_id[i]) && - (delegation_id[i] != '.') && - (delegation_id[i] != ',') && - (delegation_id[i] != '_')) - { - delegation_id = NULL; - break; - } - } - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn == NULL) || - (user_dn[0] == '\0') || - (delegation_id == NULL) || - (GRSTx509ProxyDestroy(proxydir, delegation_id, user_dn) - != GRST_RET_OK)) - { - free(proxydir); - free(user_dn); - return SOAP_ERR; - } - - free(proxydir); - free(user_dn); - return SOAP_OK; -} diff --git a/org.gridsite.core/src/grst_admin.h b/org.gridsite.core/src/grst_admin.h deleted file mode 100644 index cddc415..0000000 --- a/org.gridsite.core/src/grst_admin.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab and Shiv Kaushal, - University of Manchester. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -void GRSThttpError(char *); -void adminfooter(GRSThttpBody *, char *, char *, char *, char *); -int GRSTstrCmpShort(char *, char *); -char *makevfilename(char *, size_t, char *); - -/*CGI GACL - Edit interface functions*/ -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -/*Functions producing messages*/ -//void error(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp); - diff --git a/org.gridsite.core/src/grst_admin_file.c b/org.gridsite.core/src/grst_admin_file.c deleted file mode 100644 index d6619a6..0000000 --- a/org.gridsite.core/src/grst_admin_file.c +++ /dev/null @@ -1,1573 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// when porting: remember that sendfile() is very OS-specific! -#include - -#include - -#include "grst_admin.h" - -char *storeuploadfile(char *boundary, int *bufferused) -{ -// rewrite this to copy whole POSTed stdin HTTP body to disk then -// mmap() and pick apart? How to deal with 100MB uploaded files, say? - - char *filebuffer = NULL; - int bufferlen = 0, c, boundarylen; - - *bufferused = 0; - boundarylen = strlen(boundary); - - while ((c = getchar()) != EOF) - { - if (*bufferused > 1024*1024*100) return NULL; - - ++(*bufferused); - - if (*bufferused > bufferlen) - { - bufferlen = bufferlen + 1000; - filebuffer = realloc(filebuffer, (size_t) bufferlen); - } - - filebuffer[*bufferused - 1] = c; - - if ( (*bufferused >= boundarylen + 4) && - (boundary[boundarylen-1] == c) && - (boundary[boundarylen-2] == filebuffer[*bufferused - 2]) && - (strncmp(boundary, &filebuffer[*bufferused - boundarylen], - boundarylen) == 0)) - { - *bufferused = *bufferused - boundarylen - 4; - - if (filebuffer == NULL) return strdup(""); - else return filebuffer; - } - } - - return NULL; -} - -void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - char *boundary, *p, oneline[1086], *filename = NULL, - tmpfilename[1025], *filebuffer = NULL, *filepath, - *vfile, *dir_path_vfile; - int mimestate, bufferused = 0, itworked = 0; - FILE *fp; - GRSThttpBody bp; - -#define MIMESTUNKNOWN 1 -#define MIMESTUPLOAD 2 -#define MIMESTFILENM 3 - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - p = getenv("CONTENT_TYPE"); - boundary = &p[30]; - - mimestate = MIMESTUNKNOWN; - - while (fgets(oneline, sizeof(oneline), stdin) != NULL) - { - if (*oneline == 13) // MIME has CR/LF line breaks, CR=13 - { - if (mimestate == MIMESTUPLOAD) - { - filebuffer = storeuploadfile(boundary, &bufferused); - mimestate = MIMESTUNKNOWN; - } - else if (mimestate == MIMESTFILENM) - { - fgets(tmpfilename, sizeof(tmpfilename), stdin); - if (*tmpfilename != 13) - { - p = index(tmpfilename, 13); - *p = '\0'; - filename = strdup(tmpfilename); - } - mimestate = MIMESTUNKNOWN; - } - } - else if (GRSTstrCmpShort(oneline, - "Content-Disposition: form-data; name=\"uploadfile\"; filename=\"") - == 0) - { - mimestate = MIMESTUPLOAD; - if (filename == NULL) - { - filename = strdup(&oneline[61]); - - p = rindex(&oneline[61], '\\'); - if (p != NULL) { ++p ; filename = p; } - - p = rindex(&oneline[61], '/'); - if (p != NULL) { ++p ; filename = p; } - - p = index(filename, '"'); - if (p != NULL) *p = '\0'; - } - } - else if (GRSTstrCmpShort(oneline, - "Content-Disposition: form-data; name=\"file\"") == 0) - { - mimestate = MIMESTFILENM; - } - } - - if ((filebuffer != NULL) && (bufferused >= 0)) - { - if (filename == NULL) GRSThttpError("403 Forbidden"); - else if ((index(filename, '/') != NULL) || - (strcmp(filename, GRST_ACL_FILE) == 0)) - { - puts("Status: 403 Forbidden filename\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Forbidden filename %s\n", filename); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Forbidden filename %s

\n", - filename); - - GRSThttpPrintf(&bp, - "

New file names cannot include slashes " - "or use the reserved ACL name, %s\n", GRST_ACL_FILE); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - else - { - vfile = makevfilename(filename, bufferused, dn); - asprintf(&dir_path_vfile, "%s/%s", dir_path, vfile); - - fp = fopen(dir_path_vfile, "w"); - if (fp != NULL) - { - if ((fwrite(filebuffer, - sizeof(char), bufferused, fp) == bufferused) && - (fclose(fp) == 0)) - { - asprintf(&filepath, "%s/%s", dir_path, filename); - - unlink(filepath); /* this can fail ok */ - - itworked = (link(dir_path_vfile, filepath) == 0); - } - } - } - - free((void *) filebuffer); - } - - if (itworked) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - - puts("Status: 500 Failed trying to upload\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Failed to upload\n"); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Failed to upload

\n"); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to upload the file, but the upload failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void deletefileaction(char *dn, GRSTgaclPerm perm, char *help_uri, - char *dir_path, char *file, char *dir_uri, - char *admin_file) -{ - int fd, numfiles; - char *dir_path_file, *dir_path_vfile, *p, *vfile, *dnlistsuri, - *fulluri, *server_name, *realfile; - struct stat statbuf; - GRSThttpBody bp; - struct dirent *subdirfile_ent; - DIR *subDIR; - - if (((strcmp(file, GRST_ACL_FILE) != 0) && !GRSTgaclPermHasWrite(perm)) || - ((strcmp(file, GRST_ACL_FILE) == 0) && !GRSTgaclPermHasAdmin(perm))) - GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if ((dnlistsuri != NULL) && - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - realfile = GRSThttpUrlEncode(file); - else if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - else realfile = file; - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - if ((stat(dir_path_file, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - subDIR = opendir(dir_path_file); - if (subDIR == NULL) numfiles = 99; /* stop deletion */ - else - { - numfiles = 0; - while ((subdirfile_ent = readdir(subDIR)) != NULL) - if (subdirfile_ent->d_name[0] != '.') ++numfiles; - else if (strncmp(subdirfile_ent->d_name, - GRST_ACL_FILE, - sizeof(GRST_ACL_FILE)) == 0) ++numfiles; - closedir(subDIR); - } - - if (numfiles == 0) - { - vfile = makevfilename(file, 0, dn); - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - if (rename(dir_path_file, dir_path_vfile) == 0) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - } - } - else if (unlink(dir_path_file) == 0) - { - if (strcmp(file, GRST_ACL_FILE) != 0) - { - vfile = makevfilename(file, 0, dn); - dir_path_file = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, vfile); - - fd = open(dir_path_file, O_WRONLY | O_CREAT); - if (fd != -1) close(fd); - } - - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - - return; - } - - puts("Status: 500 Failed trying to delete\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Error deleting %s%s\n", dir_uri, file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error deleting %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to delete %s, but the delete failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator.", - file); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void deletefileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Delete %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Delete %s

\n", file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

Do you really want to delete %s?", file); - GRSThttpPrintf(&bp,"

\n", file); - GRSThttpPrintf(&bp,"\n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"
\n"); - - GRSThttpPrintf(&bp,"

Or " - "return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void renameform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Rename %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Rename %s%s

\n", dir_uri, file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

What do you want to rename %s to?

", file); - GRSThttpPrintf(&bp,"\n", file); - GRSThttpPrintf(&bp,"

New name: \n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"

\n"); - - GRSThttpPrintf(&bp,"

Or " - "return to " - "directory listing\n", dir_uri, admin_file, dir_uri); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void editfileaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *pagetext, *dir_path_file, *vfile, *dir_path_vfile, - *dnlistsuri, *server_name, *fulluri, *realfile; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if ((dnlistsuri != NULL) && - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - { - realfile = GRSThttpUrlEncode(file); - - if (realfile[0] == '.') GRSThttpError("403 Forbidden"); - } - else if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - else realfile = file; - - asprintf(&dir_path_file, "%s/%s", dir_path, realfile); - - pagetext = GRSThttpGetCGI("pagetext"); - vfile = makevfilename(file, strlen(pagetext), dn); - asprintf(&dir_path_vfile, "%s/%s", dir_path, vfile); - - fp = fopen(dir_path_vfile, "w"); - if (fp == NULL) - { - puts("Status: 500 Failed trying to write\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, - "

GridSite considers you are authorized " - "to write the file, but the write failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - - fwrite(pagetext, strlen(pagetext), sizeof(char), fp); - - fclose(fp); - - unlink(dir_path_file); - - if (link(dir_path_vfile,dir_path_file) != 0) GRSThttpError("403 Forbidden"); - - if ((strlen(file) > 7) && (strcmp(&file[strlen(file) - 5], ".html") == 0)) - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s\n\n", dir_uri, file); - else printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); -} - -void create_acl(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd; - char *tmpgacl, *newgacl; - GRSTgaclAcl *acl; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError("403 Forbidden"); - - asprintf(&tmpgacl, "%s/.tmp.XXXXXX", dir_path); - asprintf(&newgacl, "%s/%s", dir_path, GRST_ACL_FILE); - - if (((acl = GRSTgaclAclLoadforFile(dir_path)) != NULL) && - ((fd = mkstemp(tmpgacl)) != -1) && - ((fp = fdopen(fd, "w+")) != NULL) && - GRSTgaclAclPrint(acl, fp) && - (fclose(fp) == 0) && - (rename(tmpgacl, newgacl) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - - free(tmpgacl); - free(newgacl); - return; - } - - puts("Status: 500 Failed trying to create\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error creating %s%s\n", dir_uri, - GRST_ACL_FILE); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error creating %s%s

\n", - dir_uri, GRST_ACL_FILE); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to create it, but the create failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - - free(tmpgacl); - free(newgacl); -} - -void renameaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int len; - char *dir_path_file, *vfile, *dir_path_vfile, - *dnlistsuri, *newfile, *dir_path_newfile; - struct stat statbuf; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - if (stat(dir_path_file, &statbuf) != 0) GRSThttpError("404 Not Found"); - - newfile = GRSThttpGetCGI("newfile"); - - if ((strcmp(newfile, GRST_ACL_FILE) == 0) || - (strcmp(newfile, file) == 0)) GRSThttpError("403 Forbidden"); - - dir_path_newfile = malloc(strlen(dir_path) + strlen(newfile) + 2); - strcpy(dir_path_newfile, dir_path); - strcat(dir_path_newfile, "/"); - strcat(dir_path_newfile, newfile); - - vfile = makevfilename(newfile, statbuf.st_size, dn); - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - unlink(dir_path_newfile); /* just in case */ - - if ((link(dir_path_file, dir_path_vfile ) == 0) && - (link(dir_path_file, dir_path_newfile) == 0) && - (unlink(dir_path_file) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s\n\n", dir_uri); - return; - } - - puts("Status: 500 Failed trying to rename\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error renaming %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error renaming %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to rename it, but the rename failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void newdirectory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int len; - char *dir_path_file, *vfile, *dir_path_vfile, *filedup; - FILE *fp; - GRSThttpBody bp; - - if ((file[0] == '\0') || - !GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - filedup = strdup(file); - if (filedup[strlen(filedup)-1] == '/') filedup[strlen(filedup)-1] = '\0'; - if (index(filedup, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - if (mkdir(dir_path_file, 0751) == 0) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - - puts("Status: 500 Failed trying to create\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error create %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error creating directory %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, - "

GridSite considers you are authorized " - "to create the directory, but the creation failed. This " - "is probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "parent directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int numdn = 0, ifd, ofd, numdnlines = 0, i, found; - char *dir_path_file, *dir_path_tmpfile, *realfile, - *dnlistsuri, *server_name, *fulldiruri, *p, oneline[513], - **dnlines, name[81], *add; - FILE *ofp; - struct stat statbuf; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - server_name = getenv("SERVER_NAME"); - - if ((server_name == NULL) || - (dnlistsuri == NULL) || - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) != 0)) - GRSThttpError("403 Forbidden"); - - asprintf(&fulldiruri, "https://%s%s", server_name, dir_uri); - - if ((strncmp(fulldiruri, file, strlen(fulldiruri)) != 0) && - ((strncmp(fulldiruri, file, strlen(fulldiruri) - 1) != 0) || - (strlen(fulldiruri) - 1 != strlen(file)))) - { - puts("Status: 403 Forbidden\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s\n", file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s to %s

\n", - file, dir_uri); - - GRSThttpPrintf(&bp, "

You cannot create a DN List " - "with that prefix in this directory. Please see the " - "the GridSite User's Guide for an explanation."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - - p = GRSThttpGetCGI("numdn"); - if ((p == NULL) || (sscanf(p, "%d", &numdn) != 1)) - GRSThttpError("500 No number of DNs"); - - if (numdn > 0) - { - dnlines = malloc(sizeof(char *) * numdn); - - for (i=1; i <= numdn; ++i) - { - sprintf(name, "dn%d", i); - p = GRSThttpGetCGI(name); - - if (*p != '\0') - { - dnlines[numdnlines] = p; - ++numdnlines; - } - } - } - - add = GRSThttpGetCGI("add"); - - realfile = GRSThttpUrlEncode(file); - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - dir_path_tmpfile = malloc(strlen(dir_path) + 13); - strcpy(dir_path_tmpfile, dir_path); - strcat(dir_path_tmpfile, "/.tmp.XXXXXX"); - - if (((ofd = mkstemp(dir_path_tmpfile)) != -1) && - ((ofp = fdopen(ofd, "w")) != NULL)) - { - if (*add != '\0') - { - fputs(add, ofp); - fputc('\n', ofp); - } - - for (i=0; i < numdnlines; ++i) - { - fputs(dnlines[i], ofp); - fputc('\n', ofp); - } - - if ((fclose(ofp) == 0) && - ((stat(dir_path_file, &statbuf) != 0) || - (unlink(dir_path_file) == 0)) && - (rename(dir_path_tmpfile, dir_path_file) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - } - - puts("Status: 500 Failed trying to write\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to write the file, but the write failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - - /* try to clean up */ - if (stat(dir_path_tmpfile, &statbuf) == 0) unlink(dir_path_tmpfile); -} - -void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int c; - char *dir_path_file; - FILE *fp; - struct stat statbuf; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - if ((stat(dir_path_file, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("403 Forbidden"); - - fp = fopen(dir_path_file, "r"); - if (fp == NULL) GRSThttpError("500 Internal server error"); - - printf("Status: 200 OK\nContent-Type: text/html\nContent-Length: %d\n\n", - statbuf.st_size); - - while ((c = fgetc(fp)) != EOF) putchar(c); - - fflush(stdout); - fclose(fp); -} - -void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, n, i, j, enclen, num = 0; - char *encodedfile, *p, *dndecoded, modified[99], *vfile, *q, - *encdn; - time_t file_time; - size_t file_size; - struct stat statbuf; - struct dirent **namelist; - struct tm file_tm; - GRSThttpBody bp; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "History of %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

History of %s%s

\n", - dir_uri, file, dir_uri, file); - - asprintf(&vfile, "%s/%s", dir_path, file); - if (stat(vfile, &statbuf) == 0) - { - localtime_r((const time_t *) &(statbuf.st_mtime), &file_tm); - strftime(modified, sizeof(modified), - "%a %e %b %Y %k:%M", &file_tm); - - GRSThttpPrintf(&bp, "

Last modified: %s\n", modified); - } - free(vfile); - - encodedfile = GRSThttpUrlEncode(file); - for (p=encodedfile; *p != '\0'; ++p) if (*p == '%') *p = '='; - enclen = strlen(encodedfile); - - n = scandir(dir_path, &namelist, 0, alphasort); - - if (n > 0) - { - for (i = n - 1; i >= 0; --i) - { - if ((strncmp(namelist[i]->d_name, GRST_HIST_PREFIX, - sizeof(GRST_HIST_PREFIX) - 1) == 0) && - ((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX) - 1] == ':') && - (strncmp(&((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX)]), - encodedfile, enclen) == 0) && - ((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX)+enclen] == ':')) - { - if (num == 0) GRSThttpPrintf(&bp, - "

\n" - "" - "\n"); - - ++num; - - p = index(namelist[i]->d_name, ':'); - p = index(&p[1], ':'); - sscanf(&p[1], "%X:", &file_time); - p = index(&p[1], ':'); /* skip over microseconds time */ - p = index(&p[1], ':'); - sscanf(&p[1], "%X:", &file_size); - p = index(&p[1], ':'); - - encdn = strdup(&p[1]); - q = index(encdn, ':'); - if (q != NULL) *q = '\0'; - - for (q=encdn; *q != '\0'; ++q) if (*q == '=') *q = '%'; - dndecoded = GRSThttpUrlDecode(encdn); - - localtime_r((const time_t *) &file_time, &file_tm); - strftime(modified, sizeof(modified), - "%a %e %b %Y %k:%M", &file_tm); - - GRSThttpPrintf(&bp, - "\n", - modified, file_size, dndecoded); - - free(dndecoded); - - asprintf(&vfile, "%s/%s", dir_path, namelist[i]->d_name); - if ((stat(vfile, &statbuf) == 0) && (statbuf.st_size > 0)) - { - GRSThttpPrintf(&bp, "\n", - dir_uri, admin_file, dir_uri, namelist[i]->d_name); - else GRSThttpPrintf(&bp, "%s%s\">View\n", - dir_uri, namelist[i]->d_name); - } - else GRSThttpPrintf(&bp, ""); - - free(vfile); - } - } - } - - if (num > 0) GRSThttpPrintf(&bp, "
DateSize afterChanged by
%s%d%sView
 
\n"); - else GRSThttpPrintf(&bp, "

No history for this file\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void ziplist(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *shellcmd, *unzip, oneline[129]; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "Contents of %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

Contents of ZIP file %s%s

\n", - dir_uri, file, dir_uri, file); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - if (unzip != NULL) - { - GRSThttpPrintf(&bp, "
\n");
-      asprintf(&shellcmd, "cd %s ; %s -Z %s", dir_path, unzip, file);
-      fp = popen(shellcmd, "r");
-  
-      while (fgets(oneline, sizeof(oneline), fp) != NULL)           
-                          GRSThttpPrintf(&bp, "%s", oneline);         
-      pclose(fp);
-      GRSThttpPrintf(&bp, "
\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "

" - " in %s" - "" - "
" - "

(All files are placed in the same directory and files " - "beginning with "." are ignored.)

\n", - dir_uri, admin_file, dir_uri, file); - } - else GRSThttpPrintf(&bp, "

unzip path not defined!\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void unzipfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *shellcmd, *unzip, oneline[129]; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "Unzipping %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

Unzipping %s%s

\n", - dir_uri, file, dir_uri, file); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - if (unzip != NULL) - { - GRSThttpPrintf(&bp, "
\n");
-      asprintf(&shellcmd, "cd %s ; %s -jo %s -x '.*'", dir_path, unzip, file);
-      fp = popen(shellcmd, "r");
-  
-      while (fgets(oneline, sizeof(oneline), fp) != NULL)           
-                          GRSThttpPrintf(&bp, "%s", oneline);         
-      pclose(fp);
-      GRSThttpPrintf(&bp, "
\n"); - - if (GRSTgaclPermHasList(perm)) - GRSThttpPrintf(&bp, "

" - "Back to " - "directory", dir_uri, admin_file); - } - else GRSThttpPrintf(&bp, "

unzip path not defined!\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void editfileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, rawpagesize, i, c; - char *dir_path_file, *rawpage, *p; - FILE *fp = NULL; - struct stat statbuf; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - fd = open(dir_path_file, O_RDONLY); - if (fd != -1) - { - fp = fdopen(fd, "r"); - if (fp == NULL) GRSThttpError("500 File open failed!"); - - if ((fstat(fd, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("500 Not a regular file!"); - } - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Edit file %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Edit file %s

\n", file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp,"

File name: \n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp, "

\n"); - GRSThttpPrintf(&bp, "

\n"); - - if (fp != NULL) fclose(fp); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, i, c, numdn = 0; - char *dir_path_file, *rawpage, *p, *dnlistsuri, *server_name, *fulluri, - *realfile, oneline[513]; - FILE *fp = NULL; - struct stat statbuf; - GRSThttpBody bp; - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if (!GRSTgaclPermHasWrite(perm) || - (dnlistsuri == NULL) || - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) != 0)) - GRSThttpError("403 Forbidden"); - - realfile = GRSThttpUrlEncode(file); - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - fd = open(dir_path_file, O_RDONLY); - if (fd != -1) /* we dont mind open failing, but it must work if it doesnt */ - { - fp = fdopen(fd, "r"); - if (fp == NULL) GRSThttpError("500 File open failed!"); - - if ((fstat(fd, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("500 Not a regular file!"); - } - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Edit DN List %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Edit DN List

\n"); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp,"

List URL: \n", file, strlen(file)); - GRSThttpPrintf(&bp,"\n"); - - if (fp != NULL) - { - GRSThttpPrintf(&bp, "

\n" - "\n"); - - while (fgets(oneline, sizeof(oneline), fp) != NULL) - { - ++numdn; - - p = rindex(oneline, '\n'); - if (p != NULL) *p = '\0'; - - GRSThttpPrintf(&bp, "" - "\n", numdn, oneline, oneline); - } - - GRSThttpPrintf(&bp,"
Keep?Name
%s
\n"); - } - - GRSThttpPrintf(&bp,"\n", numdn); - - GRSThttpPrintf(&bp, "

Add new DN: \n"); - - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp, "

\n"); - - if (fp != NULL) fclose(fp); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - int n, is_dnlists_dir = 0, enclen, numfiles, encprefixlen; - char *d_namepath, modified[99], *absaclpath, *editable, *p, *unzip, - *dnlistsuri, *d_name, *server_name, *fulluri, *encfulluri, - *encprefix, *dnlistsprefix; - GRSThttpBody bp; - struct tm mtime_tm; - struct stat statbuf; - struct dirent **namelist, *subdirfile_ent; - DIR *subDIR; - - if (((!GRSTgaclPermHasWrite(perm)) && - (!GRSTgaclPermHasList(perm))) || - (stat(dir_path, &statbuf) != 0) || !S_ISDIR(statbuf.st_mode)) - GRSThttpError("403 Forbidden"); - - editable = getenv("GRST_EDITABLE"); - if (editable == NULL) editable = getenv("REDIRECT_GRST_EDITABLE"); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if (dnlistsuri && (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - { - is_dnlists_dir = 1; - server_name = getenv("SERVER_NAME"); - - asprintf(&fulluri, "https://%s%s", server_name, dir_uri); - encfulluri = GRSThttpUrlEncode(fulluri); - enclen = strlen(encfulluri); - - asprintf(&dnlistsprefix, "https://%s%s", server_name, dnlistsuri); - encprefix = GRSThttpUrlEncode(dnlistsprefix); - encprefixlen = strlen(encprefix); - } - - printf("Status: 200 OK\nContent-Type: text/html\n"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Manage directory %s\n", dir_uri); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Manage directory %s

\n\n", dir_uri); - - if (dir_uri[1] != '\0') - GRSThttpPrintf(&bp, - "\n", admin_file); - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasAdmin(perm)) - { - absaclpath = malloc(strlen(dir_path) + sizeof(GRST_ACL_FILE) + 1); - strcpy(absaclpath, dir_path); - strcat(absaclpath, "/"); - strcat(absaclpath, GRST_ACL_FILE); - - if (stat(absaclpath, &statbuf) == 0) /* ACL exists in THIS directory */ - { - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (!is_dnlists_dir) - { - GRSThttpPrintf(&bp, - "" - "%s\n", - GRST_ACL_FILE, - GRST_ACL_FILE, - statbuf.st_size, modified); - - GRSThttpPrintf(&bp, - "", - dir_uri, admin_file, GRST_ACL_FILE); - } - else GRSThttpPrintf(&bp, - "" - "%s\n", - GRST_ACL_FILE, - statbuf.st_size, modified); - - if (GRSTgaclPermHasAdmin(perm)) - GRSThttpPrintf(&bp, - "" - "", - dir_uri, admin_file, - dir_uri, admin_file, GRST_ACL_FILE); - else if (GRSTgaclPermHasRead(perm)) - GRSThttpPrintf(&bp, - "" - "", dir_uri, admin_file); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, "\n"); - } - else if (GRSTgaclPermHasAdmin(perm)) - GRSThttpPrintf(&bp, "\n" - "\n" - "\n", - dir_uri, admin_file); - } - - if (GRSTgaclPermHasList(perm)) - { - n = scandir(dir_path, &namelist, 0, alphasort); - while (n--) - { - if (namelist[n]->d_name[0] != '.') - { - d_namepath = malloc(strlen(dir_path) + - strlen(namelist[n]->d_name) + 2); - strcpy(d_namepath, dir_path); - strcat(d_namepath, "/"); - strcat(d_namepath, namelist[n]->d_name); - stat(d_namepath, &statbuf); - - if (S_ISDIR(statbuf.st_mode)) - { - subDIR = opendir(d_namepath); - - if (subDIR == NULL) numfiles = 99; /* stop deletion */ - else - { - numfiles = 0; - while ((subdirfile_ent = readdir(subDIR)) != NULL) - if (subdirfile_ent->d_name[0] != '.') ++numfiles; - else if (strncmp(subdirfile_ent->d_name, - GRST_ACL_FILE, - sizeof(GRST_ACL_FILE)) == 0) ++numfiles; - - closedir(subDIR); - } - } - - free(d_namepath); - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (S_ISDIR(statbuf.st_mode)) - { - GRSThttpPrintf(&bp, - "" - "%s\n", - dir_uri, namelist[n]->d_name, admin_file, - namelist[n]->d_name, - statbuf.st_size, modified); - - if (numfiles == 0) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, namelist[n]->d_name); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, "\n"); - } - else if (is_dnlists_dir) - { - if ((strlen(namelist[n]->d_name) <= encprefixlen) || - (strncmp(namelist[n]->d_name, encprefix, - encprefixlen) != 0)) continue; - - d_name = GRSThttpUrlDecode(namelist[n]->d_name); - - GRSThttpPrintf(&bp, "" - "%s" - "", - d_name, d_name, - statbuf.st_size, modified); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, "" - "" - "" - "" - "\n", - dir_uri, admin_file, d_name); - else GRSThttpPrintf(&bp, "\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, "" - "" - "" - "" - "\n", - dir_uri, admin_file, d_name); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, ""); - } - else /* regular directory, not DN Lists */ - { - d_name = namelist[n]->d_name; - - GRSThttpPrintf(&bp, - "" - "%s", - dir_uri, d_name, - d_name, - statbuf.st_size, modified); - - GRSThttpPrintf(&bp, - "", - dir_uri, admin_file, GRSThttpUrlEncode(d_name)); - - p = rindex(namelist[n]->d_name, '.'); - - if ((unzip != NULL) && - (p != NULL) && - (strcasecmp(&p[1], "zip") == 0) && - GRSTgaclPermHasRead(perm)) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, GRSThttpUrlEncode(d_name)); - else if ((p != NULL) && - (strstr(editable, &p[1]) != NULL) && - GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, GRSThttpUrlEncode(d_name)); - else GRSThttpPrintf(&bp, ""); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name)); - else - GRSThttpPrintf(&bp, "\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name)); - else - GRSThttpPrintf(&bp, ""); - } - } - - free(namelist[n]); - } - - free(namelist); - } - - if (GRSTgaclPermHasWrite(perm)) - { - if (is_dnlists_dir) - { - GRSThttpPrintf(&bp, "\n" - "" - "\n" - "\n", - dir_uri, admin_file, fulluri, strlen(fulluri)+8); - - GRSThttpPrintf(&bp, "\n" - "\n" - "\n", - dir_uri, admin_file); - } - else - { - GRSThttpPrintf(&bp, "\n" - "\n" - "" - "\n" - "\n" - "\n", - dir_uri, admin_file); - - GRSThttpPrintf(&bp, - "\n" - "\n" - "" - "" - "\n" - "" - "\n" - "\n", dir_uri, admin_file); - } - } - - GRSThttpPrintf(&bp, "
[Parent " - "directory]
%R%e %b %y
%s%ld" - "History
%s%ldEditDeleteView    
%R%e %b %y
" - "%s/%ld " - "Delete  
%s%ld 
 
  
%s%ld" - "History" - "List" - "Edit " - "Delete " - "Rename
 
New list name: " - "\n" - "
New directory: " - "\n" - "

New name:\n" - "

Upload file:New name: " - "
Local name:
\n"); - - if (!is_dnlists_dir) adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - diff --git a/org.gridsite.core/src/grst_admin_gacl.c b/org.gridsite.core/src/grst_admin_gacl.c deleted file mode 100644 index bdcccbd..0000000 --- a/org.gridsite.core/src/grst_admin_gacl.c +++ /dev/null @@ -1,981 +0,0 @@ -/* - Copyright (c) 2003-5, Shiv Kaushal, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*-----------------------------------------------------------* -* This program is part of GridSite: http://www.gridsite.org/ * -*------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include - -extern char *grst_perm_syms[]; -extern int grst_perm_vals[]; - -#include "grst_admin.h" - -// CGI GACL Editor interface functions -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp); - -// Functions for producing HTML output -void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path); -void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function); -void EndForm(GRSThttpBody *bp); -void GRSTgaclCredTableStart(GRSThttpBody *bp); -void GRSTgaclCredTableAdd(GRSTgaclUser *user, GRSTgaclEntry *entry, GRSTgaclCred *cred, GRSTgaclNamevalue *namevalue, int cred_no, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void GRSTgaclCredTableEnd(GRSTgaclEntry* entry, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -// ACL Manipulation functions -int GACLentriesInAcl(GRSTgaclAcl *acl); -int GRSTgaclCredsInEntry(GRSTgaclEntry *entry); -void check_acl_save(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSTgaclUser* user, GRSTgaclAcl *acl, GRSThttpBody *bp); -void GACLeditGetPerms(GRSTgaclEntry *entry); -GRSTgaclEntry *GACLreturnEntry(GRSTgaclAcl *acl, int entry_no); -GRSTgaclCred *GACLreturnCred(GRSTgaclEntry *entry, int cred_no); - -void StringHTMLEncode (char* string, GRSThttpBody *bp); - -void revert_acl(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -/*****************************************/ -/********** FUNCTIONS FOLLOW *************/ -/*****************************************/ - -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Shows the contents of the ACL. Gives edit 'buttons' if (int admin) == 1 - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny,timestamp; - GRSThttpBody bp; - char* AclFilename; - struct stat file_info; - int history_mode=0; - - if (admin==2){ - history_mode=1; - admin=0; - } - - /*double-check access permision*/ - if (!GRSTgaclPermHasAdmin(perm)) admin=0; - - StartHTML(&bp, dir_uri, dir_path); - - /* Load ACL from file and get timestamp*/ - if (history_mode==1) { - AclFilename=malloc(strlen(dir_path)+strlen(file)+2); - strcpy(AclFilename, dir_path); - strcat(AclFilename, "/"); - strcat(AclFilename, file); - } - else AclFilename=GRSTgaclFileFindAclname(dir_path); - - if (AclFilename==NULL){ - GRSThttpPrintf ( &bp,"The ACL was not found !!!
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - - stat(GRSTgaclFileFindAclname(dir_path), &file_info); - timestamp=file_info.st_mtime; - acl = GRSTgaclAclLoadFile(AclFilename); - - if (acl==NULL){ - GRSThttpPrintf ( &bp,"The ACL was found but could not be loaded - it could be incorrectly formatted
\n"); - adminfooter(&bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); - return; - } - - if (admin) GRSThttpPrintf (&bp,"New Entry
\n", dir_uri, admin_file, dir_uri, timestamp ); - - // Start with the first entry in the list and work through - entry=acl->firstentry; - entry_no=1; - while (entry!=NULL){ - - GRSThttpPrintf (&bp,"
Entry %d:\n", entry_no); - if (admin){ - GRSThttpPrintf (&bp,"Edit Entry ", dir_uri, admin_file, entry_no, dir_uri, timestamp ); - GRSThttpPrintf (&bp,"Delete Entry ",dir_uri, admin_file, entry_no, dir_uri, timestamp ); - GRSThttpPrintf (&bp,"

\n"); - } - - GRSTgaclCredTableStart(&bp); - - // Start with the first credential in the entry and work through - cred=entry->firstcred; - cred_no=1; - while (cred!=NULL){ - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - - GRSTgaclCredTableEnd (entry, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next entry - entry=entry->next; - entry_no++; - } - - if (!admin && GRSTgaclPermHasAdmin(perm) && !history_mode) //Print a link for admin mode, if not in admin mode but the user has admin permissions - GRSThttpPrintf (&bp,"Admin Mode", dir_uri, admin_file, dir_uri, timestamp ); - if (history_mode==1 && GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user)){ - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "revert_acl"); -//GRSThttpPrintf (&bp,"Revert to this Version", dir_uri, admin_file, dir_uri, timestamp, file ); - GRSThttpPrintf (&bp, "\n", file); - // Revert Button - GRSThttpPrintf (&bp, "

\n\n"); - } - - adminfooter(&bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); GRSThttpWriteOut(&bp); return; -} - - -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm,char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with a form asking for details required to create a new entry - GRSThttpBody bp; - int timestamp=atol(GRSThttpGetCGI("timestamp")); - GRSTgaclCred* cred; - GRSTgaclEntry *entry; - GRSTgaclNamevalue* namevalue; - - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - entry = GRSTgaclEntryNew(); - StartHTML(&bp, dir_uri, dir_path); - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "new_entry"); - GRSThttpPrintf (&bp, "NEW ENTRY IN ACL FOR %s

\n", dir_uri); - - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry,cred, namevalue, 0, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /*Submit and reset buttons - submit button sends the data in the form back to the script & new_entry() to be called*/ - EndForm(&bp); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Processes the information entered into the form from new_entry_form() and adds a new entry to the ACL - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - char *type, *value; - GRSThttpBody bp; - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Get new credential info and perform checks - type=GRSThttpGetCGI("type"); - value=GRSThttpGetCGI("cred0_value"); - - if (strcmp(type, "not_chosen")==0){ - GRSThttpError ("500 Invalid input - credential type not chosen"); - return; - } - - // Create the credential - cred=GRSTgaclCredNew(type); - if (strcmp(type, "person")==0) GRSTgaclCredAddValue(cred,"dn", value); - else if (strcmp(type, "dn-list")==0) GRSTgaclCredAddValue(cred, "url", value); - else if (strcmp(type, "voms")==0) GRSTgaclCredAddValue(cred, "fqan", value); - else if (strcmp(type, "dns")==0) GRSTgaclCredAddValue(cred, "hostname", value); - else if (strcmp(type, "any-user")==0) {} // namevalue not entered for any-user credential - else{ - GRSThttpError ("500 Invalid input - credential type not valid"); - return; - } - - // Create and empty entry, add the credential and get permissions - entry = GRSTgaclEntryNew(); - GRSTgaclEntryAddCred(entry, cred); - GACLeditGetPerms(entry); - - // Load the ACL, add the entry and save - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - GRSTgaclAclAddEntry(acl, entry); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Deletes the entry denoted by the GCI variable "entry_no"*/ - int entry_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *previous, *entry; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load the ACL - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get the number of the entry to be deleted and check okay to delete - entry_no=atol(GRSThttpGetCGI("entry_no")); - if(GACLentriesInAcl(acl)<=1){ - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "ERROR: Cannot delete all entries from the ACL
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - - // Get pointer to entry and previous entry - entry = GACLreturnEntry(acl, entry_no); - if (entry_no!=1) previous = GACLreturnEntry(acl, entry_no-1); - - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read entry from ACL file"); - return; - } - - // Perform deletion from the list by changing pointers - if (entry_no==1) acl->firstentry=entry->next; - else if (entry_no==GACLentriesInAcl(acl)) previous->next=NULL; - else previous->next=entry->next; - - // Save ACL and exit - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - - return; -} - - -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with an editable form containing details of entry denoted by CGI variable entry_no*/ - int entry_no, cred_no, i, admin=0, timestamp=atol(GRSThttpGetCGI("timestamp")); - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - // struct _GACLnamevalue *namevalue; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load ACL from file - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "EDITING ENTRY %d IN ACL FOR %s

\n", entry_no, dir_uri); - - // Start with first credential in the entry and display them in order*/ - cred=entry->firstcred; - cred_no=1; - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "edit_entry"); - GRSThttpPrintf (&bp, "\n", entry_no); - - GRSTgaclCredTableStart(&bp); - - while (cred!=NULL){ - // Start with the first namevalue in the credential - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - GRSTgaclCredTableEnd (entry, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - EndForm(&bp); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - //Processes the information entered into the form from edit_entry_form() and updates the entry corresponding to entry_no*/ - int entry_no, cred_no, i; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - char variable[30]; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load the ACL - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Start with the first credential and update each one - cred=entry->firstcred; - cred_no=1; - - while (cred!=NULL){ - if (strcmp(cred->type, "any-user")!=0){ - namevalue=cred->firstname; - sprintf(variable, "cred%d_value", cred_no); - namevalue->value=GRSThttpGetCGI(variable); - } - //Change to next credential*/ - cred=cred->next; - cred_no++; - } - - // Update permissions - GACLeditGetPerms(entry); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - - -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with a form asking for details required to create a new credential in the entry denoted by entry_no - GRSThttpBody bp; - int timestamp=atol(GRSThttpGetCGI("timestamp")), entry_no=atol(GRSThttpGetCGI("entry_no")); - GRSTgaclAcl *acl; - GRSTgaclEntry* entry; - GRSTgaclCred* cred; - GRSTgaclNamevalue* namevalue; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); // Load the ACL - - //Get pointer to the entry and perform checks - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - - if (strcmp(GRSThttpGetCGI("cmd"), "add_cred_form")==0){ //if not a new entry check to see if cred exists - cred=entry->firstcred; - while (cred!=NULL) { - if (strcmp (cred->type, "any-user")==0) { - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "ERROR: AND-ing \"any-user\" credential with other credential does not make sense
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - cred=cred->next; - } - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, " NEW CREDENTIAL IN ENTRY %d OF ACL FOR %s

\n", entry_no, dir_uri); - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "add_cred"); - - GRSThttpPrintf (&bp, " \n", entry_no); - - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry, cred, namevalue, 0, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - EndForm(&bp); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Processes the information entered into the form [add_cred_form()]and adds a new credential to the entry corresponding to entry_no - int entry_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSThttpBody bp; - char *type, *value; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load the ACL - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Create new credential and add it to entry - type=GRSThttpGetCGI("type"); - value=GRSThttpGetCGI("cred0_value"); - cred=GRSTgaclCredNew(type); - if (strcmp(type, "person") ==0) GRSTgaclCredAddValue(cred,"dn", value); - else if (strcmp(type, "dn-list") ==0) GRSTgaclCredAddValue(cred, "url", value); - else if (strcmp(type, "voms") ==0) GRSTgaclCredAddValue(cred, "fqan", value); - else if (strcmp(type, "dns") ==0) GRSTgaclCredAddValue(cred, "hostname", value); - else if (strcmp(type, "any-user")==0) {}// namevalue not entered for any-user credential - else{ - GRSThttpError ("500 Credential type not valid"); - return; - } - GRSTgaclEntryAddCred(entry, cred); - - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - - -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Deletes the credential denoted by the GCI variable "cred_no", in the entry denoted by "entry_no" - int entry_no, cred_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *previous, *cred; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - // Get pointer the the credential and perform checks - cred_no=atol(GRSThttpGetCGI("cred_no")); - cred=GACLreturnCred(entry, cred_no); - if(entry==NULL || entry_no<1 || cred_no>GRSTgaclCredsInEntry(entry)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - // Get pointer to previous credential - if needed - if (cred_no!=1) previous = GACLreturnCred(entry, cred_no-1); - - // Perform deletion from the list by changing pointers - if (cred_no==1) entry->firstcred=cred->next; - else if (cred_no==GRSTgaclCredsInEntry(entry)) previous->next=NULL; - else previous->next=cred->next; - - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp){ - // Single line printed out to forward users back to show_acl in admin mode - // Should ALWAYS called from another function so no HTML header required - // Should ALWAYS be the end of a page - GRSThttpPrintf (bp, "\n
Click Here to return to the editor", dir_uri,admin_file,dir_uri, time(NULL)); - adminfooter(bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(bp); - return; -} - - -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Prints out entry denoted by entry_no and asks if the user really wants to delete it - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny, i, timestamp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load ACL from file - - if (acl==NULL){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "

Do you really want to delete the following entry?



\n"); - GRSThttpPrintf (&bp,"
Entry %d:
\n", entry_no); - - // Print the entry out - // Start with the first credential in the entry and work through - cred=entry->firstcred; - cred_no=1; - - GRSTgaclCredTableStart(&bp); - while (cred!=NULL){ - // Start with the first namevalue in the credential - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - - GRSTgaclCredTableEnd (entry, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - StartForm(&bp, dir_uri, dir_path, admin_file, atol(GRSThttpGetCGI("timestamp")), "del_entry"); - GRSThttpPrintf (&bp, "\n", entry_no); - GRSThttpPrintf (&bp, "

\n\n"); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Prints out credential denoted by entry_no/cred_no and asks if the user really wants to delete it - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny, timestamp, i; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load ACL from file - - if (acl==NULL){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the credential and check okay - cred_no=atol(GRSThttpGetCGI("cred_no")); - cred=GACLreturnCred(entry, cred_no); - if(entry==NULL || entry_no<1 || cred_no>GRSTgaclCredsInEntry(entry)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - if(GRSTgaclCredsInEntry(entry)<=1){ - del_entry_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "

Do you really want to delete the following credential from entry %d?



", entry_no); - - // Print the credential out - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry, cred, cred->firstname, cred_no, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSThttpPrintf (&bp,"
\n"); - - // Yes Button - StartForm(&bp, dir_uri, dir_path, admin_file, atol(GRSThttpGetCGI("timestamp")), "del_cred"); - GRSThttpPrintf (&bp, "\n", entry_no); - GRSThttpPrintf (&bp, "\n", cred_no); - GRSThttpPrintf (&bp, "

\n\n"); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -int GACLentriesInAcl(GRSTgaclAcl *acl){ - // Returns the number of entries in acl - GRSTgaclEntry *entry; - int number; - - entry=acl->firstentry; - number=0; - - while (entry!=NULL) - { - number++; - entry=entry->next; - } - - return number; -} - -int GRSTgaclCredsInEntry(GRSTgaclEntry *entry){ - // Returns the number of credentials in entry - int number; - GRSTgaclCred *cred; - - cred=entry->firstcred; - number=0; - - while (cred!=NULL) - { - number++; - cred=cred->next; - } - - return number; -} - - -void GACLeditGetPerms(GRSTgaclEntry *entry){ - // Updates the permissions entry using permissions from a form produced using GRSTgaclCredTableEnd - int i; - char buf[30]; - - - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of allowed permissions*/ - { - sprintf (buf, "allow_%s", grst_perm_syms[i]); // Update allowed - if (strcmp (GRSThttpGetCGI(buf), "ON") == 0 ) GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); else GRSTgaclEntryUnallowPerm(entry, grst_perm_vals[i]); - - sprintf (buf, "deny_%s", grst_perm_syms[i]); // Update denied - if (strcmp (GRSThttpGetCGI(buf), "ON") == 0 ) GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); else GRSTgaclEntryUndenyPerm(entry, grst_perm_vals[i]); - - } - - return; -} - -GRSTgaclEntry *GACLreturnEntry(GRSTgaclAcl *acl, int entry_no){ - // Returns a pointer to entry in ACL denoted by entry_no, returns NULL if not found - int number; - GRSTgaclEntry *entry; - - if (acl==NULL) return NULL; - - entry=acl->firstentry; - number=1; - - while (entry!=NULL) - { - if (number==entry_no) return entry; - number++; - entry=entry->next; - } - - return NULL; -} - - -GRSTgaclCred *GACLreturnCred(GRSTgaclEntry *entry, int cred_no){ - // Returns a pointer to credential denoted by cred_no in entry, returns NULL if not found - int number; - GRSTgaclCred *cred; - - if (entry==NULL) return NULL; - - cred=entry->firstcred; - number=1; - - while (cred!=NULL) - { - if (number==cred_no) return cred; - number++; - cred=cred->next; - } - - return NULL; -} -void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path){ - //Start HTML output and insert page title - printf("Status: 200 OK\nContent-Type: text/html\n"); - GRSThttpBodyInit(bp); - GRSThttpPrintf(bp, "Access Control List for %s\n", dir_uri); - GRSThttpPrintHeaderFooter(bp, dir_path, GRST_HEADFILE); - return; -} -void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function){ - // Starts an HTML form with gridsite admin as the target and target_function as the value of cmd. - // Also inputs the dir_uri and the timestamp - GRSThttpPrintf (bp, "
\n", dir_uri, admin_file, dir_uri); - GRSThttpPrintf (bp, " \n", target_function); - GRSThttpPrintf (bp, " \n", timestamp); - return; -} - -void EndForm(GRSThttpBody *bp){ - GRSThttpPrintf (bp, "

\n"); - GRSThttpPrintf (bp, "
\n"); - return; -} - -void GRSTgaclCredTableStart(GRSThttpBody *bp){ - //Starts an HTML table of credentials by setting the column widths and inputting the headings - GRSThttpPrintf (bp,""); - GRSThttpPrintf (bp,""); - return; -} - -void GRSTgaclCredTableAdd(GRSTgaclUser *user, GRSTgaclEntry *entry, GRSTgaclCred *cred, GRSTgaclNamevalue *namevalue, int cred_no, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Adds the credential "cred" to a table started byGRSTgaclCredTableStart allowing the user to edit if appropriate - char* cmd = GRSThttpGetCGI("cmd"); - int edit_values=0, new_cred=0, allow_new_person=1; - int site_admin=GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user); - - if (strcmp(cmd, "new_entry_form")==0 || strcmp(cmd, "add_cred_form")==0) new_cred=1; - if (new_cred || strcmp(cmd, "edit_entry_form")==0) edit_values=1; - - if (new_cred) { /*Print out type and descriptor*/ - if (strcmp(cmd, "add_cred_form")==0){ /*if not a new entry check to see if cred exists.*/ - cred=entry->firstcred; - while (cred!=NULL) {if (strcmp (cred->type, "person")==0) allow_new_person=0; cred=cred->next;} - } - //create dummy credential for the user to edit - cred=GRSTgaclCredNew("new"); - GRSTgaclCredAddValue(cred, "", ""); - namevalue=cred->firstname; - //Drop down list of types - GRSThttpPrintf(bp,""); - GRSThttpPrintf(bp,""); - } - - else { //Print out type and descriptor for existing cred - - GRSThttpPrintf(bp,""); -} - -void GRSTgaclCredTableEnd(GRSTgaclEntry* entry, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Finishes off a table of credentials by inputting "Add Credential" link and a list of premissions in the final row - int i, blank_perms, edit_perms, show_perms; - char* cmd = GRSThttpGetCGI("cmd"); - - if (strcmp(cmd, "add_cred_form")==0 ||strcmp(cmd, "del_cred_sure")==0) show_perms=0; else show_perms=1; - if (strcmp(cmd, "edit_entry_form")==0 || strcmp(cmd, "new_entry_form")==0) edit_perms=1; else edit_perms=0; - if (strcmp(cmd, "new_entry_form")==0) blank_perms=1; else blank_perms=0; - - // If showing the last row is not required then exit - if (show_perms==0){GRSThttpPrintf (bp,"
Credential No.TypeValue
New"); - GRSThttpPrintf (bp, "
%d", cred_no); - if (admin) GRSThttpPrintf (bp,"(Delete)", dir_uri,admin_file,dir_uri, entry_no, cred_no, timestamp); - GRSThttpPrintf(bp, "%s ", cred->type); - } - - if (strcmp(cred->type, "any-user")==0) GRSThttpPrintf (bp, " "); /* Do not print out namevalue for any-user credential*/ - else{ - if (edit_values){ // Place namevalue in an editable box if appropriate - GRSThttpPrintf (bp, "value, bp); - GRSThttpPrintf (bp, "\">"); - } - else if (strcmp(cred->type, "dn-list")==0){ - GRSThttpPrintf(bp, "value, bp); - GRSThttpPrintf(bp, " \">"); - StringHTMLEncode(namevalue->value, bp); - GRSThttpPrintf(bp, ""); - } - else { GRSThttpPrintf(bp, " "); StringHTMLEncode(namevalue->value, bp);} - - } - //Print out warning symbol if cred being printed relates to current user - but NOT for users in site admin list - if (GRSTgaclUserHasCred(user, cred) && !site_admin) GRSThttpPrintf(bp, " <--"); - GRSThttpPrintf(bp, "

\n"); return;} - - GRSThttpPrintf (bp,""); - - if (admin) GRSThttpPrintf (bp,"Add Credential", dir_uri,admin_file,dir_uri, entry_no, timestamp); - - GRSThttpPrintf (bp, "\n "); - - if (blank_perms==1)entry->allowed=entry->denied=GRST_PERM_NONE; - - // Show Permissions - will produce a list or a list of check boxes depending on whether the permissions are to be edited or not - GRSThttpPrintf (bp, "Allowed: "); - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of allowed permissions*/ - { - if ( entry->allowed & grst_perm_vals[i]){ - if (edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - else GRSThttpPrintf(bp,"%s ", grst_perm_syms[i]); if (strcmp(grst_perm_syms[i], "none")==0) break; - } - else if (strcmp(grst_perm_syms[i], "none")!=0 && edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - } - - if (edit_perms) GRSThttpPrintf (bp, "

"); - GRSThttpPrintf (bp, "Denied: "); - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of denied permissions*/ - { - if ( entry->denied & grst_perm_vals[i]) - { - if (edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - else GRSThttpPrintf(bp,"%s ", grst_perm_syms[i]); - if (strcmp(grst_perm_syms[i], "none")==0) break; - } - else if (strcmp(grst_perm_syms[i], "none")!=0 && edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - } - - GRSThttpPrintf (bp, ""); - GRSThttpPrintf (bp,"
\n"); - GRSThttpPrintf (bp,"\n"); -} - -void check_acl_save(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSTgaclUser* user, GRSTgaclAcl *acl, GRSThttpBody *bp){ - // Checks if the acl for the current directory has been changed, check the current user's permissions. - // If all is okay the ACl is saved -> returns 1 else returns 0 - struct stat file_info; - GRSTgaclPerm new_perm; - char *vfile, *dir_path_vfile, *dir_path_file; - FILE *fp; - - - /*Check ACL has not been modified*/ - stat(GRSTgaclFileFindAclname(dir_path), &file_info); - if (atol(GRSThttpGetCGI("timestamp"))!=file_info.st_mtime){ - StartHTML(bp, dir_uri, dir_path); - GRSThttpPrintf (bp, "ERROR: CANNOT SAVE CHANGES

The ACL has been modified since it was last viewed\n

"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - - // check users permissions in the new ACL - - if (!GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user)) - { - new_perm = GRSTgaclAclTestUser(acl, user); - if (new_perm != perm){ - StartHTML(bp, dir_uri, dir_path); - if (!GRSTgaclPermHasAdmin(new_perm)){//Check that user still has Admin permissions - if not then exit without saving the new ACL - GRSThttpPrintf (bp, "ERROR: CANNOT SAVE CHANGES\n\n

You cannot deny yourself admin access from within the editor\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - //Functions to inform of other permission changes come next - GRSThttpPrintf (bp, "WARNING: OPERATION CHANGED YOUR PERMISSIONS!\n\n

You still have Admin permissions

\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - } - // ACL not modified, notified of permission changes - can now save - - dir_path_file=GRSTgaclFileFindAclname(dir_path); - vfile=makevfilename(".gacl", file_info.st_size, dn); // Make temporary file name - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - - // save the new ACL to the temporary file in the correct format using the GridsiteACLFormat directive - - if (strcasecmp(getenv("REDIRECT_GRST_ACL_FORMAT"), "XACML") ==0) GRSTxacmlAclSave(acl, dir_path_vfile); - else if (strcasecmp(getenv("REDIRECT_GRST_ACL_FORMAT"), "GACL") ==0) GRSTgaclAclSave(acl, dir_path_vfile); - else - { - GRSThttpPrintf (bp, "ERROR: ACL type not correctly specified"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - - - unlink(dir_path_file); - if (link (dir_path_vfile,dir_path_file)!=0) GRSThttpError("403 Forbidden"); - - printf ("Status: 302 Moved Temporarily\n Content Length: 0\nLocation: %s%s?cmd=admin_acl\n\n", dir_uri, admin_file); - return; -} - -void StringHTMLEncode (char* string, GRSThttpBody *bp){ - - char* current_char; - char* tmp; - int n; - tmp=malloc(2); - - *(tmp+1)='\0'; - current_char=string; - while(*current_char != '\0'){ - - if (*current_char == '<') GRSThttpPrintf (bp,"<"); - else if (*current_char == '>') GRSThttpPrintf (bp,">"); - else if (*current_char == '&') GRSThttpPrintf (bp,"&"); - else if (*current_char == '\'') GRSThttpPrintf (bp,"'"); - else if (*current_char == '"') GRSThttpPrintf (bp,"""); - else{ - *tmp=*current_char; - GRSThttpPrintf(bp, "%s", tmp); - - } - current_char++; - } - return; -} - -void revert_acl(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - char *AclFilename; - GRSTgaclAcl *acl; - GRSThttpBody bp; - // Load the old ACL, add the entry and save - AclFilename=malloc(strlen(dir_path)+strlen(file)+2); - strcpy(AclFilename, dir_path); - strcat(AclFilename, "/"); - strcat(AclFilename, file); - - acl = GRSTgaclAclLoadFile(AclFilename); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} diff --git a/org.gridsite.core/src/grst_admin_main.c b/org.gridsite.core/src/grst_admin_main.c deleted file mode 100644 index a9e9f0e..0000000 --- a/org.gridsite.core/src/grst_admin_main.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - Andrew McNab and Shiv Kaushal, University of Manchester. - Copyright (c) 2002-5. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// when porting: remember that sendfile() is very OS-specific! -#include - -#include - -#include "grst_admin.h" - -/* - - GridSite human/interactive management interface. This should produce - a CGI executable, usually ./sbin/real-gridsite-admin.cgi, which is - called from HTML forms either by GET or POST methods or both (ie input - present in both QUERY_STRING and the stdin of the CGI process.) - - The CGI name/value pairs used are: - - cmd = edit, managedir, print, history - file = short name of file, without path - - If real-gridsite-admin.cgi is run by an internal redirection inside - mod_gridsite (as should ALWAYS be the case) then the environment - variable REDIRECT_GRST_DIR_PATH will be set to the full path of - the directory holding the file in question. This respects any complex - URI -> file path mapping done by Apache. - -*/ - -void GRSThttpError(char *status) -{ - printf("Status: %s\n", status); - printf("Server-CGI: GridSite Admin %s\n", VERSION); - printf("Content-Length: %d\n", 2 * strlen(status) + 58); - puts("Content-Type: text/html\n"); - - printf("%s\n", status); - printf("

%s

\n", status); - - exit(0); -} - -void adminfooter(GRSThttpBody *bp, char *dn, char *help_uri, char *dir_uri, - char *admin_file) -{ - GRSThttpPrintf(bp, "

\n"); - - if (dn != NULL) GRSThttpPrintf(bp, "


You are %s
\n", dn); - else GRSThttpPrintf(bp, "
\n"); - - if (admin_file != NULL) - GRSThttpPrintf(bp, "" - "Manage directory .\n", - dir_uri, admin_file); - else GRSThttpPrintf(bp, "" - "Back to directory .\n", dir_uri); - - if (help_uri != NULL) - GRSThttpPrintf(bp, "Website Help .\n", help_uri); - - if ((getenv("GRST_NO_LINK") == NULL) && - (getenv("REDIRECT_GRST_NO_LINK") == NULL)) - GRSThttpPrintf(bp, "Built with " - "GridSite %s\n", - VERSION); - - GRSThttpPrintf(bp, "
\n"); -} - -int GRSTstrCmpShort(char *long_s, char *short_s) -{ - while (*short_s != '\0') - { - if (*long_s > *short_s) return +1; - if (*long_s < *short_s) return -1; - - ++long_s; - ++short_s; - } - - return 0; -} - -char *makevfilename(char *publicname, size_t size, char *dn) -{ - int i; - char *ext, *vfilename, *encpublicname, *encdn, *p; - struct timeval tv_now; - - gettimeofday(&tv_now, NULL); - - ext = rindex(publicname, '.'); - if (ext == NULL) ext = ""; - - encpublicname = GRSThttpUrlEncode(publicname); - for (p=encpublicname; *p != '\0'; ++p) if (*p == '%') *p = '='; - - encdn = GRSThttpUrlEncode(dn); - for (p=encdn; *p != '\0'; ++p) if (*p == '%') *p = '='; - - /* we used zero-padding for times so - alphanumeric sorting will sort chronologically too */ - - asprintf(&vfilename, "%s:%s:%08X:%05X:%X:%s:%s", GRST_HIST_PREFIX, - encpublicname, tv_now.tv_sec, tv_now.tv_usec, size, encdn, ext); - - return vfilename; -} - -void justheader(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpWriteOut(&bp); -} - -void justfooter(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasWrite(perm) - || GRSTgaclPermHasAdmin(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -int main() -{ - int i, gsiproxylimit_i = 1; - char *cmd, *dir_uri, *file, *dir_path, *admin_file, *dn = NULL, - *help_uri, *p, *content_type, *request_uri, *button, - *grst_cred_0, *gsiproxylimit, *dn_lists, buf[12]; - GRSTgaclCred *cred; - GRSTgaclUser *user = NULL; - GRSTgaclAcl *acl; - GRSTgaclPerm perm = GRST_PERM_NONE; - - help_uri = getenv("REDIRECT_GRST_HELP_URI"); /* can be NULL */ - admin_file = getenv("REDIRECT_GRST_ADMIN_FILE"); - dir_path = getenv("REDIRECT_GRST_DIR_PATH"); - request_uri = getenv("REQUEST_URI"); - - if ((dir_path == NULL) || (admin_file == NULL) || (request_uri == NULL)) - { - puts("Status: 500 Internal Server Error\nContent-type: text/plain\n\n" - "REDIRECT_GRST_DIR_PATH or REDIRECT_GRST_ADMIN_FILE " - "or REQUEST_URI missing"); - return; - } - - GRSTgaclInit(); - - grst_cred_0 = getenv("GRST_CRED_0"); - - if ((grst_cred_0 != NULL) && (cred = GRSTx509CompactToCred(grst_cred_0))) - { - gsiproxylimit = getenv("REDIRECT_GRST_GSIPROXY_LIMIT"); - if (gsiproxylimit != NULL) sscanf(gsiproxylimit, "%d", &gsiproxylimit_i); - - if (GRSTgaclCredGetDelegation(cred) <= gsiproxylimit_i) - { - user = GRSTgaclUserNew(cred); - - if ((p = index(grst_cred_0, ' ')) && - (p = index(++p, ' ')) && - (p = index(++p, ' ')) && - (p = index(++p, ' '))) dn = &p[1]; - } - /* User has a cert so check for voms attributes */ - for(i=1; ; i++) - { - sprintf (buf, "GRST_CRED_%d", i); - - - grst_cred_0 = getenv(buf); - if (grst_cred_0==NULL) break; - - if (cred=GRSTx509CompactToCred(grst_cred_0)) - GRSTgaclUserAddCred(user, cred); - } - /* no more voms attributes found found */ - } - else if ((dn = getenv("SSL_CLIENT_S_DN")) != NULL) - { - cred = GRSTgaclCredNew("person"); - GRSTgaclCredAddValue(cred, "dn", dn); - user = GRSTgaclUserNew(cred); - } - - dn_lists = getenv("REDIRECT_GRST_DN_LISTS"); - if (dn_lists == NULL) dn_lists = getenv("GRST_DN_LISTS"); - if (dn_lists != NULL) GRSTgaclUserSetDNlists(user, dn_lists); - - if (GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), - user)) perm = GRST_PERM_ALL; - else - { - p = getenv("REMOTE_HOST"); - if (p != NULL) - { - cred = GRSTgaclCredNew("dns"); - GRSTgaclCredAddValue(cred, "hostname", p); - - if (user == NULL) user = GRSTgaclUserNew(cred); - else GRSTgaclUserAddCred(user, cred); - } - - acl = GRSTgaclAclLoadforFile(dir_path); - if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user); - } - - /* we're relying on being a CGI with all this un-free()ed strdup()ing */ - - dir_uri = strdup(request_uri); - p = rindex(dir_uri, '?'); - if (p != NULL) *p = '\0'; - p = rindex(dir_uri, '/'); - if (p != NULL) p[1] = '\0'; - - content_type = getenv("CONTENT_TYPE"); - - if ((content_type != NULL) && - (GRSTstrCmpShort(content_type, "multipart/form-data; boundary=") == 0)) - { - uploadfile(dn, perm, help_uri, dir_path, dir_uri, admin_file); - return 0; - } - - cmd = GRSThttpGetCGI("cmd"); - file = GRSThttpGetCGI("file"); - button = GRSThttpGetCGI("button"); - - /* file and directory functions in grst_admin_file.c */ - - if (strcmp(cmd, "header") == 0) - justheader(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "footer") == 0) - justfooter(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "managedir") == 0) - managedir(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "print") == 0) - printfile(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "history") == 0) - filehistory(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "editdnlist") == 0) - editdnlistform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "edit") == 0) - { - if ((strcasecmp(button, "new directory") == 0) || - (strcasecmp(button, "Create") == 0)) - newdirectory(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else - editfileform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - } - else if (strcmp(cmd, "editaction") == 0) - editfileaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "editdnlistaction") == 0) - editdnlistaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "delete") == 0) - deletefileform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "deleteaction") == 0) - deletefileaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "rename") == 0) - renameform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "renameaction") == 0) - renameaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "ziplist") == 0) - ziplist(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "unzipfile") == 0) - unzipfile(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "create_acl") == 0) - create_acl(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /* GACL functions in grst_admin_gacl.c */ - - else if (strcmp(cmd, "show_acl") == 0) - show_acl(0, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "admin_acl") == 0) - show_acl(1, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "acl_history") == 0) - show_acl(2, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "revert_acl") == 0) - revert_acl(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - //show_acl(2, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"new_entry_form")==0) - new_entry_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"new_entry")==0) - new_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_entry_sure")==0) - del_entry_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_entry")==0) - del_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"edit_entry_form")==0) - edit_entry_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"edit_entry")==0) - edit_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"add_cred_form")==0) - add_cred_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"add_cred")==0) - add_cred(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_cred_sure")==0) - del_cred_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_cred")==0) - del_cred(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /* you what? */ - - else GRSThttpError("500 Internal Server Error"); -} diff --git a/org.gridsite.core/src/grst_asn1.c b/org.gridsite.core/src/grst_asn1.c deleted file mode 100644 index bc92a87..0000000 --- a/org.gridsite.core/src/grst_asn1.c +++ /dev/null @@ -1,506 +0,0 @@ - -#define _GNU_SOURCE -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "gridsite.h" - -/// ASN1 time string (in a char *) to time_t -/** - * (Use ASN1_STRING_data() to convert ASN1_GENERALIZEDTIME to char * if - * necessary) - */ - -time_t GRSTasn1TimeToTimeT(char *asn1time, size_t len) -{ - char zone; - struct tm time_tm; - - if (len == 0) len = strlen(asn1time); - - if ((len != 13) && (len != 15)) return 0; /* dont understand */ - - if ((len == 13) && - ((sscanf(asn1time, "%02d%02d%02d%02d%02d%02d%c", - &(time_tm.tm_year), - &(time_tm.tm_mon), - &(time_tm.tm_mday), - &(time_tm.tm_hour), - &(time_tm.tm_min), - &(time_tm.tm_sec), - &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ - - if ((len == 15) && - ((sscanf(asn1time, "20%02d%02d%02d%02d%02d%02d%c", - &(time_tm.tm_year), - &(time_tm.tm_mon), - &(time_tm.tm_mday), - &(time_tm.tm_hour), - &(time_tm.tm_min), - &(time_tm.tm_sec), - &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ - - /* time format fixups */ - - if (time_tm.tm_year < 90) time_tm.tm_year += 100; - --(time_tm.tm_mon); - - return timegm(&time_tm); -} - -/* this function is taken from OpenSSL without modification */ - -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent) - { - static const char fmt[]="%-18s"; - static const char fmt2[]="%2d %-15s"; - char str[128]; - const char *p,*p2=NULL; - - if (constructed & V_ASN1_CONSTRUCTED) - p="cons: "; - else - p="prim: "; - if (BIO_write(bp,p,6) < 6) goto err; -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - BIO_indent(bp,indent,128); -#endif - - p=str; - if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - sprintf(str,"priv [ %d ] ",tag); - else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - sprintf(str,"cont [ %d ]",tag); - else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - sprintf(str,"appl [ %d ]",tag); - else p = ASN1_tag2str(tag); - - if (p2 != NULL) - { - if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err; - } - else - { - if (BIO_printf(bp,fmt,p) <= 0) goto err; - } - return(1); -err: - return(0); - } - -static void GRSTasn1AddToTaglist(struct GRSTasn1TagList taglist[], - int maxtag, int *lasttag, - char *treecoords, int start, int headerlength, - int length, int tag) -{ - if ((strlen(treecoords) > GRST_ASN1_MAXCOORDLEN) || - (*lasttag + 1 > maxtag)) return; - - ++(*lasttag); - - strncpy(taglist[*lasttag].treecoords, treecoords, GRST_ASN1_MAXCOORDLEN+1); - taglist[*lasttag].start = start; - taglist[*lasttag].headerlength = headerlength; - taglist[*lasttag].length = length; - taglist[*lasttag].tag = tag; -} - -int GRSTasn1SearchTaglist(struct GRSTasn1TagList taglist[], - int lasttag, char *treecoords) -{ - int i; - - for (i=0; i <= lasttag; ++i) - { - if (strcmp(treecoords, taglist[i].treecoords) == 0) return i; - } - - return -1; -} - -static int GRSTasn1PrintPrintable(BIO *bp, char *str, int length) -{ - int ret = 0; - char *dup, *p; - - dup = strndup(str, length); - - for (p=dup; *p != '\0'; ++p) if ((*p < ' ') || (*p > '~')) *p = '.'; - - if (bp != NULL) ret = BIO_write(bp, dup, strlen(dup)); - - free(dup); - - return ret; -} - -static int GRSTasn1Parse2(BIO *bp, unsigned char **pp, long length, int offset, - int depth, int indent, int dump, char *treecoords, - struct GRSTasn1TagList taglist[], int maxtag, int *lasttag) - { - int sibling = 0; - char sibtreecoords[512]; - - unsigned char *p,*ep,*tot,*op,*opp; - long len; - int tag,xclass,ret=0; - int nl,hl,j,r; - ASN1_OBJECT *o=NULL; - ASN1_OCTET_STRING *os=NULL; - int dump_indent; - - - dump_indent = 6; /* Because we know BIO_dump_indent() */ - p= *pp; - tot=p+length; - op=p-1; - while ((p < tot) && (op < p)) - { - op=p; - j=ASN1_get_object(&p,&len,&tag,&xclass,length); - - if (j & 0x80) - { - if ((bp != NULL) && - (BIO_write(bp,"Error in encoding\n",18) <= 0)) - goto end; - ret=0; - goto end; - } - hl=(p-op); - length-=hl; - - ++sibling; - sprintf(sibtreecoords, "%s-%d", treecoords, sibling); - - GRSTasn1AddToTaglist(taglist, maxtag, lasttag, sibtreecoords, - (int)offset+(int)(op - *pp), - (int) hl, len, tag); - - if (bp != NULL) - { - BIO_printf(bp, " %s %ld %ld %d %d ", sibtreecoords, - (long)offset+(long)(op - *pp), hl, len, tag); - - GRSTasn1PrintPrintable(bp, p, -// &((*pp)[(long)offset+(long)(op - *pp)+hl]), - (len > 30) ? 30 : len); - - BIO_printf(bp, "\n"); - } - - - /* if j == 0x21 it is a constructed indefinite length object */ - if ((bp != NULL) && - (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp)) - <= 0)) goto end; - - if (j != (V_ASN1_CONSTRUCTED | 1)) - { - if ((bp != NULL) && - (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ", - depth,(long)hl,len) <= 0)) - goto end; - } - else - { - if ((bp != NULL) && - (BIO_printf(bp,"d=%-2d hl=%ld l=inf ", - depth,(long)hl) <= 0)) - goto end; - } - if ((bp != NULL) && - !asn1_print_info(bp,tag,xclass,j,(indent)?depth:0)) - goto end; - if (j & V_ASN1_CONSTRUCTED) - { - ep=p+len; - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - if (len > length) - { - if (bp != NULL) BIO_printf(bp, - "length is greater than %ld\n",length); - ret=0; - goto end; - } - if ((j == 0x21) && (len == 0)) - { - for (;;) - { - r=GRSTasn1Parse2(bp,&p,(long)(tot-p), - offset+(p - *pp),depth+1, - indent,dump,sibtreecoords, - taglist, maxtag, lasttag); - if (r == 0) { ret=0; goto end; } - if ((r == 2) || (p >= tot)) break; - } - } - else - while (p < ep) - { - r=GRSTasn1Parse2(bp,&p,(long)len, - offset+(p - *pp),depth+1, - indent,dump,sibtreecoords, - taglist, maxtag, lasttag); - if (r == 0) { ret=0; goto end; } - } - } - else if (xclass != 0) - { - p+=len; - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - } - else - { - nl=0; - if ( (tag == V_ASN1_PRINTABLESTRING) || - (tag == V_ASN1_T61STRING) || - (tag == V_ASN1_IA5STRING) || - (tag == V_ASN1_VISIBLESTRING) || - (tag == V_ASN1_UTCTIME) || - (tag == V_ASN1_GENERALIZEDTIME)) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if ((len > 0) && (bp != NULL) && - BIO_write(bp,(char *)p,(int)len) - != (int)len) - goto end; - } - else if (tag == V_ASN1_OBJECT) - { - opp=op; - if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL) - { - if (bp != NULL) - { - if (BIO_write(bp,":",1) <= 0) goto end; - i2a_ASN1_OBJECT(bp,o); - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,":BAD OBJECT",11) <= 0)) - goto end; - } - } - else if (tag == V_ASN1_BOOLEAN) - { - int ii; - - opp=op; - ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl); - if (ii < 0) - { - if ((bp != NULL) && - (BIO_write(bp,"Bad boolean\n",12))) - goto end; - } - if (bp != NULL) BIO_printf(bp,":%d",ii); - } - else if (tag == V_ASN1_BMPSTRING) - { - /* do the BMP thang */ - } - else if (tag == V_ASN1_OCTET_STRING) - { - int i; - - opp=op; - os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl); - if (os != NULL) - { - opp=os->data; - - if (os->length > 0) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) - goto end; - if ((bp != NULL) && - (GRSTasn1PrintPrintable(bp, - opp, - os->length) <= 0)) - goto end; - } - - M_ASN1_OCTET_STRING_free(os); - os=NULL; - } - } - else if (tag == V_ASN1_INTEGER) - { - ASN1_INTEGER *bs; - int i; - - opp=op; - bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl); - if (bs != NULL) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if (bs->type == V_ASN1_NEG_INTEGER) - if ((bp != NULL) && - (BIO_write(bp,"-",1) <= 0)) - goto end; - for (i=0; ilength; i++) - { - if ((bp != NULL) && - (BIO_printf(bp,"%02X", - bs->data[i]) <= 0)) - goto end; - } - if (bs->length == 0) - { - if ((bp != NULL) && - (BIO_write(bp,"00",2) <= 0)) - goto end; - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,"BAD INTEGER",11) <= 0)) - goto end; - } - M_ASN1_INTEGER_free(bs); - } - else if (tag == V_ASN1_ENUMERATED) - { - ASN1_ENUMERATED *bs; - int i; - - opp=op; - bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl); - if (bs != NULL) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if (bs->type == V_ASN1_NEG_ENUMERATED) - if ((bp != NULL) && - (BIO_write(bp,"-",1) <= 0)) - goto end; - for (i=0; ilength; i++) - { - if ((bp != NULL) && - (BIO_printf(bp,"%02X", - bs->data[i]) <= 0)) - goto end; - } - if (bs->length == 0) - { - if ((bp != NULL) && - (BIO_write(bp,"00",2) <= 0)) - goto end; - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,"BAD ENUMERATED",11) <= 0)) - goto end; - } - M_ASN1_ENUMERATED_free(bs); - } - else if (len > 0 && dump) - { - if (!nl) - { - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) - goto end; - } - if ((bp != NULL) && - (BIO_dump_indent(bp,(char *)p, - ((dump == -1 || dump > len)?len:dump), - dump_indent) <= 0)) - goto end; - nl=1; - } - - if (!nl) - { - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - } - p+=len; - if ((tag == V_ASN1_EOC) && (xclass == 0)) - { - ret=2; /* End of sequence */ - goto end; - } - } - - length-=len; - } - ret=1; -end: - if (o != NULL) ASN1_OBJECT_free(o); - if (os != NULL) M_ASN1_OCTET_STRING_free(os); - *pp=p; - return(ret); - } - -int GRSTasn1ParseDump(BIO *bp, unsigned char *pp, long len, - struct GRSTasn1TagList taglist[], - int maxtag, int *lasttag) - { - return(GRSTasn1Parse2(bp,&pp,len,0,0,0,0,"", - taglist, maxtag, lasttag)); - } - -int GRSTasn1GetX509Name(char *x509name, int maxlength, char *coords, - char *asn1string, - struct GRSTasn1TagList taglist[], int lasttag) -{ - int i, iobj, istr, n, len = 0; - ASN1_OBJECT *obj = NULL; - unsigned char coordstmp[81], *q; - const unsigned char *shortname; - - for (i=1; ; ++i) - { - snprintf(coordstmp, sizeof(coordstmp), coords, i, 1); - iobj = GRSTasn1SearchTaglist(taglist, lasttag, coordstmp); - if (iobj < 0) break; - - snprintf(coordstmp, sizeof(coordstmp), coords, i, 2); - istr = GRSTasn1SearchTaglist(taglist, lasttag, coordstmp); - if (istr < 0) break; - - q = &asn1string[taglist[iobj].start]; - d2i_ASN1_OBJECT(&obj, &q, taglist[iobj].length + - taglist[iobj].headerlength); - - n = OBJ_obj2nid(obj); -// free obj now? - shortname = OBJ_nid2sn(n); - - if (len + 2 + strlen(shortname) + taglist[istr].length >= maxlength) - { - x509name[0] = '\0'; - return GRST_RET_FAILED; - } - - sprintf(&x509name[len], "/%s=%.*s", shortname, - taglist[istr].length, - &asn1string[taglist[istr].start+taglist[istr].headerlength]); - len += 2 + strlen(shortname) + taglist[istr].length; - } - - x509name[len] = '\0'; - - return (x509name[0] != '\0') ? GRST_RET_OK : GRST_RET_FAILED; -} diff --git a/org.gridsite.core/src/grst_err.c b/org.gridsite.core/src/grst_err.c deleted file mode 100644 index 8d1e2cb..0000000 --- a/org.gridsite.core/src/grst_err.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------- - For more information about GridSite: http://www.gridsite.org/ - --------------------------------------------------------------- -*/ - -#define _GNU_SOURCE - -#include "gridsite.h" - -void (*GRSTerrorLogFunc)(char *, int, int, char *, ...) = NULL; - diff --git a/org.gridsite.core/src/grst_gacl.c b/org.gridsite.core/src/grst_gacl.c deleted file mode 100644 index c2c4ecd..0000000 --- a/org.gridsite.core/src/grst_gacl.c +++ /dev/null @@ -1,1233 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ -/*---------------------------------------------------------------* - * For more information about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include - -#include -#include -#include - -#include "gridsite.h" - -/* * - * Global variables, shared by all GACL functions but private to libgacl * - * */ - -char *grst_perm_syms[] = { "none", - "read", - "exec", - "list", - "write", - "admin", - NULL }; - -GRSTgaclPerm grst_perm_vals[] = { GRST_PERM_NONE, - GRST_PERM_READ, - GRST_PERM_EXEC, - GRST_PERM_LIST, - GRST_PERM_WRITE, - GRST_PERM_ADMIN, - -1 }; - -int GRSTgaclInit(void) -{ - xmlInitParser(); - - LIBXML_TEST_VERSION - - xmlKeepBlanksDefault(0); - - return 1; -} - -/* declare these two private functions at the start */ - -GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *); -GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *); - -/* * - * Functions to manipulate GRSTgaclCred structures * - * */ - -GRSTgaclCred *GRSTgaclCredNew(char *type) -/* - GRSTgaclCredNew - allocate a new GRSTgaclCred structure, and return - it's pointer or NULL on (malloc) error. -*/ -{ - GRSTgaclCred *newcred; - - if (type == NULL) return NULL; - - newcred = malloc(sizeof(GRSTgaclCred)); - if (newcred == NULL) return NULL; - - newcred->type = strdup(type); - newcred->delegation = 0; - newcred->firstname = NULL; - newcred->next = NULL; - - return newcred; -} - -int GRSTgaclCredAddValue(GRSTgaclCred *cred, char *rawname, char *rawvalue) -/* - GRSTgaclCredAddValue - add a name/value pair to a GRSTgaclCred -*/ -{ - int i; - char *name, *value; - GRSTgaclNamevalue *p; - - name = strdup(rawname); - - /* no leading or trailing space in value */ - - value = rawvalue; - while ((*value != '\0') && isspace(*value)) ++value; - - value = strdup(value); - - for (i=strlen(value) - 1; (i >= 0) && isspace(value[i]); --i) value[i]='\0'; - - if (cred->firstname == NULL) - { - cred->firstname = malloc(sizeof (GRSTgaclNamevalue)); - (cred->firstname)->name = name; - (cred->firstname)->value = value; - (cred->firstname)->next = NULL; - } - else - { - p = cred->firstname; - - while (p->next != NULL) p = (GRSTgaclNamevalue *) p->next; - - p->next = malloc(sizeof(GRSTgaclNamevalue)); - ((GRSTgaclNamevalue *) p->next)->name = name; - ((GRSTgaclNamevalue *) p->next)->value = value; - ((GRSTgaclNamevalue *) p->next)->next = NULL; - } - - return 1; -} - -static int GRSTgaclNamevalueFree(GRSTgaclNamevalue *p) -{ - if (p == NULL) return 1; - - if (p->next != NULL) - GRSTgaclNamevalueFree((GRSTgaclNamevalue *) p->next); - if (p->name != NULL) free(p->name); - if (p->value != NULL) free(p->value); - free(p); - - return 1; -} - -int GRSTgaclCredFree(GRSTgaclCred *cred) -/* - GRSTgaclCredFree - free memory structures of a GRSTgaclCred, - returning 1 always! -*/ -{ - if (cred == NULL) return 1; - - GRSTgaclNamevalueFree(cred->firstname); - if (cred->type != NULL) free(cred->type); - free(cred); - - return 1; -} - -static int GRSTgaclCredsFree(GRSTgaclCred *firstcred) -/* - GRSTgaclCredsFree - free a cred and all the creds in its *next chain -*/ -{ - if (firstcred == NULL) return 0; - - if (firstcred->next != NULL) GRSTgaclCredsFree(firstcred->next); - - return GRSTgaclCredFree(firstcred); -} - -static int GRSTgaclCredInsert(GRSTgaclCred *firstcred, GRSTgaclCred *newcred) -/* - GRSTgaclCredInsert - insert a cred in the *next chain of firstcred - - FOR THE MOMENT THIS JUST APPENDS! -*/ -{ - if (firstcred == NULL) return 0; - - if (firstcred->next == NULL) - { - firstcred->next = newcred; - return 1; - } - - return GRSTgaclCredInsert(firstcred->next, newcred); -} - -int GRSTgaclEntryAddCred(GRSTgaclEntry *entry, GRSTgaclCred *cred) -/* - GRSTaddCred - add a new credential to an existing entry, returning 1 - on success or 0 on error -*/ -{ - if (entry == NULL) return 0; - - if (entry->firstcred == NULL) - { - entry->firstcred = cred; - return 1; - } - else return GRSTgaclCredInsert(entry->firstcred, cred); -} - -static int GRSTgaclCredRemoveCred(GRSTgaclCred *firstcred, GRSTgaclCred *oldcred) -/* - (Private) - - GRSTgaclCredRemoveCred - remove a cred in the *next chain of firstcred - and relink the chain -*/ -{ - if (firstcred == NULL) return 0; - -// yeah, I know -} - -int GRSTgaclEntryDelCred(GRSTgaclEntry *entry, GRSTgaclCred *cred) -/* - GRSTgaclEntryDelCred - remove a new cred from an entry, returning 1 - on success (or absense) or 0 on error. -*/ -{ - if (entry == NULL) return 0; - - return GRSTgaclCredRemoveCred(entry->firstcred, cred); -} - -int GRSTgaclCredPrint(GRSTgaclCred *cred, FILE *fp) -/* - GRSTgaclCredPrint - print a credential and any name-value pairs is contains -*/ -{ - char *q; - GRSTgaclNamevalue *p; - - if (cred->firstname != NULL) - { - fprintf(fp, "<%s>\n", cred->type); - - p = cred->firstname; - - do { - fprintf(fp, "<%s>", p->name); - - for (q=p->value; *q != '\0'; ++q) - if (*q == '<') fputs("<", fp); - else if (*q == '>') fputs(">", fp); - else if (*q == '&') fputs("&" , fp); - else if (*q == '\'') fputs("'", fp); - else if (*q == '"') fputs(""", fp); - else fputc(*q, fp); - - fprintf(fp, "\n", p->name); - - p = (GRSTgaclNamevalue *) p->next; - - } while (p != NULL); - - fprintf(fp, "\n", cred->type); - } - else fprintf(fp, "<%s/>\n", cred->type); - - return 1; -} - -/* * - * Functions to manipulate GRSTgaclEntry structures * - * */ - -GRSTgaclEntry *GRSTgaclEntryNew(void) -/* - GRSTgaclEntryNew - allocate space for a new entry, returning its pointer - or NULL on failure. -*/ -{ - GRSTgaclEntry *newentry; - - newentry = (GRSTgaclEntry *) malloc(sizeof(GRSTgaclEntry)); - if (newentry == NULL) return NULL; - - newentry->firstcred = NULL; - newentry->allowed = 0; - newentry->denied = 0; - newentry->next = NULL; - - return newentry; -} - -int GRSTgaclEntryFree(GRSTgaclEntry *entry) -/* - GRSTgaclEntryFree - free up space used by an entry (always returns 1) -*/ -{ - int i; - - if (entry == NULL) return 1; - - GRSTgaclCredsFree(entry->firstcred); - - free(entry); - - return 1; -} - -static int GRSTgaclEntriesFree(GRSTgaclEntry *entry) -/* - GRSTgaclEntriesFree - free up entry and all entries linked to in its *next - chain -*/ -{ - if (entry == NULL) return 0; - - if (entry->next != NULL) GRSTgaclEntriesFree(entry->next); - - return GRSTgaclEntryFree(entry); -} - -static int GRSTgaclEntryInsert(GRSTgaclEntry *firstentry, GRSTgaclEntry *newentry) -/* - GRSTgaclEntryInsert - insert an entry in the *next chain of firstentry - - FOR THE MOMENT THIS JUST APPENDS -*/ -{ - if (firstentry == NULL) return 0; - - if (firstentry->next == NULL) - { - firstentry->next = newentry; - return 1; - } - - return GRSTgaclEntryInsert(firstentry->next, newentry); -} - -int GRSTgaclAclAddEntry(GRSTgaclAcl *acl, GRSTgaclEntry *entry) -/* - GRSTgaclAclAddEntry - add a new entry to an existing acl, returning 1 - on success or 0 on error -*/ -{ - if (acl == NULL) return 0; - - if (acl->firstentry == NULL) - { - acl->firstentry = entry; - return 1; - } - else return GRSTgaclEntryInsert(acl->firstentry, entry); -} - -int GRSTgaclEntryPrint(GRSTgaclEntry *entry, FILE *fp) -{ - GRSTgaclCred *cred; - GRSTgaclPerm i; - - fputs("\n", fp); - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - GRSTgaclCredPrint(cred, fp); - - if (entry->allowed) - { - fputs("", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if ((entry->allowed) & i) GRSTgaclPermPrint(i, fp); - - fputs("\n", fp); - } - - - if (entry->denied) - { - fputs("", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if (entry->denied & i) GRSTgaclPermPrint(i, fp); - - fputs("\n", fp); - } - - fputs("\n", fp); - - return 1; -} - -/* * - * Functions to manipulate GRSTgaclPerm items * - * */ - -int GRSTgaclPermPrint(GRSTgaclPerm perm, FILE *fp) -{ - GRSTgaclPerm i; - - for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i) - if (perm == grst_perm_vals[i]) - { - fprintf(fp, "<%s/>", grst_perm_syms[i]); - return 1; - } - - return 0; -} - -int GRSTgaclEntryAllowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->allowed = entry->allowed | perm; - - return 1; -} - -int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->allowed = entry->allowed & ~perm; - - return 1; -} - -int GRSTgaclEntryDenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->denied = entry->denied | perm; - - return 1; -} - -int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->denied = entry->denied & ~perm; - - return 1; -} - -char *GRSTgaclPermToChar(GRSTgaclPerm perm) -/* - GRSTgaclPermToChar - return char * or NULL corresponding to most significant - set bit of perm. -*/ -{ - char *p = NULL; - GRSTgaclPerm i; - - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (perm & grst_perm_vals[i]) p = grst_perm_syms[i]; - - return p; -} - -GRSTgaclPerm GRSTgaclPermFromChar(char *s) -/* - GRSTgaclPermToChar - return access perm corresponding to symbol s[] -*/ -{ - GRSTgaclPerm i; - - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (strcasecmp(grst_perm_syms[i], s) == 0) return grst_perm_vals[i]; - - return -1; -} - -/* * - * Functions to manipulate GRSTgaclAcl structures * - * */ - -GRSTgaclAcl *GRSTgaclAclNew(void) -/* - GRSTgaclAclNew - allocate a new acl and return its pointer (or NULL - on failure.) -*/ -{ - GRSTgaclAcl *newacl; - - newacl = (GRSTgaclAcl *) malloc(sizeof(GRSTgaclAcl)); - if (newacl == NULL) return NULL; - - newacl->firstentry = NULL; - - return newacl; -} - -int GRSTgaclAclFree(GRSTgaclAcl *acl) -/* - GRSTgaclAclFree - free up space used by *acl. Always returns 1. -*/ -{ - if (acl == NULL) return 1; - - GRSTgaclEntriesFree(acl->firstentry); - - return 1; -} - -int GRSTgaclAclPrint(GRSTgaclAcl *acl, FILE *fp) -{ - GRSTgaclEntry *entry; - - fputs("\n", fp); - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - GRSTgaclEntryPrint(entry, fp); - - fputs("\n", fp); - - return 1; -} - -int GRSTgaclAclSave(GRSTgaclAcl *acl, char *filename) -{ - int ret; - FILE *fp; - - fp = fopen(filename, "w"); - if (fp == NULL) return 0; - - fputs("\n", fp); - - ret = GRSTgaclAclPrint(acl, fp); - - fclose(fp); - - return ret; -} - -/* * - * Functions for loading and parsing XML using libxml * - * */ - -// need to check these for libxml memory leaks? - what needs to be freed? - -static GRSTgaclCred *GRSTgaclCredParse(xmlNodePtr cur) -/* - GRSTgaclCredParse - parse a credential stored in the libxml structure cur, - returning it as a pointer or NULL on error. -*/ -{ - xmlNodePtr cur2; - GRSTgaclCred *cred; - - cred = GRSTgaclCredNew((char *) cur->name); - - cred->firstname = NULL; - cred->next = NULL; - - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - { - if (!xmlIsBlankNode(cur2)) - GRSTgaclCredAddValue(cred, (char *) cur2->name, - (char *) xmlNodeGetContent(cur2)); - } - - return cred; -} - -static GRSTgaclEntry *GRSTgaclEntryParse(xmlNodePtr cur) -/* - GRSTgaclEntryParse - parse an entry stored in the libxml structure cur, - returning it as a pointer or NULL on error. -*/ -{ - int i; - xmlNodePtr cur2; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclPerm perm; - - if (xmlStrcmp(cur->name, (const xmlChar *) "entry") != 0) return NULL; - - cur = cur->xmlChildrenNode; - - entry = GRSTgaclEntryNew(); - - while (cur != NULL) - { - if (xmlIsBlankNode(cur)) - { - cur=cur->next; - continue; - } - else if (xmlStrcmp(cur->name, (const xmlChar *) "allow") == 0) - { - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - if (!xmlIsBlankNode(cur2)) - { - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, - (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); - } - } - else if (xmlStrcmp(cur->name, (const xmlChar *) "deny") == 0) - { - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - if (!xmlIsBlankNode(cur2)) - { - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, - (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); - } - } - else if ((cred = GRSTgaclCredParse(cur)) != NULL) - { - if (!GRSTgaclEntryAddCred(entry, cred)) - { - GRSTgaclCredFree(cred); - GRSTgaclEntryFree(entry); - return NULL; - } - } - else /* I cannot parse this - give up rather than get it wrong */ - { - GRSTgaclEntryFree(entry); - return NULL; - } - - cur=cur->next; - } - - return entry; -} - -GRSTgaclAcl *GRSTgaclAclLoadFile(char *filename) -{ - xmlDocPtr doc; - xmlNodePtr cur; - GRSTgaclAcl *acl; - - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() starting"); - - if (filename == NULL) - { - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() cannot open a NULL filename"); - return NULL; - } - - doc = xmlParseFile(filename); - if (doc == NULL) - { - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to open ACL file %s", filename); - return NULL; - } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) - { - xmlFreeDoc(doc); - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to parse root of ACL file %s", filename); - return NULL; - } - - if (!xmlStrcmp(cur->name, (const xmlChar *) "Policy")) - { - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing XACML"); - acl=GRSTxacmlAclParse(doc, cur, acl); - } - else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl")) - { - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing GACL"); - acl=GRSTgaclAclParse(doc, cur, acl); - } - else /* ACL format not recognised */ - { - xmlFreeDoc(doc); - return NULL; - } - - xmlFreeDoc(doc); - return acl; -} - -GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl) -{ - GRSTgaclEntry *entry; - - cur = cur->xmlChildrenNode; - - acl = GRSTgaclAclNew(); - - while (cur != NULL) - { - if (!xmlIsBlankNode(cur)) - { - entry = GRSTgaclEntryParse(cur); - if (entry == NULL) - { - GRSTgaclAclFree(acl); - - return NULL; - } - - GRSTgaclAclAddEntry(acl, entry); - } - - cur=cur->next; - } - - return acl; -} -int GRSTgaclFileIsAcl(char *pathandfile) -/* Return 1 if filename in *pathandfile starts GRST_ACL_FILE - Return 0 otherwise. */ -{ - char *filename; - - filename = rindex(pathandfile, '/'); - if (filename == NULL) filename = pathandfile; - else filename++; - - return (strncmp(filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0); -} - -char *GRSTgaclFileFindAclname(char *pathandfile) -/* Return malloc()ed ACL filename that governs the given file or directory - (for directories, the ACL file is in the directory itself), or NULL if none - can be found. */ -{ - int len; - char *path, *file, *p; - struct stat statbuf; - - len = strlen(pathandfile); - if (len == 0) return NULL; - - path = malloc(len + sizeof(GRST_ACL_FILE) + 2); - strcpy(path, pathandfile); - - if ((stat(path, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - (path[len-1] != '/')) - { - strcat(path, "/"); - ++len; - } - - if (path[len-1] != '/') - { - p = rindex(pathandfile, '/'); - if (p != NULL) - { - file = &p[1]; - p = rindex(path, '/'); - sprintf(p, "/%s:%s", GRST_ACL_FILE, file); - - if (stat(path, &statbuf) == 0) return path; - - *p = '\0'; /* otherwise strip off any filename */ - } - } - - while (path[0] != '\0') - { - strcat(path, "/"); - strcat(path, GRST_ACL_FILE); - - if (stat(path, &statbuf) == 0) return path; - - p = rindex(path, '/'); - *p = '\0'; /* strip off the / we added for ACL */ - - p = rindex(path, '/'); - if (p == NULL) break; /* must start without / and we there now ??? */ - - *p = '\0'; /* strip off another layer of / */ - } - - free(path); - return NULL; -} - -GRSTgaclAcl *GRSTgaclAclLoadforFile(char *pathandfile) -/* Return ACL that governs the given file or directory (for directories, - the ACL file is in the directory itself.) */ -{ - char *path; - GRSTgaclAcl *acl; - - path = GRSTgaclFileFindAclname(pathandfile); - - if (path != NULL) - { - acl = GRSTgaclAclLoadFile(path); - free(path); - return acl; - } - - return NULL; -} - -/* * - * Functions to create and query GACLuser * - * */ - -GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *cred) -{ - GRSTgaclUser *user; - - if (cred == NULL) return NULL; - - user = malloc(sizeof(GRSTgaclUser)); - - if (user != NULL) user->firstcred = cred; - - user->dnlists = NULL; - - return user; -} - -int GRSTgaclUserFree(GRSTgaclUser *user) -{ - if (user == NULL) return 1; - - if (user->firstcred != NULL) GRSTgaclCredsFree(user->firstcred); - - if (user->dnlists != NULL) free(user->dnlists); - - free(user); - - return 1; -} - -int GRSTgaclUserAddCred(GRSTgaclUser *user, GRSTgaclCred *cred) -{ - GRSTgaclCred *crediter; - - if ((user == NULL) || (cred == NULL)) return 0; - - if (user->firstcred == NULL) - { - user->firstcred = cred; - cred->next = NULL; /* so cannot be used to add whole lists */ - return 1; - } - - crediter = user->firstcred; - - while (crediter->next != NULL) crediter = crediter->next; - - crediter->next = cred; - cred->next = NULL; /* so cannot be used to add whole lists */ - - return 1; -} - -int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred) -/* test if the user has the given credential */ -{ - GRSTgaclCred *crediter; - GRSTgaclNamevalue *usernamevalue, *crednamevalue; - - if (cred == NULL) return 0; - - if (strcmp(cred->type, "any-user") == 0) return 1; - - if (user == NULL) return 0; - - if (strcmp(cred->type, "dn-list") == 0) - { - if ((cred->firstname == NULL) || - (strcmp((cred->firstname)->name, "url") != 0) || - ((cred->firstname)->next != NULL)) return 0; - - return GRSTgaclDNlistHasUser((cred->firstname)->value, user); - } - - if (strcmp(cred->type, "dns") == 0) - { - if ((user->firstcred == NULL) || - ((user->firstcred)->firstname == NULL) || - (cred->firstname == NULL) || - (strcmp((cred->firstname)->name, "hostname") != 0) || - ((cred->firstname)->next != NULL)) return 0; - - for (crediter=user->firstcred; - crediter != NULL; - crediter = crediter->next) - if (strcmp(crediter->type, "dns") == 0) - { - if ((crediter->firstname == NULL) || - (strcmp((crediter->firstname)->name, "hostname") != 0)) return 0; - - return (fnmatch((cred->firstname)->value, - (crediter->firstname)->value, FNM_CASEFOLD) == 0); - } - - - return 0; - } - - if (strcmp(cred->type, "auth-user") == 0) - { - if ((user->firstcred == NULL) || - ((user->firstcred)->firstname == NULL)) return 0; - - for (crediter=user->firstcred; - crediter != NULL; - crediter = crediter->next) - if (strcmp(crediter->type, "person") == 0) return 1; - - return 0; - } - - if (strcmp(cred->type, "level") == 0) - { - if ((user->firstcred == NULL) || - ((user->firstcred)->firstname == NULL)) return 0; - - for (crediter=user->firstcred; - crediter != NULL; - crediter = crediter->next) - if (strcmp(crediter->type, "level") == 0) - { - if (atoi(user->firstcred->firstname->value) - >= atoi(crediter->firstname->value)) return 1; - - return 0; - } - - return 0; - } - - for (crediter=user->firstcred; crediter != NULL; crediter = crediter->next) - { - if (strcmp(crediter->type, cred->type) != 0) continue; - - if ((crediter->firstname == NULL) && - (cred->firstname == NULL)) return 1; - - if ((crediter->firstname == NULL) || - (cred->firstname == NULL)) continue; - - usernamevalue = crediter->firstname; - crednamevalue = cred->firstname; - - for (;;) - { - if (strcmp(usernamevalue->name,crednamevalue->name) != 0) break; - - if (strcmp(cred->type, "person") == 0) - { - if (GRSTx509NameCmp(usernamevalue->value, - crednamevalue->value) != 0) break; - } -/* - else if (strcmp(cred->type, "level") == 0) - { - if (atoi(usernamevalue->value) - < atoi(crednamevalue->value)) break; - } -*/ - else if (strcmp(usernamevalue->value, - crednamevalue->value) != 0) break; - - /* ok if cred list runs out before user's cred list */ - if (crednamevalue->next == NULL) return 1; - - /* but not ok if more names to match which user doesn't have */ - if (usernamevalue->next == NULL) break; - - crednamevalue = (GRSTgaclNamevalue *) crednamevalue->next; - usernamevalue = (GRSTgaclNamevalue *) usernamevalue->next; - } - } - - return 0; -} - -GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *user, char *type) -/* find the first credential of a given type for this user */ -{ - GRSTgaclCred *cred; - - if (user == NULL) return NULL; - - cred = user->firstcred; - - while (cred != NULL) - { - if (strcmp(cred->type, type) == 0) return cred; - - cred = cred->next; - } - - return NULL; -} - -int GRSTgaclUserSetDNlists(GRSTgaclUser *user, char *dnlists) -{ - if ((user == NULL) || (dnlists == NULL)) return 0; - - if (user->dnlists != NULL) free(user->dnlists); - - user->dnlists = strdup(dnlists); - - return 1; -} - -/* * - * Functions to test for access perm of an individual * - * */ - -static char *recurse4file(char *dir, char *file, int recurse_level) -/* try to find file[] in dir[]. try subdirs if not found. - return full path to first found version or NULL on failure */ -{ - char *fullfilename, *fulldirname; - struct stat statbuf; - DIR *dirDIR; - struct dirent *file_ent; - - /* try to find in current directory */ - - asprintf(&fullfilename, "%s/%s", dir, file); - if (stat(fullfilename, &statbuf) == 0) return fullfilename; - free(fullfilename); - - /* maybe search in subdirectories */ - - if (recurse_level >= GRST_RECURS_LIMIT) return NULL; - - dirDIR = opendir(dir); - - if (dirDIR == NULL) return NULL; - - while ((file_ent = readdir(dirDIR)) != NULL) - { - if (file_ent->d_name[0] == '.') continue; - - asprintf(&fulldirname, "%s/%s", dir, file_ent->d_name); - - if ((stat(fulldirname, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - ((fullfilename = recurse4file(fulldirname, file, - recurse_level + 1)) != NULL)) - { - closedir(dirDIR); - return fullfilename; - } - - free(fulldirname); - } - - closedir(dirDIR); - - return NULL; -} - -int GRSTgaclDNlistHasUser(char *listurl, GRSTgaclUser *user) -{ - char *dn_lists_dirs, *dn_list_ptr, *enclisturl, *filename, *dirname, - line[512], *p; - FILE *fp; - GRSTgaclCred *cred; - - if ((listurl == NULL) || (user == NULL)) return 0; - - enclisturl = GRSThttpUrlEncode(listurl); - - if (user->dnlists != NULL) p = user->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_lists_dirs = strdup(p); /* we need to keep this for free() later! */ - dn_list_ptr = dn_lists_dirs; /* copy, for naughty function strsep() */ - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - { - filename = recurse4file(dirname, enclisturl, 0); - if (filename == NULL) continue; - - fp = fopen(filename, "r"); - free(filename); - - if (fp == NULL) continue; - - while (fgets(line, sizeof(line), fp) != NULL) - { - p = index(line, '\n'); - if (p != NULL) *p = '\0'; - - cred = user->firstcred; - - while (cred != NULL) - { - if ((strcmp(cred->type, "person") == 0) && - (cred->firstname != NULL) && - (strcmp("dn", (cred->firstname)->name) == 0) && - (GRSTx509NameCmp(line, (cred->firstname)->value) == 0)) - { - fclose(fp); - free(dn_lists_dirs); - free(enclisturl); - return 1; - } - - cred = cred->next; - } - } - - fclose(fp); - } - - free(dn_lists_dirs); - free(enclisturl); - - return 0; -} - -GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *acl, GRSTgaclUser *user) -/* - GACLgaclAclTestUser - return bit fields depending on access perms user has - for given acl. All zero for no access. If *user is - NULL, matching to "any-user" will still work. -*/ -{ - int flag, onlyanyuser; - GRSTgaclPerm allowperms = 0, denyperms = 0, allowed; - GRSTgaclEntry *entry; - GRSTgaclCred *cred, *usercred; - - if (acl == NULL) return 0; - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - { - flag = 1; /* begin by assuming this entry applies to us */ - onlyanyuser = 1; /* begin by assuming just */ - - /* now go through creds, checking they all do apply to us */ - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - if (!GRSTgaclUserHasCred(user, cred)) flag = 0; - else if (strcmp(cred->type, "any-user") != 0) onlyanyuser = 0; - - if (!flag) continue; /* flag false if a subtest failed */ - - /* does apply to us, so we remember this entry's perms */ - - /* we dont allow Write or Admin on the basis of any-user alone */ - - allowed = entry->allowed; - - if (onlyanyuser) - allowed = entry->allowed & ~GRST_PERM_WRITE & ~GRST_PERM_ADMIN; - else allowed = entry->allowed; - - allowperms = allowperms | allowed; - denyperms = denyperms | entry->denied; - } - - return (allowperms & (~ denyperms)); - /* for each perm type, any deny we saw kills any allow */ -} - -GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *acl, GRSTgaclUser *user) -/* - GRSTgaclAclTestexclUser - - return bit fields depending on ALLOW perms OTHER users - have for given acl. All zero if they have no access. - (used for testing if a user has exclusive access) -*/ -{ - int flag; - GRSTgaclPerm perm = 0; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - - if (acl == NULL) return 0; - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - { - flag = 0; /* flag will be set if cred implies other users */ - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - { - if (strcmp(cred->type, "person") != 0) - /* if we ever add support for other person-specific credentials, - they must also be recognised here */ - { - flag = 1; - break; - } - - if (!GRSTgaclUserHasCred(user, cred)) - /* if user doesnt have this person credential, assume - it refers to a different individual */ - { - flag = 1; - break; - } - } - - if (flag) perm = perm | entry->allowed; - } - - return perm; -} - -/* - Wrapper functions for gridsite-gacl.h support of legacy API -*/ - -GRSTgaclEntry *GACLparseEntry(xmlNodePtr cur) -{ - return GRSTgaclEntryParse(cur); -} diff --git a/org.gridsite.core/src/grst_htcp.c b/org.gridsite.core/src/grst_htcp.c deleted file mode 100644 index ec9672a..0000000 --- a/org.gridsite.core/src/grst_htcp.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - Copyright (c) 2002-5, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include - -#include "gridsite.h" - -int GRSThtcpNOPrequestMake(char **request, int *request_length, - unsigned int trans_id) -/* - Make a complete HTCP NOP request and return a pointer to malloc'd - memory pointing to it. -*/ -{ - *request_length = - asprintf(request,"%c%c" /* place holder for total length */ - "%c%c" /* HTCP version 0.0 */ - "%c%c" /* DATA length place holder */ - "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ - "%c%c%c%c" /* TRANS-ID placeholder */ - "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ - 0, 0, - 0, 0, - 0, 0, - GRSThtcpNOPop * 16, 2, - 0, 0, 0, 0, - 0, 2); - - if (*request_length < 0) return GRST_RET_FAILED; - - (*request)[0] = *request_length / 256; - (*request)[1] = *request_length % 256; - - (*request)[4] = (*request_length - 6) / 256; - (*request)[5] = (*request_length - 6) % 256; - - memcpy(&((*request)[8]), &trans_id, 4); - - return GRST_RET_OK; -} - -int GRSThtcpNOPresponseMake(char **message, int *message_length, - unsigned int trans_id) -/* - Make a complete HTCP NOP response for a found file and return a pointer - to malloc'd memory pointing to it. -*/ -{ - *message_length = - asprintf(message, - "%c%c" /* place holder for total length */ - "%c%c" /* HTCP version 0.0 */ - "%c%c" /* DATA length place holder */ - "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ - "%c%c%c%c" /* TRANS-ID place holder */ - "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ - 0, 0, - 0, 0, - 0, 0, - GRSThtcpNOPop * 16, 1, /* RR=1, MO=0, RESPONSE=0 (ie found) */ - 0, 0, 0, 0, - 0, 2); - - if (*message_length < 0) return GRST_RET_FAILED; - - (*message)[0] = *message_length / 256; - (*message)[1] = *message_length % 256; - - (*message)[4] = (*message_length - 6) / 256; - (*message)[5] = (*message_length - 6) % 256; - - memcpy(&((*message)[8]), &trans_id, 4); - - return GRST_RET_OK; -} - -int GRSThtcpTSTrequestMake(char **request, int *request_length, - unsigned int trans_id, - char *method, char *uri, char *req_hdrs) -/* - Make a complete HTCP TST request and return a pointer to malloc'd - memory pointing to it. -*/ -{ - if ((method == NULL) || (uri == NULL) || (req_hdrs == NULL)) - return GRST_RET_FAILED; - - *request_length = - asprintf(request,"%c%c" /* place holder for total length */ - "%c%c" /* HTCP version 0.0 */ - "%c%c" /* DATA length place holder */ - "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ - "%c%c%c%c" /* TRANS-ID placeholder */ - "%c%c%s" /* OP-DATA: METHOD */ - "%c%c%s" /* OP-DATA: URI */ - "%c%c%s" /* OP-DATA: VERSION */ - "%c%c%s" /* OP-DATA: REQ-HDRS */ - "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ - 0, 0, - 0, 0, - 0, 0, - GRSThtcpTSTop * 16, 2, - 0, 0, 0, 0, - strlen(method) / 256, strlen(method) % 256, method, - strlen(uri) / 256, strlen(uri) % 256, uri, - 0, 8, "HTTP/1.1", - strlen(req_hdrs)/256, strlen(req_hdrs) % 256, req_hdrs, - 0, 2); - - if (*request_length < 0) return GRST_RET_FAILED; - - (*request)[0] = *request_length / 256; - (*request)[1] = *request_length % 256; - - (*request)[4] = (*request_length - 6) / 256; - (*request)[5] = (*request_length - 6) % 256; - - memcpy(&((*request)[8]), &trans_id, 4); - - return GRST_RET_OK; -} - -int GRSThtcpTSTresponseMake(char **message, int *message_length, - unsigned int trans_id, - char *resp_hdrs, char *entity_hdrs, - char *cache_hdrs) -/* - Make a complete HTCP TST response for a found file and return a pointer - to malloc'd memory pointing to it. -*/ -{ - if ((resp_hdrs != NULL) && (entity_hdrs != NULL) && (cache_hdrs != NULL)) - /* found file response */ - *message_length = - asprintf(message, - "%c%c" /* place holder for total length */ - "%c%c" /* HTCP version 0.0 */ - "%c%c" /* DATA length place holder */ - "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ - "%c%c%c%c" /* TRANS-ID place holder */ - "%c%c%s" /* OP-DATA: RESP-HDRS */ - "%c%c%s" /* OP-DATA: ENTITY-HDRS */ - "%c%c%s" /* OP-DATA: CACHE-HDRS */ - "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ - 0, 0, - 0, 0, - 0, 0, - GRSThtcpTSTop * 16, 1, /* RR=1, MO=0, RESPONSE=0 (ie found) */ - 0, 0, 0, 0, - strlen(resp_hdrs) / 256, strlen(resp_hdrs) % 256, resp_hdrs, - strlen(entity_hdrs) / 256, strlen(entity_hdrs) % 256, entity_hdrs, - strlen(cache_hdrs) / 256, strlen(cache_hdrs) % 256, cache_hdrs, - 0, 2); - else if (cache_hdrs != NULL) - /* not found file response, just cache_hdrs given */ - *message_length = - asprintf(message, - "%c%c" /* place holder for total length */ - "%c%c" /* HTCP version 0.0 */ - "%c%c" /* DATA length place holder */ - "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ - "%c%c%c%c" /* TRANS-ID */ - "%c%c%s" /* OP-DATA: CACHE-HDRS */ - "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ - 0, 0, - 0, 0, - 0, 0, - GRSThtcpTSTop * 16 + 1, 1, /* RR=1, MO=0, RESPONSE=1 (missing) */ - 0, 0, 0, 0, - strlen(cache_hdrs) / 256, strlen(cache_hdrs) % 256, cache_hdrs, - 0, 2); - else return GRST_RET_FAILED; - - if (*message_length < 0) return GRST_RET_FAILED; - - (*message)[0] = *message_length / 256; - (*message)[1] = *message_length % 256; - - (*message)[4] = (*message_length - 6) / 256; - (*message)[5] = (*message_length - 6) % 256; - - memcpy(&((*message)[8]), &trans_id, 4); - - return GRST_RET_OK; -} - -int GRSThtcpMessageParse(GRSThtcpMessage *parsed, char *raw, int length) -{ - GRSThtcpCountstr *s; - - bzero(parsed, sizeof(GRSThtcpMessage)); - - if (length < (void *) &(parsed->method) - - (void *) &(parsed->total_length_msb) + 2) - return GRST_RET_FAILED; - - memcpy(parsed, raw, (void *) &(parsed->method) - - (void *) &(parsed->total_length_msb)); - - if (parsed->opcode == GRSThtcpNOPop) return GRST_RET_OK; - - if ((parsed->opcode == GRSThtcpTSTop) && (parsed->rr == 0)) - { - /* a TST request */ - - /* point to start of data/auth in raw */ - s = (GRSThtcpCountstr *) &(((GRSThtcpMessage *) raw)->method); - - /* METHOD string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->method = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - /* URI string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->uri = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - /* VERSION string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->version = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - /* REQ-HDRS string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->req_hdrs = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - return GRST_RET_OK; - } - - if ((parsed->opcode == GRSThtcpTSTop) && (parsed->rr == 1)) - { - /* a TST response */ - - /* point to start of data/auth in raw */ - s = (GRSThtcpCountstr *) &(((GRSThtcpMessage *) raw)->method); - - /* RESP-HDRS string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->resp_hdrs = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - /* ENTITY-HDRS string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->entity_hdrs = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - /* CACHE-HDRS string */ - - if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) - return GRST_RET_FAILED; - parsed->cache_hdrs = s; - s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); - - return GRST_RET_OK; - } - - return GRST_RET_FAILED; -} diff --git a/org.gridsite.core/src/grst_http.c b/org.gridsite.core/src/grst_http.c deleted file mode 100644 index c933ca0..0000000 --- a/org.gridsite.core/src/grst_http.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gridsite.h" - -void GRSThttpBodyInit(GRSThttpBody *thisbody) -{ - thisbody->size = 0; /* simple, but we don't expose internals to callers */ -} - -void GRSThttpPrintf(GRSThttpBody *thisbody, char *fmt, ...) -/* append printf() style format and arguments to *thisbody. - This requires vasprintf from glibc!! */ -{ - char *p; - size_t size; - va_list args; - - va_start(args, fmt); - size = vasprintf(&p, fmt, args); - va_end(args); - - if (size == 0) free(p); /* don't need to bother in this case */ - else if (size > 0) - { - if (thisbody->size == 0) /* need to initialise */ - { - thisbody->first = (GRSThttpCharsList *)malloc(sizeof(GRSThttpCharsList)); - thisbody->first->text = p; - thisbody->first->next = NULL; - - thisbody->last = thisbody->first; - thisbody->size = size; - } - else - { - thisbody->last->next = (GRSThttpCharsList *) - malloc(sizeof(GRSThttpCharsList)); - ((GRSThttpCharsList *) thisbody->last->next)->text = p; - ((GRSThttpCharsList *) thisbody->last->next)->next = NULL; - - thisbody->last = thisbody->last->next; - thisbody->size = thisbody->size + size; - } - } -} - -int GRSThttpCopy(GRSThttpBody *thisbody, char *file) -/* - copy a whole file, named file[], into the body output buffer, returning - 1 if file was found and copied ok, or 0 otherwise. -*/ -{ - int fd, len; - char c, *p; - struct stat statbuf; - - fd = open(file, O_RDONLY); - - if (fd == -1) return 0; - - if (fstat(fd, &statbuf) != 0) - { - close(fd); - return 0; - } - - p = malloc(statbuf.st_size + 1); - - if (p == NULL) - { - close(fd); - return 0; - } - - len = read(fd, p, statbuf.st_size); - p[len] = '\0'; - - close(fd); - - if (thisbody->size == 0) /* need to initialise */ - { - thisbody->first = (GRSThttpCharsList *) malloc(sizeof(GRSThttpCharsList)); - thisbody->first->text = p; - thisbody->first->next = NULL; - - thisbody->last = thisbody->first; - thisbody->size = len; - } - else - { - thisbody->last->next=(GRSThttpCharsList *)malloc(sizeof(GRSThttpCharsList)); - ((GRSThttpCharsList *) thisbody->last->next)->text = p; - ((GRSThttpCharsList *) thisbody->last->next)->next = NULL; - - thisbody->last = thisbody->last->next; - thisbody->size = thisbody->size + len; - } - - return 1; -} - -void GRSThttpWriteOut(GRSThttpBody *thisbody) -/* output Content-Length header, blank line then whole of the body to - standard output */ -{ - GRSThttpCharsList *p; - - printf("Content-Length: %d\n\n", thisbody->size); - - p = thisbody->first; - - while (p != NULL) - { - fputs(p->text, stdout); - - p = p->next; - } -} - -int GRSThttpPrintHeaderFooter(GRSThttpBody *bp, char *file, char *headfootname) -/* - try to print Header or Footer appropriate for absolute path file[], - returning 1 rather than 0 if found. -*/ -{ - int found = 0; - char *pathfile, *p; - struct stat statbuf; - - pathfile = malloc(strlen(file) + strlen(headfootname) + 2); - strcpy(pathfile, file); - - if ((pathfile[strlen(pathfile) - 1] != '/') && - (stat(pathfile, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) strcat(pathfile, "/"); - - for (;;) - { - p = rindex(pathfile, '/'); - if (p == NULL) break; - p[1] = '\0'; - strcat(p, headfootname); - - if (stat(pathfile, &statbuf) == 0) - { - found = GRSThttpCopy(bp, pathfile); - break; - } - - p[0] = '\0'; - } - - free(pathfile); - return found; -} - -char *GRSThttpGetCGI(char *name) -/* - Return a malloc()ed copy of CGI form parameter identified by name[], - either received by QUERY_STRING (via GET) or on stdin (via POST). - Caller must free() the returned string itself. If name[] is not found, - an empty NUL-terminated malloc()ed string is returned. name[] has any - URL-encoding reversed. -*/ -{ - char *p, *namepattern, *valuestart, *returnvalue, *querystring; - int c, i, j, n, contentlength = 0; - static char *cgiposted = NULL; - size_t size_needed; - - if (cgiposted == NULL) /* have to initialise cgiposted */ - { - p = getenv("CONTENT_LENGTH"); - if (p != NULL) sscanf(p, "%d", &contentlength); - - querystring = getenv("REDIRECT_QUERY_STRING"); - if (querystring == NULL) querystring = getenv("QUERY_STRING"); - - if (querystring == NULL) cgiposted = malloc(contentlength + 3); - else cgiposted = malloc(contentlength + strlen(querystring) + 4); - - cgiposted[0] = '&'; - - for (i = 1; i <= contentlength; ++i) - { - c = getchar(); - if (c == EOF) break; - cgiposted[i] = c; - } - - cgiposted[i] = '&'; - cgiposted[i+1] = '\0'; - - if (querystring != NULL) - { - strcat(cgiposted, querystring); - strcat(cgiposted, "&"); - } - } - - namepattern = malloc(strlen(name) + 3); - sprintf(namepattern, "&%s=", name); - - p = strstr(cgiposted, namepattern); - free(namepattern); - if (p == NULL) return strdup(""); - - valuestart = &p[strlen(name) + 2]; - - for (n=0; valuestart[n] != '&'; ++n) ; - - returnvalue = malloc(n + 1); - - j=0; - - for (i=0; i < n; ++i) - { - if ((i < n - 2) && (valuestart[i] == '%')) /* url encoded as %HH */ - { - returnvalue[j] = 0; - - if (isdigit(valuestart[i+1])) - returnvalue[j] += 16 * (valuestart[i+1] - '0'); - else if (isalpha(valuestart[i+1])) - returnvalue[j] += 16 * (10 + tolower(valuestart[i+1]) - 'a'); - - if (isdigit(valuestart[i+2])) - returnvalue[j] += valuestart[i+2] - '0'; - else if (isalpha(valuestart[i+2])) - returnvalue[j] += 10 + tolower(valuestart[i+2]) - 'a'; - - i = i + 2; - } - else if (valuestart[i] == '+') returnvalue[j] = ' '; - else returnvalue[j] = valuestart[i]; - - if (returnvalue[j] == '\r') continue; /* CR/LF -> LF */ - ++j; - } - - returnvalue[j] = '\0'; - - return returnvalue; -} - -/* * - * Utility functions * - * */ - -char *GRSThttpUrlDecode(char *in) -{ - int i, j, n; - char *out; - - n = strlen(in); - out = malloc(n + 1); - - j=0; - - for (i=0; i < n; ++i) - { - if ((i < n - 2) && (in[i] == '%')) /* url encoded as %HH */ - { - out[j] = 0; - - if (isdigit(in[i+1])) - out[j] += 16 * (in[i+1] - '0'); - else if (isalpha(in[i+1])) - out[j] += 16 * (10 + tolower(in[i+1]) - 'a'); - - if (isdigit(in[i+2])) - out[j] += in[i+2] - '0'; - else if (isalpha(in[i+2])) - out[j] += 10 + tolower(in[i+2]) - 'a'; - - i = i + 2; - } - else if (in[i] == '+') out[j] = ' '; - else out[j] = in[i]; - - ++j; - } - - out[j] = '\0'; - - return out; -} - -char *GRSThttpUrlEncode(char *in) -/* Return a pointer to a malloc'd string holding a URL-encoded (RFC 1738) - version of *in. Only A-Z a-z 0-9 . _ - are passed through unmodified. - (DN's processed by GRSThttpUrlEncode can be used as valid Unix filenames, - assuming they do not exceed restrictions on filename length.) */ -{ - char *out, *p, *q; - - out = malloc(3*strlen(in) + 1); - - p = in; - q = out; - - while (*p != '\0') - { - if (isalnum(*p) || (*p == '.') || (*p == '_') || (*p == '-')) - { - *q = *p; - ++q; - } - else - { - sprintf(q, "%%%2X", *p); - q = &q[3]; - } - - ++p; - } - - *q = '\0'; - return out; -} - -char *GRSThttpUrlMildencode(char *in) -/* Return a pointer to a malloc'd string holding a partially URL-encoded - version of *in. "Partially" means that A-Z a-z 0-9 . = - _ @ and / - are passed through unmodified. (DN's processed by GRSThttpUrlMildencode() - can be used as valid Unix paths+filenames if you are prepared to - create or simulate the resulting /X=xyz directories.) */ -{ - char *out, *p, *q; - - out = malloc(3*strlen(in) + 1); - - p = in; - q = out; - - while (*p != '\0') - { - if (isalnum(*p) || (*p == '.') || (*p == '=') || (*p == '-') - || (*p == '/') || (*p == '@') || (*p == '_')) - { - *q = *p; - ++q; - } - else if (*p == ' ') - { - *q = '+'; - ++q; - } - else - { - sprintf(q, "%%%2X", *p); - q = &q[3]; - } - - ++p; - } - - *q = '\0'; - return out; -} - -/// Return a one-time passcode string, for use with GridHTTP -/** - * Returns - * - * String is timestamp+SHA1_HASH(timestamp+":"+method+":"+URL) - * Timestamps and hashes are in lowercase hexadecimal. Timestamps are - * seconds since 00:00:00 on January 1, 1970 UTC. - */ - -/* -char *GRSThttpMakeOneTimePasscode(time_t timestamp, char *method, char *url) -{ - int len, i; - char *stringtohash, hashedstring[EVP_MAX_MD_SIZE], *returnstring; - const EVP_MD *m; - EVP_MD_CTX ctx; - - m = EVP_sha1(); - if (m == NULL) return NULL; - - asprintf(&stringtohash, "%08x:%s:%s", timestamp, method, url); - - EVP_DigestInit(&ctx, m); - EVP_DigestUpdate(&ctx, stringtohash, strlen(stringtohash)); - EVP_DigestFinal(&ctx, hashedstring, &len); - - returnstring = malloc(9 + len * 2); - - sprintf(returnstring, "%08x", timestamp); - - for (i=0; - - return returnstring; -} -*/ diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c deleted file mode 100644 index 99741d3..0000000 --- a/org.gridsite.core/src/grst_x509.c +++ /dev/null @@ -1,2160 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------- - For more information about GridSite: http://www.gridsite.org/ - --------------------------------------------------------------- -*/ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "gridsite.h" - -#define GRST_KEYSIZE 512 -#define GRST_PROXYCACHE "/../proxycache/" -#define GRST_MAX_CHAIN_LEN 9 -#define GRST_BACKDATE_SECONDS 300 - -/// Compare X509 Distinguished Name strings -int GRSTx509NameCmp(char *a, char *b) -/** - * This function attempts to do with string representations what - * would ideally be done with OIDs/values. In particular, we equate - * "/Email=" == "/emailAddress=" to deal with this important change - * between OpenSSL 0.9.6 and 0.9.7. - * Other than that, it is currently the same as ordinary strcasecmp(3) - * (for consistency with EDG/LCG/EGEE gridmapdir case insensitivity.) - */ -{ - int ret; - char *aa, *bb, *p; - - if ((a == NULL) || (b == NULL)) return 1; /* NULL never matches */ - - aa = strdup(a); - while ((p = strstr(aa, "/emailAddress=")) != NULL) - { - memmove(&p[6], &p[13], strlen(&p[13]) + 1); - p[1] = 'E'; - } - - bb = strdup(b); - while ((p = strstr(bb, "/emailAddress=")) != NULL) - { - memmove(&p[6], &p[13], strlen(&p[13]) + 1); - p[1] = 'E'; - } - - ret = strcasecmp(aa, bb); - - free(aa); - free(bb); - - return ret; -} - - -/// Check critical extensions -/** - * Returning GRST_RET_OK if all of extensions are known to us or - * OpenSSL; GRST_REF_FAILED otherwise. - * - * Since this function relies on functionality (X509_supported_extension) - * introduced in 0.9.7, then we do nothing and report an error - * (GRST_RET_FAILED) if one of the associated defines - * (X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) is absent. - */ - -int GRSTx509KnownCriticalExts(X509 *cert) -{ - int i; - char s[80]; - X509_EXTENSION *ex; - -#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION - for (i = 0; i < X509_get_ext_count(cert); ++i) - { - ex = X509_get_ext(cert, i); - - if (X509_EXTENSION_get_critical(ex) && - !X509_supported_extension(ex)) - { - OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); - - if (strcmp(s, GRST_PROXYCERTINFO_OID) != 0) return GRST_RET_FAILED; - } - } - - return GRST_RET_OK; -#else - return GRST_RET_FAILED; -#endif -} - -/// Check if certificate can be used as a CA to sign standard X509 certs -/* - * Return GRST_RET_OK if true; GRST_RET_FAILED if not. - */ - -int GRSTx509IsCA(X509 *cert) -{ - int idret, purpose_id; - - purpose_id = X509_PURPOSE_get_by_sname("sslclient"); - - /* final argument to X509_check_purpose() is whether to check for CAness */ - - if (X509_check_purpose(cert, purpose_id + X509_PURPOSE_MIN, 1)) - return GRST_RET_OK; - else return GRST_RET_FAILED; -} - -int GRSTx509ChainFree(GRSTx509Chain *chain) -{ - GRSTx509Cert *grst_cert, *next_grst_cert; - - if (chain == NULL) return GRST_RET_OK; - - next_grst_cert = chain->firstcert; - - while (next_grst_cert != NULL) - { - grst_cert = next_grst_cert; - - if (grst_cert->issuer != NULL) free(grst_cert->issuer); - if (grst_cert->dn != NULL) free(grst_cert->dn); - if (grst_cert->value != NULL) free(grst_cert->value); - if (grst_cert->ocsp != NULL) free(grst_cert->ocsp); - - next_grst_cert = grst_cert->next; - free(grst_cert); - } - - free(chain); - - return GRST_RET_OK; -} - -/// Check a specific signature against a specific (VOMS) cert -/* - * Returns GRST_RET_OK if signature is ok, other values if not. - */ - -static int GRSTx509VerifySig(time_t *time1_time, time_t *time2_time, - unsigned char *txt, int txt_len, - unsigned char *sig, int sig_len, - X509 *cert) -{ - int ret; - EVP_PKEY *prvkey; - EVP_MD_CTX ctx; - time_t voms_service_time1, voms_service_time2; - - prvkey = X509_extract_key(cert); - if (prvkey == NULL) return GRST_RET_FAILED; - - OpenSSL_add_all_digests(); -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - EVP_MD_CTX_init(&ctx); - EVP_VerifyInit_ex(&ctx, EVP_md5(), NULL); -#else - EVP_VerifyInit(&ctx, EVP_md5()); -#endif - - EVP_VerifyUpdate(&ctx, txt, txt_len); - - ret = EVP_VerifyFinal(&ctx, sig, sig_len, prvkey); - -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - EVP_MD_CTX_cleanup(&ctx); -#endif - EVP_PKEY_free(prvkey); - - if (ret != 1) return GRST_RET_FAILED; - - voms_service_time1 = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0); - if (voms_service_time1 > *time1_time) - *time1_time = voms_service_time1; - - voms_service_time2 = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0); - if (voms_service_time2 < *time1_time) - *time2_time = voms_service_time2; - - return GRST_RET_OK ; /* verified */ -} - -/// Check the signature of the VOMS attributes -/* - * Returns GRST_RET_OK if signature is ok, other values if not. - */ - -static int GRSTx509VerifyVomsSig(time_t *time1_time, time_t *time2_time, - unsigned char *asn1string, - struct GRSTasn1TagList taglist[], - int lasttag, - char *vomsdir, int acnumber) -{ -#define GRST_ASN1_COORDS_VOMS_DN "-1-1-%d-1-3-1-1-1-%%d-1-%%d" -#define GRST_ASN1_COORDS_VOMS_INFO "-1-1-%d-1" -#define GRST_ASN1_COORDS_VOMS_SIG "-1-1-%d-3" - int ret, isig, iinfo; - char *certpath, *certpath2, acvomsdn[200], dn_coords[200], - info_coords[200], sig_coords[200]; - unsigned char *q; - DIR *vomsDIR, *vomsDIR2; - struct dirent *vomsdirent, *vomsdirent2; - X509 *cert; - EVP_PKEY *prvkey; - FILE *fp; - EVP_MD_CTX ctx; - struct stat statbuf; - time_t voms_service_time1, voms_service_time2; - - if ((vomsdir == NULL) || (vomsdir[0] == '\0')) return GRST_RET_FAILED; - - snprintf(dn_coords, sizeof(dn_coords), - GRST_ASN1_COORDS_VOMS_DN, acnumber); - - if (GRSTasn1GetX509Name(acvomsdn, sizeof(acvomsdn), dn_coords, - asn1string, taglist, lasttag) != GRST_RET_OK) return GRST_RET_FAILED; - - snprintf(info_coords, sizeof(info_coords), - GRST_ASN1_COORDS_VOMS_INFO, acnumber); - iinfo = GRSTasn1SearchTaglist(taglist, lasttag, info_coords); - - snprintf(sig_coords, sizeof(sig_coords), - GRST_ASN1_COORDS_VOMS_SIG, acnumber); - isig = GRSTasn1SearchTaglist(taglist, lasttag, sig_coords); - - if ((iinfo < 0) || (isig < 0)) return GRST_RET_FAILED; - - vomsDIR = opendir(vomsdir); - if (vomsDIR == NULL) return GRST_RET_FAILED; - - while ((vomsdirent = readdir(vomsDIR)) != NULL) - { - if (vomsdirent->d_name[0] == '.') continue; - - asprintf(&certpath, "%s/%s", vomsdir, vomsdirent->d_name); - stat(certpath, &statbuf); - - if (S_ISDIR(statbuf.st_mode)) - { - vomsDIR2 = opendir(certpath); - GRSTerrorLog(GRST_LOG_DEBUG, - "Descend VOMS subdirectory %s", certpath); - free(certpath); - - if (vomsDIR2 == NULL) continue; - - - while ((vomsdirent2 = readdir(vomsDIR2)) != NULL) - { - if (vomsdirent2->d_name[0] == '.') continue; - - asprintf(&certpath2, "%s/%s/%s", - vomsdir, vomsdirent->d_name, vomsdirent2->d_name); - - fp = fopen(certpath2, "r"); - GRSTerrorLog(GRST_LOG_DEBUG, - "Examine VOMS cert %s", certpath2); - free(certpath2); - if (fp == NULL) continue; - - cert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - if (cert == NULL) continue; - - if (GRSTx509VerifySig(time1_time, time2_time, - &asn1string[taglist[iinfo].start], - taglist[iinfo].length+taglist[iinfo].headerlength, - &asn1string[taglist[isig].start+ - taglist[isig].headerlength+1], - taglist[isig].length - 1, - cert) == GRST_RET_OK) - { - GRSTerrorLog(GRST_LOG_DEBUG, " VOMS cert signature match"); - X509_free(cert); - closedir(vomsDIR2); - closedir(vomsDIR); - return GRST_RET_OK ; /* verified */ - } - - X509_free(cert); - } - - closedir(vomsDIR2); - } - else - { - fp = fopen(certpath, "r"); - GRSTerrorLog(GRST_LOG_DEBUG, "Examine VOMS cert %s", certpath); - free(certpath); - if (fp == NULL) continue; - - cert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - if (cert == NULL) continue; - - if (GRSTx509VerifySig(time1_time, time2_time, - &asn1string[taglist[iinfo].start], - taglist[iinfo].length+taglist[iinfo].headerlength, - &asn1string[taglist[isig].start+ - taglist[isig].headerlength+1], - taglist[isig].length - 1, - cert) == GRST_RET_OK) - { - X509_free(cert); - closedir(vomsDIR); - return GRST_RET_OK ; /* verified */ - } - - X509_free(cert); - } - } - - closedir(vomsDIR); - return GRST_RET_FAILED; -} - -/// Get the VOMS attributes in the given extension -/* - * Add any VOMS credentials found into the chain. Always returns GRST_RET_OK - * - even for invalid credentials, which are flagged in errors field - */ - -static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, - time_t time1_time, time_t time2_time, - X509_EXTENSION *ex, - char *ucuserdn, char *vomsdir) -{ -#define MAXTAG 500 -#define GRST_ASN1_COORDS_FQAN "-1-1-%d-1-7-1-2-1-2-%d" -#define GRST_ASN1_COORDS_USER_DN "-1-1-%d-1-2-1-1-1-1-%%d-1-%%d" -#define GRST_ASN1_COORDS_VOMS_DN "-1-1-%d-1-3-1-1-1-%%d-1-%%d" -#define GRST_ASN1_COORDS_TIME1 "-1-1-%d-1-6-1" -#define GRST_ASN1_COORDS_TIME2 "-1-1-%d-1-6-2" - ASN1_OCTET_STRING *asn1data; - char *asn1string, acuserdn[200], accadn[200], acvomsdn[200], - dn_coords[200], fqan_coords[200], time1_coords[200], - time2_coords[200]; - long asn1length; - int lasttag=-1, itag, i, acnumber = 1, chain_errors = 0; - struct GRSTasn1TagList taglist[MAXTAG+1]; - time_t actime1 = 0, actime2 = 0, time_now; - GRSTx509Cert *new_grst_cert; - - asn1data = X509_EXTENSION_get_data(ex); - asn1string = ASN1_STRING_data(asn1data); - asn1length = ASN1_STRING_length(asn1data); - - GRSTasn1ParseDump(NULL, asn1string, asn1length, taglist, MAXTAG, &lasttag); - - for (acnumber = 1; ; ++acnumber) /* go through ACs one by one */ - { - chain_errors = 0; - - snprintf(dn_coords, sizeof(dn_coords), GRST_ASN1_COORDS_USER_DN, acnumber); - if (GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), dn_coords, - asn1string, taglist, lasttag) != GRST_RET_OK) - break; - - snprintf(dn_coords, sizeof(dn_coords), GRST_ASN1_COORDS_VOMS_DN, acnumber); - if (GRSTasn1GetX509Name(acvomsdn, sizeof(acvomsdn), dn_coords, - asn1string, taglist, lasttag) != GRST_RET_OK) - break; - - if (GRSTx509NameCmp(ucuserdn, acuserdn) != 0) - chain_errors |= GRST_CERT_BAD_CHAIN; - - if (GRSTx509VerifyVomsSig(&time1_time, &time2_time, - asn1string, taglist, lasttag, vomsdir, acnumber) - != GRST_RET_OK) - chain_errors |= GRST_CERT_BAD_SIG; - - snprintf(time1_coords, sizeof(time1_coords), GRST_ASN1_COORDS_TIME1, acnumber); - itag = GRSTasn1SearchTaglist(taglist, lasttag, time1_coords); - - if (itag > -1) actime1 = GRSTasn1TimeToTimeT( - &asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - else actime1 = 0; - - snprintf(time2_coords, sizeof(time2_coords), GRST_ASN1_COORDS_TIME2, acnumber); - itag = GRSTasn1SearchTaglist(taglist, lasttag, time2_coords); - - if (itag > -1) actime2 = GRSTasn1TimeToTimeT( - &asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - else actime2 = 0; - - if (actime1 > time1_time) time1_time = actime1; - if (actime2 < time2_time) time2_time = actime2; - - time(&time_now); - if ((time1_time > time_now + 300) || (time2_time < time_now)) - chain_errors |= GRST_CERT_BAD_TIME; - - for (i=1; ; ++i) /* now go through FQANs */ - { - snprintf(fqan_coords, sizeof(fqan_coords), GRST_ASN1_COORDS_FQAN, acnumber, i); - itag = GRSTasn1SearchTaglist(taglist, lasttag, fqan_coords); - - if (itag > -1) - { - (*grst_cert)->next = malloc(sizeof(GRSTx509Cert)); - *grst_cert = (*grst_cert)->next; - bzero(*grst_cert, sizeof(GRSTx509Cert)); - - (*grst_cert)->start = time1_time; - (*grst_cert)->finish = time2_time; - asprintf(&((*grst_cert)->value), "%.*s", - taglist[itag].length, - &asn1string[taglist[itag].start+ - taglist[itag].headerlength]); - - (*grst_cert)->errors = chain_errors; /* ie may be invalid */ - (*grst_cert)->type = GRST_CERT_TYPE_VOMS; - (*grst_cert)->issuer = strdup(acvomsdn); - (*grst_cert)->dn = strdup(acuserdn); - } - else break; - } - } - - return GRST_RET_OK; -} - -/// Check certificate chain for GSI proxy acceptability. -/** - * Returns GRST_RET_OK if valid; OpenSSL X509 errors otherwise. - * - * The GridSite version handles old and new style Globus proxies, and - * proxies derived from user certificates issued with "X509v3 Basic - * Constraints: CA:FALSE" (eg UK e-Science CA) - * - * TODO: we do not yet check ProxyCertInfo and ProxyCertPolicy extensions - * (although via GRSTx509KnownCriticalExts() we can accept them.) - */ - -int GRSTx509ChainLoadCheck(GRSTx509Chain **chain, - STACK_OF(X509) *certstack, X509 *lastcert, - char *capath, char *vomsdir) -{ - X509 *cert; /* Points to the current cert in the loop */ - X509 *cacert = NULL; /* The CA root cert */ - int depth = 0; /* Depth of cert chain */ - int chain_errors = 0; /* records previous errors */ - int first_non_ca; /* number of the EEC issued to user by CA */ - char *ucuserdn = NULL; /* DN of EEC issued to user by CA */ - size_t len,len2; /* Lengths of issuer and cert DN */ - int IsCA; /* Holds whether cert is allowed to sign */ - int prevIsCA; /* Holds whether previous cert in chain is - allowed to sign */ - int prevIsLimited; /* previous cert was proxy and limited */ - int i,j,ret; /* Iteration/temp variables */ - char *proxy_part_DN; /* Pointer to end part of current-cert-in-chain - maybe eg "/CN=proxy" */ - char s[80]; - char *cacertpath; - unsigned long subjecthash = 0; /* hash of the name of first cert */ - unsigned long issuerhash = 0; /* hash of issuer name of first cert */ - FILE *fp; - X509_EXTENSION *ex; - time_t now; - GRSTx509Cert *grst_cert, *new_grst_cert; - - GRSTerrorLog(GRST_LOG_DEBUG, "GRSTx509ChainLoadCheck() starts"); - - time(&now); - - first_non_ca = 0; /* set to something predictable if things fail */ - - /* Set necessary preliminary values */ - IsCA = TRUE; /* =prevIsCA - start from a CA */ - prevIsLimited = 0; - - /* Get the client cert chain */ - if (certstack != NULL) - depth = sk_X509_num(certstack); /* How deep is that chain? */ - - if ((depth == 0) && (lastcert == NULL)) - { - *chain = NULL; - return GRST_RET_FAILED; - } - - cert = sk_X509_value(certstack, depth - 1); - subjecthash = X509_NAME_hash(X509_get_subject_name(cert)); - issuerhash = X509_NAME_hash(X509_get_issuer_name(cert)); - asprintf(&cacertpath, "%s/%.8x.0", capath, issuerhash); - - GRSTerrorLog(GRST_LOG_DEBUG, "Look for CA root file %s", cacertpath); - - fp = fopen(cacertpath, "r"); - free(cacertpath); - - if (fp == NULL) chain_errors |= GRST_CERT_BAD_CHAIN; - else - { - cacert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - if (cacert != NULL) - GRSTerrorLog(GRST_LOG_DEBUG, " Loaded CA root cert from file"); - } - - *chain = malloc(sizeof(GRSTx509Chain)); - bzero(*chain, sizeof(GRSTx509Chain)); - - /* Check the client chain */ - for (i = depth - ((subjecthash == issuerhash) ? 1 : 0); - i >= ((lastcert == NULL) ? 0 : -1); - --i) - /* loop through client-presented chain starting at CA end */ - { - GRSTerrorLog(GRST_LOG_DEBUG, "Process cert at depth %d in chain", i); - - prevIsCA=IsCA; - - new_grst_cert = malloc(sizeof(GRSTx509Cert)); - bzero(new_grst_cert, sizeof(GRSTx509Cert)); - new_grst_cert->errors = chain_errors; - - if ((*chain)->firstcert == NULL) - { - GRSTerrorLog(GRST_LOG_DEBUG, "Initialise chain"); - (*chain)->firstcert = new_grst_cert; - } - else grst_cert->next = new_grst_cert; - - grst_cert = new_grst_cert; - - /* Choose X509 certificate and point to it with 'cert' */ - if (i < 0) cert = lastcert; - else if (i == depth) - cert = cacert; /* the self-signed CA from the store*/ - else if ((i == depth - 1) && (subjecthash == issuerhash)) - cert = cacert; /* ie claims to be a copy of a self-signed CA */ - else cert = sk_X509_value(certstack, i); - - if (cert != NULL) - { - if ((i == depth - 1) && (subjecthash != issuerhash)) - { - /* if first cert does not claim to be a self-signed copy - of a CA root cert in the store, we check the signature */ - - ret = X509_check_issued(cacert, cert); - - GRSTerrorLog(GRST_LOG_DEBUG, - "Cert sig check %d returns %d", i, ret); - - if (ret != X509_V_OK) - new_grst_cert->errors |= GRST_CERT_BAD_SIG; - } - else if ((i == depth - 2) && (subjecthash == issuerhash)) - { - /* first cert claimed to be a self-signed copy of a CA root - cert in the store, we check the signature of the second - cert, using OUR copy of the CA cert DIRECT from the store */ - - ret = X509_check_issued(cacert, cert); - - GRSTerrorLog(GRST_LOG_DEBUG, - "Cert sig check %d returns %d", i, ret); - - if (ret != X509_V_OK) - new_grst_cert->errors |= GRST_CERT_BAD_SIG; - } - else if (i < depth - 1) - { - /* otherwise a normal part of the chain: note that if the - first cert claims to be a self-signed copy of a CA root - cert in the store, we never use it for sig checking */ - - ret = X509_check_issued(sk_X509_value(certstack, i + 1), cert); - - GRSTerrorLog(GRST_LOG_DEBUG, - "Cert sig check %d returns %d", i, ret); - - if ((ret != X509_V_OK) && - (ret != X509_V_ERR_KEYUSAGE_NO_CERTSIGN)) - new_grst_cert->errors |= GRST_CERT_BAD_SIG; - - /* NO_CERTSIGN can still be ok due to Proxy Certificates */ - } - - new_grst_cert->serial = (int) ASN1_INTEGER_get( - X509_get_serialNumber(cert)); - new_grst_cert->start = GRSTasn1TimeToTimeT( - ASN1_STRING_data(X509_get_notBefore(cert)), 0); - new_grst_cert->finish = GRSTasn1TimeToTimeT( - ASN1_STRING_data(X509_get_notAfter(cert)), 0); - - /* we check times and record if invalid */ - - if (now < new_grst_cert->start) - new_grst_cert->errors |= GRST_CERT_BAD_TIME; - - if (now > new_grst_cert->finish) - new_grst_cert->errors |= GRST_CERT_BAD_TIME; - - new_grst_cert->dn = X509_NAME_oneline(X509_get_subject_name(cert),NULL,0); - new_grst_cert->issuer = X509_NAME_oneline(X509_get_issuer_name(cert),NULL,0); - len = strlen(new_grst_cert->dn); - len2 = strlen(new_grst_cert->issuer); - - /* always treat a first cert from the CA files as a - CA: this is really for lousy CAs that dont create - proper v3 root certificates */ - - if (i == depth) IsCA == TRUE; - else IsCA = (GRSTx509IsCA(cert) == GRST_RET_OK); - - /* If any forebear certificate is not allowed to sign we must - assume all decendents are proxies and cannot sign either */ - if (prevIsCA) - { - if (IsCA) - { - new_grst_cert->type = GRST_CERT_TYPE_CA; - } - else - { - new_grst_cert->type = GRST_CERT_TYPE_EEC; - first_non_ca = i; - ucuserdn = new_grst_cert->dn; - } - } - else - { - new_grst_cert->type = GRST_CERT_TYPE_PROXY; - IsCA = FALSE; - /* Force proxy check next iteration. Important because I can - sign any CA I create! */ - } - - if (!prevIsCA) - { - /* issuer didn't have CA status, so this is (at best) a proxy: - check for bad proxy extension*/ - - if (prevIsLimited) /* we reject proxies of limited proxies! */ - { - new_grst_cert->errors |= GRST_CERT_BAD_CHAIN; - chain_errors |= GRST_CERT_BAD_CHAIN; - } - - /* User not allowed to sign shortened DN */ - if (len2 > len) - { - new_grst_cert->errors |= GRST_CERT_BAD_CHAIN; - chain_errors |= GRST_CERT_BAD_CHAIN; - } - - /* Proxy subject must begin with issuer. */ - if (strncmp(new_grst_cert->dn, new_grst_cert->issuer, len2) != 0) - { - new_grst_cert->errors |= GRST_CERT_BAD_CHAIN; - chain_errors |= GRST_CERT_BAD_CHAIN; - } - - /* Set pointer to end of base DN in cert_DN */ - proxy_part_DN = &(new_grst_cert->dn[len2]); - - /* First attempt at support for Old and New style GSI - proxies: /CN=anything is ok for now */ - if (strncmp(proxy_part_DN, "/CN=", 4) != 0) - { - new_grst_cert->errors |= GRST_CERT_BAD_CHAIN; - chain_errors |= GRST_CERT_BAD_CHAIN; - } - - if (strncmp(proxy_part_DN, "/CN=limited proxy", 17) == 0) - prevIsLimited = 1; /* ready for next cert ... */ - - for (j=0; j < X509_get_ext_count(cert); ++j) - { - ex = X509_get_ext(cert, j); - OBJ_obj2txt(s,sizeof(s),X509_EXTENSION_get_object(ex),1); - - if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */ - { - GRSTx509ChainVomsAdd(&grst_cert, - new_grst_cert->start, - new_grst_cert->finish, - ex, - ucuserdn, - vomsdir); - } - } - - } - } - - - } /* end of for loop */ - - if (cacert != NULL) X509_free(cacert); - - return GRST_RET_OK; -} - -/// Check certificate chain for GSI proxy acceptability. -/** - * Returns X509_V_OK/GRST_RET_OK if valid; OpenSSL X509 errors otherwise. - * - * Inspired by GSIcheck written by Mike Jones, SVE, Manchester Computing, - * The University of Manchester. - * - * The GridSite version handles old and new style Globus proxies, and - * proxies derived from user certificates issued with "X509v3 Basic - * Constraints: CA:FALSE" (eg UK e-Science CA) - * - * We do not check chain links between certs here: this is done by - * GRST_check_issued/X509_check_issued in mod_ssl's ssl_engine_init.c - * - * TODO: we do not yet check ProxyCertInfo and ProxyCertPolicy extensions - * (although via GRSTx509KnownCriticalExts() we can accept them.) - */ - -int GRSTx509CheckChain(int *first_non_ca, X509_STORE_CTX *ctx) -{ - STACK_OF(X509) *certstack; /* Points to the client's cert chain */ - X509 *cert; /* Points to the client's cert */ - int depth; /* Depth of cert chain */ - size_t len,len2; /* Lengths of issuer and cert DN */ - int IsCA; /* Holds whether cert is allowed to sign */ - int prevIsCA; /* Holds whether previous cert in chain is - allowed to sign */ - int prevIsLimited; /* previous cert was proxy and limited */ - int i,j; /* Iteration variables */ - char *cert_DN; /* Pointer to current-certificate-in-chain's - DN */ - char *issuer_DN; /* Pointer to - issuer-of-current-cert-in-chain's DN */ - char *proxy_part_DN; /* Pointer to end part of current-cert-in-chain - maybe eg "/CN=proxy" */ - time_t now; - - time(&now); - - *first_non_ca = 0; /* set to something predictable if things fail */ - - /* Check for context */ - if (!ctx) return X509_V_ERR_INVALID_CA; - /* Can't GSI-verify if there is no context. Here and throughout this - function we report all errors as X509_V_ERR_INVALID_CA. */ - - /* Set necessary preliminary values */ - IsCA = TRUE; /* =prevIsCA - start from a CA */ - prevIsLimited = 0; - - /* Get the client cert chain */ - certstack = X509_STORE_CTX_get_chain(ctx); /* Get the client's chain */ - depth = sk_X509_num(certstack); /* How deep is that chain? */ - - /* Check the client chain */ - for (i=depth-1; i >= 0; --i) - /* loop through client-presented chain starting at CA end */ - { - prevIsCA=IsCA; - - /* Check for X509 certificate and point to it with 'cert' */ - if (cert = sk_X509_value(certstack, i)) - { - /* we check times and reject immediately if invalid */ - - if (now < - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0)) - return X509_V_ERR_INVALID_CA; - - if (now > - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0)) - return X509_V_ERR_INVALID_CA; - - /* If any forebear certificate is not allowed to sign we must - assume all decendents are proxies and cannot sign either */ - if (prevIsCA) - { - /* always treat the first cert (from the CA files) as a CA */ - if (i == depth-1) IsCA = TRUE; - /* check if this cert is valid CA for signing certs */ - else IsCA = (GRSTx509IsCA(cert) == GRST_RET_OK); - - if (!IsCA) *first_non_ca = i; - } - else - { - IsCA = FALSE; - /* Force proxy check next iteration. Important because I can - sign any CA I create! */ - } - - cert_DN = X509_NAME_oneline(X509_get_subject_name(cert),NULL,0); - issuer_DN = X509_NAME_oneline(X509_get_issuer_name(cert),NULL,0); - len = strlen(cert_DN); - len2 = strlen(issuer_DN); - - /* issuer didn't have CA status, so this is (at best) a proxy: - check for bad proxy extension*/ - - if (!prevIsCA) - { - if (prevIsLimited) /* we reject proxies of limited proxies! */ - return X509_V_ERR_INVALID_CA; - - /* User not allowed to sign shortened DN */ - if (len2 > len) return X509_V_ERR_INVALID_CA; - - /* Proxy subject must begin with issuer. */ - if (strncmp(cert_DN, issuer_DN, len2) != 0) - return X509_V_ERR_INVALID_CA; - - /* Set pointer to end of base DN in cert_DN */ - proxy_part_DN = &cert_DN[len2]; - - /* First attempt at support for Old and New style GSI - proxies: /CN=anything is ok for now */ - if (strncmp(proxy_part_DN, "/CN=", 4) != 0) - return X509_V_ERR_INVALID_CA; - - if ((strncmp(proxy_part_DN, "/CN=limited proxy", 17) == 0) && - (i > 0)) prevIsLimited = 1; /* ready for next cert ... */ - } - } - } - - /* Check cert whose private key is being used by client. If previous in - chain is not allowed to be a CA then need to check this final cert for - valid proxy-icity too */ - if (!prevIsCA) - { - if (prevIsLimited) return X509_V_ERR_INVALID_CA; - /* we do not accept proxies signed by limited proxies */ - - if (cert = sk_X509_value(certstack, 0)) - { - /* Load DN & length of DN and either its issuer or the - first-bad-issuer-in-chain */ - cert_DN = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); - issuer_DN = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); - len = strlen(cert_DN); - len2 = strlen(issuer_DN); - - /* issuer didn't have CA status, check for bad proxy extension */ - - if (len2 > len) return X509_V_ERR_INVALID_CA; - /* User not allowed to sign shortened DN */ - - if (strncmp(cert_DN, issuer_DN, len2) != 0) - return X509_V_ERR_INVALID_CA; - /* Proxy subject must begin with issuer. */ - - proxy_part_DN = &cert_DN[len2]; - /* Set pointer to end of DN base in cert_DN */ - - /* Remander of subject must be either "/CN=proxy" or - "/CN=limited proxy" (or /CN=XYZ for New style GSI) */ - - /* First attempt at support for Old and New style GSI - proxies: /CN=anything is ok for now. */ - if (strncmp(proxy_part_DN, "/CN=", 4) != 0) - return X509_V_ERR_INVALID_CA; - } - } - - return X509_V_OK; /* this is also GRST_RET_OK, of course - by choice */ -} - -/// Example VerifyCallback routine - -/** - * - */ - -int GRSTx509VerifyCallback (int ok, X509_STORE_CTX *ctx) -{ - int errnum = X509_STORE_CTX_get_error(ctx); - int errdepth = X509_STORE_CTX_get_error_depth(ctx); - int first_non_ca; - -#ifndef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#endif - - if (errnum == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) - { - if (GRSTx509KnownCriticalExts(X509_STORE_CTX_get_current_cert(ctx)) - == GRST_RET_OK) - { - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - } - else if ((errdepth == 0) && - (errnum == X509_V_OK) && - (GRSTx509CheckChain(&first_non_ca, ctx) != X509_V_OK)) ok = FALSE; - - - return ok; - -// check this - -// if (ok) return GRST_RET_OK; -// else return GRST_RET_FAILED; -} - -/// Get the VOMS attributes in the given extension -/* - * Puts any VOMS credentials found into the Compact Creds string array - * starting at *creds. Always returns GRST_RET_OK - even for invalid - * credentials, which are just ignored. - */ - -int GRSTx509ParseVomsExt(int *lastcred, int maxcreds, size_t credlen, - char *creds, time_t time1_time, time_t time2_time, - X509_EXTENSION *ex, char *ucuserdn, char *vomsdir) -{ -#define MAXTAG 500 -#define GRST_ASN1_COORDS_FQAN "-1-1-%d-1-7-1-2-1-2-%d" -#define GRST_ASN1_COORDS_USER_DN "-1-1-%d-1-2-1-1-1-1-%%d-1-%%d" -#define GRST_ASN1_COORDS_TIME1 "-1-1-%d-1-6-1" -#define GRST_ASN1_COORDS_TIME2 "-1-1-%d-1-6-2" - ASN1_OCTET_STRING *asn1data; - char *asn1string, acuserdn[200], acvomsdn[200], - dn_coords[200], fqan_coords[200], time1_coords[200], - time2_coords[200]; - long asn1length; - int lasttag=-1, itag, i, acnumber = 1; - struct GRSTasn1TagList taglist[MAXTAG+1]; - time_t actime1, actime2, time_now; - - asn1data = X509_EXTENSION_get_data(ex); - asn1string = ASN1_STRING_data(asn1data); - asn1length = ASN1_STRING_length(asn1data); - - GRSTasn1ParseDump(NULL, asn1string, asn1length, taglist, MAXTAG, &lasttag); - - for (acnumber = 1; ; ++acnumber) /* go through ACs one by one */ - { - snprintf(dn_coords, sizeof(dn_coords), GRST_ASN1_COORDS_USER_DN, acnumber); - if (GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), dn_coords, - asn1string, taglist, lasttag) != GRST_RET_OK) break; - - if (GRSTx509NameCmp(ucuserdn, acuserdn) != 0) continue; - - if (GRSTx509VerifyVomsSig(&time1_time, &time2_time, - asn1string, taglist, lasttag, vomsdir, acnumber) - != GRST_RET_OK) continue; - - snprintf(time1_coords, sizeof(time1_coords), GRST_ASN1_COORDS_TIME1, acnumber); - itag = GRSTasn1SearchTaglist(taglist, lasttag, time1_coords); - actime1 = GRSTasn1TimeToTimeT(&asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - if (actime1 > time1_time) time1_time = actime1; - - snprintf(time2_coords, sizeof(time2_coords), GRST_ASN1_COORDS_TIME2, acnumber); - itag = GRSTasn1SearchTaglist(taglist, lasttag, time2_coords); - actime2 = GRSTasn1TimeToTimeT(&asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - if (actime2 < time2_time) time2_time = actime2; - - time(&time_now); - if ((time1_time > time_now + 300) || (time2_time < time_now)) - continue; /* expiration isnt invalidity ...? */ - - for (i=1; ; ++i) - { - snprintf(fqan_coords, sizeof(fqan_coords), GRST_ASN1_COORDS_FQAN, acnumber, i); - itag = GRSTasn1SearchTaglist(taglist, lasttag, fqan_coords); - - if (itag > -1) - { - if (*lastcred < maxcreds - 1) - { - ++(*lastcred); - snprintf(&creds[*lastcred * (credlen + 1)], credlen+1, - "VOMS %010lu %010lu 0 %.*s", - time1_time, time2_time, - taglist[itag].length, - &asn1string[taglist[itag].start+ - taglist[itag].headerlength]); - } - } - else break; - } - } - - return GRST_RET_OK; -} - -/// Get the VOMS attributes in the extensions to the given cert stack -/* - * Puts any VOMS credentials found into the Compact Creds string array - * starting at *creds. Always returns GRST_RET_OK. - */ - -int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, - char *creds, X509 *usercert, STACK_OF(X509) *certstack, - char *vomsdir) -{ - int i, j; - char s[80]; - unsigned char *ucuser; - X509_EXTENSION *ex; - ASN1_STRING *asn1str; - X509 *cert; - time_t time1_time = 0, time2_time = 0, uctime1_time, uctime2_time; - - uctime1_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(usercert)),0); - uctime2_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)),0); - ucuser = - X509_NAME_oneline(X509_get_subject_name(usercert), NULL, 0); - - for (j=sk_X509_num(certstack)-1; j >= 0; --j) - { - cert = sk_X509_value(certstack, j); - - time1_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0); - uctime1_time = (time1_time > uctime1_time) ? time1_time:uctime1_time; - - time2_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0); - uctime2_time = (time2_time < uctime2_time) ? time2_time:uctime2_time; - - for (i=0; i < X509_get_ext_count(cert); ++i) - { - ex = X509_get_ext(cert, i); - OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); - - if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */ - { - GRSTx509ParseVomsExt(lastcred, maxcreds, credlen, creds, - uctime1_time, uctime2_time, - ex, ucuser, vomsdir); - } - } - } - - return GRST_RET_OK; -} - -/// Turn a Compact Cred line into a GRSTgaclCred object -/** - * Returns pointer to created GRSTgaclCred or NULL or failure. - */ - -GRSTgaclCred *GRSTx509CompactToCred(char *grst_cred) -{ - int delegation; - char *p; - time_t now, notbefore, notafter; - GRSTgaclCred *cred = NULL; - - time(&now); - - if (grst_cred == NULL) return NULL; /* just in case */ - - if (strncmp(grst_cred, "X509USER ", 9) == 0) - { - if ((sscanf(grst_cred, "X509USER %lu %lu %d", - ¬before, ¬after, &delegation) == 3) - && (now >= notbefore) - && (now <= notafter) - && (p = index(grst_cred, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' '))) - { - cred = GRSTgaclCredNew("person"); - GRSTgaclCredSetDelegation(cred, delegation); - GRSTgaclCredAddValue(cred, "dn", &p[1]); - } - - return cred; - } - - if (strncmp(grst_cred, "VOMS ", 5) == 0) - { - if ((sscanf(grst_cred, "VOMS %lu %lu %d", - ¬before, ¬after, &delegation) == 3) - && (now >= notbefore) - && (now <= notafter) - && (p = index(grst_cred, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' '))) - { - /* include /VO/group/subgroup/Role=role/Capability=cap */ - - if (p[1] != '/') return NULL; /* must begin with / */ - - cred = GRSTgaclCredNew("voms"); - GRSTgaclCredSetDelegation(cred, delegation); - GRSTgaclCredAddValue(cred, "fqan", &p[1]); - } - - return cred; - } - - return NULL; /* dont recognise this credential type */ -} - -/// Get the credentials in an X509 cert/GSI proxy, including any VOMS -/** - * Credentials are placed in Compact Creds string array at *creds. - * - * Function returns GRST_RET_OK on success, or GRST_RET_FAILED if - * some inconsistency found in certificate. - */ - -int GRSTx509CompactCreds(int *lastcred, int maxcreds, size_t credlen, - char *creds, STACK_OF(X509) *certstack, char *vomsdir, - X509 *peercert) -{ - int i, j, delegation = 0; - char credtemp[credlen+1]; - X509 *cert, *usercert = NULL, *gsiproxycert = NULL; - - *lastcred = -1; - - for (i = sk_X509_num(certstack) - 1; i >= 0; --i) - { - cert = sk_X509_value(certstack, i); - - if (usercert != NULL) - { /* found a (GSI proxy) cert after the user cert */ - gsiproxycert = cert; - ++delegation; - } - - if ((usercert == NULL) && - (i < sk_X509_num(certstack) - 1) && - (GRSTx509IsCA(cert) != GRST_RET_OK)) usercert = cert; - /* found the 1st non-CA cert */ - } - - if (peercert != NULL) - { - if (usercert != NULL) /* found a (GSI proxy) cert after user cert */ - { - gsiproxycert = peercert; - ++delegation; - } - - if ((usercert == NULL) && - (GRSTx509IsCA(peercert) != GRST_RET_OK)) usercert = peercert; - /* found the 1st non-CA cert */ - } - - if ((usercert == NULL) /* if no usercert ("EEC"), we're not interested */ - || - (snprintf(credtemp, credlen+1, "X509USER %010lu %010lu %d %s", - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(usercert)),0), - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)),0), - delegation, - X509_NAME_oneline(X509_get_subject_name(usercert), NULL, 0)) >= credlen+1) - || - (*lastcred >= maxcreds-1)) - { - *lastcred = -1; /* just in case the caller looks at it */ - return GRST_RET_FAILED; /* tell caller that things didn't work out */ - } - - ++(*lastcred); - strcpy(&creds[*lastcred * (credlen + 1)], credtemp); - - if ((gsiproxycert != NULL) - && - (snprintf(credtemp, credlen+1, "GSIPROXY %010lu %010lu %d %s", - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(gsiproxycert)),0), - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(gsiproxycert)),0), - delegation, - X509_NAME_oneline(X509_get_subject_name(gsiproxycert), NULL, 0)) < credlen+1) - && - (*lastcred < maxcreds-1)) - { - ++(*lastcred); - strcpy(&creds[*lastcred * (credlen + 1)], credtemp); - - GRSTx509GetVomsCreds(lastcred, maxcreds, credlen, creds, - usercert, certstack, vomsdir); - - } - - return GRST_RET_OK; -} - -/// Find proxy file name of the current user -/** - * Return a string with the proxy file name or NULL if not present. - * This function does not check if the proxy has expired. - */ - -char *GRSTx509FindProxyFileName(void) -{ - char *p; - - p = getenv("X509_USER_PROXY"); - - if (p != NULL) return strdup(p); - - p = malloc(sizeof("/tmp/x509up_uXYYYXXXYYY")); - - sprintf(p, "/tmp/x509up_u%d", getuid()); - - return p; -} - -static void mpcerror(FILE *debugfp, char *msg) -{ - if (debugfp != NULL) - { - fputs(msg, debugfp); - ERR_print_errors_fp(debugfp); - } -} - -/// Make a GSI Proxy chain from a request, certificate and private key -/** - * The proxy chain is returned in *proxychain. If debugfp is non-NULL, - * errors are output to that file pointer. The proxy will expired in - * the given number of minutes starting from the current time. - */ - -int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, - char *reqtxt, char *cert, char *key, int minutes) -{ - char *ptr, *certchain; - int i, subjAltName_pos, ncerts; - long serial = 2796, ptrlen; - EVP_PKEY *pkey, *CApkey; - const EVP_MD *digest; - X509 *certs[GRST_MAX_CHAIN_LEN]; - X509_REQ *req; - X509_NAME *name, *CAsubject, *newsubject; - X509_NAME_ENTRY *ent; - X509V3_CTX ctx; - X509_EXTENSION *subjAltName; - STACK_OF (X509_EXTENSION) * req_exts; - FILE *fp; - BIO *reqmem, *certmem; - time_t notAfter; - - /* read in the request */ - reqmem = BIO_new(BIO_s_mem()); - BIO_puts(reqmem, reqtxt); - - if (!(req = PEM_read_bio_X509_REQ(reqmem, NULL, NULL, NULL))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading request from BIO memory\n"); - BIO_free(reqmem); - return GRST_RET_FAILED; - } - - BIO_free(reqmem); - - /* verify signature on the request */ - if (!(pkey = X509_REQ_get_pubkey (req))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting public key from request\n"); - return GRST_RET_FAILED; - } - - if (X509_REQ_verify(req, pkey) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error verifying signature on certificate\n"); - return GRST_RET_FAILED; - } - - /* read in the signing certificate */ - if (!(fp = fopen(cert, "r"))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error opening signing certificate file\n"); - return GRST_RET_FAILED; - } - - for (ncerts = 1; ncerts < GRST_MAX_CHAIN_LEN; ++ncerts) - if (!(certs[ncerts] = PEM_read_X509(fp, NULL, NULL, NULL))) break; - - if (ncerts == 1) /* zeroth cert with be new proxy cert */ - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing certificate file\n"); - return GRST_RET_FAILED; - } - - fclose(fp); - - CAsubject = X509_get_subject_name(certs[1]); - - /* read in the CA private key */ - if (!(fp = fopen(key, "r"))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing private key file\n"); - return GRST_RET_FAILED; - } - - if (!(CApkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing private key in file\n"); - return GRST_RET_FAILED; - } - - fclose(fp); - - /* get subject name */ - if (!(name = X509_REQ_get_subject_name (req))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting subject name from request\n"); - return GRST_RET_FAILED; - } - - /* create new certificate */ - if (!(certs[0] = X509_new ())) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error creating X509 object\n"); - return GRST_RET_FAILED; - } - - /* set version number for the certificate (X509v3) and the serial number - need 3 = v4 for GSI proxy?? */ - if (X509_set_version (certs[0], 3L) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting certificate version\n"); - return GRST_RET_FAILED; - } - - ASN1_INTEGER_set (X509_get_serialNumber (certs[0]), serial++); - - if (!(name = X509_get_subject_name(certs[1]))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting subject name from CA certificate\n"); - return GRST_RET_FAILED; - } - - if (X509_set_issuer_name (certs[0], name) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting issuer name of certificate\n"); - return GRST_RET_FAILED; - } - - /* set issuer and subject name of the cert from the req and the CA */ - ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("commonName"), - MBSTRING_ASC, "proxy", -1); - - newsubject = X509_NAME_dup(CAsubject); - - X509_NAME_add_entry(newsubject, ent, -1, 0); - - if (X509_set_subject_name(certs[0], newsubject) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting subject name of certificate\n"); - return GRST_RET_FAILED; - } - - /* set public key in the certificate */ - if (X509_set_pubkey(certs[0], pkey) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting public key of the certificate\n"); - return GRST_RET_FAILED; - } - - /* set duration for the certificate */ - if (!(X509_gmtime_adj (X509_get_notBefore(certs[0]), -GRST_BACKDATE_SECONDS))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting beginning time of the certificate\n"); - return GRST_RET_FAILED; - } - - if (!(X509_gmtime_adj (X509_get_notAfter(certs[0]), 60 * minutes))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting ending time of the certificate\n"); - return GRST_RET_FAILED; - } - - /* go through chain making sure this proxy is not longer lived */ - - notAfter = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[0])), 0); - - for (i=1; i < ncerts; ++i) - if (notAfter > - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), - 0)) - { - notAfter = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), - 0); - - ASN1_UTCTIME_set(X509_get_notAfter(certs[0]), notAfter); - } - - /* sign the certificate with the signing private key */ - if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_RSA) - digest = EVP_md5(); - else - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error checking signing private key for a valid digest\n"); - return GRST_RET_FAILED; - } - - if (!(X509_sign (certs[0], CApkey, digest))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error signing certificate\n"); - return GRST_RET_FAILED; - } - - /* store the completed certificate chain */ - - certchain = strdup(""); - - for (i=0; i < ncerts; ++i) - { - certmem = BIO_new(BIO_s_mem()); - - if (PEM_write_bio_X509(certmem, certs[i]) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error writing certificate to memory BIO\n"); - return GRST_RET_FAILED; - } - - ptrlen = BIO_get_mem_data(certmem, &ptr); - - certchain = realloc(certchain, strlen(certchain) + ptrlen + 1); - - strncat(certchain, ptr, ptrlen); - - BIO_free(certmem); - } - - *proxychain = certchain; - - return GRST_RET_OK; -} - -/// Find a proxy file in the proxy cache -/** - * Returns the full path and file name of proxy file associated - * with given delegation ID and user DN. - */ - -char *GRSTx509CachedProxyFind(char *proxydir, char *delegation_id, - char *user_dn) -/* - Return a pointer to a malloc'd string with the full path of the - proxy file corresponding to the given delegation_id, or NULL - if not found. -*/ -{ - char *user_dn_enc, *proxyfile; - struct stat statbuf; - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - asprintf(&proxyfile, "%s/%s/%s/userproxy.pem", - proxydir, user_dn_enc, delegation_id); - - free(user_dn_enc); - - if ((stat(proxyfile, &statbuf) != 0) || !S_ISREG(statbuf.st_mode)) - { - free(proxyfile); - return NULL; - } - - return proxyfile; -} - -/// Find a temporary proxy private key file in the proxy cache -/** - * Returns the full path and file name of the private key file associated - * with given delegation ID and user DN. - */ - -char *GRSTx509CachedProxyKeyFind(char *proxydir, char *delegation_id, - char *user_dn) -/* - Return a pointer to a malloc'd string with the full path of the - private proxy key corresponding to the given delegation_id, or NULL - if not found. -*/ -{ - char *user_dn_enc, *prvkeyfile; - struct stat statbuf; - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - asprintf(&prvkeyfile, "%s/cache/%s/%s/userkey.pem", - proxydir, user_dn_enc, delegation_id); - - free(user_dn_enc); - - if ((stat(prvkeyfile, &statbuf) != 0) || !S_ISREG(statbuf.st_mode)) - { - free(prvkeyfile); - return NULL; - } - - return prvkeyfile; -} - -static void mkdir_printf(mode_t mode, char *fmt, ...) -{ - int ret; - char *path; - va_list ap; - - va_start(ap, fmt); - vasprintf(&path, fmt, ap); - va_end(ap); - - ret = mkdir(path, mode); - - free(path); -} - -/// Create a X.509 request for a GSI proxy and its private key -/** - * Returns GRST_RET_OK on success, non-zero otherwise. Request string - * and private key are PEM encoded strings - */ - -int GRSTx509CreateProxyRequest(char **reqtxt, char **keytxt, char *ocspurl) -{ - int i; - char *ptr; - size_t ptrlen; - RSA *keypair; - X509_NAME *subject; - X509_NAME_ENTRY *ent; - EVP_PKEY *pkey; - X509_REQ *certreq; - BIO *reqmem, *keymem; - const EVP_MD *digest; - struct stat statbuf; - - /* create key pair and put it in a PEM string */ - - if ((keypair = RSA_generate_key(GRST_KEYSIZE, 65537, NULL, NULL)) == NULL) - return 1; - - keymem = BIO_new(BIO_s_mem()); - if (!PEM_write_bio_RSAPrivateKey(keymem, keypair, NULL, NULL, 0, NULL, NULL)) - { - BIO_free(keymem); - return 3; - } - - ptrlen = BIO_get_mem_data(keymem, &ptr); - - *keytxt = malloc(ptrlen + 1); - memcpy(*keytxt, ptr, ptrlen); - (*keytxt)[ptrlen] = '\0'; - - BIO_free(keymem); - - /* now create the certificate request */ - - certreq = X509_REQ_new(); - - OpenSSL_add_all_algorithms(); - - pkey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(pkey, keypair); - - X509_REQ_set_pubkey(certreq, pkey); - - subject = X509_NAME_new(); - ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("organizationName"), - MBSTRING_ASC, "Dummy", -1); - X509_NAME_add_entry (subject, ent, -1, 0); - X509_REQ_set_subject_name (certreq, subject); - - digest = EVP_md5(); - X509_REQ_sign(certreq, pkey, digest); - - reqmem = BIO_new(BIO_s_mem()); - PEM_write_bio_X509_REQ(reqmem, certreq); - ptrlen = BIO_get_mem_data(reqmem, &ptr); - - *reqtxt = malloc(ptrlen + 1); - memcpy(*reqtxt, ptr, ptrlen); - (*reqtxt)[ptrlen] = '\0'; - - BIO_free(reqmem); - - X509_REQ_free(certreq); - - return 0; -} - -/// Make and store a X.509 request for a GSI proxy -/** - * Returns GRST_RET_OK on success, non-zero otherwise. Request string - * is PEM encoded, and the key is stored in the temporary cache under - * proxydir - */ - -int GRSTx509MakeProxyRequest(char **reqtxt, char *proxydir, - char *delegation_id, char *user_dn) -{ - int i; - char *docroot, *prvkeyfile, *ptr, *user_dn_enc; - size_t ptrlen; - FILE *fp; - RSA *keypair; - X509_NAME *subject; - X509_NAME_ENTRY *ent; - EVP_PKEY *pkey; - X509_REQ *certreq; - BIO *reqmem; - const EVP_MD *digest; - struct stat statbuf; - - if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - /* create directories if necessary */ - - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/cache", proxydir); - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/cache/%s", proxydir, user_dn_enc); - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/cache/%s/%s", proxydir, user_dn_enc, delegation_id); - - /* make the new proxy private key */ - - asprintf(&prvkeyfile, "%s/cache/%s/%s/userkey.pem", - proxydir, user_dn_enc, delegation_id); - - if (prvkeyfile == NULL) - { - free(user_dn_enc); - return GRST_RET_FAILED; - } - - if ((keypair = RSA_generate_key(GRST_KEYSIZE, 65537, NULL, NULL)) == NULL) - return 1; - - if ((fp = fopen(prvkeyfile, "w")) == NULL) return 2; - - chmod(prvkeyfile, S_IRUSR | S_IWUSR); - free(prvkeyfile); - free(user_dn_enc); - - if (!PEM_write_RSAPrivateKey(fp, keypair, NULL, NULL, 0, NULL, NULL)) - return 3; - - if (fclose(fp) != 0) return 4; - - /* now create the certificate request */ - - certreq = X509_REQ_new(); - if (certreq == NULL) return 5; - - OpenSSL_add_all_algorithms(); - - pkey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(pkey, keypair); - - X509_REQ_set_pubkey(certreq, pkey); - - subject = X509_NAME_new(); - ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("organizationName"), - MBSTRING_ASC, "Dummy", -1); - X509_NAME_add_entry (subject, ent, -1, 0); - X509_REQ_set_subject_name (certreq, subject); - - digest = EVP_md5(); - X509_REQ_sign(certreq, pkey, digest); - - reqmem = BIO_new(BIO_s_mem()); - PEM_write_bio_X509_REQ(reqmem, certreq); - ptrlen = BIO_get_mem_data(reqmem, &ptr); - - *reqtxt = malloc(ptrlen + 1); - memcpy(*reqtxt, ptr, ptrlen); - (*reqtxt)[ptrlen] = '\0'; - - BIO_free(reqmem); - - X509_REQ_free(certreq); - - return 0; -} - -/// Destroy stored GSI proxy files -/** - * Returns GRST_RET_OK on success, non-zero otherwise. - * (Including GRST_RET_NO_SUCH_FILE if the private key or cert chain - * were not found.) - */ - -int GRSTx509ProxyDestroy(char *proxydir, char *delegation_id, char *user_dn) -{ - int ret = GRST_RET_OK; - char *docroot, *filename, *user_dn_enc; - - if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - /* proxy file */ - - asprintf(&filename, "%s/%s/%s/userproxy.pem", - proxydir, user_dn_enc, delegation_id); - - if (filename == NULL) - { - free(user_dn_enc); - return GRST_RET_FAILED; - } - - if (unlink(filename) != 0) ret = GRST_RET_NO_SUCH_FILE; - free(filename); - - /* voms file */ - - asprintf(&filename, "%s/%s/%s/voms.attributes", - proxydir, user_dn_enc, delegation_id); - - if (filename == NULL) - { - free(user_dn_enc); - return GRST_RET_FAILED; - } - - unlink(filename); - free(filename); - - return ret; -} - -/// Get start and finish validity times of stored GSI proxy file -/** - * Returns GRST_RET_OK on success, non-zero otherwise. - * (Including GRST_RET_NO_SUCH_FILE if the cert chain was not found.) - */ - -int GRSTx509ProxyGetTimes(char *proxydir, char *delegation_id, char *user_dn, - time_t *start, time_t *finish) -{ - char *docroot, *filename, *user_dn_enc; - FILE *fp; - X509 *cert; - - if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - asprintf(&filename, "%s/%s/%s/userproxy.pem", - proxydir, user_dn_enc, delegation_id); - - free(user_dn_enc); - - if (filename == NULL) return GRST_RET_FAILED; - - fp = fopen(filename, "r"); - free(filename); - - if (fp == NULL) return GRST_RET_NO_SUCH_FILE; - - cert = PEM_read_X509(fp, NULL, NULL, NULL); /* first cert is X.509 PC */ - - fclose(fp); - - *start = GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0); - *finish = GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0); - - X509_free(cert); - - return GRST_RET_OK; -} - -/// Create a stack of X509 certificate from a PEM-encoded string -/** - * Creates a dynamically allocated stack of X509 certificate objects - * by walking through the PEM-encoded X509 certificates. - * - * Returns GRST_RET_OK on success, non-zero otherwise. - * - */ - -int GRSTx509StringToChain(STACK_OF(X509) **certstack, char *certstring) -{ - STACK_OF(X509_INFO) *sk=NULL; - BIO *certbio; - X509_INFO *xi; - - *certstack = sk_X509_new_null(); - if (*certstack == NULL) return GRST_RET_FAILED; - - certbio = BIO_new_mem_buf(certstring, -1); - - if (!(sk=PEM_X509_INFO_read_bio(certbio, NULL, NULL, NULL))) - { - BIO_free(certbio); - sk_X509_INFO_free(sk); - sk_X509_free(*certstack); - return GRST_RET_FAILED; - } - - while (sk_X509_INFO_num(sk)) - { - xi=sk_X509_INFO_shift(sk); - if (xi->x509 != NULL) - { - sk_X509_push(*certstack, xi->x509); - xi->x509=NULL; - } - X509_INFO_free(xi); - } - - if (!sk_X509_num(*certstack)) - { - BIO_free(certbio); - sk_X509_INFO_free(sk); - sk_X509_free(*certstack); - return GRST_RET_FAILED; - } - - BIO_free(certbio); - sk_X509_INFO_free(sk); - - return GRST_RET_OK; -} - -/// Returns a Delegation ID based on hash of GRST_CRED_0, ... -/** - * Returns a malloc'd string with Delegation ID made by SHA1-hashing the - * values of the compact credentials exported by mod_gridsite - */ - -char *GRSTx509MakeDelegationID(void) -{ - unsigned char hash_delegation_id[EVP_MAX_MD_SIZE]; - int size_needed = 0, i, delegation_id_len; - char cred_name[14], *cred_value, *delegation_id; - const EVP_MD *m; - EVP_MD_CTX ctx; - - OpenSSL_add_all_digests(); - - m = EVP_sha1(); - if (m == NULL) return NULL; - - EVP_DigestInit(&ctx, m); - - for (i=0; i <= 999; ++i) - { - snprintf(cred_name, sizeof(cred_name), "GRST_CRED_%d", i); - if ((cred_value = getenv(cred_name)) == NULL) break; - - EVP_DigestUpdate(&ctx, cred_value, strlen(cred_value)); - } - - EVP_DigestFinal(&ctx, hash_delegation_id, &delegation_id_len); - - delegation_id = malloc(17); - - for (i=0; i <=7; ++i) - sprintf(&delegation_id[i*2], "%02x", hash_delegation_id[i]); - - delegation_id[16] = '\0'; - - return delegation_id; -} - -#if 0 -/// Return the short file name for the given delegation_id and user_dn -/** - * Returns a malloc'd string with the short file name (no paths) that - * derived from the hashed delegation_id and user_dn - * - * File name is SHA1_HASH(DelegationID)+"-"+SHA1_HASH(DN) where DN - * is DER encoded version of user_dn with any trailing CN=proxy removed - * Hashes are the most significant 8 bytes, in lowercase hexadecimal. - */ - -char *GRSTx509MakeProxyFileName(char *delegation_id, - STACK_OF(X509) *certstack) -{ - int i, depth, prevIsCA = 1, IsCA, hash_name_len, delegation_id_len, - der_name_len; - unsigned char *der_name, *buf, hash_name[EVP_MAX_MD_SIZE], - hash_delegation_id[EVP_MAX_MD_SIZE], - filename[34]; - X509_NAME *subject_name; - X509 *cert; - const EVP_MD *m; - EVP_MD_CTX ctx; - - depth = sk_X509_num(certstack); - - for (i=depth-1; i >= 0; --i) - /* loop through the proxy chain starting at CA end */ - { - if (cert = sk_X509_value(certstack, i)) - { - IsCA = (GRSTx509IsCA(cert) == GRST_RET_OK); - - if (prevIsCA && !IsCA) /* the full certificate of the user */ - { - break; - } - } - } - - if (i < 0) return NULL; /* not found: something wrong with the chain */ - - if ((subject_name = X509_get_subject_name(cert)) == NULL) return NULL; - - der_name_len = i2d_X509_NAME(X509_get_subject_name(cert), NULL); - if (der_name_len == 0) return NULL; - - buf = OPENSSL_malloc(der_name_len); - der_name = buf; - - - if (!i2d_X509_NAME(X509_get_subject_name(cert), &der_name)) - { - OPENSSL_free(der_name); - return NULL; - } - - OpenSSL_add_all_digests(); - - m = EVP_sha1(); - if (m == NULL) - { - OPENSSL_free(der_name); - return NULL; - } - - - EVP_DigestInit(&ctx, m); - EVP_DigestUpdate(&ctx, delegation_id, strlen(delegation_id)); - EVP_DigestFinal(&ctx, hash_delegation_id, &delegation_id_len); - - /* lots of nasty hard coded numbers: - "8bytes/16chars delegation ID" + "-" + "8bytes/16chars DN" */ - - for (i=0; i <=7; ++i) - sprintf(&filename[i*2], "%02x", hash_delegation_id[i]); - - filename[16] = '-'; - - EVP_DigestInit(&ctx, m); - EVP_DigestUpdate(&ctx, buf, der_name_len); - EVP_DigestFinal(&ctx, hash_name, &hash_name_len); - - for (i=0; i <=7; ++i) - sprintf(&filename[17 + i*2], "%02x", hash_name[i]); - - return strdup(filename); -} -#endif - -/// Store a GSI proxy chain in the proxy cache, along with the private key -/** - * Returns GRST_RET_OK on success, non-zero otherwise. The existing - * private key with the same delegation ID and user DN is moved out of - * the temporary cache. - */ - -int GRSTx509CacheProxy(char *proxydir, char *delegation_id, - char *user_dn, char *proxychain) -{ - int c, len = 0, i, ret; - char *user_dn_enc, *p, *ptr, *prvkeyfile, *proxyfile; - STACK_OF(X509) *certstack; - BIO *certmem; - X509 *cert; - long ptrlen; - FILE *ifp, *ofp; - - if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; - - /* find the existing private key file */ - - prvkeyfile = GRSTx509CachedProxyKeyFind(proxydir, delegation_id, user_dn); - - if (prvkeyfile == NULL) - { - return GRST_RET_FAILED; - } - - /* open it ready for later */ - - if ((ifp = fopen(prvkeyfile, "r")) == NULL) - { - free(prvkeyfile); - return GRST_RET_FAILED; - } - - /* get the X509 stack */ - - if (GRSTx509StringToChain(&certstack, proxychain) != GRST_RET_OK) - { - fclose(ifp); - free(prvkeyfile); - return GRST_RET_FAILED; - } - - /* create directories if necessary, and set proxy filename */ - - user_dn_enc = GRSThttpUrlEncode(user_dn); - - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/%s", proxydir, user_dn_enc); - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/%s/%s", proxydir, user_dn_enc, delegation_id); - - asprintf(&proxyfile, "%s/%s/%s/userproxy.pem", - proxydir, user_dn_enc, delegation_id); - - free(user_dn_enc); - - /* set up to write proxy file */ - - ofp = fopen(proxyfile, "w"); - chmod(proxyfile, S_IRUSR | S_IWUSR); - free(proxyfile); - - if (ofp == NULL) - { - fclose(ifp); - free(prvkeyfile); - return GRST_RET_FAILED; - } - - /* write out the most recent proxy by itself */ - - if (cert = sk_X509_value(certstack, 0)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, ofp); - } - - BIO_free(certmem); - } - - /* insert proxy private key, read from private key file */ - - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - unlink(prvkeyfile); - free(prvkeyfile); - - for (i=1; i <= sk_X509_num(certstack) - 1; ++i) - /* loop through the proxy chain starting at 2nd most recent proxy */ - { - if (cert = sk_X509_value(certstack, i)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, ofp); - } - - BIO_free(certmem); - } - } - - sk_X509_free(certstack); - - if (fclose(ifp) != 0) return GRST_RET_FAILED; - if (fclose(ofp) != 0) return GRST_RET_FAILED; - - return GRST_RET_OK; -} diff --git a/org.gridsite.core/src/grst_xacml.c b/org.gridsite.core/src/grst_xacml.c deleted file mode 100644 index c4c88ee..0000000 --- a/org.gridsite.core/src/grst_xacml.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - Andrew McNab and Shiv Kaushal, University of Manchester. - Copyright (c) 2002-3. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ -/*------------------------------------------------------------------------* - * For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include - -#include -#include -#include - -#include "gridsite.h" - -//#define XACML_DEBUG - -#ifdef XACML_DEBUG - #define XACML_DEBUG_FILE "/tmp/grstxacmldebug.out" -#endif - - -/* * - * Global variables, shared by all GACL functions by private to libgacl * - * */ - -extern char *grst_perm_syms[]; -extern GRSTgaclPerm grst_perm_vals[]; - - -FILE* debugfile; - -GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *); -GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *); - -/* * - * Functions to read in XACML 1.1 compliant format ACL * - * Functions based on method for opening GACL format * - * */ - -// need to check these for libxml memory leaks? - what needs to be freed? - - -static GRSTgaclCred *GRSTxacmlCredParse(xmlNodePtr cur) -/* - GRSTxacmlCredParse - parse a credential stored in the libxml structure cur, - returning it as a pointer or NULL on error. -*/ -{ - xmlNodePtr attr_val; - xmlNodePtr attr_des; - GRSTgaclCred *cred; - - // cur points to or , loop done outside this function. - - if ( (xmlStrcmp(cur->name, (const xmlChar *) "AnySubject") == 0)) cred = GRSTgaclCredNew("any-user"); - - else{ - - attr_val=cur->xmlChildrenNode->xmlChildrenNode; - attr_des=attr_val->next; - - cred = GRSTgaclCredNew((char *) xmlNodeGetContent(attr_des->properties->children)); - - cred->firstname = NULL; - cred->next = NULL; - - //Assumed that there is only one name/value pair per credential - GRSTgaclCredAddValue(cred, (char *) xmlNodeGetContent(attr_des->properties->next->children), - (char *) xmlNodeGetContent(attr_val)); - } - - return cred; -} - -static GRSTgaclEntry *GRSTxacmlEntryParse(xmlNodePtr cur) -/* - GRSTxacmlEntryParse - parse an entry stored in the libxml structure cur, - returning it as a pointer or NULL on error. Also checks to see if the following - tag refers to the same by checking the of both -*/ -{ - int i, check=0; - xmlDocPtr doc=cur->doc; - xmlNodePtr cur2; - xmlNodePtr rule_root=cur; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclPerm perm; - - - // Next line not needed as function only called if tag found - // if (xmlStrcmp(cur->name, (const xmlChar *) "Rule") != 0) return NULL; - // cur and rule_root point to the tag - - cur = cur->xmlChildrenNode->xmlChildrenNode; - // cur should now be pointing at tag -#ifdef XACML_DEBUG - fprintf (debugfile, "Starting to Parse Entry\n"); -#endif - entry = GRSTgaclEntryNew(); - - while (cur!=NULL){ - - if (xmlStrcmp(cur->name, (const xmlChar *) "Subjects") == 0){ -#ifdef XACML_DEBUG - fprintf (debugfile, "Starting to Parse Credentials\n"); -#endif - if (check==0){ - // cur still pointing at tag make cur2 point to and loop over them. - cur2=cur->xmlChildrenNode; - while (cur2!=NULL){ - if ( ((cred = GRSTxacmlCredParse(cur2)) != NULL) && (!GRSTgaclEntryAddCred(entry, cred))){ - GRSTgaclCredFree(cred); - GRSTgaclEntryFree(entry); - return NULL; - } - cur2=cur2->next; - } - } - } - - else if (xmlStrcmp(cur->name, (const xmlChar *) "Actions") == 0){ -#ifdef XACML_DEBUG - fprintf (debugfile, "Starting to Parse Permissions\n"); -#endif - if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Permit") == 0 ){ -#ifdef XACML_DEBUG - fprintf (debugfile, "\tPermit-ed actions: "); -#endif - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) //cur2-> - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0) - { -#ifdef XACML_DEBUG - fprintf (debugfile, "%s ", grst_perm_syms[i]); -#endif - GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); - } - } - - if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Deny") == 0 ) { -#ifdef XACML_DEBUG - fprintf (debugfile, "\tDeny-ed actions: "); -#endif - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) //cur2-> - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0) - { - -#ifdef XACML_DEBUG - fprintf (debugfile, "%s ", grst_perm_syms[i]); -#endif - GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); - } - } - - } - else{ // I cannot parse this - give up rather than get it wrong -#ifdef XACML_DEBUG - fprintf (debugfile, "OOOPSIE\n"); -#endif - GRSTgaclEntryFree(entry); - return NULL; - } - - cur=cur->next; - - // Check if next Rule should be included when end of current rule reached - // If RuleId are from the same entry (eg Entry1A and Entry1D) - // make cur point to the next Rule's tag - if (cur==NULL) - if (check==0) - if (rule_root->next!=NULL) - if ( strncmp(xmlNodeGetContent(rule_root->properties->children), // RuleId of this Rule - xmlNodeGetContent(rule_root->next->properties->children), // RuleId of next Rule - 6) == 0){ -#ifdef XACML_DEBUG - fprintf (debugfile, "End of perms and creds, next is %s \n", xmlNodeGetContent(rule_root->next->properties->children)); -#endif - rule_root=rule_root->next; - cur=rule_root->xmlChildrenNode->xmlChildrenNode; -#ifdef XACML_DEBUG - fprintf (debugfile, "skipped to <%s> tag of next Rule\n", cur->name); -#endif - check++; - } - } - - return entry; -} - -GRSTgaclAcl *GRSTxacmlAclLoadFile(char *filename) -{ - xmlDocPtr doc; - xmlNodePtr cur; - GRSTgaclAcl *acl; - - doc = xmlParseFile(filename); - if (doc == NULL) return NULL; - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) return NULL; - - if (!xmlStrcmp(cur->name, (const xmlChar *) "Policy")) { acl=GRSTxacmlAclParse(doc, cur, acl);} - else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl")) {acl=GRSTgaclAclParse(doc, cur, acl);} - else /* ACL format not recognised */ - { - xmlFreeDoc(doc); - free(cur); - return NULL; - } - - xmlFreeDoc(doc); - return acl; -} - -GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl) -{ - GRSTgaclEntry *entry; - - #ifdef XACML_DEBUG - debugfile=fopen(XACML_DEBUG_FILE, "w"); - fprintf (debugfile, "ACL loaded..\n"); - fprintf (debugfile, "Parsing XACML\n"); - #endif - - // Have an XACML policy file. - // Skip tag and set cur to first tag - cur = cur->xmlChildrenNode->next; - - acl = GRSTgaclAclNew(); - - while (cur != NULL){ - - if ( !xmlStrcmp(cur->name, (const xmlChar *)"Rule") ) - { // IF statement not needed? - #ifdef XACML_DEBUG - fprintf (debugfile, "Rule %s found\n", xmlNodeGetContent(cur->properties->children) ); - fprintf (debugfile, "Parsing Entry for this rule\n"); - #endif - entry = GRSTxacmlEntryParse(cur); - - if (entry == NULL) - { - GRSTgaclAclFree(acl); - return NULL; - } - else GRSTgaclAclAddEntry(acl, entry); - - #ifdef XACML_DEBUG - fprintf (debugfile, "Entry read in\n\n"); - #endif - } - - // If the current and next Rules are part of the same entry then advance two Rules - // If not then advance 1 - if (cur->next != NULL) - { - if ( strncmp(xmlNodeGetContent(cur->properties->children), // RuleId of this Rule - xmlNodeGetContent(cur->next->properties->children), // RuleId of next Rule - 6) == 0) - { - #ifdef XACML_DEBUG - fprintf (debugfile, "skipping next rule %s, should have been caught previously\n\n", xmlNodeGetContent(cur->next->properties->children) ); - #endif - cur=cur->next; - } // Check first 6 characters i.e. Entry1**/ - } - - cur=cur->next; - - } - - #ifdef XACML_DEBUG - fprintf (debugfile, "Finished loading ACL - Fanfare!\n"); - fclose(debugfile); - #endif - - return acl; -} - - -int GRSTxacmlFileIsAcl(char *pathandfile) -/* Return 1 if filename in *pathandfile starts GRST_ACL_FILE - Return 0 otherwise. */ -{ - char *filename; - - filename = rindex(pathandfile, '/'); - if (filename == NULL) filename = pathandfile; - else filename++; - - return (strncmp(filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0); -} - -char *GRSTxacmlFileFindAclname(char *pathandfile) -/* Return malloc()ed ACL filename that governs the given file or directory - (for directories, the ACL file is in the directory itself), or NULL if none - can be found. */ -{ - char *path, *p; - struct stat statbuf; - - path = malloc(strlen(pathandfile) + sizeof(GRST_ACL_FILE) + 1); - strcpy(path, pathandfile); - - if (stat(path, &statbuf) == 0) - { - if (!S_ISDIR(statbuf.st_mode)) /* can strip this / off straightaway */ - { - p = rindex(path, '/'); - if (p != NULL) *p = '\0'; - } - } - - while (path[0] != '\0') - { - strcat(path, "/"); - strcat(path, GRST_ACL_FILE); - - if (stat(path, &statbuf) == 0) return path; - - p = rindex(path, '/'); - *p = '\0'; /* strip off the / we added for ACL */ - - p = rindex(path, '/'); - if (p == NULL) break; /* must start without / and we there now ??? */ - - *p = '\0'; /* strip off another layer of / */ - } - - free(path); - return NULL; -} - -GRSTgaclAcl *GRSTxacmlAclLoadforFile(char *pathandfile) -/* Return ACL that governs the given file or directory (for directories, - the ACL file is in the directory itself.) */ -{ - char *path; - GRSTgaclAcl *acl; - - path = GRSTxacmlFileFindAclname(pathandfile); - - if (path != NULL) - { - acl = GRSTxacmlAclLoadFile(path); - free(path); - return acl; - } - - return NULL; -} - - - -/* * - * Functions to save ACL in XACML 1.1 compliant format * - * Functions based on method for saving to GACL format * - * */ - - -int GRSTxacmlCredPrint(GRSTgaclCred *cred, FILE *fp) -/* - GRSTxacmlCredPrint - print a credential and any name-value pairs is contains in XACML form -*/ -{ - char *q; - GRSTgaclNamevalue *p; - - if (cred->firstname != NULL) - { - - p = cred->firstname; - - do { - - fputs("\t\t\t\t\n", fp); - fputs("\t\t\t\t\t\n", fp); - fputs("\t\t\t\t\t\t", fp); - for (q=p->value; *q != '\0'; ++q) - if (*q == '<') fputs("<", fp); - else if (*q == '>') fputs(">", fp); - else if (*q == '&') fputs("&" , fp); - else if (*q == '\'') fputs("'", fp); - else if (*q == '"') fputs(""", fp); - else fputc(*q, fp); - - - fputs("\n", fp); - - fputs("\t\t\t\t\t\ttype); - fputs("\t\t\t\t\t\t\tDataType=", fp); - fprintf(fp, "\"%s\"/>\n", p->name); - fputs("\t\t\t\t\t\n", fp); - fputs("\t\t\t\t\n", fp); - p = (GRSTgaclNamevalue *) p->next; - } while (p != NULL); - - } - else fputs("\t\t\t\t\n", fp); - - return 1; -} - - -int GRSTxacmlEntryPrint(GRSTgaclEntry *entry, FILE *fp, int rule_number) -{ - GRSTgaclCred *cred; - GRSTgaclPerm i; - - if (entry->allowed){ - - fprintf(fp, "\t\n", rule_number); - fputs("\t\t\n", fp); - fputs("\t\t\t\n", fp); - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - GRSTxacmlCredPrint(cred, fp); - - fputs("\t\t\t\n", fp); - fputs("\t\t\t\n", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if ((entry->allowed) & i) GRSTxacmlPermPrint(i, fp); - - fputs("\t\t\t\n", fp); - fputs("\t\t\n", fp); - fputs("\t\n", fp); - } - - if (entry->denied){ - - fprintf(fp, "\t\n", rule_number); - fputs("\t\t\n", fp); - fputs("\t\t\t\n", fp); - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - GRSTxacmlCredPrint(cred, fp); - - fputs("\t\t\t\n", fp); - fputs("\t\t\t\n", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if (entry->denied & i) GRSTxacmlPermPrint(i, fp); - - fputs("\t\t\t\n", fp); - fputs("\t\t\n", fp); - fputs("\t\n", fp); - } - return 1; -} - - -int GRSTxacmlPermPrint(GRSTgaclPerm perm, FILE *fp) -{ - GRSTgaclPerm i; - - for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i) - if (perm == grst_perm_vals[i]) - { - - fputs("\t\t\t\t\n", fp); - fputs("\t\t\t\t\t\n", fp); - fputs("\t\t\t\t\t\t", fp); - fprintf(fp, "%s", grst_perm_syms[i]); - fputs("\n", fp); - fputs("\t\t\t\t\t\t\n", fp); - fputs("\t\t\t\t\t\n", fp); - fputs("\t\t\t\t\n",fp); - - return 1; - } - - return 0; -} - -int GRSTxacmlAclPrint(GRSTgaclAcl *acl, FILE *fp, char* dir_uri) -{ - GRSTgaclEntry *entry; - int rule_number=1; - - fputs("\n\n", fp); - - fputs("\t\n\t\t\n\t\t\t\n", fp); - fputs("\t\t\t\t\n", fp); - fputs("\t\t\t\t\t", fp); - fprintf(fp, "%s", dir_uri); - fputs("\n", fp); - fputs("\t\t\t\t\t\n", fp); - - fputs("\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t", fp); - fputs("\n\t\t\n\t\t\t\n\t\t\n\t\n\n", fp); - - for (entry = acl->firstentry; entry != NULL; entry = entry->next){ - - GRSTxacmlEntryPrint(entry, fp, rule_number); - rule_number++; - } - - fputs("\n", fp); - - return 1; -} - -int GRSTxacmlAclSave(GRSTgaclAcl *acl, char *filename, char* dir_uri) -{ - int ret; - FILE *fp; - - fp = fopen(filename, "w"); - if (fp == NULL) return 0; - - fprintf(fp,"\n"); - - ret = GRSTxacmlAclPrint(acl, fp, dir_uri); - - fclose(fp); - - return ret; -} - - - - diff --git a/org.gridsite.core/src/gsexec.c b/org.gridsite.core/src/gsexec.c deleted file mode 100644 index 4278c77..0000000 --- a/org.gridsite.core/src/gsexec.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* Copyright 1999-2004 The Apache Software Foundation - * - * 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. - */ - -/* - * suexec.c -- "Wrapper" support program for suEXEC behaviour for Apache - * - *********************************************************************** - * - * NOTE! : DO NOT edit this code!!! Unless you know what you are doing, - * editing this code might open up your system in unexpected - * ways to would-be crackers. Every precaution has been taken - * to make this code as safe as possible; alter it at your own - * risk. - * - *********************************************************************** - * - * - */ - -#include "apr.h" -#include "apr_file_io.h" -#include "ap_config.h" -#include "gsexec.h" - -#include -#include -#include -#include -#include -#if APR_HAVE_UNISTD_H -#include -#endif - -#include -#include -#include - -#ifdef HAVE_PWD_H -#include -#endif - -#ifdef HAVE_GRP_H -#include -#endif - -/* - *********************************************************************** - * There is no initgroups() in QNX, so I believe this is safe :-) - * Use cc -osuexec -3 -O -mf -DQNX suexec.c to compile. - * - * May 17, 1997. - * Igor N. Kovalenko -- infoh mail.wplus.net - *********************************************************************** - */ - -#if defined(NEED_INITGROUPS) -int initgroups(const char *name, gid_t basegid) -{ - /* QNX and MPE do not appear to support supplementary groups. */ - return 0; -} -#endif - -#if defined(SUNOS4) -extern char *sys_errlist[]; -#define strerror(x) sys_errlist[(x)] -#endif - -#if defined(PATH_MAX) -#define AP_MAXPATH PATH_MAX -#elif defined(MAXPATHLEN) -#define AP_MAXPATH MAXPATHLEN -#else -#define AP_MAXPATH 8192 -#endif - -#define AP_ENVBUF 256 - -extern char **environ; -static FILE *log = NULL; - -char *safe_env_lst[] = -{ - /* variable name starts with */ - "HTTP_", - "SSL_", - "GRST_", - - /* variable name is */ - "AUTH_TYPE=", - "CONTENT_LENGTH=", - "CONTENT_TYPE=", - "DATE_GMT=", - "DATE_LOCAL=", - "DOCUMENT_NAME=", - "DOCUMENT_PATH_INFO=", - "DOCUMENT_ROOT=", - "DOCUMENT_URI=", - "GATEWAY_INTERFACE=", - "HTTPS=", - "LAST_MODIFIED=", - "PATH_INFO=", - "PATH_TRANSLATED=", - "QUERY_STRING=", - "QUERY_STRING_UNESCAPED=", - "REMOTE_ADDR=", - "REMOTE_HOST=", - "REMOTE_IDENT=", - "REMOTE_PORT=", - "REMOTE_USER=", - "REDIRECT_HANDLER=", - "REDIRECT_QUERY_STRING=", - "REDIRECT_REMOTE_USER=", - "REDIRECT_STATUS=", - "REDIRECT_URL=", - "REQUEST_METHOD=", - "REQUEST_URI=", - "SCRIPT_FILENAME=", - "SCRIPT_NAME=", - "SCRIPT_URI=", - "SCRIPT_URL=", - "SERVER_ADMIN=", - "SERVER_NAME=", - "SERVER_ADDR=", - "SERVER_PORT=", - "SERVER_PROTOCOL=", - "SERVER_SIGNATURE=", - "SERVER_SOFTWARE=", - "UNIQUE_ID=", - "USER_NAME=", - "TZ=", - NULL -}; - - -static void err_output(int is_error, const char *fmt, va_list ap) -{ -#ifdef AP_LOG_EXEC - time_t timevar; - struct tm *lt; - - if (!log) { - if ((log = fopen(AP_LOG_EXEC, "a")) == NULL) { - fprintf(stderr, "suexec failure: could not open log file\n"); - perror("fopen"); - exit(1); - } - } - - if (is_error) { - fprintf(stderr, "suexec policy violation: see suexec log for more " - "details\n"); - } - - time(&timevar); - lt = localtime(&timevar); - - fprintf(log, "[%d-%.2d-%.2d %.2d:%.2d:%.2d]: ", - lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec); - - vfprintf(log, fmt, ap); - - fflush(log); -#endif /* AP_LOG_EXEC */ - return; -} - -static void log_err(const char *fmt,...) -{ -#ifdef AP_LOG_EXEC - va_list ap; - - va_start(ap, fmt); - err_output(1, fmt, ap); /* 1 == is_error */ - va_end(ap); -#endif /* AP_LOG_EXEC */ - return; -} - -static void log_no_err(const char *fmt,...) -{ -#ifdef AP_LOG_EXEC - va_list ap; - - va_start(ap, fmt); - err_output(0, fmt, ap); /* 0 == !is_error */ - va_end(ap); -#endif /* AP_LOG_EXEC */ - return; -} - -static void clean_env(void) -{ - char pathbuf[512]; - char **cleanenv; - char **ep; - int cidx = 0; - int idx; - - /* While cleaning the environment, the environment should be clean. - * (e.g. malloc() may get the name of a file for writing debugging info. - * Bad news if MALLOC_DEBUG_FILE is set to /etc/passwd. Sprintf() may be - * susceptible to bad locale settings....) - * (from PR 2790) - */ - char **envp = environ; - char *empty_ptr = NULL; - - environ = &empty_ptr; /* VERY safe environment */ - - if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) { - log_err("failed to malloc memory for environment\n"); - exit(120); - } - - sprintf(pathbuf, "PATH=%s", AP_SAFE_PATH); - cleanenv[cidx] = strdup(pathbuf); - cidx++; - - for (ep = envp; *ep && cidx < AP_ENVBUF-1; ep++) { - for (idx = 0; safe_env_lst[idx]; idx++) { - if (!strncmp(*ep, safe_env_lst[idx], - strlen(safe_env_lst[idx]))) { - cleanenv[cidx] = *ep; - cidx++; - break; - } - } - } - - cleanenv[cidx] = NULL; - - environ = cleanenv; -} - -/* Pool account functions */ - - -#include -#include -#include -#include -#include -#include -#include - -/****************************************************************************** -Function: mapdir_otherlink -Description: - find another link in map directory to the same inode as firstlink - and change the modification time of firstlink to now (so that we - always know when this pair was last used) - -Parameters: - firstlink, the filename of the link we already know - -Returns: - a pointer to the other link's filename (without path) or NULL if none - found (this is malloc'd and will need freeing) - -******************************************************************************/ -static char *mapdir_otherlink(char *mapdir, char *firstlink) -{ - int ret; - char *firstlinkpath, *otherlinkdup, *otherlinkpath; - struct dirent *mapdirentry; - DIR *mapdirstream; - struct stat statbuf; - ino_t firstinode; - - firstlinkpath = malloc(strlen(mapdir) + 2 + strlen(firstlink)); - sprintf(firstlinkpath, "%s/%s", mapdir, firstlink); - ret = stat(firstlinkpath, &statbuf); - free(firstlinkpath); - if (ret != 0) return NULL; - if (statbuf.st_nlink != 2) return NULL; - - firstinode = statbuf.st_ino; /* save for comparisons */ - - mapdirstream = opendir(mapdir); - - if (mapdirstream != NULL) - { - while ((mapdirentry = readdir(mapdirstream)) != NULL) - { - if (strcmp(mapdirentry->d_name, firstlink) == 0) continue; - - otherlinkpath = malloc(strlen(mapdir) + 2 + - strlen(mapdirentry->d_name)); - sprintf(otherlinkpath, "%s/%s", mapdir, - mapdirentry->d_name); - - ret = stat(otherlinkpath, &statbuf); - if ((ret == 0) && (statbuf.st_ino == firstinode)) - { - utime(otherlinkpath, (struct utimbuf *) NULL); - free(otherlinkpath); - otherlinkdup = strdup(mapdirentry->d_name); - closedir(mapdirstream); - return otherlinkdup; - } - else free(otherlinkpath); - } - - closedir(mapdirstream); - } - - return NULL; -} - -/****************************************************************************** -Function: mapdir_urlencode -Description: - Convert string to URL encoded and return pointer to the encoded - version, obtained through malloc. Calling routine must free - this. Here "URL encoded" means anything other than an isalnum() - goes to %HH where HH is its ascii value in hex; also A-Z => a-z - This name is suitable for filenames since no / or spaces. - -Parameters: - rawstring, the string to be converted - -Returns: - a pointer to the encoded string or NULL if the malloc failed - -******************************************************************************/ -static char *mapdir_urlencode(char *rawstring) -{ - int encodedchar = 0, rawchar = 0; - char * encodedstring; - - encodedstring = (char *) malloc(3 * strlen(rawstring) + 1); - - if (encodedstring == NULL) return (char *) NULL; - - while (rawstring[rawchar] != '\0') - { - if (isalnum(rawstring[rawchar])) - { - encodedstring[encodedchar] = tolower(rawstring[rawchar]); - ++rawchar; - ++encodedchar; - } - else - { - sprintf(&encodedstring[encodedchar], "%%%02x", - rawstring[rawchar]); - ++rawchar; - encodedchar = encodedchar + 3; - } - } - - encodedstring[encodedchar] = '\0'; - - return encodedstring; -} - -/****************************************************************************** -Function: mapdir_newlease -Description: - Search for an unleased local username to give to the X.509 DN or - directory key corresponding to encodedfilename, and then lease it. - -Parameters: - encodedfilename, URL-encoded X.509 DN or directory key to associate - with an unlease pool username - -Returns: - no return value -******************************************************************************/ - -void mapdir_newlease(char *mapdir, char *encodedkey) -{ - int ret; - char *userfilename, *encodedfilename; - struct dirent *mapdirentry; - DIR *mapdirstream; - struct stat statbuf; - - encodedfilename = malloc(strlen(mapdir) + (size_t) 2 + - strlen(encodedkey)); - sprintf(encodedfilename, "%s/%s", mapdir, encodedkey); - - mapdirstream = opendir(mapdir); - - while ((mapdirentry = readdir(mapdirstream)) != NULL) - { - /* we dont want any files that dont look like acceptable usernames */ - if ((*(mapdirentry->d_name) == '%') || - (strcmp(mapdirentry->d_name, "root") == 0)) continue; - else if (*(mapdirentry->d_name) == '.') continue; - else if (index(mapdirentry->d_name, '~') != NULL) continue; - - userfilename = malloc(strlen(mapdir) + (size_t) 2 + - strlen(mapdirentry->d_name)); - sprintf(userfilename, "%s/%s", mapdir, mapdirentry->d_name); - stat(userfilename, &statbuf); - - if (statbuf.st_nlink == 1) /* this one isnt leased yet */ - { - ret = link(userfilename, encodedfilename); - free(userfilename); - if (ret != 0) - { - /* link failed: this is probably because a VERY lucky - other process has obtained a lease for encodedfilename - while we were faffing around */ - closedir(mapdirstream); - free(encodedfilename); - return; - } - - stat(encodedfilename, &statbuf); - if (statbuf.st_nlink > 2) - { - /* two keys have grabbed the same username: back off */ - unlink(encodedfilename); - continue; - } - - closedir(mapdirstream); - free(encodedfilename); - return; /* link worked ok, so return */ - } - else free(userfilename); /* already in use, try next one */ - } - - closedir(mapdirstream); - free(encodedfilename); - return; /* no unleased names left: give up */ -} - -/****************************************************************************** -Based on gridmapdir_userid: - -Function: gridmapdir_userid -Description: - This is equivalent to globus_gss_assist_gridmap but for the dynamic - user ids in the gridmapdir: maps a globusID to a local unix user id, - either one already leased, or calls gridmapdir_newlease() to obtain - a new lease. This is called by globus_gss_assist_gridmap if the - local user id in the static gridmap file begins . (for a dynamic id) - -Parameters: - globusidp, globus client name who requested authentication - usernameprefix, prefix of the local usernames which would - be acceptable (or "\0" ) - *userid returned userid name for local system. - -Returns: - - 0 on success - !=0 on failure - -******************************************************************************/ - - - -int GRSTexecGetMapping(char **target_uname, char **target_gname, - char *mapdir, char *key) -{ - char *encodedkey; - struct passwd *pw = NULL; - - if (key[0] != '/') return 1; /* must be a proper X.509 DN or path */ - - encodedkey = mapdir_urlencode(key); - *target_uname = mapdir_otherlink(mapdir, encodedkey); - - if (*target_uname == NULL) /* maybe no lease yet */ - { - mapdir_newlease(mapdir, encodedkey); - /* try making a lease */ - - *target_uname = mapdir_otherlink(mapdir, encodedkey); - /* check if there is a now a lease - possibly made by someone else */ - - if (*target_uname == NULL) - { - free(encodedkey); - return 1; /* still no good */ - } - } - - free(encodedkey); - - /* - * Get the group name of target user. - (Contributed by Gerben Venekamp venekamp@nikhef.nl ) - */ - - if ((pw = getpwnam(*target_uname)) != NULL) - { - struct group grp = { NULL, NULL, -1, NULL }; - struct group *tst = NULL; - char tmp_buf[100]; - - /* - * NOTE: Do not use the getgrgid() function call! Calling this function - * will overwrite the contents of the internal buffer associated with - * this call. Hence, further down the execution path we will run into - * a wall, head first; simply because the guid has changed to that of - * the targer uid. The only solution out of the situation is avoiding - * the function call and manage the needed buffers ourselves. - */ - - switch (getgrgid_r(pw->pw_gid, &grp, tmp_buf, sizeof(tmp_buf), &tst)) - { - case 0: /* no error */ - *target_gname = strdup(grp.gr_name); - break; - case ERANGE: - log_err("The buffer for holding strings is too small " - "(%d byte now)\n", sizeof(tmp_buf)); - break; - default: - log_err("Could not get group name for user (%s)\n", - *target_uname); - } - - /* Test if all was well. */ - - if (target_gname == NULL) - { - exit(102); - } - } - else - { - log_err("Could not get info for the target user (%s)\n",*target_uname); - exit(102); - } - - log_no_err("target group name determined (%s -> %s)\n", - *target_uname, *target_gname); - - return 0; -} - -void internal_server_error(void) -{ - /* use this when its probably an httpd.conf configuration error */ - - puts("Status: 500 Internal Server Error\n" - "Content-Type: text/html\n\n" - "500 Internal Server Error\n" - "

Internal Server Error

"); -} - -void forbidden_error(void) -{ - /* use this when unix file permissions/ownerships are probably wrong */ - - puts("Status: 403 Forbidden\n" - "Content-Type: text/html\n\n" - "403 Forbidden\n" - "

Forbidden

"); -} - -int main(int argc, char *argv[]) -{ - int userdir = 0; /* ~userdir flag */ - uid_t uid; /* user information */ - gid_t gid; /* target group placeholder */ - uid_t httpd_uid; /* uid for AP_HTTPD_USER */ - gid_t httpd_gid; /* uid for AP_HTTPD_GROUP */ - char *mapping_type; /* suexec / X509DN / directory */ - char *grst_cred_0; /* GRST_CRED_0 */ - char *map_x509dn; /* DN to use as pool acct. key */ - char *map_directory; /* directory as pool acct. key */ - - char *diskmode_env; /* GRST_DISK_MODE as a string */ - apr_fileperms_t diskmode_apr; /* GRST_DISK_MODE as Apache perms */ - mode_t diskmode_t; /* GRST_DISK_MODE as mode_t */ - - char *target_uname; /* target user name */ - char *target_gname; /* target group name */ - char *target_homedir; /* target home directory */ - char *actual_uname; /* actual user name */ - char *actual_gname; /* actual group name */ - char *prog; /* name of this program */ - char *cmd; /* command to be executed */ - char cwd[AP_MAXPATH]; /* current working directory */ - char dwd[AP_MAXPATH]; /* docroot working directory */ - struct passwd *pw; /* password entry holder */ - struct group *gr; /* group entry holder */ - struct stat dir_info; /* directory info holder */ - struct stat prg_info; /* program info holder */ - - /* - * Start with a "clean" environment - */ - clean_env(); - - prog = argv[0]; - /* - * Check existence/validity of the UID of the user - * running this program. Error out if invalid. - */ - uid = getuid(); - if ((pw = getpwuid(uid)) == NULL) { - log_err("crit: invalid uid: (%ld)\n", uid); - internal_server_error(); - exit(102); - } - /* - * Check existence/validity of the GID of the user - * running this program. Error out if invalid. - */ - gid = getgid(); - if ((gr = getgrgid(gid)) == NULL) { - log_err("crit: invalid gid: (%ld)\n", gid); - internal_server_error(); - exit(102); - } - /* - * See if this is a 'how were you compiled' request, and - * comply if so. - */ - if ((argc > 1) - && (! strcmp(argv[1], "-V")) - && ((uid == 0) -#ifdef _OSD_POSIX - /* User name comparisons are case insensitive on BS2000/OSD */ - || (! strcasecmp(AP_HTTPD_USER, pw->pw_name))) -#else /* _OSD_POSIX */ - || (! strcmp(AP_HTTPD_USER, pw->pw_name))) -#endif /* _OSD_POSIX */ - ) { -#ifdef AP_DOC_ROOT - fprintf(stderr, " -D AP_DOC_ROOT=\"%s\"\n", AP_DOC_ROOT); -#endif -#ifdef AP_GID_MIN - fprintf(stderr, " -D AP_GID_MIN=%d\n", AP_GID_MIN); -#endif -#ifdef AP_HTTPD_USER - fprintf(stderr, " -D AP_HTTPD_USER=\"%s\"\n", AP_HTTPD_USER); -#endif -#ifdef AP_LOG_EXEC - fprintf(stderr, " -D AP_LOG_EXEC=\"%s\"\n", AP_LOG_EXEC); -#endif -#ifdef AP_SAFE_PATH - fprintf(stderr, " -D AP_SAFE_PATH=\"%s\"\n", AP_SAFE_PATH); -#endif -#ifdef AP_SUEXEC_UMASK - fprintf(stderr, " -D AP_SUEXEC_UMASK=%03o\n", AP_SUEXEC_UMASK); -#endif -#ifdef AP_UID_MIN - fprintf(stderr, " -D AP_UID_MIN=%d\n", AP_UID_MIN); -#endif -#ifdef AP_USERDIR_SUFFIX - fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX); -#endif - exit(0); - } - /* - * If there are a proper number of arguments, set - * all of them to variables. Otherwise, error out. - */ - if (argc < 4) { - log_err("too few arguments\n"); - internal_server_error(); - exit(101); - } - - mapping_type = getenv("GRST_EXEC_METHOD"); - if ((mapping_type == NULL) || - (mapping_type[0] == '\0') || - (strcasecmp(mapping_type, "suexec") == 0)) - { - target_uname = argv[1]; - target_gname = argv[2]; - mapping_type = NULL; - } - else if (strcasecmp(mapping_type, "X509DN") == 0) - { - if ((grst_cred_0 = getenv("GRST_CRED_0")) == NULL) - map_x509dn = getenv("SSL_CLIENT_S_DN"); - else map_x509dn = index(grst_cred_0, '/'); - - if ((map_x509dn == NULL) || (map_x509dn[0] == '\0')) - { - log_err("No GRST_CRED_0/SSL_CLIENT_S_DN despite X509DN mapping\n"); - forbidden_error(); - exit(151); - } - - if (GRSTexecGetMapping(&target_uname, &target_gname, - GRST_EXECMAPDIR, map_x509dn) - != 0) - { - log_err("GRSTexecGetMapping() failed mapping \"%s\"\n", - map_x509dn); - forbidden_error(); - exit(152); - } - } - else if (strcasecmp(mapping_type, "directory") == 0) - { - map_directory = getenv("GRST_EXEC_DIRECTORY"); - if (map_directory == NULL) - { - log_err("No GRST_EXEC_DIRECTORY despite directory mapping\n"); - internal_server_error(); - exit(153); - } - - if (GRSTexecGetMapping(&target_uname, &target_gname, - GRST_EXECMAPDIR, map_directory) - != 0) - { - log_err("GRSTexecGetMapping() failed mapping \"%s\"\n", - map_directory); - internal_server_error(); - exit(154); - } - } - else - { - log_err("mapping type \"%s\" not recognised\n", mapping_type); - internal_server_error(); - exit(155); - } - - cmd = argv[3]; - - /* - * Check to see if the user running this program - * is the user allowed to do so as defined in - * suexec.h. If not the allowed user, error out. - */ -#ifdef _OSD_POSIX - /* User name comparisons are case insensitive on BS2000/OSD */ - if (strcasecmp(AP_HTTPD_USER, pw->pw_name)) { - log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER); - internal_server_error(); - exit(103); - } - /* User name comparisons are case insensitive on BS2000/OSD */ - if (strcasecmp(AP_HTTPD_GROUP, gr->gr_name)) { - log_err("group mismatch (%s instead of %s)\n", gr->gr_name, AP_HTTPD_GROUP); - internal_server_error(); - exit(103); - } -#else /*_OSD_POSIX*/ - if (strcmp(AP_HTTPD_USER, pw->pw_name)) { - log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER); - internal_server_error(); - exit(103); - } - if (strcmp(AP_HTTPD_GROUP, gr->gr_name)) { - log_err("group mismatch (%s instead of %s)\n", gr->gr_name, AP_HTTPD_GROUP); - internal_server_error(); - exit(103); - } -#endif /*_OSD_POSIX*/ - - /* Since they match (via name) save these for later */ - - httpd_uid = uid; - httpd_gid = gid; - - /* - * Check for a leading '/' (absolute path) in the command to be executed, - * or attempts to back up out of the current directory, - * to protect against attacks. If any are - * found, error out. Naughty naughty crackers. - */ - if ((cmd[0] == '/') || (!strncmp(cmd, "../", 3)) - || (strstr(cmd, "/../") != NULL)) { - log_err("invalid command (%s)\n", cmd); - internal_server_error(); - exit(104); - } - - /* - * Check to see if this is a ~userdir request. If - * so, set the flag, and remove the '~' from the - * target username. - */ - if (!strncmp("~", target_uname, 1)) { - target_uname++; - userdir = 1; - } - - /* - * Error out if the target username is invalid. - */ - if (strspn(target_uname, "1234567890") != strlen(target_uname)) { - if ((pw = getpwnam(target_uname)) == NULL) { - log_err("invalid target user name: (%s)\n", target_uname); - internal_server_error(); - exit(105); - } - } - else { - if ((pw = getpwuid(atoi(target_uname))) == NULL) { - log_err("invalid target user id: (%s)\n", target_uname); - internal_server_error(); - exit(121); - } - } - - /* - * Error out if the target group name is invalid. - */ - if (strspn(target_gname, "1234567890") != strlen(target_gname)) { - if ((gr = getgrnam(target_gname)) == NULL) { - log_err("invalid target group name: (%s)\n", target_gname); - internal_server_error(); - exit(106); - } - gid = gr->gr_gid; - actual_gname = strdup(gr->gr_name); - } - else { - gid = atoi(target_gname); - actual_gname = strdup(target_gname); - } - -#ifdef _OSD_POSIX - /* - * Initialize BS2000 user environment - */ - { - pid_t pid; - int status; - - switch (pid = ufork(target_uname)) { - case -1: /* Error */ - log_err("failed to setup bs2000 environment for user %s: %s\n", - target_uname, strerror(errno)); - internal_server_error(); - exit(150); - case 0: /* Child */ - break; - default: /* Father */ - while (pid != waitpid(pid, &status, 0)) - ; - /* @@@ FIXME: should we deal with STOP signals as well? */ - if (WIFSIGNALED(status)) { - kill (getpid(), WTERMSIG(status)); - } - internal_server_error(); - exit(WEXITSTATUS(status)); - } - } -#endif /*_OSD_POSIX*/ - - /* - * Save these for later since initgroups will hose the struct - */ - uid = pw->pw_uid; - actual_uname = strdup(pw->pw_name); - target_homedir = strdup(pw->pw_dir); - - /* - * Log the transaction here to be sure we have an open log - * before we setuid(). - */ - log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", - target_uname, actual_uname, - target_gname, actual_gname, - cmd); - - /* - * Error out if attempt is made to execute as root or as - * a UID less than AP_UID_MIN. Tsk tsk. - */ - if ((uid == 0) || (uid < AP_UID_MIN)) { - log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd); - internal_server_error(); - exit(107); - } - - /* - * Error out if attempt is made to execute as root group - * or as a GID less than AP_GID_MIN. Tsk tsk. - */ - if ((gid == 0) || (gid < AP_GID_MIN)) { - log_err("cannot run as forbidden gid (%d/%s)\n", gid, cmd); - internal_server_error(); - exit(108); - } - - /* - * Change UID/GID here so that the following tests work over NFS. - * - * Initialize the group access list for the target user, - * and setgid() to the target group. If unsuccessful, error out. - */ - if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0)) { - log_err("failed to setgid (%ld: %s)\n", gid, cmd); - internal_server_error(); - exit(109); - } - - /* - * setuid() to the target user. Error out on fail. - */ - if ((setuid(uid)) != 0) { - log_err("failed to setuid (%ld: %s)\n", uid, cmd); - internal_server_error(); - exit(110); - } - - /* - * Get the current working directory, as well as the proper - * document root (dependant upon whether or not it is a - * ~userdir request). Error out if we cannot get either one, - * or if the current working directory is not in the docroot. - * Use chdir()s and getcwd()s to avoid problems with symlinked - * directories. Yuck. - */ - if (getcwd(cwd, AP_MAXPATH) == NULL) { - log_err("cannot get current working directory\n"); - internal_server_error(); - exit(111); - } - -#if 0 - if (userdir) { - if (((chdir(target_homedir)) != 0) || - ((chdir(AP_USERDIR_SUFFIX)) != 0) || - ((getcwd(dwd, AP_MAXPATH)) == NULL) || - ((chdir(cwd)) != 0)) { - log_err("cannot get docroot information (%s)\n", target_homedir); - internal_server_error(); - exit(112); - } - } - else { - if (((chdir(AP_DOC_ROOT)) != 0) || - ((getcwd(dwd, AP_MAXPATH)) == NULL) || - ((chdir(cwd)) != 0)) { - log_err("cannot get docroot information (%s)\n", AP_DOC_ROOT); - internal_server_error(); - exit(113); - } - } - - if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { - log_err("command not in docroot (%s/%s)\n", cwd, cmd); - internal_server_error(); - exit(114); - } -#endif - - /* - * Stat the cwd and verify it is a directory, or error out. - */ - if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) { - log_err("cannot stat directory: (%s)\n", cwd); - internal_server_error(); - exit(115); - } - - /* - * Error out if cwd is writable by others. - */ - if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) { - log_err("directory is writable by others: (%s)\n", cwd); - forbidden_error(); - exit(116); - } - - /* - * Error out if we cannot stat the program. - */ - if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) { - log_err("cannot stat program: (%s)\n", cmd); - forbidden_error(); - exit(117); - } - - /* - * Error out if the program is writable by others. - */ - if (prg_info.st_mode & S_IWOTH) { - log_err("file is writable by others: (%s/%s)\n", cwd, cmd); - forbidden_error(); - exit(118); - } - - /* - * Error out if the file is setuid or setgid. - */ - if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) { - log_err("file is either setuid or setgid: (%s/%s)\n", cwd, cmd); - forbidden_error(); - exit(119); - } - - /* - * Error out if the target name/group is different from - * the name/group of the cwd or the program AND the name/group - * of the cwd and program are not the AP_HTTPD_USER/AP_HTTPD_GROUP - * AND the name/group of the cwd and program are not root - */ - if (((uid != dir_info.st_uid) && (httpd_uid != dir_info.st_uid) - && (0 != dir_info.st_uid)) || - ((gid != dir_info.st_gid) && (httpd_gid != dir_info.st_gid) - && (0 != dir_info.st_gid)) || - ((uid != prg_info.st_uid) && (httpd_uid != prg_info.st_uid) - && (0 != prg_info.st_uid)) || - ((gid != prg_info.st_gid) && (httpd_gid != prg_info.st_gid) - && (0 != prg_info.st_gid))) - { - log_err("target (%ld/%ld) or %s (%ld/%ld) or root (0/0) uid/gid " - "mismatch with directory (%ld/%ld) or program (%ld/%ld)\n", - uid, gid, AP_HTTPD_USER, httpd_uid, httpd_gid, - dir_info.st_uid, dir_info.st_gid, - prg_info.st_uid, prg_info.st_gid); - forbidden_error(); - exit(120); - } - /* - * Error out if the program is not executable for the user. - * Otherwise, she won't find any error in the logs except for - * "[error] Premature end of script headers: ..." - */ - if (!(prg_info.st_mode & S_IXUSR)) { - log_err("file has no execute permission: (%s/%s)\n", cwd, cmd); - forbidden_error(); - exit(121); - } - - diskmode_env = getenv("GRST_DISK_MODE"); - if (diskmode_env != NULL) - { - diskmode_apr = 0; - sscanf(diskmode_env, "%i", &diskmode_apr); - - diskmode_t = S_IRUSR | S_IWUSR; - - if (diskmode_apr & APR_GREAD ) diskmode_t |= S_IRGRP; - if (diskmode_apr & APR_GWRITE) diskmode_t |= S_IWGRP; - if (diskmode_apr & APR_WREAD ) diskmode_t |= S_IROTH; - - diskmode_t &= (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); - -// log_err("diskmode_env=%s diskmode_apr=%x diskmode_t=%o ~diskmode_t=%o\n", diskmode_env, diskmode_apr, diskmode_t, ~diskmode_t); - - umask(~diskmode_t); - } -#ifdef AP_SUEXEC_UMASK - else umask(AP_SUEXEC_UMASK); -#else - else umask(~(S_IRUSR | S_IWUSR)); -#endif /* AP_SUEXEC_UMASK */ - - /* - * Be sure to close the log file so the CGI can't - * mess with it. If the exec fails, it will be reopened - * automatically when log_err is called. Note that the log - * might not actually be open if AP_LOG_EXEC isn't defined. - * However, the "log" cell isn't ifdef'd so let's be defensive - * and assume someone might have done something with it - * outside an ifdef'd AP_LOG_EXEC block. - */ - if (log != NULL) { - fclose(log); - log = NULL; - } - - /* - * Execute the command, replacing our image with its own. - */ -#ifdef NEED_HASHBANG_EMUL - /* We need the #! emulation when we want to execute scripts */ - { - extern char **environ; - - ap_execve(cmd, &argv[3], environ); - } -#else /*NEED_HASHBANG_EMUL*/ - execv(cmd, &argv[3]); -#endif /*NEED_HASHBANG_EMUL*/ - - /* - * (I can't help myself...sorry.) - * - * Uh oh. Still here. Where's the kaboom? There was supposed to be an - * EARTH-shattering kaboom! - * - * Oh well, log the failure and error out. - */ - log_err("(%d)%s: exec failed (%s)\n", errno, strerror(errno), cmd); - internal_server_error(); - exit(255); -} diff --git a/org.gridsite.core/src/gsexec.h b/org.gridsite.core/src/gsexec.h deleted file mode 100644 index b777421..0000000 --- a/org.gridsite.core/src/gsexec.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright 1999-2004 The Apache Software Foundation - * - * 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. - */ - -/* - * suexec.h -- user-definable variables for the suexec wrapper code. - * (See README.configure on how to customize these variables.) - */ - - -#ifndef _SUEXEC_H -#define _SUEXEC_H - -/* - * Include ap_config_layout so we can work out where the default htdocsdir - * and logsdir are. - */ -#include "ap_config_layout.h" - -/* - * HTTPD_USER -- Define as the username under which Apache normally - * runs. This is the only user allowed to execute - * this program. - */ -#ifndef AP_HTTPD_USER -#define AP_HTTPD_USER "apache" -#endif - -/* - * HTTPD_GROUP -- Define as the group under which Apache normally - * runs. This is the only user allowed to execute - * this program. - */ -#ifndef AP_HTTPD_GROUP -#define AP_HTTPD_GROUP "apache" -#endif - -/* - * UID_MIN -- Define this as the lowest UID allowed to be a target user - * for suEXEC. For most systems, 500 or 100 is common, but - * 99 will include user nobody on RedHat Linux systems. - */ -#ifdef AP_UID_MIN -#undef AP_UID_MIN -#endif -#define AP_UID_MIN 99 - -/* - * GID_MIN -- Define this as the lowest GID allowed to be a target group - * for suEXEC. For most systems, 100 is common, but 99 will - * include group nobody on RedHat Linux systems. - */ -#ifdef AP_GID_MIN -#undef AP_GID_MIN -#endif -#define AP_GID_MIN 99 - -/* - * USERDIR_SUFFIX -- Define to be the subdirectory under users' - * home directories where suEXEC access should - * be allowed. All executables under this directory - * will be executable by suEXEC as the user so - * they should be "safe" programs. If you are - * using a "simple" UserDir directive (ie. one - * without a "*" in it) this should be set to - * the same value. suEXEC will not work properly - * in cases where the UserDir directive points to - * a location that is not the same as the user's - * home directory as referenced in the passwd file. - * - * If you have VirtualHosts with a different - * UserDir for each, you will need to define them to - * all reside in one parent directory; then name that - * parent directory here. IF THIS IS NOT DEFINED - * PROPERLY, ~USERDIR CGI REQUESTS WILL NOT WORK! - * See the suEXEC documentation for more detailed - * information. - */ -#ifndef AP_USERDIR_SUFFIX -#define AP_USERDIR_SUFFIX "public_html" -#endif - -/* - * LOG_EXEC -- Define this as a filename if you want all suEXEC - * transactions and errors logged for auditing and - * debugging purposes. - */ -#ifndef AP_LOG_EXEC -#define AP_LOG_EXEC DEFAULT_EXP_LOGFILEDIR "/suexec_log" /* Need me? */ -#endif - -/* - * DOC_ROOT -- Define as the DocumentRoot set for Apache. This - * will be the only hierarchy (aside from UserDirs) - * that can be used for suEXEC behavior. - */ -#ifndef AP_DOC_ROOT -#define AP_DOC_ROOT DEFAULT_EXP_HTDOCSDIR -#endif - -/* - * SAFE_PATH -- Define a safe PATH environment to pass to CGI executables. - * - */ -#ifndef AP_SAFE_PATH -#define AP_SAFE_PATH "/usr/local/bin:/usr/bin:/bin" -#endif - -/* - * GRST_EXECMAPDIR -- Location of the gridmapdir-style directory of lock files - * - */ -#define GRST_EXECMAPDIR "/var/www/execmapdir" - -#endif /* _SUEXEC_H */ diff --git a/org.gridsite.core/src/htcp.c b/org.gridsite.core/src/htcp.c deleted file mode 100644 index b682d17..0000000 --- a/org.gridsite.core/src/htcp.c +++ /dev/null @@ -1,2032 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gridsite.h" - -/* deal with older versions of libcurl and curl.h */ - -#ifndef CURLOPT_WRITEDATA -#define CURLOPT_WRITEDATA CURLOPT_FILE -#endif - -#ifndef CURLOPT_READDATA -#define CURLOPT_READDATA CURLOPT_FILE -#endif - -#ifndef CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND -#endif - -#define HTCP_GET 1 -#define HTCP_PUT 2 -#define HTCP_DELETE 3 -#define HTCP_LIST 4 -#define HTCP_LONGLIST 5 -#define HTCP_MKDIR 6 -#define HTCP_MOVE 7 -#define HTCP_PING 8 -#define HTCP_FIND 9 -#define HTCP_RMTCP 10 - -#define HTCP_SITECAST_GROUPS 32 - -#define HTCP_HOST_CONF "/etc/htcp.conf" -#define HTCP_USER_CONF ".htcp.conf" - -struct grst_stream_data { char *source; - char *destination; - int ishttps; - int method; - FILE *fp; - char *cert; - char *key; - char *capath; - char *useragent; - char *errorbuf; - int noverify; - int anonymous; - int gridhttp; - int verbose; - int timeout; - char *groups; - int sitecast; - char *domain; } ; - -struct grst_index_blob { char *text; - size_t used; - size_t allocated; } ; - -struct grst_dir_list { char *filename; - size_t length; - int length_set; - time_t modified; - int modified_set; } ; - -struct grst_header_data { int retcode; - char *location; - char *gridhttppasscode; - size_t length; - int length_set; - time_t modified; - int modified_set; - struct grst_stream_data *common_data; } ; - -struct grst_sitecast_group { unsigned char quad1; unsigned char quad2; - unsigned char quad3; unsigned char quad4; - int port; int timewait; int ttl; }; - -size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p) -/* Find the values of the return code, Content-Length, Last-Modified - and Location headers */ -{ - float f; - char *s, *q; - size_t realsize; - struct tm modified_tm; - struct grst_header_data *header_data; - - header_data = (struct grst_header_data *) p; - realsize = size * nmemb; - s = malloc(realsize + 1); - memcpy(s, ptr, realsize); - s[realsize] = '\0'; - - if (sscanf(s, "Content-Length: %d", &(header_data->length)) == 1) - header_data->length_set = 1; - else if (sscanf(s, "HTTP/%f %d ", &f, &(header_data->retcode)) == 2) ; - else if (strncmp(s, "Location: ", 10) == 0) - { - header_data->location = strdup(&s[10]); - - for (q=header_data->location; *q != '\0'; ++q) - if ((*q == '\r') || (*q == '\n')) *q = '\0'; - - if (header_data->common_data->verbose > 0) - fprintf(stderr, "Received Location: %s\n", header_data->location); - } - else if (strncmp(s, "Set-Cookie: GRIDHTTP_PASSCODE=", 29) == 0) - { - header_data->gridhttppasscode = strdup(&s[12]); - q = index(header_data->gridhttppasscode, ';'); - if (q != NULL) *q = '\0'; - - if (header_data->common_data->verbose > 0) - fprintf(stderr, "Received GridHTTP Auth Cookie: %s\n", - header_data->gridhttppasscode); - } - else if (strncmp(s, "Last-Modified: ", 15) == 0) - { - /* follow RFC 2616: first try RFC 822 (kosher), then RFC 850 and - asctime() formats too. Must be GMT whatever the format. */ - - if (strptime(&s[15], "%a, %d %b %Y %T GMT", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - else if (strptime(&s[15], "%a, %d-%b-%y %T GMT", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - else if (strptime(&s[15], "%a %b %d %T %Y", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - } - - free(s); - return realsize; -} - -int set_std_opts(CURL *easyhandle, struct grst_stream_data *common_data) -{ - struct stat statbuf; - - curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 0); - - if ((common_data->cert != NULL) && (common_data->key != NULL)) - { - curl_easy_setopt(easyhandle, CURLOPT_SSLENGINE, NULL); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERT, common_data->cert); - curl_easy_setopt(easyhandle, CURLOPT_SSLKEY, common_data->key); - } - else - { - curl_easy_setopt(easyhandle, CURLOPT_SSLENGINE, "RSA"); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERTTYPE, "ENG"); - } - - if (common_data->capath != NULL) - { -#if (LIBCURL_VERSION_NUM >= 0x070908) - if ((stat(common_data->capath, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) - curl_easy_setopt(easyhandle, CURLOPT_CAPATH, common_data->capath); - else -#endif - curl_easy_setopt(easyhandle, CURLOPT_CAINFO, common_data->capath); - } - - if (common_data->noverify) - { - curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 0); - } - else - { - curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 2); - curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 2); - } - - return 1; -} - -int do_rmtcp(char *sources[], char *destination, - struct grst_stream_data *common_data) -{ - CURL *easyhandle; - char *p, *thisdestination; - int isrc, anyerror = 0, thiserror, isdirdest; - struct grst_header_data header_data; - struct curl_slist *gh_header_slist=NULL, *nogh_header_slist=NULL; - char remoteserver[255]; - - easyhandle = curl_easy_init(); - if( !easyhandle ) - { - fprintf(stderr, "Cannot initialize CURL handle while preparing to copy file.\n"); - exit(-1); - } - - common_data->gridhttp = 1; // for debug purpose - if (common_data->gridhttp) - { - asprintf(&p, "Upgrade: GridHTTP/1.0"); - gh_header_slist = curl_slist_append(gh_header_slist, p); - free(p); - - nogh_header_slist = curl_slist_append(nogh_header_slist, "Upgrade:"); - } - - // common_data->verbose = 1; //for debug purpose - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - set_std_opts(easyhandle, common_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - - if (destination[strlen(destination) - 1] != '/') - { - isdirdest = 0; - thisdestination = destination; - } - else isdirdest = 1; - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (isdirdest) - { - p = rindex(sources[isrc], '/'); - if (p == NULL) p = sources[isrc]; - else p++; - - asprintf(&thisdestination, "%s%s", destination, p); - } - - if( strncmp(sources[isrc], "https://", 8) == 0 ){ - if (common_data->verbose > 0) - fprintf(stderr, "%s -> %s\n", sources[isrc], thisdestination); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - if ((common_data->gridhttp) && - (strncmp(sources[isrc], "https://", 8) == 0)) - { - if (common_data->verbose > 0) - fprintf(stderr, "Add Upgrade: GridHTTP/1.0\n"); - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,gh_header_slist); - } - else - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nogh_header_slist); - - header_data.retcode = 0; - header_data.location = NULL; - header_data.gridhttppasscode = NULL; - header_data.common_data = common_data; - thiserror = curl_easy_perform(easyhandle); - - } - - asprintf(&p, "Destination: %s", thisdestination); - nogh_header_slist=NULL; - nogh_header_slist = curl_slist_append(nogh_header_slist,p); - // fprintf(stdout, "complete destination file: %s\n", p); - free(p); - - // send request to destination server, - // to ask it to download file from source server - strcpy( remoteserver, destination); - while( (p=strrchr(remoteserver, '/')) !=NULL) - { - if( *(p-1) == '/' )break; - else *p = '\0'; - } - - common_data->source = sources[isrc]; - common_data->destination = remoteserver; - set_std_opts(easyhandle, common_data); - // send copy request to copy server (destination) - asprintf(&p, "COPY %s", sources[isrc]); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, p);//"COPY");//gh_header_slist); - curl_easy_setopt(easyhandle, CURLOPT_URL, remoteserver); - curl_easy_setopt(easyhandle, CURLOPT_COOKIE, header_data.gridhttppasscode); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, nogh_header_slist); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - thiserror = curl_easy_perform(easyhandle); - free(p); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; - -} - -int do_copies(char *sources[], char *destination, - struct grst_stream_data *common_data) -{ - char *p, *thisdestination; - int isrc, anyerror = 0, thiserror, isdirdest; - CURL *easyhandle; - struct stat statbuf; - struct grst_header_data header_data; - struct curl_slist *gh_header_slist = NULL, *nogh_header_slist = NULL; - - easyhandle = curl_easy_init(); - - if (common_data->gridhttp) - { - asprintf(&p, "Upgrade: GridHTTP/1.0"); - gh_header_slist = curl_slist_append(gh_header_slist, p); - free(p); - - nogh_header_slist = curl_slist_append(nogh_header_slist, "Upgrade:"); - } - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - set_std_opts(easyhandle, common_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - - if (destination[strlen(destination) - 1] != '/') - { - isdirdest = 0; - thisdestination = destination; - } - else isdirdest = 1; - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (isdirdest) - { - p = rindex(sources[isrc], '/'); - if (p == NULL) p = sources[isrc]; - else p++; - - asprintf(&thisdestination, "%s%s", destination, p); - } - - if (common_data->verbose > 0) - fprintf(stderr, "Copy %s -> %s\n", sources[isrc], thisdestination); - - if (common_data->method == HTCP_GET) - { - common_data->fp = fopen(thisdestination, "w"); - if (common_data->fp == NULL) - { - fprintf(stderr,"... failed to open destination source file %s\n", - thisdestination); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, common_data->fp); - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - if ((common_data->gridhttp) && - (strncmp(sources[isrc], "https://", 8) == 0)) - { - if (common_data->verbose > 0) - fprintf(stderr, "Add Upgrade: GridHTTP/1.0\n"); - - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,gh_header_slist); - } - else - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nogh_header_slist); - } - else if (common_data->method == HTCP_PUT) - { - if (stat(sources[isrc], &statbuf) != 0) - { - fprintf(stderr, "... source file %s not found\n", sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - common_data->fp = fopen(sources[isrc], "r"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open source file %s\n", - sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - curl_easy_setopt(easyhandle, CURLOPT_READDATA, common_data->fp); - curl_easy_setopt(easyhandle, CURLOPT_URL, thisdestination); - curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, statbuf.st_size); - curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1); - - if ((common_data->gridhttp) && - (strncmp(thisdestination, "https://", 8) == 0)) - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,gh_header_slist); - else - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nogh_header_slist); - } - - header_data.retcode = 0; - header_data.location = NULL; - header_data.gridhttppasscode = NULL; - header_data.common_data = common_data; - thiserror = curl_easy_perform(easyhandle); - - fclose(common_data->fp); - - if ((common_data->gridhttp) && - (thiserror == 0) && - (header_data.retcode == 302) && - (header_data.location != NULL) && - (strncmp(header_data.location, "http://", 7) == 0) && - (header_data.gridhttppasscode != NULL)) - { - if (common_data->verbose > 0) - fprintf(stderr, "... Found (%d)\nGridHTTP redirect to %s\n", - header_data.retcode, header_data.location); - - /* try again with new URL and all the previous CURL options */ - - if (common_data->method == HTCP_GET) - { - common_data->fp = fopen(thisdestination, "w"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open destination source " - "file %s\n", thisdestination); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - } - else if (common_data->method == HTCP_PUT) - { - common_data->fp = fopen(sources[isrc], "r"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open source file %s\n", - sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - } - - header_data.retcode = 0; - curl_easy_setopt(easyhandle, CURLOPT_URL, header_data.location); - curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, nogh_header_slist); - curl_easy_setopt(easyhandle, CURLOPT_COOKIE, - header_data.gridhttppasscode); - thiserror = curl_easy_perform(easyhandle); - - fclose(common_data->fp); - } - - if ((thiserror != 0) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - if (isdirdest) free(thisdestination); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_deletes(char *sources[], struct grst_stream_data *common_data) -{ - int isrc, anyerror = 0, thiserror; - CURL *easyhandle; - struct grst_header_data header_data; - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "DELETE"); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Deleting %s\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_move(char *source, char *destination, - struct grst_stream_data *common_data) -{ - int anyerror = 0, thiserror; - char *destination_header; - CURL *easyhandle; - struct grst_header_data header_data; - struct curl_slist *header_slist = NULL; - - easyhandle = curl_easy_init(); - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - asprintf(&destination_header, "Destination: %s", destination); - header_slist = curl_slist_append(header_slist, destination_header); - curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, header_slist); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "MOVE"); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - set_std_opts(easyhandle, common_data); - - if (common_data->verbose > 0) - fprintf(stderr, "Moving %s to %s\n", source, destination); - - curl_easy_setopt(easyhandle, CURLOPT_URL, source); - - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_mkdirs(char *sources[], struct grst_stream_data *common_data) -{ - int isrc, anyerror = 0, thiserror; - CURL *easyhandle; - struct grst_header_data header_data; - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "PUT"); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Make directory %s\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_ping(struct grst_stream_data *common_data_ptr) -{ - int request_length, response_length, i, ret, s, igroup; - struct sockaddr_in srv, from; - socklen_t fromlen; -#define MAXBUF 8192 - char *request, response[MAXBUF], *p; - GRSThtcpMessage msg; - struct timeval start_timeval, wait_timeval, response_timeval; - struct grst_sitecast_group sitecast_groups[HTCP_SITECAST_GROUPS]; - fd_set readsckts; - - /* parse common_data_ptr->groups */ - - p = common_data_ptr->groups; - igroup = -1; - - for (igroup=-1; igroup+1 < HTCP_SITECAST_GROUPS; ++igroup) - { - sitecast_groups[igroup+1].port = GRST_HTCP_PORT; - sitecast_groups[igroup+1].timewait = 1; - sitecast_groups[igroup+1].ttl = 1; - - ret = sscanf(p, "%d.%d.%d.%d:%d:%d:%d", - &(sitecast_groups[igroup+1].quad1), - &(sitecast_groups[igroup+1].quad2), - &(sitecast_groups[igroup+1].quad3), - &(sitecast_groups[igroup+1].quad4), - &(sitecast_groups[igroup+1].port), - &(sitecast_groups[igroup+1].ttl), - &(sitecast_groups[igroup+1].timewait)); - - if (ret == 0) break; /* end of list ? */ - - if (ret < 5) - { - fprintf(stderr, "Failed to parse multicast group " - "parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - ++igroup; - - if ((p = index(p, ',')) == NULL) break; - ++p; - } - - if (igroup == -1) - { - fprintf(stderr, "Failed to parse multicast group parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - { - fprintf(stderr, "Failed to open UDP socket\n"); - return CURLE_FAILED_INIT; - } - - /* loop through multicast groups and send off the NOP pings */ - - gettimeofday(&start_timeval, NULL); - - for (i=0; i <= igroup; ++i) - { - bzero(&srv, sizeof(srv)); - srv.sin_family = AF_INET; - srv.sin_port = htons(sitecast_groups[i].port); - srv.sin_addr.s_addr = htonl(sitecast_groups[i].quad1*0x1000000 - + sitecast_groups[i].quad2*0x10000 - + sitecast_groups[i].quad3*0x100 - + sitecast_groups[i].quad4); - - GRSThtcpNOPrequestMake(&request, &request_length, - (int) (start_timeval.tv_usec + i)); - - sendto(s, request, request_length, 0, (struct sockaddr *) &srv, - sizeof(srv)); - free(request); - - if (common_data_ptr->verbose > 0) - fprintf(stderr, "UDP/HTCP NOP ping to %d:%d:%d:%d %d\n", - sitecast_groups[i].quad1, - sitecast_groups[i].quad2, - sitecast_groups[i].quad3, - sitecast_groups[i].quad4, - sitecast_groups[i].port); - } - - /* reusing wait_timeval is a Linux-specific feature of select() */ - wait_timeval.tv_sec = common_data_ptr->timeout - ? common_data_ptr->timeout : 60; - wait_timeval.tv_usec = 0; - - while ((wait_timeval.tv_sec > 0) || (wait_timeval.tv_usec > 0)) - { - FD_ZERO(&readsckts); - FD_SET(s, &readsckts); - - ret = select(s + 1, &readsckts, NULL, NULL, &wait_timeval); - gettimeofday(&response_timeval, NULL); - - if (ret > 0) - { - response_length = recvfrom(s, response, MAXBUF, - 0, &from, &fromlen); - - if (common_data_ptr->verbose > 0) - fprintf(stderr, "UDP mesg from %s:%d\n", - inet_ntoa(from.sin_addr), ntohs(from.sin_port)); - - if ((GRSThtcpMessageParse(&msg, response, response_length) - == GRST_RET_OK) && - (msg.opcode == GRSThtcpNOPop) && (msg.rr == 1) && - (msg.trans_id >= (int) start_timeval.tv_usec) && - (msg.trans_id <= (int) (start_timeval.tv_usec + igroup))) - { - printf("%s:%d %.3fms\n", - inet_ntoa(from.sin_addr), - ntohs(from.sin_port), - (((long) 1000000 * response_timeval.tv_sec) + - ((long) response_timeval.tv_usec) - - ((long) 1000000 * start_timeval.tv_sec) - - ((long) start_timeval.tv_usec)) / 1000.0); - } - } - } - - return GRST_RET_OK; -} - -int do_finds(char *sources[], - struct grst_stream_data *common_data_ptr, int num) -{ - int isrc; - - int request_length, response_length, i, ret, s, igroup; - struct sockaddr_in srv, from; - socklen_t fromlen; -#define MAXBUF 8192 - char *request, response[MAXBUF], *p; - GRSThtcpMessage msg; - struct timeval start_timeval, wait_timeval; - struct grst_sitecast_group sitecast_groups[HTCP_SITECAST_GROUPS]; - fd_set readsckts; - - /* parse common_data_ptr->groups */ - - if (common_data_ptr->groups == NULL) - { - fprintf(stderr, "No multicast groups given\n"); - return CURLE_FAILED_INIT; - } - - p = common_data_ptr->groups; - igroup = -1; - - for (igroup=-1; igroup+1 < HTCP_SITECAST_GROUPS;) - { - sitecast_groups[igroup+1].port = GRST_HTCP_PORT; - sitecast_groups[igroup+1].timewait = 1; - sitecast_groups[igroup+1].ttl = 1; - - ret = sscanf(p, "%d.%d.%d.%d:%d:%d:%d", - &(sitecast_groups[igroup+1].quad1), - &(sitecast_groups[igroup+1].quad2), - &(sitecast_groups[igroup+1].quad3), - &(sitecast_groups[igroup+1].quad4), - &(sitecast_groups[igroup+1].port), - &(sitecast_groups[igroup+1].ttl), - &(sitecast_groups[igroup+1].timewait)); - - if (ret == 0) break; /* end of list ? */ - - if (ret < 5) - { - fprintf(stderr, "Failed to parse multicast group " - "parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - ++igroup; - - if ((p = index(p, ',')) == NULL) break; - ++p; - } - - if (igroup == -1) - { - fprintf(stderr, "Failed to parse multicast group parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - { - fprintf(stderr, "Failed to open UDP socket\n"); - return CURLE_FAILED_INIT; - } - - /* loop through multicast groups since we need to take each - ones timewait into account */ - - gettimeofday(&start_timeval, NULL); - - for (i=0; i <= igroup; ++i) - { - if (common_data_ptr->verbose) - fprintf(stderr, "Querying multicast group %d.%d.%d.%d:%d:%d:%d\n", - sitecast_groups[i].quad1, sitecast_groups[i].quad2, - sitecast_groups[i].quad3, sitecast_groups[i].quad4, - sitecast_groups[i].port, sitecast_groups[i].ttl, - sitecast_groups[i].timewait); - - bzero(&srv, sizeof(srv)); - srv.sin_family = AF_INET; - srv.sin_port = htons(sitecast_groups[i].port); - srv.sin_addr.s_addr = htonl(sitecast_groups[i].quad1*0x1000000 - + sitecast_groups[i].quad2*0x10000 - + sitecast_groups[i].quad3*0x100 - + sitecast_groups[i].quad4); - - /* send off queries, one for each source file */ - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - GRSThtcpTSTrequestMake(&request, &request_length, - (int) (start_timeval.tv_usec + isrc), - "GET", sources[isrc], ""); - - sendto(s, request, request_length, 0, - (struct sockaddr *) &srv, sizeof(srv)); - - free(request); - } - - /* reusing wait_timeval is a Linux-specific feature of select() */ - wait_timeval.tv_usec = 0; - wait_timeval.tv_sec = sitecast_groups[i].timewait; - - while ((wait_timeval.tv_sec > 0) || (wait_timeval.tv_usec > 0)) - { - FD_ZERO(&readsckts); - FD_SET(s, &readsckts); - - ret = select(s + 1, &readsckts, NULL, NULL, &wait_timeval); - - if (ret > 0) - { - response_length = recvfrom(s, response, MAXBUF, - 0, &from, &fromlen); - - if ((GRSThtcpMessageParse(&msg, response, response_length) - == GRST_RET_OK) && - (msg.opcode == GRSThtcpTSTop) && (msg.rr == 1) && - (msg.trans_id >= (int) start_timeval.tv_usec) && - (msg.trans_id < (int) (start_timeval.tv_usec + num)) && - (msg.resp_hdrs != NULL) && - (GRSThtcpCountstrLen(msg.resp_hdrs) > 12)) - { - if (num > 1) printf("%s -> %.*s\n", - sources[msg.trans_id - (int) start_timeval.tv_usec], - GRSThtcpCountstrLen(msg.resp_hdrs) - 12, - &(msg.resp_hdrs->text[10])); - else printf("%.*s\n", - GRSThtcpCountstrLen(msg.resp_hdrs) - 12, - &(msg.resp_hdrs->text[10])); - } - } - } - - } - - return GRST_RET_OK; -} - -int translate_sitecast_url(char **source_ptr, - struct grst_stream_data *common_data_ptr) -{ - int request_length, response_length, i, ret, s, igroup; - struct sockaddr_in srv, from; - socklen_t fromlen; -#define MAXBUF 8192 - char *request, response[MAXBUF], *p; - GRSThtcpMessage msg; - struct timeval start_timeval, wait_timeval; - struct grst_sitecast_group sitecast_groups[HTCP_SITECAST_GROUPS]; - fd_set readsckts; - - /* parse common_data_ptr->groups */ - - if (common_data_ptr->groups == NULL) - { - fprintf(stderr, "No multicast groups given\n"); - return CURLE_FAILED_INIT; - } - - p = common_data_ptr->groups; - igroup = -1; - - for (igroup=-1; igroup+1 < HTCP_SITECAST_GROUPS;) - { - sitecast_groups[igroup+1].port = GRST_HTCP_PORT; - sitecast_groups[igroup+1].timewait = 1; - sitecast_groups[igroup+1].ttl = 1; - - ret = sscanf(p, "%d.%d.%d.%d:%d:%d:%d", - &(sitecast_groups[igroup+1].quad1), - &(sitecast_groups[igroup+1].quad2), - &(sitecast_groups[igroup+1].quad3), - &(sitecast_groups[igroup+1].quad4), - &(sitecast_groups[igroup+1].port), - &(sitecast_groups[igroup+1].ttl), - &(sitecast_groups[igroup+1].timewait)); - - if (ret == 0) break; /* end of list ? */ - - if (ret < 5) - { - fprintf(stderr, "Failed to parse multicast group " - "parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - ++igroup; - - if ((p = index(p, ',')) == NULL) break; - ++p; - } - - if (igroup == -1) - { - fprintf(stderr, "Failed to parse multicast group parameter %s\n", p); - return CURLE_FAILED_INIT; - } - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - { - fprintf(stderr, "Failed to open UDP socket\n"); - return CURLE_FAILED_INIT; - } - - /* loop through multicast groups since we need to take each - ones timewait into account */ - - gettimeofday(&start_timeval, NULL); - - for (i=0; i <= igroup; ++i) - { - if (common_data_ptr->verbose) - fprintf(stderr, "Querying multicast group %d.%d.%d.%d:%d:%d:%d\n", - sitecast_groups[i].quad1, sitecast_groups[i].quad2, - sitecast_groups[i].quad3, sitecast_groups[i].quad4, - sitecast_groups[i].port, sitecast_groups[i].ttl, - sitecast_groups[i].timewait); - - bzero(&srv, sizeof(srv)); - srv.sin_family = AF_INET; - srv.sin_port = htons(sitecast_groups[i].port); - srv.sin_addr.s_addr = htonl(sitecast_groups[i].quad1*0x1000000 - + sitecast_groups[i].quad2*0x10000 - + sitecast_groups[i].quad3*0x100 - + sitecast_groups[i].quad4); - - /* send off queries, one for each source file */ - - GRSThtcpTSTrequestMake(&request, &request_length, - (int) (start_timeval.tv_usec), - "GET", *source_ptr, ""); - - sendto(s, request, request_length, 0, - (struct sockaddr *) &srv, sizeof(srv)); - - free(request); - - /* reusing wait_timeval is a Linux-specific feature of select() */ - wait_timeval.tv_usec = 0; - wait_timeval.tv_sec = sitecast_groups[i].timewait; - - while ((wait_timeval.tv_sec > 0) || (wait_timeval.tv_usec > 0)) - { - FD_ZERO(&readsckts); - FD_SET(s, &readsckts); - - ret = select(s + 1, &readsckts, NULL, NULL, &wait_timeval); - - if (ret > 0) - { - response_length = recvfrom(s, response, MAXBUF, - 0, &from, &fromlen); - - if ((GRSThtcpMessageParse(&msg, response, response_length) - == GRST_RET_OK) && - (msg.opcode == GRSThtcpTSTop) && (msg.rr == 1) && - (msg.trans_id == (int) start_timeval.tv_usec) && - (msg.resp_hdrs != NULL) && - (GRSThtcpCountstrLen(msg.resp_hdrs) > 12)) - { - /* found one */ - - if (common_data_ptr->verbose > 0) - fprintf(stderr, "Sitecast %s -> %.*s\n", - *source_ptr, - GRSThtcpCountstrLen(msg.resp_hdrs) - 12, - &(msg.resp_hdrs->text[10])); - - free(*source_ptr); - - asprintf(source_ptr, "%.*s", - GRSThtcpCountstrLen(msg.resp_hdrs) - 12, - &(msg.resp_hdrs->text[10])); - - return GRST_RET_OK; - } - } - } - - } - - return GRST_RET_OK; -} - -size_t rawindex_callback(void *ptr, size_t size, size_t nmemb, void *data) -{ - if ( ((struct grst_index_blob *) data)->used + size * nmemb >= - ((struct grst_index_blob *) data)->allocated ) - { - ((struct grst_index_blob *) data)->allocated = - ((struct grst_index_blob *) data)->used + size * nmemb + 4096; - - ((struct grst_index_blob *) data)->text = - realloc( ((struct grst_index_blob *) data)->text, - ((struct grst_index_blob *) data)->allocated ); - } - - memcpy( &( ((struct grst_index_blob *) - data)->text[((struct grst_index_blob *) data)->used] ), - ptr, size * nmemb); - - ((struct grst_index_blob *) data)->used += size * nmemb; - - return size * nmemb; -} - -char *canonicalise(char *link, char *source) -{ - int i, j, srclen; - char *s; - - srclen = strlen(source); - - if ((strncmp(link, "https://", 8) == 0) || - (strncmp(link, "http://", 7) == 0)) - { - if (strncmp(link, source, srclen) != 0) return NULL; /* other site */ - - if (link[srclen] == '\0') return NULL; /* we dont self-link! */ - - for (i=0; link[srclen + i] != '\0'; ++i) - if (link[srclen + i] == '/') - { - if (link[srclen + i + 1] != '\0') return NULL; /* no subdirs */ - else return strdup(&link[srclen]); /* resolves to this dir */ - } - } - else if (link[0] != '/') /* relative link - need to check for subsubdirs */ - { - for (i=0; link[i] != '\0'; ++i) - if ((link[i] == '/') && (link[i+1] != '\0')) return NULL; - - s = strdup(link); - - for (i=0; s[i] != '\0'; ++i) - if (s[i] == '#') - { - s[i] = '\0'; - break; - } - - return s; - } - - /* absolute link on this server, starting / */ - - for (i=8; source[i] != '\0'; ++i) if (source[i] == '/') break; - - if (strncmp(link, &source[i], srclen - i) != 0) return NULL; - - for (j = srclen - i; link[j] != '\0'; ++j) - if ((link[j] == '/') && (link[j+1] != '\0')) return NULL; - - s = strdup(&link[srclen - i]); - - for (i=0; s[i] != '\0'; ++i) - if (s[i] == '#') - { - s[i] = '\0'; - break; - } - - if (s[0] == '\0') /* on second thoughts... */ - { - free(s); - return NULL; - } - - return s; -} - -int grst_dir_list_cmp(const void *a, const void *b) -{ - return strcmp( ((struct grst_dir_list *) a)->filename, - ((struct grst_dir_list *) b)->filename); -} - -struct grst_dir_list *index_to_dir_list(char *text, char *source) -{ - int taglevel = 0, wordnew = 1, i, namestart, used = 0, - allocated = 256; - char *p, *s; - struct grst_dir_list *list; - - list = (struct grst_dir_list *) - malloc(allocated * sizeof(struct grst_dir_list)); - - list[0].filename = NULL; - list[0].length = 0; - list[0].length_set = 0; - list[0].modified = 0; - list[0].modified_set = 0; - - for (p=text; *p != '\0'; ++p) - { - if (*p == '<') - { - ++taglevel; - - if ((taglevel == 1) && (list[used].filename != NULL)) - { - ++used; - if (used >= allocated) - { - allocated += 256; - list = (struct grst_dir_list *) - realloc((void *) list, - allocated * sizeof(struct grst_dir_list)); - } - - list[used].filename = NULL; - list[used].length = 0; - list[used].length_set = 0; - list[used].modified = 0; - list[used].modified_set = 0; - } - - wordnew = 1; - continue; - } - - if (*p == '>') - { - --taglevel; - wordnew = 1; - continue; - } - - if (isspace(*p)) - { - wordnew = 1; - continue; - } - - if ((wordnew) && (taglevel == 1)) - { - if (((*p == 'h') || (*p == 'H')) && - (strncasecmp(p, "href=", 5) == 0)) - { - if (p[5] == '"') { namestart = 6; - for (i=namestart; (p[i] != '\0') && - (p[i] != '"' ) && - (p[i] != '\n') && - (p[i] != '\t') && - (p[i] != '>' ) ; ++i) ; } - else { namestart = 5; - for (i=namestart; (p[i] != '\0') && - (p[i] != '"' ) && - (p[i] != ' ' ) && - (p[i] != '\n') && - (p[i] != '\t') && - (p[i] != ')' ) && - (p[i] != '>' ) ; ++i) ; } - if (i > namestart) - { - s = malloc(1 + i - namestart); - memcpy(s, &p[namestart], i - namestart); - s[i - namestart] = '\0'; - - list[used].filename = canonicalise(s, source); - free(s); - } - - p = &p[i-1]; /* -1 since continue results in ++i */ - continue; - } - - if (((*p == 'c') || (*p == 'C')) && - (strncasecmp(p, "content-length=", 15) == 0)) - { - list[used].length = 0; - list[used].length_set = 1; - - if (p[15] == '"') list[used].length = atoi(&p[16]); - else list[used].length = atoi(&p[15]); - - p = &p[15]; - continue; - } - - if (((*p == 'l') || (*p == 'L')) && - (strncasecmp(p, "last-modified=", 14) == 0)) - { - list[used].modified = 0; - list[used].modified_set = 1; - - if (p[14] == '"') list[used].modified = atoi(&p[15]); - else list[used].modified = atoi(&p[14]); - - p = &p[14]; - continue; - } - } - - wordnew = 0; - } - - qsort((void *) list, used, sizeof(struct grst_dir_list), grst_dir_list_cmp); - - return list; -} - -int do_listings(char *sources[], struct grst_stream_data *common_data, - int islonglist) -{ - int isrc, anyerror = 0, thiserror, i, isdir, ilast; - CURL *easyhandle; - const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - char *s; - struct grst_index_blob rawindex; - struct grst_dir_list *list; - struct grst_header_data header_data; - struct tm modified_tm; - time_t now; - - time(&now); - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Listing %s\n", sources[isrc]); - - if (sources[1] != NULL) printf("\n%s:\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - if (sources[isrc][strlen(sources[isrc])-1] == '/') - { - isdir = 1; - curl_easy_setopt(easyhandle,CURLOPT_WRITEFUNCTION,rawindex_callback); - curl_easy_setopt(easyhandle,CURLOPT_WRITEDATA,(void *) &rawindex); - curl_easy_setopt(easyhandle,CURLOPT_NOBODY,0); - rawindex.text = NULL; - rawindex.used = 0; - rawindex.allocated = 0; - } - else - { - isdir = 0; - curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, NULL); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - } - - header_data.gridhttppasscode = NULL; - header_data.length_set = 0; - header_data.modified_set = 0; - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (isdir) - { - if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - rawindex.text[rawindex.used] = '\0'; - - list = index_to_dir_list(rawindex.text, sources[isrc]); - ilast = -1; - - for (i=0; list[i].filename != NULL; ++i) - { - if (list[i].filename[0] == '.') continue; - - if (strncmp(list[i].filename, "mailto:", 7) == 0) continue; - - if ((ilast >= 0) && - (strcmp(list[i].filename, list[ilast].filename) == 0)) - continue; - ilast=i; - - if (islonglist) - { - if (!list[i].length_set || !list[i].modified_set) - { - curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, - NULL); - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, NULL); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - asprintf(&s, "%s%s", sources[isrc], list[i].filename); - curl_easy_setopt(easyhandle, CURLOPT_URL, s); - - header_data.gridhttppasscode = NULL; - header_data.length_set = 0; - header_data.modified_set = 0; - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - free(s); - - if ((thiserror == 0) && - (header_data.retcode >= 200) && - (header_data.retcode <= 299)) - { - if (header_data.length_set) - { - list[i].length_set = 1; - list[i].length = header_data.length; - } - - if (header_data.modified_set) - { - list[i].modified_set = 1; - list[i].modified = header_data.modified; - } - } - } - - if (list[i].length_set) printf("%10ld ", list[i].length); - else fputs(" ? ", stdout); - - if (list[i].modified_set) - { - localtime_r(&(list[i].modified), &modified_tm); - - if (list[i].modified < now - 15552000) - printf("%s %2d %4d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_year + 1900); - else printf("%s %2d %02d:%02d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_hour, - modified_tm.tm_min); - } - else fputs(" ? ? ? ", stdout); - } - - puts(list[i].filename); - } - } - else - { - if (islonglist) - { - printf("%10ld ", header_data.length); - - localtime_r(&(header_data.modified), &modified_tm); - - if (header_data.modified < now - 15552000) - printf("%s %2d %4d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_year + 1900); - else printf("%s %2d %02d:%02d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_hour, - modified_tm.tm_min); - } - - puts(sources[isrc]); - } - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -#if (LIBCURL_VERSION_NUM < 0x070908) -char *make_tmp_ca_roots(char *dir) -/* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory, - so we make a temporary file with the concatenated CA root certs: that - is, all the files in that directory which end in .0 */ -{ - int ofd, ifd, c; - size_t size; - char tmp_ca_roots[] = "/tmp/.ca-roots-XXXXXX", buffer[4096], *s; - DIR *rootsDIR; - struct dirent *root_ent; - - if ((rootsDIR = opendir(dir)) == NULL) return NULL; - - if ((ofd = mkstemp(tmp_ca_roots)) == -1) - { - closedir(rootsDIR); - return NULL; - } - - while ((root_ent = readdir(rootsDIR)) != NULL) - { - if ((root_ent->d_name[0] != '.') && - (strlen(root_ent->d_name) > 2) && - (strncmp(&(root_ent->d_name[strlen(root_ent->d_name)-2]), - ".0", 2) == 0)) - { - asprintf(&s, "%s/%s", dir, root_ent->d_name); - ifd = open(s, O_RDONLY); - free(s); - - if (ifd != -1) - { - while ((size = read(ifd, buffer, sizeof(buffer))) > 0) - write(ofd, buffer, size); - close(ifd); - } - } - } - - closedir(rootsDIR); - - if (close(ofd) == 0) return strdup(tmp_ca_roots); - - unlink(tmp_ca_roots); /* try to clean up */ - - return NULL; -} -#endif - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [options] Source-URL[s] [Destination URL]\n" - "%s is one of a set of clients to fetch files or directory listings\n" -"from remote servers using HTTP or HTTPS, or to put or delete files or\n" -"directories onto remote servers using HTTPS. htcp is similar to scp(1)\n" -"but uses HTTP/HTTPS rather than ssh as its transfer protocol.\n" -"See the htcp(1) or http://www.gridsite.org/ for details.\n" -"(Version: %s)\n", p, p, VERSION); -} - -struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"cert", 1, 0, 0}, - {"key", 1, 0, 0}, - {"capath", 1, 0, 0}, - {"delete", 0, 0, 0}, - {"list", 0, 0, 0}, - {"long-list", 0, 0, 0}, - {"mkdir", 0, 0, 0}, - {"no-verify", 0, 0, 0}, - {"anon", 0, 0, 0}, - {"grid-http", 0, 0, 0}, - {"move", 0, 0, 0}, - {"ping", 0, 0, 0}, - {"groups", 1, 0, 0}, - {"timeout", 1, 0, 0}, - {"sitecast", 0, 0, 0}, - {"domain", 1, 0, 0}, - {"find", 0, 0, 0}, - {"rmtcp", 0, 0, 0}, - {"conf", 1, 0, 0}, - {0, 0, 0, 0} }; - -int update_common_data(struct grst_stream_data *, int, char *); - -void parse_conf(struct grst_stream_data *common_data_ptr, char *conf_file) -{ - int option_index; - char line[1001], *p; - FILE *fp; - - fp = fopen(conf_file, "r"); - if (fp == NULL) - { - if (common_data_ptr->verbose) - fprintf(stderr, "Failed to open configuration file %s\n", conf_file); - return; - } - - if (common_data_ptr->verbose) - fprintf(stderr, "Opened configuration file %s\n", conf_file); - - while (fgets(line, sizeof(line), fp) != NULL) - { - if ((p = index(line, '\n')) != NULL) *p = '\0'; - - for (option_index=0; - long_options[option_index].name != NULL; ++option_index) - { - if (long_options[option_index].has_arg && - (strncmp(line, long_options[option_index].name, - strlen(long_options[option_index].name)) == 0) && - (line[strlen(long_options[option_index].name)] == '=')) - { - update_common_data(common_data_ptr, option_index, - strdup(&line[strlen(long_options[option_index].name) + 1])); - break; - } - - if (!long_options[option_index].has_arg && - (strcmp(line, long_options[option_index].name) == 0)) - { - update_common_data(common_data_ptr, option_index, ""); - break; - } - } - } - - fclose(fp); -} - -int update_common_data(struct grst_stream_data *common_data_ptr, - int option_index, char *optarg) -{ - if (option_index == 1) common_data_ptr->cert = optarg; - else if (option_index == 2) common_data_ptr->key = optarg; - else if (option_index == 3) common_data_ptr->capath = optarg; - else if (option_index == 4) common_data_ptr->method = HTCP_DELETE; - else if (option_index == 5) common_data_ptr->method = HTCP_LIST; - else if (option_index == 6) common_data_ptr->method = HTCP_LONGLIST; - else if (option_index == 7) common_data_ptr->method = HTCP_MKDIR; - else if (option_index == 8) common_data_ptr->noverify = 1; - else if (option_index == 9) common_data_ptr->anonymous = 1; - else if (option_index ==10) common_data_ptr->gridhttp = 1; - else if (option_index ==11) common_data_ptr->method = HTCP_MOVE; - else if (option_index ==12) common_data_ptr->method = HTCP_PING; - else if (option_index ==13) common_data_ptr->groups = optarg; - else if (option_index ==14) common_data_ptr->timeout = atoi(optarg); - else if (option_index ==15) common_data_ptr->sitecast = 1; - else if (option_index ==16) { common_data_ptr->sitecast = 1; - common_data_ptr->domain = optarg; } - else if (option_index ==17) common_data_ptr->method = HTCP_FIND; - else if (option_index ==18) { printf("OK\n");common_data_ptr->method = HTCP_RMTCP;} - /* option_index == 19 is used by the --conf command line-only option */ - else return GRST_RET_FAILED; - - return GRST_RET_OK; -} - -int main(int argc, char *argv[]) -{ - char **sources, *destination = NULL, *executable, *p, *htcp_conf; - int c, i, option_index, anyerror; - struct stat statbuf; - struct grst_stream_data common_data; - struct passwd *userpasswd; - -#if (LIBCURL_VERSION_NUM < 0x070908) - char *tmp_ca_roots = NULL; -#endif - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - common_data.cert = NULL; - common_data.key = NULL; - common_data.capath = NULL; - common_data.method = 0; - common_data.errorbuf = malloc(CURL_ERROR_SIZE); - asprintf(&(common_data.useragent), - "htcp/%s (http://www.gridsite.org/)", VERSION); - common_data.verbose = 0; - common_data.noverify = 0; - common_data.anonymous = 0; - common_data.gridhttp = 0; - - common_data.groups = NULL; - common_data.timeout = 0; - common_data.sitecast = 0; - common_data.domain = NULL; - - if ((argc > 1) && ((strcmp(argv[1], "--verbose") == 0) || - (strcmp(argv[1], "-v") == 0))) common_data.verbose = 1; - - /* examine any configuration files */ - - parse_conf(&common_data, HTCP_HOST_CONF); - - userpasswd = getpwuid(geteuid()); - asprintf(&htcp_conf, "%s/%s", userpasswd->pw_dir, HTCP_USER_CONF); - parse_conf(&common_data, htcp_conf); - free(htcp_conf); - - htcp_conf = getenv("HTCP_CONF"); - if (htcp_conf != NULL) parse_conf(&common_data, htcp_conf); - - common_data.verbose = 0; - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 19) parse_conf(&common_data, optarg); - else update_common_data(&common_data, option_index, optarg); - } - else if (c == 'v') ++(common_data.verbose); - } - - if (common_data.verbose > 0) - { - p = rindex(argv[0], '/'); - if (p != NULL) ++p; - else p = argv[0]; - fprintf(stderr, "%s version %s\n", p, VERSION); - } - - if (common_data.anonymous) /* prevent any use of user certs */ - { - common_data.cert = NULL; - common_data.key = NULL; - } - else if ((common_data.cert == NULL) && (common_data.key != NULL)) - common_data.cert = common_data.key; - else if ((common_data.cert != NULL) && (common_data.key == NULL)) - common_data.key = common_data.cert; - else if ((common_data.cert == NULL) && (common_data.key == NULL)) - { - common_data.cert = getenv("X509_USER_PROXY"); - if (common_data.cert != NULL) common_data.key = common_data.cert; - else - { - asprintf(&(common_data.cert), "/tmp/x509up_u%d", geteuid()); - - /* one fine day, we will check the proxy file for expiry too ... */ - - if (stat(common_data.cert, &statbuf) == 0) - common_data.key = common_data.cert; - else - { - common_data.cert = getenv("X509_USER_CERT"); - common_data.key = getenv("X509_USER_KEY"); - - if ((common_data.cert == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(common_data.cert), "%s/.globus/usercert.pem", - userpasswd->pw_dir); - - if ((common_data.key == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(common_data.key), "%s/.globus/userkey.pem", - userpasswd->pw_dir); - } - } - } - - if (common_data.capath == NULL) common_data.capath = getenv("X509_CERT_DIR"); - - if (common_data.capath == NULL) - common_data.capath = "/etc/grid-security/certificates"; - -#if (LIBCURL_VERSION_NUM < 0x070908) - /* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory */ - - if ((common_data.capath != NULL) && - (stat(common_data.capath, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - tmp_ca_roots = make_tmp_ca_roots(common_data.capath); - common_data.capath = tmp_ca_roots; - } -#endif - - executable = rindex(argv[0], '/'); - if (executable != NULL) executable++; - else executable = argv[0]; - - if (common_data.method == 0) /* command-line options override exec name */ - { - if (strcmp(executable,"htls")==0) common_data.method=HTCP_LIST; - else if (strcmp(executable,"htll")==0) common_data.method=HTCP_LONGLIST; - else if (strcmp(executable,"htrm")==0) common_data.method=HTCP_DELETE; - else if (strcmp(executable,"htmkdir")==0) common_data.method=HTCP_MKDIR; - else if (strcmp(executable,"htmv")==0) common_data.method=HTCP_MOVE; - else if (strcmp(executable,"htping")==0) common_data.method=HTCP_PING; - else if (strcmp(executable,"htfind")==0) common_data.method=HTCP_FIND; - else if (strcmp(executable,"htrmtcp")==0) common_data.method=HTCP_RMTCP; - } - - if (common_data.method == HTCP_PING) - { - if (common_data.groups != NULL) return do_ping(&common_data); - - fprintf(stderr, "Must specify at least one multicast group\n\n"); - printsyntax(argv[0]); - return CURLE_FAILED_INIT; - } - - if ((common_data.method == HTCP_DELETE) || - (common_data.method == HTCP_LIST) || - (common_data.method == HTCP_FIND) || - (common_data.method == HTCP_MKDIR) || - (common_data.method == HTCP_LONGLIST)) - { - if (optind >= argc) - { - fprintf(stderr, "Must give at least 1 non-option argument\n\n"); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - sources = (char **) malloc(sizeof(char *) * (1 + argc - optind)); - for (i=0; i < argc - optind; ++i) - { - sources[i] = argv[optind + i]; - - if ((common_data.method == HTCP_MKDIR) && - (sources[i][strlen(sources[i])-1] != '/')) - { - fprintf(stderr, "Argument \"%s\" is not a " - "directory URL (no trailing /)\n\n", sources[i]); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - } - - sources[i] = NULL; - - if (common_data.method == HTCP_DELETE) - anyerror = do_deletes(sources, &common_data); - else if (common_data.method == HTCP_MKDIR) - anyerror = do_mkdirs(sources, &common_data); - else if (common_data.method == HTCP_FIND) - anyerror = do_finds(sources, &common_data, argc - optind); - else if (common_data.method == HTCP_LONGLIST) - anyerror = do_listings(sources, &common_data, 1); - else anyerror = do_listings(sources, &common_data, 0); - - if (anyerror > 99) anyerror = CURLE_HTTP_RETURNED_ERROR; - - return anyerror; - } - - if (common_data.method == HTCP_MOVE) - { - if (optind >= argc - 1) - { - fputs("Must give exactly 2 non-option arguments\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - anyerror = do_move(argv[optind], argv[optind + 1], &common_data); - - if (anyerror > 99) anyerror = CURLE_HTTP_RETURNED_ERROR; - - return anyerror; - } - - if (optind >= argc - 1) - { - fputs("Must give at least 2 non-option arguments\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - sources = (char **) malloc(sizeof(char *) * (argc - optind)); - - for (i=0; i < (argc - optind - 1); ++i) - { - if (strncmp(argv[optind + i], "file:", 5) == 0) - sources[i] = strdup(&argv[optind + i][5]); - else sources[i] = strdup(argv[optind + i]); - - if (sources[i][0] == '\0') - { - fprintf(stderr, "Source argument %d is empty\n\n", i + 1); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - } - - sources[i] = NULL; - - if (strncmp(argv[optind+i], "file:", 5) == 0) - { - if ((argv[optind+i][strlen(argv[optind+i]) - 1] != '/') && - (stat(&argv[optind + i][5], &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) - asprintf(&destination, "%s/", &argv[optind + i][5]); - else destination = strdup(&argv[optind + i][5]); - } - else if ((strncmp(argv[optind+i], "http://", 7) != 0) && - (strncmp(argv[optind+i], "https://", 8) != 0)) - { - if ((argv[optind+i][strlen(argv[optind+i]) - 1] != '/') && - (stat(argv[optind+i], &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) - asprintf(&destination, "%s/", argv[optind+i]); - else destination = strdup(argv[optind+i]); - } - else destination = strdup(argv[optind+i]); - - if (destination[0] == '\0') - { - fputs("Destination argument is empty\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((argc - optind > 2) && (destination[strlen(destination)-1] != '/')) - { - fputs("For multiple sources, destination " - "must be a directory (end in /)\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - // remote file copy - if ( common_data.method == HTCP_RMTCP ) - { - anyerror = do_rmtcp(sources, destination, &common_data); - fprintf(stdout, "The file has been moved!\n"); - // printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((strncmp(destination, "http://", 7) == 0) || - (strncmp(destination, "https://", 8) == 0)) - common_data.method = HTCP_PUT; - else common_data.method = HTCP_GET; - - for (i=0; sources[i] != NULL; ++i) - { - if ((common_data.method == HTCP_PUT) && - ((strncmp(sources[i], "http://", 7) == 0) || - (strncmp(sources[i], "https://", 8) == 0))) - { - fputs("Cannot have both source and destination remote\n\n",stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if (common_data.method == HTCP_GET) - { - if ((strncmp(sources[i], "http://", 7) != 0) && - (strncmp(sources[i], "https://", 8) != 0)) - { - fputs("Cannot have both source and " - "destination local (for now)\n\n",stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((common_data.sitecast) && - ((common_data.domain == NULL) || - - ((strncmp(sources[i], "http://", 7) == 0) && - (strncmp(&sources[i][7], common_data.domain, - strlen(common_data.domain)) == 0) && - ((sources[i][7+strlen(common_data.domain)] == ':') || - (sources[i][7+strlen(common_data.domain)] == '/'))) || - - ((strncmp(sources[i], "https://", 8) == 0) && - (strncmp(&sources[i][8], common_data.domain, - strlen(common_data.domain)) == 0) && - ((sources[i][8+strlen(common_data.domain)] == ':') || - (sources[i][8+strlen(common_data.domain)] == '/'))))) - { - translate_sitecast_url(&sources[i], &common_data); - } - } - } - - anyerror = do_copies(sources, destination, &common_data); - if (anyerror > 99) anyerror = CURLE_HTTP_RETURNED_ERROR; - - return anyerror; -} diff --git a/org.gridsite.core/src/htproxyput.c b/org.gridsite.core/src/htproxyput.c deleted file mode 100644 index 688b509..0000000 --- a/org.gridsite.core/src/htproxyput.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - Copyright (c) 2002-6, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - -Build with: - -gcc -lcurl -lssl -lcrypto -o grst-proxy-put grst-proxy-put.c libgridsite.a - -http://www.gridpp.ac.uk/authz/gridsite/ - -*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include "DelegationSoapBinding.nsmap" - -#define HTPROXY_PUT 0 -#define HTPROXY_RENEW 1 -#define HTPROXY_DESTROY 2 -#define HTPROXY_TIME 3 -#define HTPROXY_UNIXTIME 4 -#define HTPROXY_MAKE 5 -#define HTPROXY_INFO 6 - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [options] URL\n" - "(Version: %s)\n", p, VERSION); -} - -void htproxy_logfunc(char *file, int line, int level, char *fmt, ...) -{ - char *mesg; - va_list ap; - - va_start(ap, fmt); - vasprintf(&mesg, fmt, ap); - va_end(ap); - - fprintf(stderr, "%s(%d) %s\n", file, line, mesg); - - free(mesg); -} - -int main(int argc, char *argv[]) -{ - char *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, - *cert = NULL, *key = NULL, *capath = NULL, *keycert, timestr[81], - *vomsdir = "/etc/grid-security/vomsdir", - *executable, *keytxt, *proxychain, *ptr, *p; - struct ns__putProxyResponse *unused; - struct tm *finish_tm; - int option_index, c, noverify = 0, i, ret, - method = HTPROXY_PUT, verbose = 0, fd, minutes; - struct soap soap_get, soap_put; - struct ns__getProxyReqResponse getProxyReqResponse; - struct ns__getNewProxyReqResponse getNewProxyReqResponse; - struct ns__renewProxyReqResponse renewProxyReqResponse; - struct ns__destroyResponse destroyResponse; - struct ns__getTerminationTimeResponse getTerminationTimeResponse; - FILE *ifp, *ofp; - STACK_OF(X509) *x509_certstack; - X509 *x509_cert; - BIO *certmem; - GRSTx509Chain *grst_chain = NULL; - GRSTx509Cert *grst_cert = NULL; - long ptrlen; - struct stat statbuf; - struct passwd *userpasswd; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"cert", 1, 0, 0}, - {"key", 1, 0, 0}, - {"capath", 1, 0, 0}, - {"destroy", 0, 0, 0}, - {"time", 0, 0, 0}, - {"no-verify", 0, 0, 0}, - {"valid", 1, 0, 0}, - {"delegation-id",1, 0, 0}, - {"put", 0, 0, 0}, - {"renew", 0, 0, 0}, - {"unixtime", 0, 0, 0}, - {"make", 0, 0, 0}, - {"info", 0, 0, 0}, - {0, 0, 0, 0} }; - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 1) cert = optarg; - else if (option_index == 2) key = optarg; - else if (option_index == 3) capath = optarg; - else if (option_index == 4) method = HTPROXY_DESTROY; - else if (option_index == 5) method = HTPROXY_TIME; - else if (option_index == 6) noverify = 1; - else if (option_index == 7) valid = optarg; - else if (option_index == 8) delegation_id = optarg; - else if (option_index == 9) method = HTPROXY_PUT; - else if (option_index == 10) method = HTPROXY_RENEW; - else if (option_index == 11) method = HTPROXY_UNIXTIME; - else if (option_index == 12) method = HTPROXY_MAKE; - else if (option_index == 13) method = HTPROXY_INFO; - } - else if (c == 'v') - { - GRSTerrorLogFunc = htproxy_logfunc; - ++verbose; - } - } - - executable = rindex(argv[0], '/'); - if (executable != NULL) executable++; - else executable = argv[0]; - - if (strcmp(executable, "htproxydestroy") == 0) method = HTPROXY_DESTROY; - else if (strcmp(executable, "htproxyrenew") == 0) method = HTPROXY_RENEW; - else if (strcmp(executable, "htproxytime") == 0) method = HTPROXY_TIME; - else if (strcmp(executable, "htproxyunixtime") == 0) - method = HTPROXY_UNIXTIME; - else if (strcmp(executable, "htproxymake") == 0) method = HTPROXY_MAKE; - else if (strcmp(executable, "htproxyinfo") == 0) method = HTPROXY_INFO; - - if ((method != HTPROXY_MAKE) && - (method != HTPROXY_INFO) && (optind + 1 != argc)) - { - fprintf(stderr, "Must specify a delegation service URL!\n"); - return 1; - } - - if ((method == HTPROXY_RENEW) && (delegation_id[0] == '\0')) - { - fprintf(stderr, "Must give a Delegation ID when renewing\n"); - return 1; - } - - if (valid == NULL) minutes = 60 * 12; - else minutes = atoi(valid); - - if (verbose) fprintf(stderr, "Proxy valid for %d minutes\n", minutes); - - ERR_load_crypto_strings (); - OpenSSL_add_all_algorithms(); - - if ((cert == NULL) && (key != NULL)) cert = key; - else if ((cert != NULL) && (key == NULL)) key = cert; - else if ((cert == NULL) && (key == NULL)) - { - if (method != HTPROXY_MAKE) cert = getenv("X509_USER_PROXY"); - - if (cert != NULL) key = cert; - else - { - if (method != HTPROXY_MAKE) - asprintf(&(cert), "/tmp/x509up_u%d", geteuid()); - - /* one fine day, we will check the proxy file for - expiry too to avoid suprises when we try to use it ... */ - - if (stat(cert, &statbuf) == 0) key = cert; - else if (method != HTPROXY_INFO) - { - cert = getenv("X509_USER_CERT"); - key = getenv("X509_USER_KEY"); - - userpasswd = getpwuid(geteuid()); - - if ((cert == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(cert), "%s/.globus/usercert.pem", - userpasswd->pw_dir); - - if ((key == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(key), "%s/.globus/userkey.pem", - userpasswd->pw_dir); - - } - } - } - - if (capath == NULL) capath = getenv("X509_CERT_DIR"); - if (capath == NULL) capath = "/etc/grid-security/certificates"; - - if (verbose) fprintf(stderr, "key=%s\ncert=%s\ncapath=%s\n", - key, cert, capath); - - if ((key != NULL) && (cert != NULL) && - (strcmp(key, cert) != 0)) /* we have to concatenate for gSOAP */ - { - keycert = strdup("/tmp/.XXXXXX"); - - fd = mkstemp(keycert); - ofp = fdopen(fd, "w"); - - ifp = fopen(key, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); - - ifp = fopen(cert, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); - - fclose(ofp); - - if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert); - } - else keycert = key; - - if ((method == HTPROXY_PUT) || (method == HTPROXY_RENEW)) - { - if (verbose) - { - fprintf(stderr, "Using SOAP delegation protocol\n"); - fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - } - - soap_init(&soap_get); - - if (soap_ssl_client_context(&soap_get, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - if ((method == HTPROXY_RENEW) && (delegation_id[0] != '\0')) - { - if (verbose) fprintf(stderr, "Send renewProxyReq to service\n"); - - soap_call_ns__renewProxyReq(&soap_get, - argv[optind], /* HTTPS url of service */ - "http://www.gridsite.org/namespaces/delegation-1", - delegation_id, - &renewProxyReqResponse); - - if (soap_get.error) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - reqtxt = renewProxyReqResponse._renewProxyReqReturn; - } - else - { - if (verbose) fprintf(stderr, "Send getNewProxyReq to service\n"); - - soap_call_ns__getNewProxyReq(&soap_get, - argv[optind], /* HTTPS url of service */ - "http://www.gridsite.org/namespaces/delegation-1", - &getNewProxyReqResponse); - - if (soap_get.error) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - reqtxt = getNewProxyReqResponse.getNewProxyReqReturn->proxyRequest; - delegation_id = - getNewProxyReqResponse.getNewProxyReqReturn->delegationID; - } - - if (verbose) fprintf(stderr, "reqtxt:\n%s", reqtxt); - - if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) - != GRST_RET_OK) - { - return 1; - } - - soap_init(&soap_put); - - if (verbose) fprintf(stderr, "Send putProxy to service:\n%s\n", certtxt); - - if (soap_ssl_client_context(&soap_put, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - soap_call_ns__putProxy(&soap_put, argv[optind], - "http://www.gridsite.org/namespaces/delegation-1", - delegation_id, - certtxt, unused); - if (soap_put.error) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - puts(delegation_id); - - return 0; - } - else if (method == HTPROXY_DESTROY) - { - if (verbose) - { - fprintf(stderr, "Using SOAP proxy destroy protocol\n"); - fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - } - - soap_init(&soap_put); - - if (verbose) fprintf(stderr, "Send destroy to service:\n"); - - if (soap_ssl_client_context(&soap_put, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - soap_call_ns__destroy(&soap_put, argv[optind], - "http://www.gridsite.org/namespaces/delegation-1", - delegation_id, - &destroyResponse); - if (soap_put.error) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - return 0; - } - else if ((method == HTPROXY_TIME) || (method == HTPROXY_UNIXTIME)) - { - if (verbose) - { - fprintf(stderr, "Using SOAP proxy get expiration time protocol\n"); - fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - } - - soap_init(&soap_put); - - if (verbose) fprintf(stderr, "Send get time to service:\n"); - - if (soap_ssl_client_context(&soap_put, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - soap_call_ns__getTerminationTime(&soap_put, argv[optind], - "http://www.gridsite.org/namespaces/delegation-1", - delegation_id, - &getTerminationTimeResponse); - if (soap_put.error) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - - if (method == HTPROXY_UNIXTIME) - printf("%ld\n", getTerminationTimeResponse._getTerminationTimeReturn); - else - { - finish_tm = - localtime(&(getTerminationTimeResponse._getTerminationTimeReturn)); - - strftime(timestr, sizeof(timestr), - "%a %b %e %H:%M:%S %Z %Y\n", finish_tm); - - fputs(timestr, stdout); - } - - return 0; - } - else if (method == HTPROXY_MAKE) - { - if (GRSTx509CreateProxyRequest(&reqtxt, &keytxt, NULL) != GRST_RET_OK) - { - fprintf(stderr, "Failed to create internal proxy cert request\n"); - return 1; - } - - if (GRSTx509MakeProxyCert(&proxychain, NULL, reqtxt, cert, key, minutes) - != GRST_RET_OK) - { - fprintf(stderr, "Failed to sign internal proxy cert request\n"); - return 2; - } - - if (GRSTx509StringToChain(&x509_certstack, proxychain) != GRST_RET_OK) - { - fprintf(stderr, "Failed to convert internal proxy chain\n"); - return 3; - } - - if (x509_cert = sk_X509_value(x509_certstack, 0)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, x509_cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, stdout); - } - - BIO_free(certmem); - } - - fputs(keytxt, stdout); - - for (i=1; i <= sk_X509_num(x509_certstack) - 1; ++i) - /* loop through the proxy chain starting at 2nd most recent proxy */ - { - if (x509_cert = sk_X509_value(x509_certstack, i)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, x509_cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, stdout); - } - - BIO_free(certmem); - } - } - - sk_X509_free(x509_certstack); - - return 0; - } - else if (method == HTPROXY_INFO) - { - if (cert != NULL) - { - if (verbose) fprintf(stderr, "Getting proxy info from %s\n", cert); - - ifp = fopen(cert, "r"); - if (ifp == NULL) - { - fprintf(stderr, "Failed to open proxy file\n"); - return 2; - } - } - else - { - if (verbose) fprintf(stderr, "Getting proxy info from stdin\n"); - ifp = stdin; - } - - ptrlen = 4096; - ptr = malloc(ptrlen); - i = 0; - - while ((c = fgetc(ifp)) != EOF) - { - ptr[i] = c; - ++i; - - if (i >= ptrlen) - { - ptrlen += 4096; - ptr = realloc(ptr, ptrlen); - } - } - - ptr[i] = '\0'; - if (cert != NULL) fclose(ifp); - - if ((GRSTx509StringToChain(&x509_certstack, ptr) != GRST_RET_OK) || - (x509_certstack == NULL)) - { - fprintf(stderr, "Failed to parse proxy file for certificate chain\n"); - free(ptr); - return 2; - } - - free(ptr); - - if (verbose) fprintf(stderr, "Parsing certificate chain\n"); - - ret = GRSTx509ChainLoadCheck(&grst_chain, x509_certstack, NULL, - capath, vomsdir); - - if ((ret != GRST_RET_OK) || - (grst_chain == NULL) || (grst_chain->firstcert == NULL)) - { - fprintf(stderr, "Failed parsing certificate chain\n"); - return 3; - } - - grst_cert = grst_chain->firstcert; - - for (i=0; grst_cert != NULL; grst_cert = grst_cert->next, ++i) - { - if (grst_cert->type == GRST_CERT_TYPE_CA) p = "(CA) "; - else if (grst_cert->type == GRST_CERT_TYPE_EEC) p = "(EEC) "; - else if (grst_cert->type == GRST_CERT_TYPE_PROXY) p = "(PC) "; - else if (grst_cert->type == GRST_CERT_TYPE_VOMS) p = "(AC) "; - else p = ""; - - printf("%d %s%s\n", i, p, - (grst_cert->type == GRST_CERT_TYPE_VOMS) - ? grst_cert->value : grst_cert->dn); - - printf(" Status : %d ( %s%s%s%s%s%s)\n", grst_cert->errors, - (grst_cert->errors == 0) ? "OK " : "", - (grst_cert->errors & GRST_CERT_BAD_FORMAT) ? "BAD_FORMAT ":"", - (grst_cert->errors & GRST_CERT_BAD_CHAIN) ? "BAD_CHAIN ":"", - (grst_cert->errors & GRST_CERT_BAD_SIG) ? "BAD_SIG ":"", - (grst_cert->errors & GRST_CERT_BAD_TIME) ? "BAD_TIME ":"", - (grst_cert->errors & GRST_CERT_BAD_OCSP) ? "BAD_OCSP ":""); - - printf(" Start : %s", ctime(&(grst_cert->start))); - printf(" Finish : %s", ctime(&(grst_cert->finish))); - - if (grst_cert->type == GRST_CERT_TYPE_VOMS) - { - printf(" User DN : %s\n", grst_cert->dn); - printf(" VOMS DN : %s\n\n", grst_cert->issuer); - } - else - { - printf(" Serial : %d\n", grst_cert->serial); - printf(" Issuer : %s\n\n", grst_cert->issuer); - } - } - - GRSTx509ChainFree(grst_chain); - } - /* weirdness */ -} - diff --git a/org.gridsite.core/src/make-gridsite-spec b/org.gridsite.core/src/make-gridsite-spec deleted file mode 100755 index 3b81780..0000000 --- a/org.gridsite.core/src/make-gridsite-spec +++ /dev/null @@ -1,301 +0,0 @@ -#!/bin/sh - -# test to see if fuse-devel (or fuse.h and libfuse) is installed -# -cat <fuse-test.c -#include -int main() { struct fuse_context ctx; -return fuse_main(0, (char **) 0, (struct fuse_operations *) 0); } -EOF -make fuse-test -if [ $? = 0 ] ; then have_fuse=1 ; fi - -# test to see if gsoap-devel (or stdsoap2.h and libgsoapssl) is installed -# -cat <gsoap-test.c -#include -#ifdef SOAP_BEGIN -main() { return; } -#endif -EOF -make GSOAPDIR=$GSOAPDIR STDSOAP2=$STDSOAP2 gridsite-delegation.cgi -if [ $? = 0 ] ; then have_gsoap=1 ; fi - -cat <gridsite.spec -# -# Autogenerated by make-gridsite-spec -# -# You should modify make-gridsite-spec and rebuild RPM with make rpm -# rather than editing this spec file -# -Name: gridsite -Version: ${PATCH_VERSION:-1.x.x} -# This next piece of .spec/sed magic puts the build OS version in the release -Release: 1%(sed 's/^\([A-Z]\)[^ ]* \([A-Z]\)[^0-9]*\([0-9][^ ]*\).*/\1\2\3/g' /etc/redhat-release | sed 's/[^A-Z,a-z,0-9]//g') -Summary: GridSite -License: Modified BSD -Group: System Environment/Daemons -Source: %{name}-%{version}.src.tar.gz -Prefix: ${MYPREFIX:-/usr} -URL: http://www.gridsite.org/ -Vendor: GridPP -Requires: libxml2 -#Buildrequires: libxml2-devel,curl-ssl-devel,httpd-devel -Packager: Andrew McNab - -%description -GridSite adds GSI, VOMS and GACL support to Apache 2.0 (mod_gridsite), -a library for manipulating these technologies (libgridsite), and CGI -programs for interactive management of HTTP(S) servers (gridsite-admin.cgi) - -See http://www.gridsite.org/ for details. - -%package shared -Group: Development/Libraries -Summary: GridSite shared library and core documentation - -%description shared -GridSite shared library and core documentation - -See http://www.gridsite.org/ for details. - -%package devel -Group: Development/Libraries -Summary: GridSite .a libraries and .h headers - -%description devel -GridSite development libraries - -See http://www.gridsite.org/ for details. - -%package apache -Group: System Environment/Daemons -Summary: GridSite mod_gridsite module for Apache httpd -Requires: gridsite-shared - -%description apache -GridSite Apache module and CGI binaries - -See http://www.gridsite.org/ for details. - -%package commands -Group: Applications/Internet -Summary: HTTP(S) read/write client and other GridSite commands -Requires: curl, gridsite-shared - -%description commands -htcp is a client to fetch files or directory listings from remote -servers using HTTP or HTTPS, or to put or delete files or directories -onto remote servers using HTTPS. htcp is similar to scp(1), but uses -HTTP/HTTPS rather than ssh as its transfer protocol. - -See http://www.gridsite.org/ for details. - -%package gsexec -Group: Applications/Internet -Summary: gsexec binary for the Apache HTTP server - -%description gsexec -This package includes the /usr/sbin/gsexec binary which can be installed -to allow the Apache HTTP server to run CGI programs (and any programs -executed by SSI pages) as a user other than the 'apache' user. gsexec -is a drop-in replacement for suexec, with extended functionality for use -with GridSite and Grid Security credentials. - -See http://www.gridsite.org/ for details. - -%prep - -%setup - -%build -cd src -make prefix=\$RPM_BUILD_ROOT/%{prefix} \ - GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ - OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT - -EOF - -if [ $have_fuse ] ; then -cat <>gridsite.spec -make prefix=\$RPM_BUILD_ROOT/%{prefix} \ - GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ - OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT \ - slashgrid - -EOF -fi - -if [ $have_gsoap ] ; then -cat <>gridsite.spec -make prefix=\$RPM_BUILD_ROOT/%{prefix} \ - GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ - OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT \ - gridsite-delegation.cgi htproxyput - -EOF -fi - -cat <>gridsite.spec - -%install -cd src -make install prefix=\$RPM_BUILD_ROOT/%{prefix} \ -GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ -OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT -EOF - -if [ $have_fuse ] ; then - -cat <>gridsite.spec - -mkdir -p \$RPM_BUILD_ROOT/etc/rc.d/init.d -make install-slashgrid prefix=\$RPM_BUILD_ROOT/%{prefix} \ - GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ - OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT -EOF -fi - -if [ $have_gsoap ] ; then - -cat <>gridsite.spec - -make install-ws prefix=\$RPM_BUILD_ROOT/%{prefix} \ - GSOAPDIR=$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \ - OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT -EOF -fi - -cat <>gridsite.spec - -%post shared -if [ "\$UID" = "0" ] ; then - /sbin/ldconfig -fi - -%postun -if [ "\$UID" = "0" ] ; then - /sbin/ldconfig -fi - -%files shared -%attr(-, root, root) %{prefix}/lib/libgridsite.so.%{version} -%attr(-, root, root) %{prefix}/lib/libgridsite.so -%attr(-, root, root) %{prefix}/lib/libgridsite_globus.so.%{version} -%attr(-, root, root) %{prefix}/lib/libgridsite_globus.so -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x} - -%files devel -%attr(-, root, root) %{prefix}/include/gridsite.h -%attr(-, root, root) %{prefix}/include/gridsite-gacl.h -%attr(-, root, root) %{prefix}/lib/libgridsite.a -%attr(-, root, root) %{prefix}/lib/libgridsite_globus.a - -%files apache -%attr(-, root, root) %{prefix}/share/man/man8/mod_gridsite.8.gz -%attr(-, root, root) %{prefix}/lib/httpd/modules/mod_gridsite.so -%attr(-, root, root) %{prefix}/sbin/real-gridsite-admin.cgi -%attr(-, root, root) %{prefix}/sbin/gridsite-copy.cgi - -%files commands -%attr(-, root, root) %{prefix}/bin/htcp -%attr(-, root, root) %{prefix}/bin/htls -%attr(-, root, root) %{prefix}/bin/htll -%attr(-, root, root) %{prefix}/bin/htrm -%attr(-, root, root) %{prefix}/bin/htmkdir -%attr(-, root, root) %{prefix}/bin/htmv -%attr(-, root, root) %{prefix}/bin/htping -%attr(-, root, root) %{prefix}/bin/htfind -%attr(-, root, root) %{prefix}/bin/urlencode -%attr(-, root, root) %{prefix}/bin/findproxyfile -%attr(-, root, root) %{prefix}/share/man/man1/htcp.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htrm.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htls.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htll.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htmkdir.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htmv.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htping.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htfind.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/urlencode.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/findproxyfile.1.gz - -%files gsexec -%attr(4510, root, apache) %{prefix}/sbin/gsexec -%attr(-, root, root) %{prefix}/share/man/man8/gsexec.8.gz -EOF - -if [ $have_fuse ] ; then - -cat <>gridsite.spec -%package slashgrid -Group: Applications/Internet -Summary: slashgrid daemon -Requires: curl,fuse,fuse-libs - -%description slashgrid -SlashGrid daemon - -%post slashgrid -mkdir -p /grid - -%preun slashgrid -/sbin/service slashgrid stop ; : - -%files slashgrid -%attr(0744, root, root) %{prefix}/sbin/slashgrid -%attr(0744, root, root) /etc/rc.d/init.d/slashgrid -%attr(0700, root, root) /var/spool/slashgrid -%attr(-, root, root) %{prefix}/share/man/man8/slashgrid.8.gz -EOF - -fi - -if [ $have_gsoap ] ; then - -cat <>gridsite.spec -%package services -Group: Applications/Internet -Summary: GridSite WS gridsite-delegation.cgi - -%description services -GridSite WS delegation service, gridsite-delegation.cgi - -%files services -%attr(-, root, root) %{prefix}/sbin/gridsite-delegation.cgi -%attr(-, root, root) %{prefix}/share/man/man8/gridsite-delegation.8.gz -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/delegation-1.1.0.wsdl -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/gridsite-delegation.8 - -%package service-clients -Group: Applications/Internet -Summary: GridSite WS htproxyput -Requires: curl, gridsite-shared - -%description service-clients -GridSite WS delegation client, htproxyput - -See http://www.gridsite.org/ for details. - -%files service-clients -%attr(-, root, root) %{prefix}/bin/htproxyput -%attr(-, root, root) %{prefix}/bin/htproxydestroy -%attr(-, root, root) %{prefix}/bin/htproxytime -%attr(-, root, root) %{prefix}/bin/htproxyunixtime -%attr(-, root, root) %{prefix}/bin/htproxyrenew -%attr(-, root, root) %{prefix}/bin/htproxyinfo -%attr(-, root, root) %{prefix}/share/man/man1/htproxyput.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htproxydestroy.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htproxytime.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htproxyunixtime.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htproxyrenew.1.gz -%attr(-, root, root) %{prefix}/share/man/man1/htproxyinfo.1.gz -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyput.1 -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxydestroy.1 -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxytime.1 -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyunixtime.1 -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyrenew.1 -%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyinfo.1 -EOF - -fi - diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c deleted file mode 100644 index 16febab..0000000 --- a/org.gridsite.core/src/mod_gridsite.c +++ /dev/null @@ -1,3572 +0,0 @@ -/* - Copyright (c) 2003-6, Andrew McNab, Shiv Kaushal, Joseph Dada, - and Yibiao Li, University of Manchester. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - - This program includes code from dav_parse_range() from Apache mod_dav.c, - and associated code contributed by David O Callaghan - - Copyright 2000-2005 The Apache Software Foundation or its licensors, as - applicable. - - 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. -*/ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "mod_ssl-private.h" - -#include "gridsite.h" - -#ifndef UNSET -#define UNSET -1 -#endif - -#define GRST_SESSIONS_DIR "/var/www/sessions" - -module AP_MODULE_DECLARE_DATA gridsite_module; - -#define GRST_SITECAST_GROUPS 32 - -struct sitecast_group - { int socket; int quad1; int quad2; int quad3; int quad4; int port; }; - -#define GRST_SITECAST_ALIASES 32 - -struct sitecast_alias - { const char *sitecast_url; const char *scheme; int port; - const char *local_path; const char *local_hostname; }; - -/* Globals, defined by main server directives in httpd.conf - These are assigned default values in create_gridsite_srv_config() */ - -int gridhttpport = 0; /* set by create_gridsite_srv_config, used as flag */ -char *sessionsdir = NULL; -char *sitecastdnlists = NULL; -char *ocspmodes = NULL; -struct sitecast_group sitecastgroups[GRST_SITECAST_GROUPS+1]; -struct sitecast_alias sitecastaliases[GRST_SITECAST_ALIASES]; - -typedef struct -{ - int auth; - int envs; - int format; - int indexes; - char *indexheader; - int gridsitelink; - char *adminfile; - char *adminuri; - char *helpuri; - char *dnlists; - char *dnlistsuri; - char *adminlist; - int gsiproxylimit; - char *unzip; - char *methods; - char *editable; - char *headfile; - char *footfile; - int gridhttp; - char *aclformat; - char *aclpath; - char *execmethod; - char *delegationuri; - ap_unix_identity_t execugid; - apr_fileperms_t diskmode; -} mod_gridsite_dir_cfg; /* per-directory config choices */ - - -/* - * parse_content_range() is loosely - * based on modules/dav/main/mod_dav.c from Apache - */ - -int parse_content_range(request_rec *r, apr_off_t *range_start, - apr_off_t *range_end, apr_off_t *range_length) -{ -// this all needs verifying to be ok for large (>2GB, >4GB) files - - const char *range_c; - char *range; - char *dash; - char *slash; - - range_c = apr_table_get(r->headers_in, "content-range"); - if (range_c == NULL) return 0; - - range = apr_pstrdup(r->pool, range_c); - - if ((strncasecmp(range, "bytes ", 6) != 0) || - ((dash = ap_strchr(range, '-')) == NULL) || - ((slash = ap_strchr(range, '/')) == NULL)) - { - return 0; /* malformed header. ignore it (per S14.16 of RFC2616) */ - } - - *dash = *slash = '\0'; - - // Check for GridSite-specific Content-Range: bytes *-*/LENGTH form - - if ((range[6] == '*') && (dash[1] == '*')) - { - if (slash[1] == '*') return 0; /* invalid truncation length */ - - *range_length = apr_atoi64(&slash[1]); - *range_start = 0; - *range_end = 0; - - return 1; /* a valid (truncation) length */ - } - - *range_length = 0; - *range_start = apr_atoi64(&range[6]); - *range_end = apr_atoi64(&dash[1]); - - if ((*range_end < *range_start) || - ((slash[1] != '*') && (apr_atoi64(&slash[1]) <= *range_end))) - return 0; /* ignore invalid ranges */ - - /* we now have a valid range */ - return 1; -} - -char *make_admin_footer(request_rec *r, mod_gridsite_dir_cfg *conf, - int isdirectory) -/* - make string holding last modified text and admin links -*/ -{ - char *out, *https, *p, *dn = NULL, *file = NULL, *permstr = NULL, - *temp, modified[99], *dir_uri, *grst_cred_0 = NULL; - GRSTgaclPerm perm = GRST_PERM_NONE; - struct tm mtime_tm; - time_t mtime_time; - - https = (char *) apr_table_get(r->subprocess_env, "HTTPS"); - - dir_uri = apr_pstrdup(r->pool, r->uri); - p = rindex(dir_uri, '/'); - - if (p == NULL) return ""; - - file = apr_pstrdup(r->pool, &p[1]); - p[1] = '\0'; - /* dir_uri always gets both a leading and a trailing slash */ - - out = apr_pstrdup(r->pool, "

\n"); - - if (!isdirectory) - { - mtime_time = apr_time_sec(r->finfo.mtime); - - localtime_r(&mtime_time, &mtime_tm); - strftime(modified, sizeof(modified), - "%a %e %B %Y", &mtime_tm); - temp = apr_psprintf(r->pool,"


Last modified %s\n", modified); - out = apr_pstrcat(r->pool, out, temp, NULL); - - if ((conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0') && - (strncmp(file, GRST_HIST_PREFIX, sizeof(GRST_HIST_PREFIX)-1) != 0)) - { - temp = apr_psprintf(r->pool, - ". " - "View page history\n", - conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - out = apr_pstrcat(r->pool, out, "", NULL); - } - - out = apr_pstrcat(r->pool, out, "
", NULL); - - if (r->connection->notes != NULL) - grst_cred_0 = (char *) - apr_table_get(r->connection->notes, "GRST_CRED_0"); - - if ((grst_cred_0 != NULL) && - (strncmp(grst_cred_0, "X509USER ", sizeof("X509USER")) == 0)) - { - p = index(grst_cred_0, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) dn = p; - } - } - } - } - - if (dn != NULL) - { - temp = apr_psprintf(r->pool, "You are %s
\n", dn); - out = apr_pstrcat(r->pool, out, temp, NULL); - - if (r->notes != NULL) - permstr = (char *) apr_table_get(r->notes, "GRST_PERM"); - - if ((permstr != NULL) && - (conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0')) - { - sscanf(permstr, "%d", &perm); - - if (!isdirectory && - GRSTgaclPermHasWrite(perm) && - (strncmp(file, GRST_HIST_PREFIX, - sizeof(GRST_HIST_PREFIX) - 1) != 0)) - { - temp = apr_psprintf(r->pool, - "" - "Edit page .\n", conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasWrite(perm)) - { - temp = apr_psprintf(r->pool, - "Manage directory .\n", - dir_uri, conf->adminfile); - - out = apr_pstrcat(r->pool, out, temp, NULL); - } - } - } - - if ((https != NULL) && (strcasecmp(https, "on") == 0)) - temp = apr_psprintf(r->pool, - "Switch to HTTP \n", - r->server->server_hostname, r->unparsed_uri); - else temp = apr_psprintf(r->pool, - "Switch to HTTPS \n", - r->server->server_hostname, r->unparsed_uri); - - out = apr_pstrcat(r->pool, out, temp, NULL); - - if ((conf->helpuri != NULL) && (conf->helpuri[0] != '\0')) - { - temp = apr_psprintf(r->pool, - ". Website Help\n", conf->helpuri); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if ((!isdirectory) && - (conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0')) - { - temp = apr_psprintf(r->pool, ". " - "Print View\n", conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if (conf->gridsitelink) - { - temp = apr_psprintf(r->pool, - ". Built with " - "GridSite %s\n", VERSION); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - out = apr_pstrcat(r->pool, out, "\n
\n", NULL); - - return out; -} - -void delegation_header(request_rec *r, mod_gridsite_dir_cfg *conf){ - - apr_table_add(r->headers_out, - apr_pstrdup(r->pool, "Proxy-Delegation-Service"), - apr_psprintf(r->pool,"https://%s%s", r->hostname, conf->delegationuri)); - return; - -} - -int html_format(request_rec *r, mod_gridsite_dir_cfg *conf) -/* - try to do GridSite formatting of .html files (NOT .shtml etc) -*/ -{ - int i, fd, errstatus; - char *buf, *p, *file, *s, *head_formatted, *header_formatted, - *body_formatted, *admin_formatted, *footer_formatted; - size_t length; - struct stat statbuf; - apr_file_t *fp; - - if (r->finfo.filetype == APR_NOFILE) return HTTP_NOT_FOUND; - - if (apr_file_open(&fp, r->filename, APR_READ, 0, r->pool) != 0) - return HTTP_INTERNAL_SERVER_ERROR; - - - /* Put in Delegation service header if required */ - if (conf->delegationuri) delegation_header(r, conf); - - file = rindex(r->uri, '/'); - if (file != NULL) ++file; /* file points to name without path */ - - buf = apr_palloc(r->pool, (size_t)(r->finfo.size + 1)); - length = r->finfo.size; - apr_file_read(fp, buf, &length); - buf[r->finfo.size] = '\0'; - apr_file_close(fp); - - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = apr_palloc(r->pool, - strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - if (fd == -1) /* not found, so set up not to output one */ - { - head_formatted = apr_pstrdup(r->pool, ""); - header_formatted = apr_pstrdup(r->pool, ""); - body_formatted = buf; - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - - p = strstr(buf, "pool, ""); - body_formatted = buf; - } - else - { - *p = '\0'; - head_formatted = buf; - ++p; - - while ((*p != '>') && (*p != '\0')) ++p; - - if (*p == '\0') - { - body_formatted = p; - } - else - { - *p = '\0'; - ++p; - body_formatted = p; - } - } - } - - /* **** remove closing tag from body **** */ - - p = strstr(body_formatted, "pool, - strlen(r->filename) + strlen(conf->footfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - if (fd == -1) /* failed to find a footer, so set up empty default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body_formatted) + strlen(admin_formatted) + - strlen(footer_formatted); - - ap_set_content_length(r, length); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body_formatted, r); - ap_rputs(admin_formatted, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -int html_dir_list(request_rec *r, mod_gridsite_dir_cfg *conf) -/* - output HTML directory listing, with level of formatting controlled - by GridSiteHtmlFormat/conf->format -*/ -{ - int i, fd, n, nn; - char *buf, *p, *s, *head_formatted, *header_formatted, - *body_formatted, *admin_formatted, *footer_formatted, *temp, - modified[99], *d_namepath, *indexheaderpath, *indexheadertext; - size_t length; - struct stat statbuf; - struct tm mtime_tm; - struct dirent **namelist; - - if (r->finfo.filetype == APR_NOFILE) return HTTP_NOT_FOUND; - - /* Put in Delegation service header if required */ - if (conf->delegationuri) delegation_header(r, conf); - - head_formatted = apr_psprintf(r->pool, - "Directory listing %s\n", r->uri); - - if (conf->format) - { - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = apr_palloc(r->pool, - strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - if (fd == -1) /* not found, so set up to output sensible default */ - { - header_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else header_formatted = apr_pstrdup(r->pool, ""); - - body_formatted = apr_psprintf(r->pool, - "

Directory listing %s

\n", r->uri); - - if (conf->indexheader != NULL) - { - indexheaderpath = apr_psprintf(r->pool, "%s/%s", r->filename, - conf->indexheader); - fd = open(indexheaderpath, O_RDONLY); - if (fd != -1) - { - fstat(fd, &statbuf); - indexheadertext = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, indexheadertext, statbuf.st_size); - indexheadertext[statbuf.st_size] = '\0'; - close(fd); - - body_formatted = apr_pstrcat(r->pool, body_formatted, - indexheadertext, NULL); - } - } - - body_formatted = apr_pstrcat(r->pool, body_formatted, "

\n", NULL); - - if (r->unparsed_uri[1] != '\0') - body_formatted = apr_pstrcat(r->pool, body_formatted, - "\n", - NULL); - - nn = scandir(r->filename, &namelist, 0, versionsort); - for (n=0; n < nn; ++n) - { - if ((namelist[n]->d_name[0] != '.') && - ((conf->indexheader == NULL) || - (strcmp(conf->indexheader, namelist[n]->d_name) != 0))) - { - d_namepath = apr_psprintf(r->pool, "%s/%s", r->filename, - namelist[n]->d_name); - stat(d_namepath, &statbuf); - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (S_ISDIR(statbuf.st_mode)) - temp = apr_psprintf(r->pool, - "" - "%s\n", - namelist[n]->d_name, statbuf.st_size, statbuf.st_mtime, - namelist[n]->d_name, - statbuf.st_size, modified); - else temp = apr_psprintf(r->pool, - "" - "%s\n", - namelist[n]->d_name, statbuf.st_size, statbuf.st_mtime, - namelist[n]->d_name, - statbuf.st_size, modified); - - body_formatted = apr_pstrcat(r->pool,body_formatted,temp,NULL); - } - - free(namelist[n]); - } - - free(namelist); - - body_formatted = apr_pstrcat(r->pool, body_formatted, "
[Parent directory]
%R%e %b %y
" - "%s/%ld
" - "%s%ld
\n", NULL); - - if (conf->format) - { - /* **** set up dynamic part of footer to go at end of body **** */ - - admin_formatted = make_admin_footer(r, conf, TRUE); - - /* **** try to find a footer file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = apr_palloc(r->pool, - strlen(r->filename) + strlen(conf->footfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - if (fd == -1) /* failed to find a footer, so use standard default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else - { - admin_formatted = apr_pstrdup(r->pool, ""); - footer_formatted = apr_pstrdup(r->pool, ""); - } - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body_formatted) + strlen(admin_formatted) + - strlen(footer_formatted); - - ap_set_content_length(r, length); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body_formatted, r); - ap_rputs(admin_formatted, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf) -{ - int i; - char *httpurl, *filetemplate, *cookievalue, *envname_i, - *grst_cred_i, expires_str[APR_RFC822_DATE_LEN]; - apr_uint64_t gridauthcookie; - apr_table_t *env; - apr_time_t expires_time; - apr_file_t *fp; - - /* create random cookie and gridauthcookie file */ - - if (apr_generate_random_bytes((char *) &gridauthcookie, - sizeof(gridauthcookie)) - != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Generated GridHTTP passcode %016llx", gridauthcookie); - - filetemplate = apr_psprintf(r->pool, "%s/passcode-%016llxXXXXXX", - ap_server_root_relative(r->pool, - sessionsdir), - gridauthcookie); - - if (apr_file_mktemp(&fp, - filetemplate, - APR_CREATE | APR_WRITE | APR_EXCL, - r->pool) - != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Created passcode file %s", filetemplate); - - expires_time = apr_time_now() + apr_time_from_sec(300); - /* passcode cookies are valid for only 5 mins! */ - - apr_file_printf(fp, - "expires=%lu\ndomain=%s\npath=%s\nonetime=yes\nmethod=%s\n", - (time_t) apr_time_sec(expires_time), - r->hostname, r->uri, r->method); - /* above variables are evaluated in order and method= MUST be last! */ - - for (i=0; ; ++i) - { - envname_i = apr_psprintf(r->pool, "GRST_CRED_%d", i); - if (grst_cred_i = (char *) - apr_table_get(r->connection->notes, envname_i)) - { - apr_file_printf(fp, "%s=%s\n", envname_i, grst_cred_i); - } - else break; /* GRST_CRED_i are numbered consecutively */ - } - - if (apr_file_close(fp) != APR_SUCCESS) - { - apr_file_remove(filetemplate, r->pool); /* try to clean up */ - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* send redirection header back to client */ - - cookievalue = rindex(filetemplate, '-'); - if (cookievalue != NULL) ++cookievalue; - else cookievalue = filetemplate; - - apr_rfc822_date(expires_str, expires_time); - - apr_table_add(r->headers_out, - apr_pstrdup(r->pool, "Set-Cookie"), - apr_psprintf(r->pool, - "GRIDHTTP_PASSCODE=%s; " - "expires=%s; " - "domain=%s; " - "path=%s", - cookievalue, expires_str, r->hostname, r->uri)); - - if (gridhttpport != DEFAULT_HTTP_PORT) - httpurl = apr_psprintf(r->pool, "http://%s:%d%s", r->hostname, - gridhttpport, ap_escape_uri(r->pool, r->uri)); - else httpurl = apr_pstrcat(r->pool, "http://", r->hostname, - ap_escape_uri(r->pool, r->uri), NULL); - - apr_table_setn(r->headers_out, apr_pstrdup(r->pool, "Location"), httpurl); - - r->status = HTTP_MOVED_TEMPORARILY; - return OK; -} - -int http_put_method(request_rec *r, mod_gridsite_dir_cfg *conf) -{ - char buf[2048], *filename, *dirname, *basename; - const char *p; - size_t block_length, length_sent; - int retcode, stat_ret; - apr_file_t *fp; - struct stat statbuf; - int has_range = 0, is_done = 0; - apr_off_t range_start, range_end, range_length, length_to_send, length = 0; - - /* *** check if directory creation: PUT /.../ *** */ - - if ((r->unparsed_uri != NULL) && - (r->unparsed_uri[0] != '\0') && - (r->unparsed_uri[strlen(r->unparsed_uri) - 1] == '/')) - { - if (apr_dir_make(r->filename, - conf->diskmode - | APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE, - r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; - - /* we force the permissions, rather than accept any existing ones */ - - apr_file_perms_set(r->filename, conf->diskmode - | APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE); - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - return OK; - } - - /* *** otherwise assume trying to create a regular file *** */ - - stat_ret = stat(r->filename, &statbuf); - - /* find if a range is specified */ - - has_range = parse_content_range(r, &range_start, &range_end, &range_length); - - if (has_range) - { - if ((range_start == 0) && (range_end == 0)) /* truncate? */ - { - if (stat_ret != 0) return HTTP_NOT_FOUND; - - if (truncate(r->filename, range_length) != 0) - return HTTP_INTERNAL_SERVER_ERROR; - else return OK; - } - - filename = r->filename; - - if (apr_file_open(&fp, filename, APR_WRITE | APR_CREATE | APR_BUFFERED, - conf->diskmode, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; - } - else /* use temporary file if not a partial transfer */ - { - dirname = apr_pstrdup(r->pool, r->filename); - basename = rindex(dirname, '/'); - if (basename == NULL) return HTTP_INTERNAL_SERVER_ERROR; - - *basename = '\0'; - ++basename; - - filename = apr_psprintf(r->pool, - "%s/.grsttmp-%s-XXXXXX", dirname, basename); - - if (apr_file_mktemp(&fp, filename, - APR_CREATE | APR_WRITE | APR_BUFFERED | APR_EXCL, r->pool) - != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; -/* - p = apr_table_get(r->headers_in, "Content-Length"); - if (p != NULL) - { - length = (apr_off_t) atol(p); - if (length > 16384) - { - if (apr_file_seek(fp, APR_SET, &length) == 0) - { - block_length = 1; - apr_file_write(fp, "0", &block_length); - } - - apr_file_seek(fp, APR_SET, 0); - } - } -*/ - } - - /* we force the permissions, rather than accept any existing ones */ - - apr_file_perms_set(filename, conf->diskmode); - - if (has_range) - { - if (apr_file_seek(fp, APR_SET, &range_start) != 0) - { - retcode = HTTP_INTERNAL_SERVER_ERROR; - return retcode; - } - - length_to_send = range_end - range_start + 1; - } - - retcode = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); - if (retcode == OK) - { - if (has_range) length_sent = 0; - - if (ap_should_client_block(r)) - while ((block_length = ap_get_client_block(r, buf, sizeof(buf))) > 0) - { - if (has_range && (length_sent + block_length > length_to_send)) - { - block_length = length_to_send - length_sent; - is_done = 1; - } - - if (apr_file_write(fp, buf, &block_length) != 0) - { - retcode = HTTP_INTERNAL_SERVER_ERROR; - break; - } - - if (has_range) - { - if (is_done) break; - else length_sent += block_length; - } - } - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - } - - if ((apr_file_close(fp) != 0) || (retcode == HTTP_INTERNAL_SERVER_ERROR)) - { - if (strcmp(filename, r->filename) != 0) remove(filename); - return HTTP_INTERNAL_SERVER_ERROR; - } - - if ((strcmp(filename, r->filename) != 0) && - (apr_file_rename(filename, r->filename, r->pool) != 0)) - return HTTP_FORBIDDEN; /* best guess as to the problem ... */ - - if ((retcode == OK) && (stat_ret != 0)) - { - retcode = HTTP_CREATED; - ap_custom_response(r, HTTP_CREATED, ""); - } - - return retcode; -} - -int http_delete_method(request_rec *r, mod_gridsite_dir_cfg *conf) -{ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Try remove(%s)", r->filename); - - if (remove(r->filename) != 0) return HTTP_FORBIDDEN; - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - - return OK; -} - -int http_move_method(request_rec *r, mod_gridsite_dir_cfg *conf) -{ - char *destination_translated = NULL; - - if (r->notes != NULL) destination_translated = - (char *) apr_table_get(r->notes, "GRST_DESTINATION_TRANSLATED"); - - if (destination_translated == NULL) return HTTP_BAD_REQUEST; - - if (strcmp(r->filename, destination_translated) == 0) - return HTTP_FORBIDDEN; - - if (apr_file_rename(r->filename, destination_translated, r->pool) != 0) - return HTTP_FORBIDDEN; - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - - return OK; -} - -static int mod_gridsite_dir_handler(request_rec *r, mod_gridsite_dir_cfg *conf) -/* - handler switch for directories -*/ -{ - /* *** is this a write method? only possible if GridSiteAuth on *** */ - - if (conf->auth) - { - if ((r->method_number == M_PUT) && - (conf->methods != NULL) && - (strstr(conf->methods, " PUT " ) != NULL)) - return http_put_method(r, conf); - - if ((r->method_number == M_DELETE) && - (conf->methods != NULL) && - (strstr(conf->methods, " DELETE ") != NULL)) - return http_delete_method(r, conf); - } - - /* *** directory listing? *** */ - if ((r->method_number == M_GET) && (conf->indexes)) - return html_dir_list(r, conf); /* directory listing */ - - return DECLINED; /* *** nothing to see here, move along *** */ -} - -static int mod_gridsite_nondir_handler(request_rec *r, mod_gridsite_dir_cfg *conf) -/* - one big handler switch for everything other than directories, since we - might be responding to MIME * / * for local PUT, MOVE, COPY and DELETE, - and GET inside ghost directories. -*/ -{ - char *upgradeheader, *upgradespaced, *p; - const char *https_env; - - /* *** is this a write method or GridHTTP HTTPS->HTTP redirection? - only possible if GridSiteAuth on *** */ - - if (conf->auth) - { - if ((conf->gridhttp) && - ((r->method_number == M_GET) || - ((r->method_number == M_PUT) && - (strstr(conf->methods, " PUT ") != NULL))) && - ((upgradeheader = (char *) apr_table_get(r->headers_in, - "Upgrade")) != NULL) && - ((https_env=apr_table_get(r->subprocess_env,"HTTPS")) != NULL) && - (strcasecmp(https_env, "on") == 0)) - { - upgradespaced = apr_psprintf(r->pool, " %s ", upgradeheader); - - for (p=upgradespaced; *p != '\0'; ++p) - if ((*p == ',') || (*p == '\t')) *p = ' '; - -// TODO: what if we're pointing at a CGI or some dynamic content??? - - if (strstr(upgradespaced, " GridHTTP/1.0 ") != NULL) - return http_gridhttp(r, conf); - } - - if ((r->method_number == M_PUT) && - (conf->methods != NULL) && - (strstr(conf->methods, " PUT " ) != NULL)) - return http_put_method(r, conf); - - if ((r->method_number == M_DELETE) && - (conf->methods != NULL) && - (strstr(conf->methods, " DELETE ") != NULL)) - return http_delete_method(r, conf); - - if ((r->method_number == M_MOVE) && - (conf->methods != NULL) && - (strstr(conf->methods, " MOVE ") != NULL)) - return http_move_method(r, conf); - } - - /* *** check if a special ghost admin CGI *** */ - - if (conf->adminfile && conf->adminuri && - (strlen(r->filename) > strlen(conf->adminfile) + 1) && - (strcmp(&(r->filename[strlen(r->filename) - strlen(conf->adminfile)]), - conf->adminfile) == 0) && - (r->filename[strlen(r->filename)-strlen(conf->adminfile)-1] == '/') && - ((r->method_number == M_POST) || - (r->method_number == M_GET))) - { - ap_internal_redirect(conf->adminuri, r); - return OK; - } - - /* *** finally look for .html files that we should format *** */ - - if ((conf->format) && /* conf->format set by GridSiteHtmlFormat on */ - (strlen(r->filename) > 5) && - (strcmp(&(r->filename[strlen(r->filename)-5]), ".html") == 0) && - (r->method_number == M_GET)) return html_format(r, conf); - - return DECLINED; /* *** nothing to see here, move along *** */ -} - -static void recurse4dirlist(char *dirname, time_t *dirs_time, - char *fulluri, int fullurilen, - char *encfulluri, int enclen, - apr_pool_t *pool, char **body, - int recurse_level) -/* try to find DN Lists in dir[] and its subdirs that match the fulluri[] - prefix. add blobs of HTML to body as they are found. */ -{ - char *unencname, modified[99], *oneline, *d_namepath; - DIR *oneDIR; - struct dirent *onedirent; - struct tm mtime_tm; - size_t length; - struct stat statbuf; - - if ((stat(dirname, &statbuf) != 0) || - (!S_ISDIR(statbuf.st_mode)) || - ((oneDIR = opendir(dirname)) == NULL)) return; - - if (statbuf.st_mtime > *dirs_time) *dirs_time = statbuf.st_mtime; - - while ((onedirent = readdir(oneDIR)) != NULL) - { - if (onedirent->d_name[0] == '.') continue; - - d_namepath = apr_psprintf(pool, "%s/%s", dirname, onedirent->d_name); - if (stat(d_namepath, &statbuf) != 0) continue; - - if (S_ISDIR(statbuf.st_mode) && (recurse_level < GRST_RECURS_LIMIT)) - recurse4dirlist(d_namepath, dirs_time, fulluri, - fullurilen, encfulluri, enclen, - pool, body, recurse_level + 1); - else if ((strncmp(onedirent->d_name, encfulluri, enclen) == 0) && - (onedirent->d_name[strlen(onedirent->d_name) - 1] != '~')) - { - unencname = GRSThttpUrlDecode(onedirent->d_name); - - if (strncmp(unencname, fulluri, fullurilen) == 0) - { - - if (statbuf.st_mtime > *dirs_time) - *dirs_time = statbuf.st_mtime; - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "%R%e %b %y", - &mtime_tm); - - oneline = apr_psprintf(pool, - "" - "%s" - "%ld%s\n", - &unencname[fullurilen], statbuf.st_size, - statbuf.st_mtime, unencname, - statbuf.st_size, modified); - - *body = apr_pstrcat(pool, *body, oneline, NULL); - } - - free(unencname); /* libgridsite doesnt use pools */ - } - } - - closedir(oneDIR); -} - -static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r, - mod_gridsite_dir_cfg *conf) -/* - virtual DN-list file lister: make all DN lists on the dn-lists - path of this server appear to be in the dn-lists directory itself - (ie where they appear in the DN lists path doesnt matter, as long - as their name matches) -*/ -{ - int enclen, fullurilen, fd; - char *fulluri, *encfulluri, *dn_list_ptr, *dirname, *unencname, - *body, *oneline, *p, *s, - *head_formatted, *header_formatted, *footer_formatted, - *permstr = NULL; - struct stat statbuf; - size_t length; - time_t dirs_time = 0; - GRSTgaclPerm perm = GRST_PERM_NONE; - - if (r->notes != NULL) - permstr = (char *) apr_table_get(r->notes, "GRST_PERM"); - - if (permstr != NULL) sscanf(permstr, "%d", &perm); - - fulluri = apr_psprintf(r->pool, "https://%s%s", - ap_get_server_name(r), conf->dnlistsuri); - fullurilen = strlen(fulluri); - - encfulluri = GRSThttpUrlEncode(fulluri); - enclen = strlen(encfulluri); - - if (conf->dnlists != NULL) p = conf->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_list_ptr = apr_pstrdup(r->pool, p); - - head_formatted = apr_psprintf(r->pool, - "Directory listing %s\n", r->uri); - - if (conf->format) - { - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* not found, so set up to output sensible default */ - { - header_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else header_formatted = apr_pstrdup(r->pool, ""); - - body = apr_psprintf(r->pool, - "

Directory listing %s

\n", r->uri); - - if ((r->uri)[1] != '\0') - body = apr_pstrcat(r->pool, body, - "\n", - NULL); - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - recurse4dirlist(dirname, &dirs_time, fulluri, fullurilen, - encfulluri, enclen, r->pool, &body, 0); - - if ((stat(r->filename, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - GRSTgaclPermHasWrite(perm)) - { - oneline = apr_psprintf(r->pool, - "\n" - "" - "\n", - r->uri, conf->adminfile); - - body = apr_pstrcat(r->pool, body, oneline, NULL); - } - - body = apr_pstrcat(r->pool, body, "
[Parent directory]
\n", NULL); - - free(encfulluri); /* libgridsite doesnt use pools */ - - if (conf->format) - { - /* **** try to find a footer file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->footfile)); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* failed to find a footer, so use standard default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else footer_formatted = apr_pstrdup(r->pool, ""); - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body) + strlen(footer_formatted); - - ap_set_content_length(r, length); - r->mtime = apr_time_from_sec(dirs_time); - ap_set_last_modified(r); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -static char *recurse4file(char *dir, char *file, apr_pool_t *pool, - int recurse_level) -/* try to find file[] in dir[]. try subdirs if not found. - return full path to first found version or NULL on failure */ -{ - char *fullfilename, *fulldirname; - struct stat statbuf; - DIR *dirDIR; - struct dirent *file_ent; - - /* try to find in current directory */ - - fullfilename = apr_psprintf(pool, "%s/%s", dir, file); - - if (stat(fullfilename, &statbuf) == 0) return fullfilename; - - /* maybe search in subdirectories */ - - if (recurse_level >= GRST_RECURS_LIMIT) return NULL; - - dirDIR = opendir(dir); - - if (dirDIR == NULL) return NULL; - - while ((file_ent = readdir(dirDIR)) != NULL) - { - if (file_ent->d_name[0] == '.') continue; - - fulldirname = apr_psprintf(pool, "%s/%s", dir, file_ent->d_name); - if ((stat(fulldirname, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - ((fullfilename = recurse4file(fulldirname, file, - pool, recurse_level + 1)) != NULL)) - { - closedir(dirDIR); - return fullfilename; - } - } - - closedir(dirDIR); - - return NULL; -} - -static int mod_gridsite_dnlistsuri_handler(request_rec *r, - mod_gridsite_dir_cfg *conf) -/* - virtual DN-list file generator -*/ -{ - int fd; - char *fulluri, *encfulluri, *dn_list_ptr, *filename, *dirname, *p, - *buf; - struct stat statbuf; - - /* *** check if a special ghost admin CGI *** */ - - if (conf->adminfile && conf->adminuri && - (strlen(r->filename) > strlen(conf->adminfile) + 1) && - (strcmp(&(r->filename[strlen(r->filename) - strlen(conf->adminfile)]), - conf->adminfile) == 0) && - (r->filename[strlen(r->filename)-strlen(conf->adminfile)-1] == '/') && - ((r->method_number == M_POST) || - (r->method_number == M_GET))) - { - ap_internal_redirect(conf->adminuri, r); - return OK; - } - - fulluri = apr_psprintf(r->pool, "https://%s%s", - ap_get_server_name(r), r->uri); - - encfulluri = GRSThttpUrlEncode(fulluri); - - if (conf->dnlists != NULL) p = conf->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_list_ptr = apr_pstrdup(r->pool, p); - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - { - filename = recurse4file(dirname, encfulluri, r->pool, 0); - - if (filename == NULL) continue; - - fd = open(filename, O_RDONLY); - - if (fd == -1) continue; - - fstat(fd, &statbuf); - ap_set_content_length(r, (apr_off_t) statbuf.st_size); - r->mtime = apr_time_from_sec(statbuf.st_mtime); - ap_set_content_type(r, "text/plain"); - ap_set_last_modified(r); - - buf = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, buf, statbuf.st_size); - buf[statbuf.st_size] = '\0'; - - ap_rputs(buf, r); - - close(fd); - - return OK; - } - - return HTTP_NOT_FOUND; -} - -static void *create_gridsite_srv_config(apr_pool_t *p, server_rec *s) -{ - int i; - - /* only run once (in base server) */ - if (!(s->is_virtual) && (gridhttpport == 0)) - { - gridhttpport = GRST_HTTP_PORT; - - sessionsdir = apr_pstrdup(p, GRST_SESSIONS_DIR); - /* GridSiteSessionsDir dir-path */ - - sitecastdnlists = NULL; - - sitecastgroups[0].quad1 = 0; - sitecastgroups[0].quad2 = 0; - sitecastgroups[0].quad3 = 0; - sitecastgroups[0].quad4 = 0; - sitecastgroups[0].port = GRST_HTCP_PORT; - /* GridSiteCastUniPort udp-port */ - - for (i=1; i <= GRST_SITECAST_GROUPS; ++i) - { - sitecastgroups[i].port = 0; /* GridSiteCastGroup mcast-list */ - } - - for (i=1; i <= GRST_SITECAST_ALIASES; ++i) - { - sitecastaliases[i].sitecast_url = NULL; - sitecastaliases[i].port = 0; - sitecastaliases[i].scheme = NULL; - sitecastaliases[i].local_path = NULL; - sitecastaliases[i].local_hostname = NULL; - } /* GridSiteCastAlias url path */ - } - - return NULL; -} - -static void *create_gridsite_dir_config(apr_pool_t *p, char *path) -{ - mod_gridsite_dir_cfg *conf = apr_palloc(p, sizeof(*conf)); - - if (path == NULL) /* set up document root defaults */ - { - conf->auth = 0; /* GridSiteAuth on/off */ - conf->envs = 1; /* GridSiteEnvs on/off */ - conf->format = 0; /* GridSiteHtmlFormat on/off */ - conf->indexes = 0; /* GridSiteIndexes on/off */ - conf->indexheader = NULL; /* GridSiteIndexHeader File-value */ - conf->gridsitelink = 1; /* GridSiteLink on/off */ - conf->adminfile = apr_pstrdup(p, GRST_ADMIN_FILE); - /* GridSiteAdminFile File-value */ - conf->adminuri = NULL; /* GridSiteAdminURI URI-value */ - conf->helpuri = NULL; /* GridSiteHelpURI URI-value */ - conf->dnlists = NULL; /* GridSiteDNlists Search-path */ - conf->dnlistsuri = NULL; /* GridSiteDNlistsURI URI-value */ - conf->adminlist = NULL; /* GridSiteAdminList URI-value */ - conf->gsiproxylimit = 1; /* GridSiteGSIProxyLimit number */ - conf->unzip = NULL; /* GridSiteUnzip file-path */ - - conf->methods = apr_pstrdup(p, " GET "); - /* GridSiteMethods methods */ - - conf->editable = apr_pstrdup(p, " txt shtml html htm css js php jsp "); - /* GridSiteEditable types */ - - conf->headfile = apr_pstrdup(p, GRST_HEADFILE); - conf->footfile = apr_pstrdup(p, GRST_FOOTFILE); - /* GridSiteHeadFile and GridSiteFootFile file name */ - - conf->gridhttp = 0; /* GridSiteGridHTTP on/off */ - conf->aclformat = apr_pstrdup(p, "GACL"); - /* GridSiteACLFormat gacl/xacml */ - conf->aclpath = NULL; /* GridSiteACLPath acl-path */ - conf->delegationuri = NULL; /* GridSiteDelegationURI URI-value */ - conf->execmethod = NULL; - /* GridSiteExecMethod nosetuid/suexec/X509DN/directory */ - - conf->execugid.uid = 0; /* GridSiteUserGroup User Group */ - conf->execugid.gid = 0; /* ditto */ - conf->execugid.userdir = 0; /* ditto */ - - conf->diskmode = APR_UREAD | APR_UWRITE; - /* GridSiteDiskMode group-mode world-mode - GroupNone | GroupRead | GroupWrite WorldNone | WorldRead */ - } - else - { - conf->auth = UNSET; /* GridSiteAuth on/off */ - conf->envs = UNSET; /* GridSiteEnvs on/off */ - conf->format = UNSET; /* GridSiteHtmlFormat on/off */ - conf->indexes = UNSET; /* GridSiteIndexes on/off */ - conf->indexheader = NULL; /* GridSiteIndexHeader File-value */ - conf->gridsitelink = UNSET; /* GridSiteLink on/off */ - conf->adminfile = NULL; /* GridSiteAdminFile File-value */ - conf->adminuri = NULL; /* GridSiteAdminURI URI-value */ - conf->helpuri = NULL; /* GridSiteHelpURI URI-value */ - conf->dnlists = NULL; /* GridSiteDNlists Search-path */ - conf->dnlistsuri = NULL; /* GridSiteDNlistsURI URI-value */ - conf->adminlist = NULL; /* GridSiteAdminList URI-value */ - conf->gsiproxylimit = UNSET; /* GridSiteGSIProxyLimit number */ - conf->unzip = NULL; /* GridSiteUnzip file-path */ - conf->methods = NULL; /* GridSiteMethods methods */ - conf->editable = NULL; /* GridSiteEditable types */ - conf->headfile = NULL; /* GridSiteHeadFile file name */ - conf->footfile = NULL; /* GridSiteFootFile file name */ - conf->gridhttp = UNSET; /* GridSiteGridHTTP on/off */ - conf->aclformat = NULL; /* GridSiteACLFormat gacl/xacml */ - conf->aclpath = NULL; /* GridSiteACLPath acl-path */ - conf->delegationuri = NULL; /* GridSiteDelegationURI URI-value */ - conf->execmethod = NULL; /* GridSiteExecMethod */ - conf->execugid.uid = UNSET; /* GridSiteUserGroup User Group */ - conf->execugid.gid = UNSET; /* ditto */ - conf->execugid.userdir = UNSET; /* ditto */ - conf->diskmode = UNSET; /* GridSiteDiskMode group world */ - } - - return conf; -} - -static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, - void *vdirect) -/* merge directory with server-wide directory configs */ -{ - mod_gridsite_dir_cfg *conf, *server, *direct; - - server = (mod_gridsite_dir_cfg *) vserver; - direct = (mod_gridsite_dir_cfg *) vdirect; - conf = apr_palloc(p, sizeof(*conf)); - - if (direct->auth != UNSET) conf->auth = direct->auth; - else conf->auth = server->auth; - - if (direct->envs != UNSET) conf->envs = direct->envs; - else conf->envs = server->envs; - - if (direct->format != UNSET) conf->format = direct->format; - else conf->format = server->format; - - if (direct->indexes != UNSET) conf->indexes = direct->indexes; - else conf->indexes = server->indexes; - - if (direct->gridsitelink != UNSET) conf->gridsitelink=direct->gridsitelink; - else conf->gridsitelink=server->gridsitelink; - - if (direct->indexheader != NULL) conf->indexheader = direct->indexheader; - else conf->indexheader = server->indexheader; - - if (direct->adminfile != NULL) conf->adminfile = direct->adminfile; - else conf->adminfile = server->adminfile; - - if (direct->adminuri != NULL) conf->adminuri = direct->adminuri; - else conf->adminuri = server->adminuri; - - if (direct->helpuri != NULL) conf->helpuri = direct->helpuri; - else conf->helpuri = server->helpuri; - - if (direct->dnlists != NULL) conf->dnlists = direct->dnlists; - else conf->dnlists = server->dnlists; - - if (direct->dnlistsuri != NULL) conf->dnlistsuri = direct->dnlistsuri; - else conf->dnlistsuri = server->dnlistsuri; - - if (direct->adminlist != NULL) conf->adminlist = direct->adminlist; - else conf->adminlist = server->adminlist; - - if (direct->gsiproxylimit != UNSET) - conf->gsiproxylimit = direct->gsiproxylimit; - else conf->gsiproxylimit = server->gsiproxylimit; - - if (direct->unzip != NULL) conf->unzip = direct->unzip; - else conf->unzip = server->unzip; - - if (direct->methods != NULL) conf->methods = direct->methods; - else conf->methods = server->methods; - - if (direct->editable != NULL) conf->editable = direct->editable; - else conf->editable = server->editable; - - if (direct->headfile != NULL) conf->headfile = direct->headfile; - else conf->headfile = server->headfile; - - if (direct->footfile != NULL) conf->footfile = direct->footfile; - else conf->footfile = server->footfile; - - if (direct->gridhttp != UNSET) conf->gridhttp = direct->gridhttp; - else conf->gridhttp = server->gridhttp; - - if (direct->aclformat != NULL) conf->aclformat = direct->aclformat; - else conf->aclformat = server->aclformat; - - if (direct->aclpath != NULL) conf->aclpath = direct->aclpath; - else conf->aclpath = server->aclpath; - - if (direct->delegationuri != NULL) conf->delegationuri = direct->delegationuri; - else conf->delegationuri = server->delegationuri; - - if (direct->execmethod != NULL) conf->execmethod = direct->execmethod; - else conf->execmethod = server->execmethod; - - if (direct->execugid.uid != UNSET) - { conf->execugid.uid = direct->execugid.uid; - conf->execugid.gid = direct->execugid.gid; - conf->execugid.userdir = direct->execugid.userdir; } - else - { conf->execugid.uid = server->execugid.uid; - conf->execugid.gid = server->execugid.gid; - conf->execugid.userdir = server->execugid.userdir; } - - if (direct->diskmode != UNSET) conf->diskmode = direct->diskmode; - else conf->diskmode = server->diskmode; - - return conf; -} - -static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, - const char *parm) -{ - int n, i; - char *p; - - if (strcasecmp(a->cmd->name, "GridSiteSessionsDir") == 0) - { - if (a->server->is_virtual) - return "GridSiteSessionsDir cannot be used inside a virtual server"; - - sessionsdir = apr_pstrdup(a->pool, parm); - } -/* GridSiteOnetimesDir is deprecated in favour of GridSiteSessionsDir */ - else if (strcasecmp(a->cmd->name, "GridSiteOnetimesDir") == 0) - { - if (a->server->is_virtual) - return "GridSiteOnetimesDir cannot be used inside a virtual server"; - - sessionsdir = apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteGridHTTPport") == 0) - { - gridhttpport = atoi(parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteCastDNlists") == 0) - { - if (a->server->is_virtual) - return "GridSiteDNlists cannot be used inside a virtual server"; - - sitecastdnlists = apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteCastUniPort") == 0) - { - if (a->server->is_virtual) - return "GridSiteCastUniPort cannot be used inside a virtual server"; - - if (sscanf(parm, "%d", &(sitecastgroups[0].port)) != 1) - return "Failed parsing GridSiteCastUniPort numeric value"; - } - else if (strcasecmp(a->cmd->name, "GridSiteCastGroup") == 0) - { - if (a->server->is_virtual) - return "GridSiteCastGroup cannot be used inside a virtual server"; - - for (i=1; i <= GRST_SITECAST_GROUPS; ++i) - { - if (sitecastgroups[i].port == 0) /* a free slot */ - { - sitecastgroups[i].port = GRST_HTCP_PORT; - - if (sscanf(parm, "%d.%d.%d.%d:%d", - &(sitecastgroups[i].quad1), - &(sitecastgroups[i].quad2), - &(sitecastgroups[i].quad3), - &(sitecastgroups[i].quad4), - &(sitecastgroups[i].port)) < 4) - return "Failed parsing GridSiteCastGroup nnn.nnn.nnn.nnn[:port]"; - - break; - } - } - - if (i > GRST_SITECAST_GROUPS) - return "Maximum GridSiteCastGroup groups reached"; - } - else if (strcasecmp(a->cmd->name, "GridSiteAdminFile") == 0) - { - if (index(parm, '/') != NULL) - return "/ not permitted in GridSiteAdminFile"; - - ((mod_gridsite_dir_cfg *) cfg)->adminfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteAdminURI") == 0) - { - if (*parm != '/') return "GridSiteAdminURI must begin with /"; - - ((mod_gridsite_dir_cfg *) cfg)->adminuri = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteHelpURI") == 0) - { - if (*parm != '/') return "GridSiteHelpURI must begin with /"; - - ((mod_gridsite_dir_cfg *) cfg)->helpuri = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteDNlists") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->dnlists = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteDNlistsURI") == 0) - { - if (*parm != '/') return "GridSiteDNlistsURI must begin with /"; - - if ((*parm != '\0') && (parm[strlen(parm) - 1] == '/')) - ((mod_gridsite_dir_cfg *) cfg)->dnlistsuri = - apr_pstrdup(a->pool, parm); - else - ((mod_gridsite_dir_cfg *) cfg)->dnlistsuri = - apr_pstrcat(a->pool, parm, "/", NULL); - } - else if (strcasecmp(a->cmd->name, "GridSiteAdminList") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->adminlist = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteGSIProxyLimit") == 0) - { - n = -1; - - if ((sscanf(parm, "%d", &n) == 1) && (n >= 0)) - ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit = n; - else return "GridSiteGSIProxyLimit must be a number >= 0"; - } - else if (strcasecmp(a->cmd->name, "GridSiteUnzip") == 0) - { - if (*parm != '/') return "GridSiteUnzip must begin with /"; - - ((mod_gridsite_dir_cfg *) cfg)->unzip = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteMethods") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->methods = - apr_psprintf(a->pool, " %s ", parm); - - for (p = ((mod_gridsite_dir_cfg *) cfg)->methods; - *p != '\0'; - ++p) if (*p == '\t') *p = ' '; - } - else if (strcasecmp(a->cmd->name, "GridSiteOCSP") == 0) - { - ocspmodes = apr_psprintf(a->pool, " %s ", parm); - - for (p = ocspmodes; *p != '\0'; ++p) - if (*p == '\t') *p = ' '; - else *p = tolower(*p); - } - else if (strcasecmp(a->cmd->name, "GridSiteEditable") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->editable = - apr_psprintf(a->pool, " %s ", parm); - - for (p = ((mod_gridsite_dir_cfg *) cfg)->editable; - *p != '\0'; - ++p) if (*p == '\t') *p = ' '; - } - else if (strcasecmp(a->cmd->name, "GridSiteHeadFile") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->headfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteFootFile") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->footfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteIndexHeader") == 0) - { - if (index(parm, '/') != NULL) - return "/ not permitted in GridSiteIndexHeader"; - - ((mod_gridsite_dir_cfg *) cfg)->indexheader = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteACLFormat") == 0) - { - if ((strcasecmp(parm,"GACL") != 0) && - (strcasecmp(parm,"XACML") != 0)) - return "GridsiteACLFormat must be either GACL or XACML"; - - ((mod_gridsite_dir_cfg *) cfg)->aclformat = apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteACLPath") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->aclpath = apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteDelegationURI") == 0) - { - if (*parm != '/') return "GridSiteDelegationURI must begin with /"; - - if (*parm != '\0') - ((mod_gridsite_dir_cfg *) cfg)->delegationuri = - apr_pstrdup(a->pool, parm); - - } - else if (strcasecmp(a->cmd->name, "GridSiteExecMethod") == 0) - { - if (strcasecmp(parm, "nosetuid") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->execmethod = NULL; - return NULL; - } - - if ((strcasecmp(parm, "suexec") != 0) && - (strcasecmp(parm, "X509DN") != 0) && - (strcasecmp(parm, "directory") != 0)) - return "GridsiteExecMethod must be nosetuid, suexec, X509DN or directory"; - - ((mod_gridsite_dir_cfg *) cfg)->execmethod = apr_pstrdup(a->pool, parm); - } - - return NULL; -} - -static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg, - const char *parm1, const char *parm2) -{ - int i; - char *p, *q; - - if (strcasecmp(a->cmd->name, "GridSiteUserGroup") == 0) - { - if (!(unixd_config.suexec_enabled)) - return "Using GridSiteUserGroup will " - "require rebuilding Apache with suexec support!"; - - /* NB ap_uname2id/ap_gname2id are NOT thread safe - but OK - as long as not used in .htaccess, just at server start time */ - - ((mod_gridsite_dir_cfg *) cfg)->execugid.uid = ap_uname2id(parm1); - ((mod_gridsite_dir_cfg *) cfg)->execugid.gid = ap_gname2id(parm2); - ((mod_gridsite_dir_cfg *) cfg)->execugid.userdir = 0; - } - else if (strcasecmp(a->cmd->name, "GridSiteDiskMode") == 0) - { - if ((strcasecmp(parm1, "GroupNone" ) != 0) && - (strcasecmp(parm1, "GroupRead" ) != 0) && - (strcasecmp(parm1, "GroupWrite") != 0)) - return "First parameter of GridSiteDiskMode must be " - "GroupNone, GroupRead or GroupWrite!"; - - if ((strcasecmp(parm2, "WorldNone" ) != 0) && - (strcasecmp(parm2, "WorldRead" ) != 0)) - return "Second parameter of GridSiteDiskMode must be " - "WorldNone or WorldRead!"; - - ((mod_gridsite_dir_cfg *) cfg)->diskmode = - APR_UREAD | APR_UWRITE - | ( APR_GREAD * (strcasecmp(parm1, "GroupRead") == 0)) - | ((APR_GREAD | APR_GWRITE) * (strcasecmp(parm1, "GroupWrite") == 0)) - | ((APR_GREAD | APR_WREAD) * (strcasecmp(parm2, "WorldRead") == 0)); - } - else if (strcasecmp(a->cmd->name, "GridSiteCastAlias") == 0) - { - for (i=0; i < GRST_SITECAST_ALIASES; ++i) /* look for free slot */ - { - if (sitecastaliases[i].sitecast_url == NULL) - { - sitecastaliases[i].scheme = apr_pstrdup(a->pool, parm1); - - if (((p = index(sitecastaliases[i].scheme, ':')) == NULL) - || (p[1] != '/') || (p[2] != '/')) - return "GridSiteCastAlias URL must begin with scheme (http/https/gsiftp/...) and ://"; - - *p = '\0'; - ++p; - while (*p == '/') ++p; - - if ((q = index(p, '/')) == NULL) - return "GridSiteCastAlias URL must be of form scheme://domain:port/dirs"; - - *q = '\0'; - - p = index(p, ':'); - if (p == NULL) - { - return "GridSiteCastAlias URL must include the port number"; - } - - if (sscanf(p, ":%d", &(sitecastaliases[i].port)) != 1) - return "Unable to parse numeric port number in GridSiteCastAlias"; - - sitecastaliases[i].sitecast_url = apr_pstrdup(a->pool, parm1); - sitecastaliases[i].local_path = apr_pstrdup(a->pool, parm2); - sitecastaliases[i].local_hostname = apr_pstrdup(a->pool, - a->server->server_hostname); - - break; - } - } - } - - return NULL; -} - -static const char *mod_gridsite_flag_cmds(cmd_parms *a, void *cfg, - int flag) -{ - if (strcasecmp(a->cmd->name, "GridSiteAuth") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->auth = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteEnvs") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->envs = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteHtmlFormat") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->format = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteIndexes") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->indexes = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteLink") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->gridsitelink = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteGridHTTP") == 0) - { -// TODO: return error if try this on non-HTTPS virtual server - - ((mod_gridsite_dir_cfg *) cfg)->gridhttp = flag; - } - - return NULL; -} - -static const command_rec mod_gridsite_cmds[] = -{ -// TODO: need to check and document valid contexts for each command! - - AP_INIT_FLAG("GridSiteAuth", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteEnvs", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteHtmlFormat", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteIndexes", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteLink", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - - AP_INIT_TAKE1("GridSiteAdminFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Ghost per-directory admin CGI"), - AP_INIT_TAKE1("GridSiteAdminURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of real gridsite-admin.cgi"), - AP_INIT_TAKE1("GridSiteHelpURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of Website Help pages"), - AP_INIT_TAKE1("GridSiteDNlists", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "DN Lists directories search path"), - AP_INIT_TAKE1("GridSiteDNlistsURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of published DN lists"), - AP_INIT_TAKE1("GridSiteAdminList", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of admin DN List"), - AP_INIT_TAKE1("GridSiteGSIProxyLimit", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Max level of GSI proxy validity"), - AP_INIT_TAKE1("GridSiteUnzip", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Absolute path to unzip command"), - - AP_INIT_RAW_ARGS("GridSiteMethods", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "permitted HTTP methods"), - AP_INIT_RAW_ARGS("GridSiteOCSP", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "Set OCSP lookups"), - AP_INIT_RAW_ARGS("GridSiteEditable", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "editable file extensions"), - AP_INIT_TAKE1("GridSiteHeadFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of HTML header"), - AP_INIT_TAKE1("GridSiteFootFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of HTML footer"), - AP_INIT_TAKE1("GridSiteIndexHeader", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of directory header"), - - AP_INIT_FLAG("GridSiteGridHTTP", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_TAKE1("GridSiteGridHTTPport", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "GridHTTP port"), - AP_INIT_TAKE1("GridSiteSessionsDir", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "directory with GridHTTP passcodes and SSL session creds"), -/* GridSiteOnetimesDir is deprecated in favour of GridSiteSessionsDir */ - AP_INIT_TAKE1("GridSiteOnetimesDir", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "directory with GridHTTP passcodes"), - - AP_INIT_TAKE1("GridSiteCastDNlists", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "DN Lists directories search path for SiteCast"), - AP_INIT_TAKE1("GridSiteCastUniPort", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "UDP port for unicast/replies"), - AP_INIT_TAKE1("GridSiteCastGroup", mod_gridsite_take1_cmds, - NULL, RSRC_CONF, "multicast group[:port] to listen for HTCP on"), - AP_INIT_TAKE2("GridSiteCastAlias", mod_gridsite_take2_cmds, - NULL, RSRC_CONF, "URL and local path mapping"), - - AP_INIT_TAKE1("GridSiteACLFormat", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "format to save access control lists in"), - AP_INIT_TAKE1("GridSiteACLPath", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "explicit location of access control file"), - - AP_INIT_TAKE1("GridSiteDelegationURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of the delegation service CGI"), - - AP_INIT_TAKE1("GridSiteExecMethod", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "execution strategy used by gsexec"), - - AP_INIT_TAKE2("GridSiteUserGroup", mod_gridsite_take2_cmds, - NULL, OR_FILEINFO, - "user and group of gsexec processes in suexec mode"), - - AP_INIT_TAKE2("GridSiteDiskMode", mod_gridsite_take2_cmds, - NULL, OR_FILEINFO, - "group and world file modes for new files/directories"), - - {NULL} -}; - -/* Blank unset these HTTP headers, to prevent injection attacks. - This is run before mod_shib's check_user_id hook, which may - legitimately create such headers. */ - -static int mod_gridsite_check_user_id(request_rec *r) -{ - apr_table_unset(r->headers_in, "User-Distinguished-Name"); -#if 0 - apr_table_unset(r->headers_in, "User-Distinguished-Name-2"); -#endif - apr_table_unset(r->headers_in, "Nist-LoA"); - apr_table_unset(r->headers_in, "LoA"); - apr_table_unset(r->headers_in, "VOMS-Attribute"); - - return DECLINED; /* ie carry on processing request */ -} - -static int mod_gridsite_first_fixups(request_rec *r) -{ - mod_gridsite_dir_cfg *conf; - - if (r->finfo.filetype != APR_DIR) return DECLINED; - - conf = (mod_gridsite_dir_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - /* we handle DN Lists as regular files, even if they also match - directory names */ - - if ((conf != NULL) && - (conf->dnlistsuri != NULL) && - (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0) && - (strcmp(r->uri, conf->dnlistsuri) != 0)) - { - r->finfo.filetype = APR_REG; - } - - return DECLINED; -} - - -int GRST_get_session_id(SSL *ssl, char *session_id, size_t len) -{ - int i; - SSL_SESSION *session; - - if (((session = SSL_get_session(ssl)) == NULL) || - (session->session_id_length == 0)) return GRST_RET_FAILED; - - if (2 * session->session_id_length + 1 > len) return GRST_RET_FAILED; - - for (i=0; i < (int) session->session_id_length; ++i) - sprintf(&(session_id[i*2]), "%02X", (unsigned char) session->session_id[i]); - - session_id[i*2] = '\0'; - - return GRST_RET_OK; -} - -int GRST_load_ssl_creds(SSL *ssl, conn_rec *conn) -{ - char session_id[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2], *sessionfile = NULL, - line[512], *p; - apr_file_t *fp = NULL; - int i; - - if (GRST_get_session_id(ssl, session_id, sizeof(session_id)) != GRST_RET_OK) - return GRST_RET_FAILED; - - sessionfile = apr_psprintf(conn->pool, "%s/sslcreds-%s", - ap_server_root_relative(conn->pool, sessionsdir), - session_id); - - if (apr_file_open(&fp, sessionfile, APR_READ, 0, conn->pool) != APR_SUCCESS) - return GRST_RET_FAILED; - - while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) - { - if (sscanf(line, "GRST_CRED_%d=", &i) == 1) - { - p = index(line, '='); - - apr_table_setn(conn->notes, - apr_psprintf(conn->pool, "GRST_CRED_%d", i), - apr_pstrdup(conn->pool, &p[1])); - } - else if (sscanf(line, "GRST_OCSP_URL_%d=", &i) == 1) - { - p = index(line, '='); - - apr_table_setn(conn->notes, - apr_psprintf(conn->pool, "GRST_OCSP_URL_%d", i), - apr_pstrdup(conn->pool, &p[1])); - } - } - - apr_file_close(fp); - - /* connection notes created by GRST_save_ssl_creds() are now reloaded */ - apr_table_set(conn->notes, "GRST_save_ssl_creds", "yes"); - - return GRST_RET_OK; -} - -/* - Save result of GRSTx509CompactCreds() into connection notes, and - write out in an SSL session creds file. -*/ - -void GRST_save_ssl_creds(conn_rec *conn, - STACK_OF(X509) *certstack, X509 *peercert) -{ - int i, lastcred; - const int maxcreds = 99; - const size_t credlen = 1024; - char creds[maxcreds][credlen+1], envname[14], *tempfile = NULL, - *sessionfile, session_id[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2]; - apr_file_t *fp = NULL; - SSL *ssl; - SSLConnRec *sslconn; - - /* check if already done */ - - if ((certstack != NULL) && (conn->notes != NULL) && - (apr_table_get(conn->notes, "GRST_save_ssl_creds") != NULL)) return; - - /* we at least need to say we've been run */ - - apr_table_set(conn->notes, "GRST_save_ssl_creds", "yes"); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server, - "set GRST_save_ssl_creds"); - - sslconn = (SSLConnRec *)ap_get_module_config(conn->conn_config,&ssl_module); - - if ((sslconn != NULL) && - ((ssl = sslconn->ssl) != NULL) && - (GRST_get_session_id(ssl,session_id,sizeof(session_id)) == GRST_RET_OK)) - { - sessionfile = apr_psprintf(conn->pool, "%s/sslcreds-%s", - ap_server_root_relative(conn->pool, sessionsdir), - session_id); - - tempfile = apr_pstrcat(conn->pool, - ap_server_root_relative(conn->pool, sessionsdir), - "/tmp-XXXXXX", NULL); - - if ((tempfile != NULL) && (tempfile[0] != '\0')) - apr_file_mktemp(&fp, tempfile, - APR_CREATE | APR_WRITE | APR_EXCL, conn->pool); - } - - if (GRSTx509CompactCreds(&lastcred, maxcreds, credlen, (char *) creds, - certstack, GRST_VOMS_DIR, peercert) == GRST_RET_OK) - { - for (i=0; i <= lastcred; ++i) - { - apr_table_setn(conn->notes, - apr_psprintf(conn->pool, "GRST_CRED_%d", i), - apr_pstrdup(conn->pool, creds[i])); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server, - "store GRST_CRED_%d=%s", i, creds[i]); - - if (fp != NULL) apr_file_printf(fp, "GRST_CRED_%d=%s\n", - i, creds[i]); - } - - /* free remaining dup'd certs? */ - } - - /* this needs to be merged into compactcreds in grst_x509? */ - - if (ocspmodes != NULL) - { - int j; - const char *ex_sn; - char s[80]; - X509 *cert; - X509_EXTENSION *ex; - - for (j=sk_X509_num(certstack)-1; j >= 0; --j) - { - cert = sk_X509_value(certstack, j); - - for (i=0; i < X509_get_ext_count(cert); ++i) - { - ex = X509_get_ext(cert, i); - - OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 0); - - if (strcmp(s, "authorityInfoAccess") == 0) /* OCSP */ - { - apr_table_setn(conn->notes, "GRST_OCSP_URL", - (const char *) X509_EXTENSION_get_data(ex)); - - /* strategy is to remove what has been checked, - for this connnection */ - apr_table_set(conn->notes, "GRST_OCSP_UNCHECKED", - ocspmodes); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server, - "store GRST_OCSP_URL_%d=%s", i, X509_EXTENSION_get_data(ex)); - - if (fp != NULL) apr_file_printf(fp, "GRST_OCSP_URL_%d=%s\n", - i, X509_EXTENSION_get_data(ex)); - } - } - } - } - - /* end of bit that needs to go into grst_x509 */ - - if (fp != NULL) - { - apr_file_close(fp); - apr_file_rename(tempfile, sessionfile, conn->pool); - } -} - -static char *get_aclpath_component(request_rec *r, int n) -/* - Get the nth component of REQUEST_URI, or component 0 - which is the server name. - -*/ -{ - int ii, i, nn; - - if (n == 0) return r->server->server_hostname; - - if (r->uri == NULL) return NULL; /* some kind of internal error? */ - - i = 1; /* start of first component */ - nn = 1; - - for (ii=1; r->uri[ii] != '\0'; ++ii) /* look for this component */ - { - if (r->uri[ii] == '/') /* end of a component */ - { - if (nn == n) break; - - ++nn; - i = ii + 1; - } - else if ((r->uri[ii] == '.') && (r->uri[ii+1] == '.')) - { - return NULL; /* can this happen? dont allow anyway */ - } - } - - if (nn != n) return NULL; /* no component for this number */ - - return apr_psprintf(r->pool, "%.*s", ii - i, &(r->uri[i])); -} - -static char *make_aclpath(request_rec *r, char *format) -{ - int i, n; - char *formatted, *p; - - formatted = apr_pstrdup(r->pool, format); - - while (1) - { - for (i=0; (formatted[i] != '\0') && (formatted[i] != '%'); ++i) ; - - if (formatted[i] == '\0') break; - - if ((formatted[i] == '%') && (formatted[i+1] == '%')) - { - ++i; - continue; - } - - if (sscanf(&formatted[i+1], "%d", &n) != 1) - { - return NULL; /* not %% or %0,%1,... */ - } - - formatted[i] = '\0'; - - for (i++; isdigit(formatted[i]); ++i) ; - - if ((p = get_aclpath_component(r, n)) == NULL) return NULL; - - formatted = apr_pstrcat(r->pool, formatted, p, &formatted[i],NULL); - i += strlen(p); - } - - return ap_server_root_relative(r->pool, formatted); -} - -static int mod_gridsite_perm_handler(request_rec *r) -/* - Do authentication/authorization here rather than in the normal module - auth functions since the results of mod_ssl are available. - - We also publish environment variables here if requested by GridSiteEnv. -*/ -{ - int retcode = DECLINED, i, n, file_is_acl = 0, - destination_is_acl = 0, proxylevel, ishttps = 0; - char *dn, *p, envname[14], *grst_cred_0 = NULL, *dir_path, - *remotehost, s[99], *grst_cred_i, *cookies, *file, *https, - *gridauthpasscode = NULL, *cookiefile, oneline[1025], *key_i, - *destination = NULL, *destination_uri = NULL, *querytmp, - *destination_prefix = NULL, *destination_translated = NULL, - *aclpath = NULL; - char *vomsAttribute = NULL, *loa; - const char *content_type; - time_t now, notbefore, notafter; - apr_table_t *env; - apr_finfo_t cookiefile_info; - apr_file_t *fp; - request_rec *destreq; - GRSTgaclCred *cred = NULL, *cred_0 = NULL; - GRSTgaclUser *user = NULL; - GRSTgaclPerm perm = GRST_PERM_NONE, destination_perm = GRST_PERM_NONE; - GRSTgaclAcl *acl = NULL; - mod_gridsite_dir_cfg *cfg; - SSLConnRec *sslconn; - STACK_OF(X509) *certstack; - X509 *peercert; - - cfg = (mod_gridsite_dir_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - if (cfg == NULL) return DECLINED; - - if ((cfg->auth == 0) && - (cfg->envs == 0)) - return DECLINED; /* if not turned on, look invisible */ - - env = r->subprocess_env; - - /* Get the user's attributes from Shibboleth and set up user credential - based on the attributes if authentication has been carried out using - a Shibboleth Identity Provider.*/ - - /* Get DN from a Shibboleth attribute */ - - dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name"); -#if 0 - if ((dn == NULL) || (*dn == '\0')) - dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name-2"); -#endif - - if ((dn != NULL) && (*dn == '\0')) dn = NULL; - - if (dn != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "DN: %s", dn); - - /* Get the NIST LoA attribute */ - loa = (char *) apr_table_get(r->headers_in, "nist-loa"); - - if ((loa == NULL) || (*loa == '\0')) - loa = (char *) apr_table_get(r->headers_in, "loa"); - - if ((loa != NULL) && (*loa == '\0')) loa = NULL; - - if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "nist-loa: %s", loa); - - /* Set up user credential based on the DN and LoA attributes */ - - if (dn != NULL) - { - cred = GRSTgaclCredNew("person"); - GRSTgaclCredAddValue(cred, "dn", dn); - user = GRSTgaclUserNew(cred); - cred = GRSTgaclCredNew("level"); - - if (loa != NULL) GRSTgaclCredAddValue(cred, "nist-loa", loa); - else GRSTgaclCredAddValue(cred, "nist-loa", "2"); - - GRSTgaclUserAddCred(user, cred); - } - - /* Set up user credential based on VOMS Attribute from Shibboleth? */ - - vomsAttribute = (char *) apr_table_get(r->headers_in, "VOMS-Attribute"); - if (vomsAttribute != NULL) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "VOMS-Attribute: %s", vomsAttribute); - - cred = GRSTgaclCredNew("voms"); - GRSTgaclCredAddValue(cred, "fqan", vomsAttribute); - if (user == NULL) user = GRSTgaclUserNew(cred); - else GRSTgaclUserAddCred(user, cred); - } - - p = (char *) apr_table_get(r->subprocess_env, "HTTPS"); - if ((p != NULL) && (strcmp(p, "on") == 0)) ishttps = 1; - - /* reload per-connection (SSL) cred variables? */ - - sslconn = (SSLConnRec *) ap_get_module_config(r->connection->conn_config, - &ssl_module); - if ((user == NULL) && - (sslconn != NULL) && - (sslconn->ssl != NULL) && - (sslconn->ssl->session != NULL) && - (r->connection->notes != NULL) && - (apr_table_get(r->connection->notes, "GRST_save_ssl_creds") == NULL)) - { - if (GRST_load_ssl_creds(sslconn->ssl, r->connection) == GRST_RET_OK) - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Restored SSL session data from session cache file"); - } - - proxylevel = ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit + 1; - - if ((user == NULL) && - (r->connection->notes != NULL) && - ((grst_cred_0 = (char *) - apr_table_get(r->connection->notes, "GRST_CRED_0")) != NULL) && - (sscanf(grst_cred_0, "X509USER %*d %*d %d ", &proxylevel) == 1) && - (proxylevel <= ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit)) - { - apr_table_setn(env, "GRST_CRED_0", grst_cred_0); - - cred_0 = GRSTx509CompactToCred(grst_cred_0); - if (cred_0 != NULL) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Using identity %s from SSL/TLS", grst_cred_0); - - user = GRSTgaclUserNew(cred_0); - - /* check for VOMS GRST_CRED_i too */ - - for (i=1; ; ++i) - { - snprintf(envname, sizeof(envname), "GRST_CRED_%d", i); - if (grst_cred_i = (char *) - apr_table_get(r->connection->notes,envname)) - { - if (((mod_gridsite_dir_cfg *) cfg)->envs) - apr_table_setn(env, - apr_pstrdup(r->pool, envname), - grst_cred_i); - - if (cred = GRSTx509CompactToCred(grst_cred_i)) - GRSTgaclUserAddCred(user, cred); - } - else break; /* GRST_CRED_i are numbered consecutively */ - } - - cred = GRSTgaclCredNew("level"); - if (proxylevel == 0) GRSTgaclCredAddValue(cred, "nist-loa", "3"); - else GRSTgaclCredAddValue(cred, "nist-loa", "2"); - GRSTgaclUserAddCred(user, cred); - } - } - - if ((user != NULL) && ((mod_gridsite_dir_cfg *) cfg)->dnlists) - GRSTgaclUserSetDNlists(user, ((mod_gridsite_dir_cfg *) cfg)->dnlists); - - /* add DNS credential */ - - remotehost = (char *) ap_get_remote_host(r->connection, - r->per_dir_config, REMOTE_DOUBLE_REV, NULL); - if ((remotehost != NULL) && (*remotehost != '\0')) - { - cred = GRSTgaclCredNew("dns"); - GRSTgaclCredAddValue(cred, "hostname", remotehost); - - if (user == NULL) user = GRSTgaclUserNew(cred); - else GRSTgaclUserAddCred(user, cred); - } - - /* check for Destination: header and evaluate if present */ - - if ((destination = (char *) apr_table_get(r->headers_in, - "Destination")) != NULL) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Destination header found, value=%s", destination); - - destination_prefix = apr_psprintf(r->pool, "https://%s:%d/", - r->server->server_hostname, (int) r->server->port); - - if (strncmp(destination_prefix, destination, - strlen(destination_prefix)) == 0) - destination_uri = &destination[strlen(destination_prefix)-1]; - else if ((int) r->server->port == 443) - { - destination_prefix = apr_psprintf(r->pool, "https://%s/", - r->server->server_hostname); - - if (strncmp(destination_prefix, destination, - strlen(destination_prefix)) == 0) - destination_uri = &destination[strlen(destination_prefix)-1]; - } - - if (destination_uri != NULL) - { - destreq = ap_sub_req_method_uri("GET", destination_uri, r, NULL); - - if ((destreq != NULL) && (destreq->filename != NULL) - && (destreq->path_info != NULL)) - { - destination_translated = apr_pstrcat(r->pool, - destreq->filename, destreq->path_info, NULL); - - apr_table_setn(r->notes, "GRST_DESTINATION_TRANSLATED", - destination_translated); - - if (((mod_gridsite_dir_cfg *) cfg)->envs) - apr_table_setn(env, "GRST_DESTINATION_TRANSLATED", - destination_translated); - - p = rindex(destination_translated, '/'); - if ((p != NULL) && (strcmp(&p[1], GRST_ACL_FILE) == 0)) - destination_is_acl = 1; - } - } - } - - /* this checks for NULL arguments itself */ - if (GRSTgaclDNlistHasUser(((mod_gridsite_dir_cfg *) cfg)->adminlist, user)) - { - perm = GRST_PERM_ALL; - if (destination_translated != NULL) destination_perm = GRST_PERM_ALL; - } - else - { - if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL) - { - aclpath = make_aclpath(r,((mod_gridsite_dir_cfg *) cfg)->aclpath); - - if (aclpath != NULL) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Examine ACL file %s (from ACL path %s)", - aclpath, ((mod_gridsite_dir_cfg *) cfg)->aclpath); - - acl = GRSTgaclAclLoadFile(aclpath); - } - else ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Failed to make ACL file from ACL path %s, URI %s)", - ((mod_gridsite_dir_cfg *) cfg)->aclpath, r->uri); - } - else acl = GRSTgaclAclLoadforFile(r->filename); - - if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user); - GRSTgaclAclFree(acl); - - if (destination_translated != NULL) - { - acl = GRSTgaclAclLoadforFile(destination_translated); - if (acl != NULL) destination_perm = GRSTgaclAclTestUser(acl, user); - GRSTgaclAclFree(acl); - - apr_table_setn(r->notes, "GRST_DESTINATION_PERM", - apr_psprintf(r->pool, "%d", destination_perm)); - - if (((mod_gridsite_dir_cfg *) cfg)->envs) - apr_table_setn(env, "GRST_DESTINATION_PERM", - apr_psprintf(r->pool, "%d", destination_perm)); - } - } - - /* first look for GRIDHTTP_PASSCODE cookie */ - - if ((p = (char *) apr_table_get(r->headers_in, "Cookie")) != NULL) - { - cookies = apr_pstrcat(r->pool, " ", p, NULL); - gridauthpasscode = strstr(cookies, " GRIDHTTP_PASSCODE="); - - if (gridauthpasscode != NULL) - { - gridauthpasscode = &gridauthpasscode[19]; - - for (p = gridauthpasscode; - (*p != '\0') && (*p != ';'); ++p) - if (!isalnum(*p)) *p = '\0'; - } - } - - /* then look for GRIDHTTP_PASSCODE in QUERY_STRING ie after ? */ - - if (gridauthpasscode == NULL) - { - if ((r->parsed_uri.query != NULL) && (r->parsed_uri.query[0] != '\0')) - { - querytmp = apr_pstrcat(r->pool,"&",r->parsed_uri.query,"&",NULL); - - gridauthpasscode = strstr(querytmp, "&GRIDHTTP_PASSCODE="); - - if (gridauthpasscode != NULL) - { - gridauthpasscode = &gridauthpasscode[19]; - - for (p = gridauthpasscode; - (*p != '\0') && (*p != '&'); ++p) - if (!isalnum(*p)) *p = '\0'; - } - } - } - - if ((gridauthpasscode != NULL) && (gridauthpasscode[0] != '\0')) - { - cookiefile = apr_psprintf(r->pool, "%s/passcode-%s", - ap_server_root_relative(r->pool, - sessionsdir), - gridauthpasscode); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Opening GridHTTP passcode file %s", cookiefile); - - if ((apr_stat(&cookiefile_info, cookiefile, - APR_FINFO_TYPE, r->pool) == APR_SUCCESS) && - (cookiefile_info.filetype == APR_REG) && - (apr_file_open(&fp, cookiefile, APR_READ, 0, r->pool) - == APR_SUCCESS)) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Reading GridHTTP passcode file %s", cookiefile); - - while (apr_file_gets(oneline, - sizeof(oneline), fp) == APR_SUCCESS) - { - p = index(oneline, '\n'); - if (p != NULL) *p = '\0'; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "%s: %s", cookiefile, oneline); - - if ((strncmp(oneline, "expires=", 8) == 0) && - (apr_time_from_sec(atoll(&oneline[8])) < - apr_time_now())) - break; - else if ((strncmp(oneline, "domain=", 7) == 0) && - (strcmp(&oneline[7], r->hostname) != 0)) - break; /* exact needed in the version */ - else if ((strncmp(oneline, "path=", 5) == 0) && - (strcmp(&oneline[5], r->uri) != 0)) - break; - else if ((strncmp(oneline, "onetime=yes", 11) == 0) - && !ishttps) - apr_file_remove(cookiefile, r->pool); - else if (strncmp(oneline, "method=PUT", 10) == 0) - perm |= GRST_PERM_WRITE; - else if (strncmp(oneline, "method=GET", 10) == 0) - perm |= GRST_PERM_READ; - } - - apr_file_close(fp); - } - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "After GACL/Onetime evaluation, GRST_PERM=%d", perm); - - /* set permission and GACL environment variables */ - - apr_table_setn(r->notes, "GRST_PERM", apr_psprintf(r->pool, "%d", perm)); - - if (((mod_gridsite_dir_cfg *) cfg)->envs) - { - apr_table_setn(env, "GRST_PERM", apr_psprintf(r->pool, "%d", perm)); - - if (((dir_path = apr_pstrdup(r->pool, r->filename)) != NULL) && - ((p = rindex(dir_path, '/')) != NULL)) - { - *p = '\0'; - apr_table_setn(env, "GRST_DIR_PATH", dir_path); - } - - if (((mod_gridsite_dir_cfg *) cfg)->helpuri != NULL) - apr_table_setn(env, "GRST_HELP_URI", - ((mod_gridsite_dir_cfg *) cfg)->helpuri); - - if (((mod_gridsite_dir_cfg *) cfg)->adminfile != NULL) - apr_table_setn(env, "GRST_ADMIN_FILE", - ((mod_gridsite_dir_cfg *) cfg)->adminfile); - - if (((mod_gridsite_dir_cfg *) cfg)->editable != NULL) - apr_table_setn(env, "GRST_EDITABLE", - ((mod_gridsite_dir_cfg *) cfg)->editable); - - if (((mod_gridsite_dir_cfg *) cfg)->headfile != NULL) - apr_table_setn(env, "GRST_HEAD_FILE", - ((mod_gridsite_dir_cfg *) cfg)->headfile); - - if (((mod_gridsite_dir_cfg *) cfg)->footfile != NULL) - apr_table_setn(env, "GRST_FOOT_FILE", - ((mod_gridsite_dir_cfg *) cfg)->footfile); - - if (((mod_gridsite_dir_cfg *) cfg)->dnlists != NULL) - apr_table_setn(env, "GRST_DN_LISTS", - ((mod_gridsite_dir_cfg *) cfg)->dnlists); - - if (((mod_gridsite_dir_cfg *) cfg)->dnlistsuri != NULL) - apr_table_setn(env, "GRST_DN_LISTS_URI", - ((mod_gridsite_dir_cfg *) cfg)->dnlistsuri); - - if (((mod_gridsite_dir_cfg *) cfg)->adminlist != NULL) - apr_table_setn(env, "GRST_ADMIN_LIST", - ((mod_gridsite_dir_cfg *) cfg)->adminlist); - - apr_table_setn(env, "GRST_GSIPROXY_LIMIT", - apr_psprintf(r->pool, "%d", - ((mod_gridsite_dir_cfg *)cfg)->gsiproxylimit)); - - if (((mod_gridsite_dir_cfg *) cfg)->unzip != NULL) - apr_table_setn(env, "GRST_UNZIP", - ((mod_gridsite_dir_cfg *) cfg)->unzip); - - if (!(((mod_gridsite_dir_cfg *) cfg)->gridsitelink)) - apr_table_setn(env, "GRST_NO_LINK", "1"); - - if (((mod_gridsite_dir_cfg *) cfg)->aclformat != NULL) - apr_table_setn(env, "GRST_ACL_FORMAT", - ((mod_gridsite_dir_cfg *) cfg)->aclformat); - - if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL) - apr_table_setn(env, "GRST_ACL_PATH", - ((mod_gridsite_dir_cfg *) cfg)->aclpath); - - if (((mod_gridsite_dir_cfg *) cfg)->delegationuri != NULL) - apr_table_setn(env, "GRST_DELEGATION_URI", - ((mod_gridsite_dir_cfg *) cfg)->delegationuri); - - - if (((mod_gridsite_dir_cfg *) cfg)->execmethod != NULL) - { - apr_table_setn(env, "GRST_EXEC_METHOD", - ((mod_gridsite_dir_cfg *) cfg)->execmethod); - - if ((strcasecmp(((mod_gridsite_dir_cfg *) cfg)->execmethod, - "directory") == 0) && (r->filename != NULL)) - { - if ((r->content_type != NULL) && - (strcmp(r->content_type, DIR_MAGIC_TYPE) == 0)) - apr_table_setn(env, "GRST_EXEC_DIRECTORY", r->filename); - else - { - file = apr_pstrdup(r->pool, r->filename); - p = rindex(file, '/'); - if (p != NULL) - { - *p = '\0'; - apr_table_setn(env, "GRST_EXEC_DIRECTORY", file); - } - } - } - } - - apr_table_setn(env, "GRST_DISK_MODE", - apr_psprintf(r->pool, "0x%04x", - ((mod_gridsite_dir_cfg *)cfg)->diskmode)); - } - - if (((mod_gridsite_dir_cfg *) cfg)->auth) - { - /* *** Check HTTP method to decide which perm bits to check *** */ - - if ((r->filename != NULL) && - ((p = rindex(r->filename, '/')) != NULL) && - (strcmp(&p[1], GRST_ACL_FILE) == 0)) file_is_acl = 1; - - content_type = r->content_type; - if ((content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) == 0) && - (((mod_gridsite_dir_cfg *) cfg)->dnlistsuri != NULL) && - (strncmp(r->uri, - ((mod_gridsite_dir_cfg *) cfg)->dnlistsuri, - strlen(((mod_gridsite_dir_cfg *) cfg)->dnlistsuri)) == 0) && - (strlen(r->uri) > strlen(((mod_gridsite_dir_cfg *) cfg)->dnlistsuri))) - content_type = "text/html"; - - if ( GRSTgaclPermHasNone(perm) || - - /* first two M_GET conditions make the subtle distinction - between .../ that maps to .../index.html (governed by - Read perm) or to dir list (governed by List perm); - third M_GET condition deals with typeless CGI requests */ - - ((r->method_number == M_GET) && - !GRSTgaclPermHasRead(perm) && - (content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) != 0)) || - - ((r->method_number == M_GET) && - !GRSTgaclPermHasList(perm) && - (content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) == 0)) || - - ((r->method_number == M_GET) && - !GRSTgaclPermHasRead(perm) && - (content_type == NULL)) || - - ((r->method_number == M_POST) && !GRSTgaclPermHasRead(perm) ) || - - (((r->method_number == M_PUT) || - (r->method_number == M_DELETE)) && - !GRSTgaclPermHasWrite(perm) && !file_is_acl) || - - ((r->method_number == M_MOVE) && - ((!GRSTgaclPermHasWrite(perm) && !file_is_acl) || - (!GRSTgaclPermHasAdmin(perm) && file_is_acl) || - (!GRSTgaclPermHasWrite(destination_perm) - && !destination_is_acl) || - (!GRSTgaclPermHasAdmin(destination_perm) - && destination_is_acl)) ) || - - (((r->method_number == M_PUT) || - (r->method_number == M_DELETE)) && - !GRSTgaclPermHasAdmin(perm) && file_is_acl) || - - /* for WebDAV/Subversion */ - - (((r->method_number == M_PROPFIND) || - (r->method_number == M_REPORT)) && - !GRSTgaclPermHasRead(perm)) || - - (((r->method_number == M_CHECKOUT) || - (r->method_number == M_MERGE) || - (r->method_number == M_MKACTIVITY) || - (r->method_number == M_MKCOL) || - (r->method_number == M_LOCK) || - (r->method_number == M_UNLOCK)) && - !GRSTgaclPermHasWrite(perm)) - - ) retcode = HTTP_FORBIDDEN; - } - - return retcode; -} - -int GRST_X509_check_issued_wrapper(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) -/* We change the default callback to use our wrapper and discard errors - due to GSI proxy chains (ie where users certs act as CAs) */ -{ - int ret; - ret = X509_check_issued(issuer, x); - if (ret == X509_V_OK) - return 1; - - /* Non self-signed certs without signing are ok if they passed - the other checks inside X509_check_issued. Is this enough? */ - if ((ret == X509_V_ERR_KEYUSAGE_NO_CERTSIGN) && - (X509_NAME_cmp(X509_get_subject_name(issuer), - X509_get_subject_name(x)) != 0)) return 1; - - /* If we haven't asked for issuer errors don't set ctx */ - if (!(ctx->flags & X509_V_FLAG_CB_ISSUER_CHECK)) return 0; - - ctx->error = ret; - ctx->current_cert = x; - ctx->current_issuer = issuer; - return ctx->verify_cb(0, ctx); -} - -/* Later OpenSSL versions add a second pointer ... */ -int GRST_verify_cert_wrapper(X509_STORE_CTX *ctx, void *p) - -/* Earlier ones have a single argument ... */ -// int GRST_verify_cert_wrapper(X509_STORE_CTX *ctx) - -/* Before 0.9.7 we cannot change the check_issued callback directly in - the X509_STORE, so we must insert it in another callback that gets - called early enough */ -{ - ctx->check_issued = GRST_X509_check_issued_wrapper; - - return X509_verify_cert(ctx); -} - -int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) -{ - SSL *ssl = (SSL *) X509_STORE_CTX_get_app_data(ctx); - conn_rec *conn = (conn_rec *) SSL_get_app_data(ssl); - server_rec *s = conn->base_server; - SSLConnRec *sslconn = - (SSLConnRec *) ap_get_module_config(conn->conn_config, &ssl_module); - int errnum = X509_STORE_CTX_get_error(ctx); - int errdepth = X509_STORE_CTX_get_error_depth(ctx); - int returned_ok; - int first_non_ca; - STACK_OF(X509) *certstack; - - /* - * GSI Proxy user-cert-as-CA handling: - * we skip Invalid CA errors at this stage, since we will check this - * again at errdepth=0 for the full chain using GRSTx509CheckChain - */ - if (errnum == X509_V_ERR_INVALID_CA) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "Skip Invalid CA error in case a GSI Proxy"); - - sslconn->verify_error = NULL; - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - - /* - * New style GSI Proxy handling, with critical ProxyCertInfo - * extension: we use GRSTx509KnownCriticalExts() to check this - */ -#ifndef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#endif - if (errnum == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) - { - if (GRSTx509KnownCriticalExts(X509_STORE_CTX_get_current_cert(ctx)) - == GRST_RET_OK) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "GRSTx509KnownCriticalExts() accepts previously " - "Unhandled Critical Extension (GSI Proxy?)"); - - sslconn->verify_error = NULL; - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - } - - returned_ok = ssl_callback_SSLVerify(ok, ctx); - - /* in case ssl_callback_SSLVerify changed it */ - errnum = X509_STORE_CTX_get_error(ctx); - - if ((errdepth == 0) && (errnum == X509_V_OK)) - /* - * We've now got the last certificate - the identity being used for - * this connection. At this point we check the whole chain for valid - * CAs or, failing that, GSI-proxy validity using GRSTx509CheckChain. - */ - { - errnum = GRSTx509CheckChain(&first_non_ca, ctx); - - if (errnum != X509_V_OK) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "Invalid certificate chain reported by " - "GRSTx509CheckChain()"); - - sslconn->verify_error = X509_verify_cert_error_string(errnum); - ok = FALSE; - } - else - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Valid certificate" - " chain reported by GRSTx509CheckChain()"); - - /* Put result of GRSTx509CompactCreds() into connection notes */ - if ((certstack = - (STACK_OF(X509) *) X509_STORE_CTX_get_chain(ctx)) != NULL) - GRST_save_ssl_creds(conn, certstack, NULL); - } - } - - return returned_ok; -} - -void sitecast_handle_NOP_request(server_rec *main_server, - GRSThtcpMessage *htcp_mesg, int igroup, - struct sockaddr_in *client_addr_ptr) -{ - int outbuf_len; - char *outbuf; - - if (GRSThtcpNOPresponseMake(&outbuf, &outbuf_len, - htcp_mesg->trans_id) == GRST_RET_OK) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast sends NOP response from port %d to %s:%d", - sitecastgroups[0].port, inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - - sendto(sitecastgroups[0].socket, outbuf, outbuf_len, 0, - client_addr_ptr, sizeof(struct sockaddr_in)); - - free(outbuf); - } -} - -void sitecast_handle_TST_GET(server_rec *main_server, - GRSThtcpMessage *htcp_mesg, int igroup, - struct sockaddr_in *client_addr_ptr) -{ - int i, outbuf_len, ialias; - char *filename, *outbuf, *location, *local_uri = NULL; - struct stat statbuf; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast responder received TST GET with uri %s", - htcp_mesg->uri->text, GRSThtcpCountstrLen(htcp_mesg->uri)); - - /* find if any GridSiteCastAlias lines match */ - - for (ialias=0; ialias < GRST_SITECAST_ALIASES ; ++ialias) - { - if (sitecastaliases[ialias].sitecast_url == NULL) return; /* no match */ - - if ((strlen(sitecastaliases[ialias].sitecast_url) - <= GRSThtcpCountstrLen(htcp_mesg->uri)) && - (strncmp(sitecastaliases[ialias].sitecast_url, - htcp_mesg->uri->text, - strlen(sitecastaliases[ialias].sitecast_url))==0)) break; - } - - if (ialias == GRST_SITECAST_ALIASES) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast responder does not handle %*s requested by %s:%d", - GRSThtcpCountstrLen(htcp_mesg->uri), - htcp_mesg->uri->text, - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - - return; /* no match */ - } - - /* convert URL to filename, using alias mapping */ - - asprintf(&filename, "%s%*s", - sitecastaliases[ialias].local_path, - GRSThtcpCountstrLen(htcp_mesg->uri) - - strlen(sitecastaliases[ialias].sitecast_url), - &(htcp_mesg->uri->text[strlen(sitecastaliases[ialias].sitecast_url)]) ); - - if (stat(filename, &statbuf) == 0) /* found file */ - { - asprintf(&location, "Location: %s://%s:%d/%s\r\n", - sitecastaliases[ialias].scheme, - sitecastaliases[ialias].local_hostname, - sitecastaliases[ialias].port, - &(htcp_mesg->uri->text[strlen(sitecastaliases[ialias].sitecast_url)]) ); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast finds %*s at %s, redirects with %s", - GRSThtcpCountstrLen(htcp_mesg->uri), - htcp_mesg->uri->text, filename, location); - - if (GRSThtcpTSTresponseMake(&outbuf, &outbuf_len, - htcp_mesg->trans_id, - location, "", "") == GRST_RET_OK) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast sends TST response from port %d to %s:%d", - sitecastgroups[0].port, inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - - sendto(sitecastgroups[0].socket, outbuf, outbuf_len, 0, - client_addr_ptr, sizeof(struct sockaddr_in)); - - free(outbuf); - } - - free(location); - } - - free(filename); -} - -void sitecast_handle_request(server_rec *main_server, - char *reqbuf, int reqbuf_len, int igroup, - struct sockaddr_in *client_addr_ptr) -{ - GRSThtcpMessage htcp_mesg; - - if (GRSThtcpMessageParse(&htcp_mesg,reqbuf,reqbuf_len) != GRST_RET_OK) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast responder rejects format of UDP message from %s:%d", - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - return; - } - - if (htcp_mesg.rr != 0) /* ignore HTCP responses: we just do requests */ - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast responder ignores HTCP response from %s:%d", - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - return; - } - - if (htcp_mesg.opcode == GRSThtcpNOPop) - { - sitecast_handle_NOP_request(main_server, &htcp_mesg, - igroup, client_addr_ptr); - return; - } - - if (htcp_mesg.opcode == GRSThtcpTSTop) - { - if (((GRSThtcpCountstrLen(htcp_mesg.method) == 3) && - (strncmp(htcp_mesg.method->text, "GET", 3) == 0)) || - ((GRSThtcpCountstrLen(htcp_mesg.method) == 4) && - (strncmp(htcp_mesg.method->text, "HEAD", 4) == 0))) - { - sitecast_handle_TST_GET(main_server, &htcp_mesg, - igroup, client_addr_ptr); - return; - } - - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast responder rejects method %*s in TST message from %s:%d", - GRSThtcpCountstrLen(htcp_mesg.method), htcp_mesg.method->text, - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - return; - } - - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast does not implement HTCP op-code %d in message from %s:%d", - htcp_mesg.opcode, - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); -} - -void sitecast_responder(server_rec *main_server) -{ -#define GRST_SITECAST_MAXBUF 8192 - char reqbuf[GRST_SITECAST_MAXBUF], *p; - int n, reqbuf_len, i, j, igroup, - quad1, quad2, quad3, quad4, port, retval, client_addr_len; - struct sockaddr_in srv, client_addr; - struct ip_mreq mreq; - fd_set readsckts; - struct hostent *server_hostent; - - strcpy((char *) main_server->process->argv[0], "GridSiteCast UDP responder"); - - /* initialise unicast/replies socket first */ - - bzero(&srv, sizeof(srv)); - srv.sin_family = AF_INET; - srv.sin_port = htons(sitecastgroups[0].port); - - if ((server_hostent = gethostbyname(main_server->server_hostname)) == NULL) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast UDP Responder fails to look up servername %s", - main_server->server_hostname); - return; - } - - srv.sin_addr.s_addr = (u_int32_t) (server_hostent->h_addr_list[0][0]); - - if (((sitecastgroups[0].socket - = socket(AF_INET, SOCK_DGRAM, 0)) < 0) || - (bind(sitecastgroups[0].socket, - (struct sockaddr *) &srv, sizeof(srv)) < 0)) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "mod_gridsite: sitecast responder fails on unicast bind (%s)", - strerror(errno)); - return; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast UDP unicast/replies on %d.%d.%d.%d:%d", - server_hostent->h_addr_list[0][0], - server_hostent->h_addr_list[0][1], - server_hostent->h_addr_list[0][2], - server_hostent->h_addr_list[0][3], - sitecastgroups[0].port); - - /* initialise multicast listener sockets next */ - - for (i=1; (i <= GRST_SITECAST_GROUPS) && - (sitecastgroups[i].port != 0); ++i) - { - bzero(&srv, sizeof(srv)); - srv.sin_family = AF_INET; - srv.sin_port = htons(sitecastgroups[i].port); - srv.sin_addr.s_addr = htonl(sitecastgroups[i].quad1*0x1000000 - + sitecastgroups[i].quad2*0x10000 - + sitecastgroups[i].quad3*0x100 - + sitecastgroups[i].quad4); - - if (((sitecastgroups[i].socket - = socket(AF_INET, SOCK_DGRAM, 0)) < 0) || - (bind(sitecastgroups[i].socket, - (struct sockaddr *) &srv, sizeof(srv)) < 0)) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast UDP Responder fails on multicast bind (%s)", - strerror(errno)); - return; - } - - bzero(&mreq, sizeof(mreq)); - mreq.imr_multiaddr.s_addr = srv.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - - if (setsockopt(sitecastgroups[i].socket, IPPROTO_IP, - IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, - "SiteCast UDP Responder fails on setting multicast (%s)", - strerror(errno)); - return; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast UDP Responder listening on %d.%d.%d.%d:%d", - sitecastgroups[i].quad1, sitecastgroups[i].quad2, - sitecastgroups[i].quad3, sitecastgroups[i].quad4, - sitecastgroups[i].port); - } - - for (i=0; (i < GRST_SITECAST_ALIASES) && - (sitecastaliases[i].sitecast_url != NULL) ; ++i) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast alias for %s (%s,%d) to %s (%s)", - sitecastaliases[i].sitecast_url, - sitecastaliases[i].scheme, - sitecastaliases[i].port, - sitecastaliases[i].local_path, - sitecastaliases[i].local_hostname); - } - - while (1) /* **** main listening loop **** */ - { - /* set up bitmasks for select */ - - FD_ZERO(&readsckts); - - n = 0; - for (i=0; (i <= GRST_SITECAST_GROUPS) && - (sitecastgroups[i].port != 0); ++i) /* reset bitmask */ - { - FD_SET(sitecastgroups[i].socket, &readsckts); - if (sitecastgroups[i].socket > n) n = sitecastgroups[i].socket; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast UDP Responder waiting for requests"); - - if ((retval = select(n + 1, &readsckts, NULL, NULL, NULL)) < 1) - continue; /* < 1 on timeout or error */ - - for (igroup=0; (igroup <= GRST_SITECAST_GROUPS) && - (sitecastgroups[igroup].port != 0); ++igroup) - { - if (FD_ISSET(sitecastgroups[igroup].socket, &readsckts)) - { - client_addr_len = sizeof(client_addr); - - if ((reqbuf_len = recvfrom(sitecastgroups[igroup].socket, - reqbuf, GRST_SITECAST_MAXBUF, 0, - (struct sockaddr *) &client_addr, &client_addr_len)) >= 0) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast receives UDP message from %s:%d " - "to %d.%d.%d.%d:%d", - inet_ntoa(client_addr.sin_addr), - ntohs(client_addr.sin_port), - sitecastgroups[igroup].quad1, - sitecastgroups[igroup].quad2, - sitecastgroups[igroup].quad3, - sitecastgroups[igroup].quad4, - sitecastgroups[igroup].port); - - sitecast_handle_request(main_server, reqbuf, - reqbuf_len, igroup, - &client_addr); - } - } - } - - } /* **** end of main listening loop **** */ -} - -static int mod_gridsite_server_post_config(apr_pool_t *pPool, - apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *main_server) -{ - SSL_CTX *ctx; - SSLSrvConfigRec *sc; - server_rec *this_server; - apr_proc_t *procnew = NULL; - apr_status_t status; - char *path; - const char *userdata_key = "sitecast_init"; - - apr_pool_userdata_get((void **) &procnew, userdata_key, - main_server->process->pool); - - /* we only fork responder if one not already forked and we have at - least one GridSiteCastAlias defined. This means it is possible - to run a responder with no groups - listening on unicast only! */ - - if ((procnew == NULL) && - (sitecastaliases[0].sitecast_url != NULL)) - { - /* UDP multicast responder required but not yet started */ - - procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew)); - apr_pool_userdata_set((const void *) procnew, userdata_key, - apr_pool_cleanup_null, main_server->process->pool); - - status = apr_proc_fork(procnew, pPool); - - if (status < 0) - { - ap_log_error(APLOG_MARK, APLOG_CRIT, status, main_server, - "mod_gridsite: Failed to spawn SiteCast responder process"); - return HTTP_INTERNAL_SERVER_ERROR; - } - else if (status == APR_INCHILD) - { - ap_log_error(APLOG_MARK, APLOG_NOTICE, status, main_server, - "mod_gridsite: Spawning SiteCast responder process"); - sitecast_responder(main_server); - exit(-1); - } - - apr_pool_note_subprocess(main_server->process->pool, - procnew, APR_KILL_AFTER_TIMEOUT); - } - - /* continue with normal HTTP/HTTPS servers */ - - ap_add_version_component(pPool, - apr_psprintf(pPool, "mod_gridsite/%s", VERSION)); - - for (this_server = main_server; - this_server != NULL; - this_server = this_server->next) - { - /* we do some GridSite OpenSSL magic for HTTPS servers */ - - sc = ap_get_module_config(this_server->module_config, &ssl_module); - - if ((sc != NULL) && - (sc->enabled) && - (sc->server != NULL) && - (sc->server->ssl_ctx != NULL)) - { - ctx = sc->server->ssl_ctx; - - /* in 0.9.7 we could set the issuer-checking callback directly */ -// ctx->cert_store->check_issued = GRST_X509_check_issued_wrapper; - - /* but in case 0.9.6 we do it indirectly with another wrapper */ - SSL_CTX_set_cert_verify_callback(ctx, - GRST_verify_cert_wrapper, - (void *) NULL); - - /* whatever version, we can set the SSLVerify wrapper properly */ - SSL_CTX_set_verify(ctx, ctx->verify_mode, - GRST_callback_SSLVerify_wrapper); - - if (main_server->loglevel >= APLOG_DEBUG) - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "Set mod_ssl verify callbacks to GridSite wrappers"); - } - } - - /* create sessions directory if necessary */ - - path = ap_server_root_relative(pPool, sessionsdir); - apr_dir_make_recursive(path, APR_UREAD | APR_UWRITE | APR_UEXECUTE, pPool); - chown(path, unixd_config.user_id, unixd_config.group_id); - - return OK; -} - -static void mod_gridsite_child_init(apr_pool_t *pPool, server_rec *pServer) -{ - apr_time_t cutoff_time; - apr_dir_t *dir; - char *filename; - apr_finfo_t finfo; - SSLSrvConfigRec *sc = ap_get_module_config(pServer->module_config, - &ssl_module); - GRSTgaclInit(); - - /* expire old ssl creds files */ - - if (sc != NULL) - { - cutoff_time = apr_time_now() - - apr_time_from_sec(sc->session_cache_timeout); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServer, - "Cutoff time for ssl creds cache: %ld", - (long) apr_time_sec(cutoff_time)); - - if (apr_dir_open(&dir, - ap_server_root_relative(pPool, sessionsdir), pPool) == APR_SUCCESS) - { - while (apr_dir_read(&finfo, - APR_FINFO_CTIME | APR_FINFO_NAME, dir) == APR_SUCCESS) - { - if ((finfo.ctime < cutoff_time) && - (strncmp(finfo.name, "sslcreds-", 9) == 0)) - { - filename = apr_pstrcat(pPool, - ap_server_root_relative(pPool, sessionsdir), - "/", finfo.name, NULL); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServer, - "Remove %s from ssl creds cache", filename); - - apr_file_remove(filename, pPool); - } - } - - apr_dir_close(dir); - } - } -} - -static int mod_gridsite_handler(request_rec *r) -{ - mod_gridsite_dir_cfg *conf; - - conf = (mod_gridsite_dir_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - if ((conf->dnlistsuri != NULL) && - (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0)) - { - if (strcmp(r->uri, conf->dnlistsuri) == 0) - return mod_gridsite_dnlistsuri_dir_handler(r, conf); - - return mod_gridsite_dnlistsuri_handler(r, conf); - } - - if (strcmp(r->handler, DIR_MAGIC_TYPE) == 0) - return mod_gridsite_dir_handler(r, conf); - - return mod_gridsite_nondir_handler(r, conf); -} - -static ap_unix_identity_t *mod_gridsite_get_suexec_id_doer(const request_rec *r) -{ - mod_gridsite_dir_cfg *conf; - - conf = (mod_gridsite_dir_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - if ((conf->execugid.uid != UNSET) && - (conf->execmethod != NULL)) - { - - /* also push GRST_EXEC_DIRECTORY into request environment here too */ - - return &(conf->execugid); - } - - return NULL; -} - -static void register_hooks(apr_pool_t *p) -{ - /* config and handler stuff */ - - ap_hook_post_config(mod_gridsite_server_post_config, NULL, NULL, - APR_HOOK_LAST); - ap_hook_child_init(mod_gridsite_child_init, NULL, NULL, APR_HOOK_MIDDLE); - - ap_hook_check_user_id(mod_gridsite_check_user_id, NULL, NULL, - APR_HOOK_REALLY_FIRST); - - ap_hook_fixups(mod_gridsite_first_fixups,NULL,NULL,APR_HOOK_FIRST); - - ap_hook_fixups(mod_gridsite_perm_handler,NULL,NULL,APR_HOOK_REALLY_LAST); - - ap_hook_handler(mod_gridsite_handler, NULL, NULL, APR_HOOK_FIRST); - - ap_hook_get_suexec_identity(mod_gridsite_get_suexec_id_doer, - NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA gridsite_module = -{ - STANDARD20_MODULE_STUFF, - create_gridsite_dir_config, /* dir config creater */ - merge_gridsite_dir_config, /* dir merger */ - create_gridsite_srv_config, /* create server config */ - NULL, /* merge server config */ - mod_gridsite_cmds, /* command apr_table_t */ - register_hooks /* register hooks */ -}; diff --git a/org.gridsite.core/src/mod_ssl-private.h b/org.gridsite.core/src/mod_ssl-private.h deleted file mode 100644 index 7b0b784..0000000 --- a/org.gridsite.core/src/mod_ssl-private.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2003-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - - Portions of this code are derived from Apache mod_ssl, and are covered - by the Apache Software License: - - * Copyright 2001-2004 The Apache Software Foundation - * - * 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. - */ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - - -/* - * After 2.0.49, Apache mod_ssl has most of the mod_ssl structures defined - * in ssl_private.h, which is not installed along with httpd-devel (eg in - * the FC2 RPM.) This include file provides SIMPLIFIED structures for use - * by mod_gridsite: for example, pointers to unused structures are replaced - * by void * and some of the structures are truncated when only the early - * members are used. - * - * CLEARLY, THIS WILL BREAK IF THERE ARE MAJOR CHANGES TO ssl_private.h!!! - */ - -#include - -typedef enum { - SSL_SHUTDOWN_TYPE_UNSET, - SSL_SHUTDOWN_TYPE_STANDARD, - SSL_SHUTDOWN_TYPE_UNCLEAN, - SSL_SHUTDOWN_TYPE_ACCURATE -} ssl_shutdown_type_e; - -typedef struct { - SSL *ssl; - const char *client_dn; - X509 *client_cert; - ssl_shutdown_type_e shutdown_type; - const char *verify_info; - const char *verify_error; - int verify_depth; - int is_proxy; - int disabled; - int non_ssl_request; -} SSLConnRec; - -typedef struct { - void *sc; /* pointer back to server config */ - SSL_CTX *ssl_ctx; -} modssl_ctx_t; - -typedef struct { - void *mc; - unsigned int enabled; - unsigned int proxy_enabled; - const char *vhost_id; - int vhost_id_len; - int session_cache_timeout; - modssl_ctx_t *server; - modssl_ctx_t *proxy; -} SSLSrvConfigRec; - -extern module AP_MODULE_DECLARE_DATA ssl_module; diff --git a/org.gridsite.core/src/roffit b/org.gridsite.core/src/roffit deleted file mode 100755 index d1c7263..0000000 --- a/org.gridsite.core/src/roffit +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/env perl -# -# roffit: convert man page source files to HTML -# -# Read an nroff file. Output a HTML file. -# -# This is a very simple script, but I use it on very simple man pages and I've -# found no other script that makes beautiful web pages. -# -my $version = "0.3"; # (14 November 2003) -# Author: Daniel Stenberg -# Please email me improvements. -# -# You're free to do whatever you want with this script. -# -# Changes: -# -# 0.3 - Daniel Fandrich brought: -# o deal with .lp lines -# o .TH needs no section portion anymore -# o added generator meta tag in the header -# -# 0.2 - fixed the name for the SH section -# - added links from all words within \fIthis\fP or \fBthis\fP -# that has the same text as a .SH or .IP. -# - -use strict; -#use warnings; - -my $InFH = \*STDIN; -my $OutFH = \*STDOUT; -my $debugFH = \*STDERR; - -my %manpage; -my @out; - -my $indentlevel=0; # logical levels, not columns -my @p; -my $within_tp; -my $standalone=1; # by default we make stand-alone HTML pages -my $pre; -my %anchor; # hash with all anchors - -while($ARGV[0]) { - if($ARGV[0] eq "--bare") { - # don't include headers and stuff - $standalone=0; - shift @ARGV; - } - else { - printf $debugFH "unknown option: %s\n", $ARGV[0] if($ARGV[0] ne "-h"); - print $debugFH "Usage: roffit [options] < infile > outfile\n", - "Options:\n", - " --bare Do not put in HTML, HEAD, BODY tags\n"; - exit; - } -} - -sub showp { - my @p = @_; - push @out, "\n

", @p; -} - -sub defaultcss { - print $OutFH < -P.level0 { - padding-left: 2em; -} - -P.level1 { - padding-left: 4em; -} - -P.level2 { - padding-left: 6em; -} - -span.emphasis { - font-style: italic; -} - -span.bold { - font-weight: bold; -} - -span.manpage { - font-weight: bold; -} - -h2.nroffsh { - background-color: #e0e0e0; -} - -span.nroffip { - font-weight: bold; - font-size: 120%; - font-family: monospace; -} - -p.roffit { - text-align: center; - font-size: 80%; -} - -ENDOFCSS - ; -} - -sub text2name { - my ($text) = @_; - $text =~ s/^ *([^ ]*).*/$1/g; - $text =~ s/[^a-zA-Z0-9-]//g; - return $text; -} - -# scan through the file and check for sections we should convert -# to proper links -sub linkfile { - my @new; - for(@out) { - my $line=$_; - my $l; - while($line =~ s/([^<]*)<\/span>/[]/) { - my ($style, $name)=($1, $2); - - $l = text2name($name); - - #printf $debugFH "$style - $name - %s - %d\n", - #$l, $anchor{$l}; - - my $link; - if($anchor{$l}) { - $link="$name"; - } - else { - $link="$name"; - } - $line =~ s/\[\]/$link/; - } - push @new, $line; - } - return @new; -} - -sub parsefile { - - while(<$InFH>) { - my $in = $_; - my $out; - # print $debugFH "DEBUG IN: $_"; - - $in =~ s/[\r\n]//g if(!$pre); # tear off newlines - - if($in =~ /^\.([^ \n]*)(.*)/) { - # this is a line starting with a dot, that means it is special - my ($keyword, $rest) = ($1, $2); - $out = ""; - - # cut off initial spaces - $rest =~ s/^ +//g; - - if($keyword eq "\\\"") { - # this is a comment, skip this line - } - elsif($keyword =~ /^TH$/i) { - # man page header: - # curl 1 "22 Oct 2003" "Curl 7.10.8" "Curl Manual" - # NAME SECTION DATE VERSION MANUAL - if($rest =~ /([^ ]*) (\d+) \"([^\"]*)\" \"([^\"]*)\"(\"([^\"]*)\")?/) { - # strict matching only so far - $manpage{'name'} = $1; - $manpage{'section'} = $2; - $manpage{'date'} = $3; - $manpage{'version'} = $4; - $manpage{'manual'} = $6; - } - } - elsif($keyword =~ /^SH$/i) { - # Section Header - showp(@p); - @p=""; - if($pre) { - push @out, "\n"; - $pre = 0; - } - - my $name = text2name($rest); - $anchor{$name}=1; - - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - $out = "

$rest

"; - $indentlevel=0; - $within_tp=0; - } - elsif(($keyword =~ /^B$/i) || ($keyword =~ /^BI$/i)) { - # Make B and BI the same for simplicity - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - push @p, "$rest "; - } - elsif($keyword =~ /^I$/i) { - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - push @p, "$rest "; - } - elsif($keyword =~ /^RS$/i) { - # the start of another indent-level. for inlined tables - # within an "IP" - showp(@p); - @p=""; - $indentlevel++; - } - elsif($keyword =~ /^RE$/i) { - # end of the RS section - showp(@p); - @p=""; - $indentlevel--; - } - elsif($keyword =~ /^NF$/i) { - # We let nf start a
 section
-                showp(@p);
-                @p="";
-                push @out, "
\n";
-                $pre=1
-            }
-            elsif($keyword =~ /^TP$/i) {
-                # Used within an "RS" section to make a new line. The first
-                # TP as a column indicator, but we decide to do that
-                # controlling in the CSS instead.
-                $within_tp=1;
-                showp(@p);
-                @p="";                
-            }
-            elsif($keyword =~ /^IP$/i) {
-                # start of a new paragraph coming up
-                showp(@p);
-                @p="";
-
-                my $name= text2name($rest);
-                $anchor{$name}=1;
-
-                $rest =~ s/\"//g; # cut off quotes
-                $rest =~ s//>/g;
-                
-                $indentlevel-- if ($indentlevel);
-                push @p, "$rest ";
-                # make this a single-line title
-                showp(@p);
-                @p="";
-                $indentlevel++;
-                $within_tp=0;
-            }
-            elsif($keyword =~ /^ad$/i) {
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^sp$/i) {
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^lp$/i) {
-                # marks end of a paragraph
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^pp$/i) {
-                # PP ends a TP section, but some TP sections don't use it
-                $within_tp=0;
-            }
-            elsif($keyword =~ /^so$/i) {
-                # This keyword refers to a different man page, named in the
-                # $rest.
-                # We don't support this
-                push @out, "See the $rest man page.\n";
-            }
-            elsif($keyword =~ /^BR$/i) {
-                # I'm not sure what this does exactly, but this is commonly
-                # used to include pointers to other man pages. Let's assume
-                # it only does that for now.
-                # blabla (3)
-                # or "blabla (3)"
-                # or strcmp "(3), " strcasecmp "(3)"
-                # etc
-                
-                $rest =~ s/\"//g; # cut off quotes
-                my @all = split /,/, $rest;
-                for(@all) {
-                    if(/([^ ]*) *\((\d+)\)/) {
-                        # TODO: this looks like a man page, check if there's a
-                        # HTML file for it and if so make a link to it
-                    }
-
-                    push @p, "$_ ";
-                }
-            }
-            else {
-                showp(@p);
-                print $debugFH "ALERT: unknown keyword \"$keyword\"\n";
-            }
-        }
-        else {
-            # text line, decode \-stuff
-            my $txt = $in;
-
-            $txt =~ s//>/g;
-            $txt =~ s/\\&//g; # cut off \&
-            $txt =~ s/\\fI//g;
-            $txt =~ s/\\fB//g;
-            $txt =~ s/\\fP/<\/span>/g;
-            $txt =~ s/\\//g;
-
-            if($txt =~ /^[ \t\r\n]*$/) {
-                # no contents, marks end of a paragraph
-                showp(@p);
-                @p="";
-            }
-            else {
-                $txt =~ s/^ /\ \;/g;
-                push @p, "$txt ";
-            }
-            $out ="";
-        }
-
-        if($out) {
-            push @out, $out;
-   #         print $debugFH "DEBUG OUT: $out\n";
-        }
-        else {
-   #         print $debugFH "DEBUG OUT: [withheld]\n";
-        }
-    }
-    showp(@p);
-}
-
-parsefile();
-
-my @conv = linkfile();
-
-my $title=sprintf("%s man page",
-                  $manpage{'name'}?$manpage{'name'}:"secret");
-
-if($standalone) {
-    print $OutFH <
-$title
-
-MOO
-    ;
-    defaultcss();
-    print "\n";
-}
-
-print $OutFH @conv;
-print $OutFH <
- This HTML page was made with roffit.
-ROFFIT
-    ;
-
-if($standalone) {
-    print "\n";
-}
diff --git a/org.gridsite.core/src/showx509exts.c b/org.gridsite.core/src/showx509exts.c
deleted file mode 100644
index 86f0290..0000000
--- a/org.gridsite.core/src/showx509exts.c
+++ /dev/null
@@ -1,133 +0,0 @@
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "gridsite.h"
-
-#define MAXTAG 500
-                                 
-main()
-{
-   X509   *cert, *tmpcert;
-   STACK_OF(X509) *certstack = sk_X509_new_null();
-   FILE   *fp;
-   struct vomsdata *vd;
-   int    i, j, vomserror, i1, i2, j1, j2, lastobject;
-   X509_EXTENSION *ex;
-   ASN1_OBJECT *asnobject;
-   char s[80], *t;
-   ASN1_OCTET_STRING *asndata;
-   BIO *out;
-   unsigned char *p, *op, *tot, *p1, *p2, *q, *oq;
-   long len1, length1, len2, length2;
-   int tag,xclass,ret=0;
-   struct GRSTasn1TagList taglist[MAXTAG+1];
-   int lasttag=-1, itag;
-   
- 
-   OpenSSL_add_all_algorithms();
-   ERR_load_crypto_strings();
-//   seed_prng();
-   
-//   fp = fopen("proxy-with-voms", "r");
-   fp = fopen("/tmp/x509up_u300", "r");
-   
-   cert = PEM_read_X509(fp, NULL, NULL, NULL);
-      
-   fclose(fp);
-
-   out=BIO_new(BIO_s_file());                                                                                        
-   BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
-        
-   for (i = 0; i < X509_get_ext_count(cert); ++i)
-      {
-        lasttag=-1;
-      
-        ex = X509_get_ext(cert, i);
-
-        OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1);        
-        printf("%d OID=%s\n", i, s);
-        
-        asnobject = X509_EXTENSION_get_object(ex);
-        asndata = X509_EXTENSION_get_data(ex);
-
-        p1 = ASN1_STRING_data(asndata);
-        p = p1;
-        length1 = ASN1_STRING_length(asndata);
-              
-        GRSTasn1ParseDump(out, p1, length1, taglist, MAXTAG, &lasttag);
-
-{
-        int n, tag, xclass;
-        unsigned char *q, buf[100];
-        const unsigned char *dn, hash[EVP_MAX_MD_SIZE];
-        ASN1_OBJECT *obj = NULL;
-        const EVP_MD *m;
-        EVP_MD_CTX ctx;
-        char creds[501][101];
-        int lastcred = -1;
-   
-        itag = GRSTasn1SearchTaglist(taglist, lasttag, 
-               "-1-1-1-1-2-1-1-1-1-1-1-1");
-               
-        X509_NAME *xname;
-        
-        q = &p[taglist[itag].start];
-        
-        d2i_ASN1_OBJECT(&obj, &q, taglist[itag].length + 
-                                  taglist[itag].headerlength);
-
-        n  = OBJ_obj2nid(obj);
-        dn = OBJ_nid2sn(n);
-                         
-//        dn = X509_NAME_oneline(xname,NULL,0);
-        
-        printf("n=%d dn=%s obj2txt=%s\n", n, dn, OBJ_obj2txt(NULL,0,obj,1));
-
-        GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-2-1-1-1-1-%d-1-%d", 
-                            p1, taglist, lasttag);
-        printf("%s\n", buf);
-        GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-3-1-1-1-%d-1-%d", 
-                            p1, taglist, lasttag);
-        printf("%s\n", buf);
-
-        lastcred = -1;        
-        ret = GRSTx509ParseVomsExt(&lastcred, 500, 100, creds, 0, 2000040861,
-                             ex, 
-                  "/C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab",
-                  "/etc/grid-security/vomsdir");
-                  
-                  
-        printf("GRSTx509ParseVomsExt() returns %d, %d\n", ret, lastcred);
-                  
-        for (j=0; j <= lastcred;  ++j)
-         printf("cred=%d %s\n", j, creds[j]);
-        
-/*        
-        m = EVP_md5();
-        EVP_DigestInit(&ctx, m); 
-        EVP_DigestUpdate(&ctx, delegation_id, strlen(delegation_id));
-        EVP_DigestFinal(&ctx, hash, &delegation_id_len);
- */      
-}              
-
-/*       
-        itag = GRSTasn1SearchTaglist(taglist, &lasttag,
-                                     "1-1-1-1-1-7-1-2-1-2-1");
-                                    
-        printf("tag=%d %s %d %.*s\n",
-               itag, taglist[itag].treecoords, taglist[itag].tag,
-               taglist[itag].length, 
-               &p[taglist[itag].start+taglist[itag].headerlength]);
-*/
-      }
-}
diff --git a/org.gridsite.core/src/slashgrid.c b/org.gridsite.core/src/slashgrid.c
deleted file mode 100644
index 8ae240c..0000000
--- a/org.gridsite.core/src/slashgrid.c
+++ /dev/null
@@ -1,2492 +0,0 @@
-/*
-   Copyright (c) 2003-6, Andrew McNab,
-   University of Manchester. All rights reserved.
-
-   Redistribution and use in source and binary forms, with or
-   without modification, are permitted provided that the following
-   conditions are met:
-
-     o Redistributions of source code must retain the above
-       copyright notice, this list of conditions and the following
-       disclaimer. 
-     o Redistributions in binary form must reproduce the above
-       copyright notice, this list of conditions and the following
-       disclaimer in the documentation and/or other materials
-       provided with the distribution. 
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-   POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*------------------------------------------------------------------*
- * This program is part of GridSite: http://www.gridsite.org/       *
- *------------------------------------------------------------------*/
-
-#define _GNU_SOURCE
-#define _XOPEN_SOURCE
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include               
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-#include "gridsite.h"
-
-#define GRST_SLASH_PIDFILE "/var/run/slashgrid.pid"
-
-#define GRST_SLASH_HEADERS "/var/spool/slashgrid/headers"
-#define GRST_SLASH_BLOCKS  "/var/spool/slashgrid/blocks"
-#define GRST_SLASH_TMP     "/var/spool/slashgrid/tmp"
-#define GRST_SLASH_DIRFILE "::DIR::"
-
-#define GRST_SLASH_HEAD   0
-#define GRST_SLASH_GET    1
-#define GRST_SLASH_PUT    2
-#define GRST_SLASH_DELETE 3
-#define GRST_SLASH_MOVE   4
-#define GRST_SLASH_TRUNC  5
-
-#define GRST_SLASH_HEADERS_EXPIRE	60
-#define GRST_SLASH_BLOCK_SIZE		4096
-#define GRST_SLASH_MAX_HANDLES		16
-
-#define GRST_SLASH_MAX_LOCATION		1024
-
-/* maximum number of SiteCast groups */
-#define GRST_SLASH_MAX_GROUPS		10
-
-#define GRST_SLASH_HTCP_PORT		777
-
-#ifndef CURLOPT_WRITEDATA
-#define CURLOPT_WRITEDATA CURLOPT_FILE
-#endif
- 
-#ifndef CURLOPT_READDATA
-#define CURLOPT_READDATA CURLOPT_INFILE
-#endif
-
-#ifndef CURLE_HTTP_RETURNED_ERROR
-#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND
-#endif
-
-struct grst_body_text { char   *text;
-                        size_t  used;
-                        size_t  allocated; } ;
-
-struct grst_read_data { const char  *buf;
-                        off_t sent; 
-                        off_t maxsent; };
-
-struct grst_dir_list { char   *filename;
-                       off_t   length;
-                       int     length_set;
-                       time_t  modified;
-                       int     modified_set; } ;
-
-struct grst_request { int     retcode;                         
-                      char    location[GRST_SLASH_MAX_LOCATION+1];
-                      size_t  length;
-                      int     length_set;
-                      time_t  modified;                           
-                      int     modified_set; 
-                      void   *readfunction;
-                      void   *readdata;
-                      void   *writefunction;
-                      void   *writedata;
-                      size_t  infilesize;
-                      char   *errorbuffer;
-                      char   *url;
-                      int     method;
-                      char   *destination;
-                      off_t   start;
-                      off_t   finish; } ;
-
-struct grst_handle { pthread_mutex_t	mutex;
-                     CURL		*curl_handle;
-                     uid_t		uid;
-                     char		*proxyfile;
-                     time_t		last_used;
-                   }  handles[GRST_SLASH_MAX_HANDLES];
- 
-int debugmode         = 0;
-int number_of_tries   = 1, sitecast_domain_len = 0;
-char *sitecast_domain = NULL, *sitecast_groups = NULL, *local_root = NULL,
-     *gridmapdir = NULL;
-uid_t local_uid = 0;
-gid_t local_gid = 0;
-
-size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p)
-/* Find the values of the return code, Content-Length, Last-Modified
-   and Location headers */
-{
-  float f;
-  char  *s, *q;
-  size_t realsize;
-  struct tm modified_tm;
-  struct grst_request *request_data = (struct grst_request *) p;
-
-  realsize = size * nmemb;
-  s = malloc(realsize + 1);
-  memcpy(s, ptr, realsize);
-  s[realsize] = '\0';
-
-  if      (sscanf(s, "Content-Length: %d", &(request_data->length)) == 1) 
-            request_data->length_set = 1;
-  else if (sscanf(s, "HTTP/%f %d ", &f, &(request_data->retcode)) == 2) ;
-  else if (strncmp(s, "Location: ", 10) == 0) 
-      {
-        strncpy(request_data->location, &s[10], GRST_SLASH_MAX_LOCATION);
-        /* the location string is 1 byte longer and zeroed before use */
-        
-        for (q=request_data->location; *q != '\0'; ++q)
-         if ((*q == '\r') || (*q == '\n')) *q = '\0';
-      }
-  else if (strncmp(s, "Last-Modified: ", 15) == 0)
-      {
-        /* follow RFC 2616: first try RFC 822 (kosher), then RFC 850 and 
-           asctime() formats too. Must be GMT whatever the format. */
-
-        if (strptime(&s[15], "%a, %d %b %Y %T GMT", &modified_tm) != NULL)
-          {
-            request_data->modified = mktime(&modified_tm);
-            request_data->modified_set = 1;
-          }
-        else if (strptime(&s[15], "%a, %d-%b-%y %T GMT", &modified_tm) != NULL)
-          {
-            request_data->modified = mktime(&modified_tm);
-            request_data->modified_set = 1;
-          }
-        else if (strptime(&s[15], "%a %b %d %T %Y", &modified_tm) != NULL)
-          {
-            request_data->modified = mktime(&modified_tm);
-            request_data->modified_set = 1;
-          }
-      }
-    
-  free(s);
-  return realsize;
-}
-
-int debug_callback(CURL *handle, curl_infotype infotype, 
-                   char *rawmesg, size_t size, void *i)
-{
-  int   n;
-  char *mesg;
-
-  if ((infotype == CURLINFO_DATA_IN) ||
-      (infotype == CURLINFO_DATA_OUT)) return 0;
-
-  mesg = malloc(size + 1);
-  
-  for (n=0; n < size; ++n)
-     {
-       if ((rawmesg[n] == '\r') && (n >= size - 2)) mesg[n] = '\0';
-       else if (((rawmesg[n] == '\r') || (rawmesg[n] == '\n')) && 
-                (infotype == CURLINFO_HEADER_IN)) mesg[n] = '<';
-       else if (((rawmesg[n] == '\r') || (rawmesg[n] == '\n')) && 
-                (infotype == CURLINFO_HEADER_OUT)) mesg[n] = '>';
-       else if ((rawmesg[n] < ' ') || (rawmesg[n] >= 127)) mesg[n] = '.';
-       else mesg[n] = rawmesg[n];
-     }
-     
-  mesg[n] = '\0';
-
-  syslog(LOG_DEBUG, "%d %s%s%s%s", 
-                    *((int *) i), 
-                    (infotype == CURLINFO_HEADER_IN ) ? "<<" : "",
-                    (infotype == CURLINFO_HEADER_OUT) ? ">>" : "",
-                    (infotype == CURLINFO_TEXT      ) ? "**" : "",
-                    mesg);
-
-  free(mesg);  
-  return 0;
-}                  
-
-
-int translate_sitecast_url(char **sitecast_url, char *raw_url)
-{
-  int request_length, response_length, i, ret, s, igroup;
-  struct sockaddr_in srv, from;
-  socklen_t fromlen;
-#define MAXBUF 8192  
-  char *request, response[MAXBUF], *p;
-  GRSThtcpMessage msg;
-  struct timeval start_timeval, wait_timeval;
-  struct grst_sitecast_group 
-   { unsigned char quad1; unsigned char quad2;
-     unsigned char quad3; unsigned char quad4;
-     int port; int timewait; int ttl; } groups[GRST_SLASH_MAX_GROUPS];
-  fd_set readsckts;
-
-  p = sitecast_groups;
-  igroup = -1;
-
-  for (igroup=-1; igroup+1 < GRST_SLASH_MAX_GROUPS;)
-     {  
-       /* defaults for when sscanf fails to find all parameters */
-
-       groups[igroup+1].port     = GRST_SLASH_HTCP_PORT;
-       groups[igroup+1].timewait = 1;
-       groups[igroup+1].ttl      = 1;
-       
-       ret = sscanf(p, "%d.%d.%d.%d:%d:%d:%d", 
-                 &(groups[igroup+1].quad1),
-                 &(groups[igroup+1].quad2),    
-                 &(groups[igroup+1].quad3),
-                 &(groups[igroup+1].quad4),    
-                 &(groups[igroup+1].port),
-                 &(groups[igroup+1].ttl),
-                 &(groups[igroup+1].timewait));
-
-       if (ret == 0) break; /* end of list ? */
-         
-       if (ret < 5)
-         {
-           syslog(LOG_WARNING,
-                  "Failed parsing multicast group parameter %s\n", p);
-           return GRST_RET_FAILED;
-         }
-         
-       ++igroup;  
-       
-       if ((p = index(p, ',')) == NULL) break;       
-       ++p;
-     }
-
-  if (igroup == -1)
-    {
-      syslog(LOG_WARNING, "Failed parsing multicast group parameter %s\n", p);
-      return GRST_RET_FAILED;
-    }
-
-  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
-    {
-      syslog(LOG_WARNING, "Failed to open SiteCast UDP socket\n");
-      return GRST_RET_FAILED;
-    }
-
-  /* loop through multicast groups since we need to take each 
-     ones timewait into account */
-
-  gettimeofday(&start_timeval, NULL);
-
-  for (i=0; i <= igroup; ++i)
-     {
-       if (debugmode)
-        syslog(LOG_DEBUG, "Querying multicast group %d.%d.%d.%d:%d:%d:%d\n",
-                groups[i].quad1, groups[i].quad2,
-                groups[i].quad3, groups[i].quad4,
-                groups[i].port, groups[i].ttl,
-                groups[i].timewait);
-        
-       bzero(&srv, sizeof(srv));
-       srv.sin_family = AF_INET;
-       srv.sin_port = htons(groups[i].port);
-       srv.sin_addr.s_addr = htonl(groups[i].quad1*0x1000000
-                                 + groups[i].quad2*0x10000
-                                 + groups[i].quad3*0x100
-                                 + groups[i].quad4);
-
-       /* send off queries, one for each source file */
-
-       GRSThtcpTSTrequestMake(&request, &request_length, 
-                                   (int) (start_timeval.tv_usec),
-                                   "GET", raw_url, "");
-
-       sendto(s, request, request_length, 0, 
-                       (struct sockaddr *) &srv, sizeof(srv));
-
-       free(request);
-          
-       /* reusing wait_timeval is a Linux-specific feature of select() */
-       wait_timeval.tv_usec = 0;
-       wait_timeval.tv_sec  = groups[i].timewait;
-
-       while ((wait_timeval.tv_sec > 0) || (wait_timeval.tv_usec > 0))
-            {
-              FD_ZERO(&readsckts);
-              FD_SET(s, &readsckts);
-  
-              ret = select(s + 1, &readsckts, NULL, NULL, &wait_timeval);
-
-              if (ret > 0)
-                {
-                  response_length = recvfrom(s, response, MAXBUF,
-                                             0, &from, &fromlen);
-  
-                  if ((GRSThtcpMessageParse(&msg, response, response_length) 
-                                                      == GRST_RET_OK) &&
-                      (msg.opcode == GRSThtcpTSTop) && (msg.rr == 1) && 
-                      (msg.trans_id == (int) start_timeval.tv_usec) &&
-                      (msg.resp_hdrs != NULL) &&
-                      (GRSThtcpCountstrLen(msg.resp_hdrs) > 12))
-                    { 
-                      /* found one */ 
-
-                      if (debugmode)
-                        syslog(LOG_DEBUG, "Sitecast %s -> %.*s\n",
-                                raw_url, 
-                                GRSThtcpCountstrLen(msg.resp_hdrs) - 12,
-                                &(msg.resp_hdrs->text[10]));
-                      
-                      asprintf(sitecast_url, "%.*s",
-                          GRSThtcpCountstrLen(msg.resp_hdrs) - 12, 
-                          &(msg.resp_hdrs->text[10]));
-                          
-                      return GRST_RET_OK;
-                    }
-                }
-            }
-     }
-     
-  return GRST_RET_FAILED;
-}
-
-char *check_x509_user_proxy(pid_t pid)
-{
-  int fd;
-  char file[80], *proxyfile = NULL, *pid_environ, *p;
-  struct stat statbuf1, statbuf2;
-  
-  snprintf(file, sizeof(file), "/proc/%d/environ", (int) pid);
-  
-  if ((fd = open(file, O_RDONLY)) == -1) return NULL;
-
-  if (debugmode) syslog(LOG_DEBUG, "Opened for %d environ in %s", (int) pid, file);
-  
-  fstat(fd, &statbuf1);
-  
-  pid_environ = malloc(statbuf1.st_size + 1);
-  
-  read(fd, pid_environ, statbuf1.st_size);
-  
-  close(fd);
-  
-  pid_environ[statbuf1.st_size] = '\0';
-    
-  for (p = pid_environ; p < pid_environ + statbuf1.st_size; p += (strlen(p) + 1))
-     {
-       if (debugmode) syslog(LOG_DEBUG, "Examine %s in environ", p);
-  
-       if (strncmp(p, "X509_USER_PROXY=", 16) == 0)
-         {
-           if ((p[16] != '\0') &&
-               (stat(&p[16], &statbuf2) == 0)) proxyfile = strdup(&p[16]);
-           break;
-         }
-     }
-  
-  free(pid_environ);
-
-  return proxyfile;    
-}
-
-char *mapdir_uid_to_dn(uid_t uid)
-{
-     int            ret;
-     char           *firstlinkpath, *otherlinkpath, *dn, *buf = NULL;
-     struct dirent  *mapdirentry;
-     DIR            *mapdirstream;
-     ino_t          firstinode;
-     long           buflen;
-     struct stat    statbuf;
-     struct passwd  pw, *pwp;
-     
-     if (gridmapdir == NULL) return NULL;
-
-     buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
-     buf = malloc(buflen);
-
-     if ((buflen <= 0) ||
-         (getpwuid_r(uid, &pw, buf, buflen, &pwp) != 0) ||
-         (pw.pw_name == NULL))
-       {
-         if (buf != NULL) free(buf);
-         return NULL;
-       }
-
-     asprintf(&firstlinkpath, "%s/%s", gridmapdir, pw.pw_name);
-     ret = stat(firstlinkpath, &statbuf);
-
-     free(firstlinkpath);
-
-     if ((ret != 0) || (statbuf.st_nlink != 2))
-       {
-         free(buf);
-         return NULL;
-       }
-
-     firstinode = statbuf.st_ino; /* save for comparisons */
-
-     mapdirstream = opendir(gridmapdir);
-
-     if (mapdirstream != NULL)
-       {
-         while ((mapdirentry = readdir(mapdirstream)) != NULL)
-              {
-                 if (strcmp(mapdirentry->d_name, pw.pw_name) == 0) continue;
-
-                 if (mapdirentry->d_ino == firstinode)
-                   {
-                      asprintf(&otherlinkpath, "%s/%s", gridmapdir,
-                                            mapdirentry->d_name);
-
-                      utime(otherlinkpath, (struct utimbuf *) NULL);
-                      free(otherlinkpath);
-                      
-                      dn = GRSThttpUrlDecode(mapdirentry->d_name);
-            
-                      if (debugmode) syslog(LOG_DEBUG, "mapdir_uid_to_dn "
-                                  "maps %s(%d) to %s", pw.pw_name, uid, dn);
-
-                      closedir(mapdirstream);
-                      free(buf);
-                      return dn;
-                   }
-              }
-
-         closedir(mapdirstream);
-       }
-
-     free(buf);
-     return NULL;
-}
-
-
-int perform_request(struct grst_request *request_data,
-                    struct fuse_context *fuse_ctx)
-{
-  int                ret, i, j, itry, ishttps = 0;
-  char              *proxyfile = NULL, *range_header = NULL, *url;
-  struct stat        statbuf;
-  struct curl_slist *headers_list = NULL;
-
-  if (strncmp(request_data->url, "https://", 8) == 0) /* HTTPS options */
-    {
-// check for X509_USER_PROXY in that PID's environ too
-      ishttps = 1;
-
-      if ((proxyfile = check_x509_user_proxy(fuse_ctx->pid)) == NULL)
-        {
-          asprintf(&proxyfile, "/tmp/x509up_u%d", fuse_ctx->uid);
-          /* if proxyfile is used, it will be referenced by handles[].proxyfile
-             and freed when this handle is eventually freed */
-
-          if ((stat(proxyfile, &statbuf) != 0) ||
-              (statbuf.st_uid != fuse_ctx->uid))
-            {
-              free(proxyfile);
-              proxyfile = NULL;
-            }
-        }
-    }
-
-  if (debugmode && (proxyfile != NULL))
-       syslog(LOG_DEBUG, "Using proxy file %s", proxyfile);
-
-  /* try to find an existing handle for this uid/proxyfile */
-
-  for (i=0; i < GRST_SLASH_MAX_HANDLES; ++i)
-     {
-       if ((handles[i].curl_handle != NULL)  &&
-           (handles[i].uid == fuse_ctx->uid) &&
-           (((handles[i].proxyfile == NULL) && (proxyfile == NULL)) ||
-            ((handles[i].proxyfile != NULL) && (proxyfile != NULL) &&
-             (strcmp(handles[i].proxyfile, proxyfile) == 0))))
-         {
-           break;
-         }
-     }
-     
-  if (i >= GRST_SLASH_MAX_HANDLES) /* no existing match found */
-    {
-      i=0;
-    
-      for (j=0; j < GRST_SLASH_MAX_HANDLES; ++j)
-         {
-           if (handles[j].curl_handle == NULL) /* unused slot */
-             {
-               i = j;
-               break;
-             }
-             
-           if (handles[j].last_used < handles[i].last_used) i = j;
-         }
-    }
-
-  /* now lock this handle and recheck settings inside the mutex lock */
-
-  pthread_mutex_lock(&(handles[i].mutex)); /* unlock just before return */
-
-  if ((handles[i].curl_handle == NULL)  ||
-      (handles[i].uid != fuse_ctx->uid) ||
-      (((handles[i].proxyfile != NULL) || (proxyfile != NULL)) &&
-       ((handles[i].proxyfile == NULL) || (proxyfile == NULL) ||
-        (strcmp(handles[i].proxyfile, proxyfile) != 0))))
-    {
-      /* we do need to initialise this handle */
-      
-      handles[i].uid = fuse_ctx->uid;
-
-      if (handles[i].curl_handle != NULL)
-                              curl_easy_cleanup(handles[i].curl_handle);
-      handles[i].curl_handle = curl_easy_init();
-      
-      if (handles[i].proxyfile != NULL) free(handles[i].proxyfile);
-      handles[i].proxyfile = proxyfile; /* proxyfile might be NULL itself */
-      
-      if (handles[i].proxyfile != NULL)
-        {
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLCERTTYPE, "PEM");
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLCERT,
-                                                    handles[i].proxyfile);
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLKEYTYPE, "PEM");
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLKEY,  
-                                                    handles[i].proxyfile);
-        }
-      else
-        {
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLKEYTYPE,  "ENG");
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLCERTTYPE, "ENG");
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSLCERT,     NULL);
-        }
-
-      if (debugmode)
-        {
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_VERBOSE, 1);
-          curl_easy_setopt(handles[i].curl_handle, CURLOPT_DEBUGFUNCTION,
-                                                          debug_callback);
-        }
-
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_USERAGENT, 
-                       "SlashGrid http://www.gridsite.org/slashgrid/");
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_FOLLOWLOCATION, 0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HEADERFUNCTION, headers_callback);
-
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CAPATH, 
-                                        "/etc/grid-security/certificates");
-
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYPEER, 2);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
-    }   
-
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata);
-
-  if (request_data->method == GRST_SLASH_GET)
-    {
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, NULL);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 1);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
-    }
-  else if ((request_data->method == GRST_SLASH_PUT) || 
-           (request_data->method == GRST_SLASH_TRUNC))
-    {
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, NULL);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  1);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE,  
-                                            (long) request_data->infilesize);
-    }
-  else if (request_data->method == GRST_SLASH_DELETE)
-    {
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
-    }
-  else if (request_data->method == GRST_SLASH_MOVE)
-    {
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "MOVE");
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
-    }
-  else /* default or GRST_SLASH_HEAD */
-    {
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, NULL);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  1);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
-    }
-
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEHEADER, request_data);
-  
-  if (request_data->errorbuffer != NULL)
-        curl_easy_setopt(handles[i].curl_handle, CURLOPT_ERRORBUFFER,
-                                      request_data->errorbuffer);
-
-  if (debugmode)
-        curl_easy_setopt(handles[i].curl_handle, CURLOPT_DEBUGDATA, &i);
-
-/* Move to higher up
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction);
-  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata);
-*/
-  if ((request_data->start >= 0) && 
-      (request_data->finish >= request_data->start))
-    {
-      if (request_data->method == GRST_SLASH_PUT)
-           asprintf(&range_header, "Content-Range: bytes %ld-%ld/*", 
-               (long) request_data->start, (long) request_data->finish);
-      else if (request_data->method == GRST_SLASH_TRUNC)
-           asprintf(&range_header, "Content-Range: bytes *-*/%ld", 
-               (long) request_data->finish);
-      else asprintf(&range_header, "Range: bytes=%ld-%ld", 
-               (long) request_data->start, (long) request_data->finish);
-
-      headers_list = curl_slist_append(headers_list, range_header);
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPHEADER, headers_list);
-    }
-  else curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPHEADER, NULL);
-
-  /* retry loop */
-
-  for (itry=1; itry <= number_of_tries; ++itry)
-     {
-       request_data->length_set   = 0;
-       request_data->modified_set = 0;
-       request_data->retcode      = 0;
-       request_data->location[0]  = '\0';
-    
-       if ((sitecast_domain != NULL) &&
-           (sitecast_groups != NULL) &&
-
-           ((request_data->method == GRST_SLASH_HEAD) ||
-            (request_data->method == GRST_SLASH_GET)) &&
-
-           ((!ishttps && 
-             (strncmp(&(request_data->url[7]), sitecast_domain, 
-                                   sitecast_domain_len) == 0) &&
-             ((request_data->url[7+sitecast_domain_len] == ':') ||
-              (request_data->url[7+sitecast_domain_len] == '/')) )
-                                                                   ||
-            (ishttps &&
-             (strncmp(&(request_data->url[8]), sitecast_domain, 
-                                    sitecast_domain_len) == 0) &&
-             ((request_data->url[8+sitecast_domain_len] == ':') ||
-              (request_data->url[8+sitecast_domain_len] == '/')) ) ) )
-         {
-           if (debugmode)
-             syslog(LOG_DEBUG, "Apply SiteCast to URL %s", request_data->url);
-
-           if (translate_sitecast_url(&url, request_data->url) ==
-                GRST_RET_OK)
-             {
-               curl_easy_setopt(handles[i].curl_handle,
-                                            CURLOPT_URL, url);
-               ret = curl_easy_perform(handles[i].curl_handle);
-
-               free(url);               
-             }
-           else
-             {
-               ret = 1;
-               request_data->retcode = 404; /* HTTP not found */
-             }
-         }
-       else
-         {
-           curl_easy_setopt(handles[i].curl_handle,
-                                            CURLOPT_URL, request_data->url);
-           ret = curl_easy_perform(handles[i].curl_handle);
-         }
-
-// tests on whether to retry due to server error / timeout go here...
-       break;
-     }
-
-  if (headers_list != NULL) curl_slist_free_all(headers_list);
-  if (range_header != NULL) free(range_header);
-
-  pthread_mutex_unlock(&(handles[i].mutex));
-  
-  return ret;
-}
-
-size_t rawbody_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
-  if ( ((struct grst_body_text *) data)->used + size * nmemb >=
-                             ((struct grst_body_text *) data)->allocated )
-    {
-      ((struct grst_body_text *) data)->allocated = 
-        ((struct grst_body_text *) data)->used + size * nmemb + 4096;
-
-      ((struct grst_body_text *) data)->text = 
-         realloc( ((struct grst_body_text *) data)->text,
-                  ((struct grst_body_text *) data)->allocated );
-    }
-    
-  memcpy( &( ((struct grst_body_text *) 
-                 data)->text[((struct grst_body_text *) data)->used] ),
-          ptr, size * nmemb);
-          
-  ((struct grst_body_text *) data)->used += size * nmemb;
-  
-  return size * nmemb;
-}
-
-size_t null_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
-  return size * nmemb;
-}
-
-size_t read_data_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
-  size_t sent;
-  
-  if (((struct grst_read_data *) data)->sent 
-        >= ((struct grst_read_data *) data)->maxsent) return 0;
-        
-  if (size * nmemb + ((struct grst_read_data *) data)->sent 
-        >= ((struct grst_read_data *) data)->maxsent)
-    {
-      sent = ((struct grst_read_data *) data)->maxsent 
-             - ((struct grst_read_data *) data)->sent;
-    }
-  else sent = size * nmemb;        
-
-  memcpy(ptr, 
-         ((struct grst_read_data *) data)->buf +
-         ((struct grst_read_data *) data)->sent,
-         sent);
-
-  ((struct grst_read_data *) data)->sent += sent;
-  
-  return sent;
-}
-
-char *canonicalise(char *link, char *source)
-{
-  int   i, j, srclen;
-  char *s;
-
-  srclen = strlen(source);
-
-  if ((strncmp(link, "https://", 8) == 0) ||
-      (strncmp(link, "http://", 7) == 0))
-    {
-      if (strncmp(link, source, srclen) != 0) return NULL; /* other site */
-      
-      if (link[srclen] == '\0') return NULL; /* we dont self-link! */
-      
-      for (i=0; link[srclen + i] != '\0'; ++i)
-        if (link[srclen + i] == '/')
-          { 
-            if (link[srclen + i + 1] != '\0') return NULL; /* no subdirs */
-            else return strdup(&link[srclen]); /* resolves to this dir */
-          }
-    }
-  else if (link[0] != '/') /* relative link - need to check for subsubdirs */
-    {
-      for (i=0; link[i] != '\0'; ++i) 
-        if ((link[i] == '/') && (link[i+1] != '\0')) return NULL;
-
-      s = strdup(link);
-      
-      for (i=0; s[i] != '\0'; ++i) 
-       if (s[i] == '#')
-         {
-           s[i] = '\0';
-           break;
-         }
-
-      return s;
-    }
-
-  /* absolute link on this server, starting / */
-
-  for (i=8; source[i] != '\0'; ++i) if (source[i] == '/') break;
-       
-  if (strncmp(link, &source[i], srclen - i) != 0) return NULL;
-
-  for (j = srclen - i; link[j] != '\0'; ++j)
-        if ((link[j] == '/') && (link[j+1] != '\0')) return NULL;
-        
-  s = strdup(&link[srclen - i]);
-      
-  for (i=0; s[i] != '\0'; ++i) 
-       if (s[i] == '#')
-         {
-           s[i] = '\0';
-           break;
-         }
-
-  if (s[0] == '\0') /* on second thoughts... */
-    {
-      free(s);
-      return NULL;
-    }
-         
-  return s;      
-}
-
-int grst_dir_list_cmp(const void *a, const void *b)
-{
-  return strcmp( ((struct grst_dir_list *) a)->filename, 
-                 ((struct grst_dir_list *) b)->filename);
-}
-
-struct grst_dir_list *index_to_dir_list(char *text, char *source)
-{
-  int   taglevel = 0, wordnew = 1, i, namestart, used = 0, 
-        allocated = 256;
-  char *p, *s;
-  struct grst_dir_list *list;
-  
-  list = (struct grst_dir_list *)
-              malloc(allocated * sizeof(struct grst_dir_list));
-              
-  list[0].filename     = NULL;
-  list[0].length       = 0;
-  list[0].length_set   = 0;
-  list[0].modified     = 0;
-  list[0].modified_set = 0;
-    
-  for (p=text; *p != '\0'; ++p)
-     {
-       if (*p == '<') 
-         {
-           ++taglevel;
-           
-           if ((taglevel == 1) && (list[used].filename != NULL))
-             {
-               ++used;
-               if (used >= allocated) 
-                 {
-                   allocated += 256;
-                   list = (struct grst_dir_list *)
-                           realloc((void *) list,
-                                   allocated * sizeof(struct grst_dir_list));
-                 }
-                 
-               list[used].filename     = NULL;
-               list[used].length       = 0;
-               list[used].length_set   = 0;
-               list[used].modified     = 0;
-               list[used].modified_set = 0;
-             }
-
-           wordnew = 1;
-           continue;
-         }
-
-       if (*p == '>') 
-         {
-           --taglevel;
-           wordnew = 1;
-           continue;
-         }
-         
-       if (isspace(*p))
-         {
-           wordnew = 1;
-           continue;
-         }
-
-       if ((wordnew) && (taglevel == 1))
-         {        
-           if (((*p == 'h') || (*p == 'H')) && 
-               (strncasecmp(p, "href=", 5) == 0))
-             {
-               if (p[5] == '"') { namestart = 6;
-                                  for (i=namestart; (p[i] != '\0') &&
-                                                    (p[i] != '"' ) &&
-                                                    (p[i] != '\n') &&
-                                                    (p[i] != '\t') &&
-                                                    (p[i] != '>' ) ; ++i) ; }
-               else { namestart = 5;
-                      for (i=namestart; (p[i] != '\0') &&
-                                        (p[i] != '"' ) &&
-                                        (p[i] != ' ' ) &&
-                                        (p[i] != '\n') &&
-                                        (p[i] != '\t') &&
-                                        (p[i] != ')' ) &&
-                                        (p[i] != '>' ) ; ++i) ; }
-               if (i > namestart)
-                 {
-                   s = malloc(1 + i - namestart);
-                   memcpy(s, &p[namestart], i - namestart);
-                   s[i - namestart] = '\0';
-
-                   list[used].filename = canonicalise(s, source);
-                   free(s);
-                   
-                   if ((list[used].filename != NULL) &&
-                       ((list[used].filename[0] == '\0') ||
-                        (strcmp(list[used].filename, "/") == 0)))
-                     {
-                       free(list[used].filename);
-                       list[used].filename = NULL;
-                     }
-                 }
-                 
-               p = &p[i-1]; /* -1 since continue results in ++i */
-               continue;
-             }
-
-           if (((*p == 'c') || (*p == 'C')) && 
-               (strncasecmp(p, "content-length=", 15) == 0))
-             {
-               list[used].length     = 0;
-               list[used].length_set = 1;
-               
-               if (p[15] == '"') list[used].length = atoi(&p[16]);
-               else              list[used].length = atoi(&p[15]);
-
-               p = &p[15];
-               continue;
-             }
-
-           if (((*p == 'l') || (*p == 'L')) && 
-               (strncasecmp(p, "last-modified=", 14) == 0))
-             {
-               list[used].modified     = 0;
-               list[used].modified_set = 1;
-               
-               if (p[14] == '"') list[used].modified = atoi(&p[15]);
-               else              list[used].modified = atoi(&p[14]);
-
-               p = &p[14];
-               continue;
-             }
-         }
-         
-       wordnew = 0;
-     }  
-
-  qsort((void *) list, used, sizeof(struct grst_dir_list), grst_dir_list_cmp);
-
-  return list;  
-}
-
-#if 0
-static char *GRSThttpUrlMildencode(char *in)
-/* Return a pointer to a malloc'd string holding a partially URL-encoded
-   version of *in. "Partially" means that A-Z a-z 0-9 . = - _ @ and /
-   are passed through unmodified. (DN's processed by GRSThttpUrlMildencode()
-   can be used as valid Unix paths+filenames if you are prepared to
-   create or simulate the resulting /X=xyz directories.) */
-{
-  char *out, *p, *q;
-
-  out = malloc(3*strlen(in) + 1);
-
-  p = in;
-  q = out;
-
-  while (*p != '\0')
-       {
-         if (isalnum(*p) || (*p == '.') || (*p == '=') || (*p == '-')
-                         || (*p == '/') || (*p == '@') || (*p == '_'))
-           {
-             *q = *p;
-             ++q;
-           }
-         else if (*p == ' ')
-           {
-             *q = '+';
-             ++q;
-           }
-         else
-           {
-             sprintf(q, "%%%2X", *p);
-             q = &q[3];
-           }
-
-         ++p;
-       }
-
-  *q = '\0';
-  return out;
-}
-#endif
-
-GRSTgaclPerm get_gaclPerm(struct fuse_context *fuse_ctx, char *path)
-{
-  GRSTgaclPerm perm = GRST_PERM_NONE; 
-  GRSTgaclCred *cred;
-  GRSTgaclUser *user = NULL;
-  GRSTgaclAcl  *acl;
-  char *dn = NULL;
-
-// eventually want a UID cache here...
-
-/*
-// want root to be able to read anything, and to write to anything under
-// local_root - need to test if talking about a symbolic link??
-  if (fuse_ctx->uid == 0) 
-    {
-      if (debugmode) syslog(LOG_DEBUG, 
-              "get_gaclPerm returns perm=%d for root user", GRST_PERM_ALL);
-      return GRST_PERM_ALL;
-    }
-*/
-  dn = mapdir_uid_to_dn(fuse_ctx->uid);
-  
-  if (dn != NULL)
-    {
-      cred = GRSTgaclCredNew("person");
-      GRSTgaclCredAddValue(cred, "dn", dn);
-      user = GRSTgaclUserNew(cred);
-      free(dn);
-    }   
-  
-  acl  = GRSTgaclAclLoadforFile(path); 
-  perm = GRSTgaclAclTestUser(acl, user);
-  GRSTgaclAclFree(acl);
-  GRSTgaclUserFree(user);
-  
-  if (strstr(path, GRST_ACL_FILE) != NULL) perm &= ~GRST_PERM_WRITE;
-
-  if (debugmode) syslog(LOG_DEBUG, "get_gaclPerm returns perm=%d", perm);
-
-  return perm;            
-}
-
-int read_headers_from_cache(struct fuse_context *fuse_ctx, char *filename, 
-                            off_t *length, time_t *modified)
-{
-  char *encoded_filename, *disk_filename;
-  int   len;
-  long  content_length, last_modified;
-  FILE *fp;
-  struct stat statbuf;
-  time_t now;
-  
-  encoded_filename = GRSThttpUrlMildencode(filename);
-  
-  len = strlen(encoded_filename);
-
-  if (encoded_filename[len - 1] == '/') /* a directory */
-       asprintf(&disk_filename, "%s/%d%s%s", 
-                GRST_SLASH_HEADERS, fuse_ctx->uid, encoded_filename, GRST_SLASH_DIRFILE);
-  else asprintf(&disk_filename, "%s/%d%s%s", 
-                GRST_SLASH_HEADERS, fuse_ctx->uid, encoded_filename);
-
-  free(encoded_filename);
-
-// Change to fstat for the benefit of multiple threads:
-
-  if (stat(disk_filename, &statbuf) != 0) /* no cache file to read */
-    {
-      free(disk_filename);
-      return 0;
-    }
-
-  time(&now);
-
-  if (statbuf.st_mtime < now - GRST_SLASH_HEADERS_EXPIRE)
-    {
-      unlink(disk_filename); /* tidy up expired cache file */
-      free(disk_filename);
-      return 0;
-    }      
-
-  last_modified  = 0;
-  content_length = 0;
-
-  if (debugmode) syslog(LOG_DEBUG, "Opening %s from cache", disk_filename);
-
-  fp = fopen(disk_filename, "r");
-  free(disk_filename);
-
-  if (fp != NULL)
-    {
-      fscanf(fp, "content-length=%ld last-modified=%ld ", 
-                 &content_length, &last_modified);
-      fclose(fp);
-
-      if (debugmode) syslog(LOG_DEBUG, "content-length=%ld last-modified=%ld", 
-                            content_length, last_modified);
-
-      *length   = (off_t)  content_length;
-      *modified = (time_t) last_modified;
-
-      return 1;
-    }
-
-  return 0;
-}
-
-int write_headers_to_cache(struct fuse_context *fuse_ctx, char *filename, 
-                           off_t length, time_t modified)
-{
-  int         fd, len;
-  char       *tempfile, *headline, *encoded_filename, *p, *newdir,
-             *new_filename;
-  struct stat statbuf;
-
-  asprintf(&tempfile, "%s/headers-XXXXXX", GRST_SLASH_TMP);
-  fd = mkstemp(tempfile);
-
-  if (fd == -1)
-    {
-      free(tempfile);
-      return 0;
-    }
-
-  asprintf(&headline, "content-length=%ld last-modified=%ld \n", 
-                                (long) length, (long) modified);
-  
-  if ((write(fd, headline, strlen(headline)) == -1) ||
-      (close(fd) == -1))
-    {
-      free(tempfile);
-      free(headline);
-      return 0;
-    }
-
-  free(headline);
-                     
-  encoded_filename = GRSThttpUrlMildencode(filename);
-
-// need to protect against .. ?
-   
-  for (p = encoded_filename; *p != '\0'; ++p)
-     {  
-       if (*p != '/') continue;
-     
-       *p = '\0';
-       asprintf(&newdir, "%s/%d%s", GRST_SLASH_HEADERS, fuse_ctx->uid, encoded_filename);
-       *p = '/';
-           
-       if (stat(newdir, &statbuf) == 0)
-         {
-           if (!S_ISDIR(statbuf.st_mode)) /* exists already - not a directory! */
-             {
-               unlink(newdir);
-               mkdir(newdir, S_IRUSR | S_IWUSR | S_IXUSR);
-             }
-           /* else it already exists as a directory - so ok */
-         }
-       else mkdir(newdir, S_IRUSR | S_IWUSR | S_IXUSR);
-
-       free(newdir);
-     }
-
-  len = strlen(encoded_filename);
-
-  if (encoded_filename[len - 1] == '/') /* a directory */
-       asprintf(&new_filename, "%s/%d%s%s", 
-                GRST_SLASH_HEADERS, fuse_ctx->uid, encoded_filename, GRST_SLASH_DIRFILE);
-  else asprintf(&new_filename, "%s/%d%s", 
-                GRST_SLASH_HEADERS, fuse_ctx->uid, encoded_filename);
-
-  free(encoded_filename);
-  
-  if ((stat(new_filename, &statbuf) == 0) && S_ISDIR(statbuf.st_mode))
-    {
-// need change this to do it recursively in case any files/subdirs too
-      rmdir(new_filename);
-    }
-
-  rename(tempfile, new_filename);
-
-  if (debugmode) syslog(LOG_DEBUG, "Added %s to cache (%ld %ld)\n", 
-                                   new_filename, length, modified);
-
-  free(tempfile);
-  free(new_filename);
-
-  return 1;
-}
-
-static int slashgrid_readdir(const char *path, void *buf, 
-                             fuse_fill_dir_t filler,
-                             off_t offset, struct fuse_file_info *fi)
-{
-  (void) offset;
-  (void) fi;
-
-  int          anyerror = 0, thiserror, i, ilast, len, isdir;
-  const char  *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
-                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-  char        *s, *url, errorbuffer[CURL_ERROR_SIZE+1] = "", *dirname, *p;
-  struct       grst_body_text  rawindex;
-  struct       grst_dir_list   *list;
-  struct       grst_request request_data;
-  struct       tm               modified_tm;
-  struct       stat             stat_tmp;
-  time_t                        now;
-  struct fuse_context fuse_ctx;
-  struct dirent **dirlist;
-  GRSTgaclPerm  perm;
-  
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if (debugmode) syslog(LOG_DEBUG, "in slashgrid_readdir");
-
-  if (strcmp(path, "/") == 0)
-    {
-      filler(buf, ".",     NULL, 0);
-      filler(buf, "..",    NULL, 0);
-      filler(buf, "http",  NULL, 0);
-      filler(buf, "https", NULL, 0);
-      return 0;
-    }
-    
-  if ((strcmp(path, "/http") == 0) || (strcmp(path, "/https") == 0))
-    {
-      filler(buf, ".",     NULL, 0);
-      filler(buf, "..",    NULL, 0);
-
-      asprintf(&dirname, "%s/%d%s", GRST_SLASH_HEADERS, fuse_ctx.uid, path);
-      ilast = scandir(dirname, &dirlist, 0, alphasort) - 1;
-
-      for (i=0; i <= ilast; ++i)
-         {
-           if (dirlist[i]->d_name[0] != '.')
-                 filler(buf, dirlist[i]->d_name, NULL, 0);
-           free(dirlist[i]);
-         }
-         
-      if (ilast >= 0) free(dirlist);      
-      free(dirname);
-    
-      return 0;
-    }
-  else if ((local_root != NULL) &&
-           ((strcmp(path, "/local") == 0) || 
-            (strncmp(path, "/local/", 7) == 0)))
-    {
-      asprintf(&dirname, "%s%s/", local_root, &path[6]);
-
-      perm = get_gaclPerm(&fuse_ctx, dirname);
-
-      if (!GRSTgaclPermHasList(perm))
-        {
-          free(dirname);
-          return -EACCES;
-        }
-        
-      ilast = scandir(dirname, &dirlist, 0, alphasort) - 1;
-      free(dirname);
-
-      if (ilast < 0) return -ENOENT;
-              
-//      filler(buf, ".",     NULL, 0);
-//      filler(buf, "..",    NULL, 0);
-
-      for (i=0; i <= ilast; ++i)
-         {
-//           if (dirlist[i]->d_name[0] != '.')
-                 filler(buf, dirlist[i]->d_name, NULL, 0);
-           free(dirlist[i]);
-         }
-         
-      free(dirlist);      
-
-      return 0;
-    }
-  else if (strncmp(path, "/http/", 6) == 0)
-    asprintf(&url, "http://%s/", &path[6]);
-  else if (strncmp(path, "/https/", 7) == 0)
-    asprintf(&url, "https://%s/", &path[7]);
-  else return -ENOENT;
-
-  rawindex.text      = NULL;
-  rawindex.used      = 0;
-  rawindex.allocated = 0;
-
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = rawbody_callback;
-  request_data.writedata     = (void *) &rawindex;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_GET;
-  request_data.start         = -1;
-  request_data.finish        = -1;
-  
-  if (debugmode) syslog(LOG_DEBUG, "Get directory listing from URL %s", url);
-  
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  if ((thiserror != 0) ||
-           (request_data.retcode <  200) ||
-           (request_data.retcode >= 300))
-         {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-           
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-         }
-  else
-         {
-           time(&now);
-
-           filler(buf, ".", NULL, 0);
-           filler(buf, "..", NULL, 0);
-
-           rawindex.text[rawindex.used] = '\0';
-
-// we need to get this out of headers cache instead iff still valid
-
-           list  = index_to_dir_list(rawindex.text, url);
-           ilast = -1;
-
-           for (i=0; list[i].filename != NULL; ++i)
-              {
-                if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_readdir, list[%d].filename=%s",
-                         i, list[i].filename);
-              
-                if (strncmp(list[i].filename, "mailto:", 7) == 0) continue;
-
-                len = strlen(list[i].filename);
-                if (list[i].filename[len-1] == '/')
-                  {
-                    isdir = 1;
-                    list[i].filename[len-1] = '\0';
-                  }
-                else 
-                  {
-                    isdir = 0;
-                    
-                    if ((p = index(list[i].filename, '?')) != NULL) *p = '\0';
-                  }
-                
-                /* skip over duplicates */
-                
-                if ((ilast >= 0) && 
-                    (strcmp(list[i].filename, list[ilast].filename) == 0))
-                                                                 continue;
-                ilast=i; /* last distinct entry */
-                
-                if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_readdir, list[%d].filename=%s not dup",
-                         i, list[i].filename);
-
-                asprintf(&s, "%s/%s", path, list[i].filename);
-                write_headers_to_cache(&fuse_ctx, s, list[i].length, 
-                                       list[i].modified);
-                free(s);
-           
-                bzero(&stat_tmp, sizeof(struct stat));
-
-                stat_tmp.st_size  = list[i].length;
-                stat_tmp.st_mtime = list[i].modified;
-                stat_tmp.st_ctime = list[i].modified;
-                stat_tmp.st_atime = now;
-                stat_tmp.st_mode  = isdir ? 0777 : 0666;
-                filler(buf, list[i].filename, &stat_tmp, 0);
-
-                if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_readdir, filler list[%d].filename=%s %lu %lu",
-                         i, list[i].filename, stat_tmp.st_size, stat_tmp.st_mtime);
-              }
-         }
-     
-  if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_readdir, return 0");
-  return 0;
-}
-
-static int slashgrid_getattr(const char *rawpath, struct stat *stbuf)
-{
-  int          anyerror = 0, thiserror, i, ilast, len, ret;
-  char        *s, *url, *path, errorbuffer[CURL_ERROR_SIZE+1] = "", *p;
-  struct       grst_dir_list   *list;
-  struct       grst_request request_data;
-  struct       tm               modified_tm;
-  struct       stat             stat_tmp;
-  time_t                        now;
-  GRSTgaclPerm dirperm, perm;
-
-  struct fuse_context fuse_ctx;
-
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_getattr, rawpath=%s UID=%d\n",
-                         rawpath, fuse_ctx.uid);
-
-  memset(stbuf, 0, sizeof(struct stat));
-  stbuf->st_mode  = S_IFREG | 0755;
-  stbuf->st_nlink = 1;
-  
-  if ((strcmp(rawpath, "/")      == 0) ||
-      (strcmp(rawpath, "/http")  == 0) ||
-      (strcmp(rawpath, "/https") == 0) ||
-      ((local_root != NULL) && (strcmp(rawpath, "/local") == 0)))
-    {
-      stbuf->st_mode = S_IFDIR | 0755;
-              
-      return 0; /* Empty top level directories: OK */
-    }
-  else if (strncmp(rawpath, "/http/", 6) == 0)
-    {
-      if (index(&rawpath[6], '/') == NULL) /* top directory for remote server */
-        {
-          stbuf->st_mode = S_IFDIR | 0755;
-          
-          asprintf(&url, "http://%s/", &rawpath[6]);
-          asprintf(&path, "%s/", rawpath);
-        }
-      else 
-        {
-          asprintf(&url, "http://%s", &rawpath[6]);      
-          path = strdup(rawpath);
-        }
-    }
-  else if (strncmp(rawpath, "/https/", 7) == 0)
-    {
-      if (index(&rawpath[7], '/') == NULL) /* top directory for remote server */
-        {
-          stbuf->st_mode = S_IFDIR | 0755;
-
-          asprintf(&url, "https://%s/", &rawpath[7]);
-          asprintf(&path, "%s/", rawpath);
-        }
-      else 
-        {
-          asprintf(&url, "https://%s", &rawpath[7]);
-          path = strdup(rawpath);
-        }
-    }
-  else if ((local_root != NULL) && (strncmp(rawpath, "/local/", 7) == 0))
-    {      
-      asprintf(&path, "%s/%s", local_root, &rawpath[7]);
- 
-      ret = stat(path, &stat_tmp);
-
-      if (debugmode) syslog(LOG_DEBUG, "path=%s ret=%d", path, ret);
-
-      if ((ret == 0) && S_ISDIR(stat_tmp.st_mode))
-        {
-          dirperm = get_gaclPerm(&fuse_ctx, path);
-        
-          p = rindex(path, '/');
-          if (p != NULL) *p = '\0'; 
-          /* strip off directory name itself if a directory, 
-             so get the GACL of the parent directory */
-
-          perm = get_gaclPerm(&fuse_ctx, path);
-        }
-      else
-        {      
-          perm = get_gaclPerm(&fuse_ctx, path);
-          dirperm = perm;
-        }
-
-      if (!GRSTgaclPermHasRead(perm)) ret = -EACCES;
-      else if (ret == 0)
-        {
-          stbuf->st_nlink   = 1;
-          stbuf->st_uid     = fuse_ctx.uid;
-          stbuf->st_gid     = fuse_ctx.gid;
-          stbuf->st_size    = stat_tmp.st_size;
-          stbuf->st_blksize = stat_tmp.st_blksize;
-          stbuf->st_blocks  = stat_tmp.st_blocks;
-          stbuf->st_atime   = stat_tmp.st_atime;
-          stbuf->st_mtime   = stat_tmp.st_mtime;
-          stbuf->st_ctime   = stat_tmp.st_ctime;
-        
-          if (S_ISDIR(stat_tmp.st_mode))
-            {
-              stbuf->st_mode = S_IFDIR;
-            
-              if (GRSTgaclPermHasWrite(dirperm)) 
-                                        stbuf->st_mode |= S_IWUSR;
-
-              if (GRSTgaclPermHasList(dirperm)) 
-                                        stbuf->st_mode |= S_IRUSR | S_IXUSR;
-            }
-          else
-            {
-              stbuf->st_mode = S_IFREG;
-
-              if (GRSTgaclPermHasWrite(perm)) 
-                                        stbuf->st_mode |= S_IWUSR;
-
-              if (GRSTgaclPermHasRead(perm)) 
-                                        stbuf->st_mode |= S_IRUSR;
-            }          
-            
-          
-        }  
-      else ret = -ENOENT;
-      
-      free(path);
-
-      if (debugmode) syslog(LOG_DEBUG, "slashgrid_getattr returns %d for %s",
-                                       ret, rawpath);
-      return ret;
-    }
-  else return -ENOENT;
-  
-  time(&now);
-
-  if (read_headers_from_cache(&fuse_ctx, path, 
-                              &(stbuf->st_size), &(stbuf->st_mtime)))
-    {
-      if (debugmode) syslog(LOG_DEBUG, 
-          "Retrieving details for %s from cache (%ld %ld)\n", url,
-          (long) stbuf->st_mtime, (long) stbuf->st_size);
-    
-      stbuf->st_ctime = stbuf->st_mtime;
-      stbuf->st_atime = now;
-      
-      free(url);
-      free(path);
-      return 0;    
-    }
-  
-  if (debugmode) syslog(LOG_DEBUG, "Get details for %s over network\n", url);
-
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = null_callback;
-  request_data.writedata     = NULL;
-  request_data.readfunction  = null_callback;
-  request_data.readdata      = NULL;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_HEAD;
-  request_data.start         = -1;
-  request_data.finish        = -1;
-
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  if (debugmode) syslog(LOG_DEBUG, "perform_request returns error=%d (%s)\n",
-                        thiserror, errorbuffer);
-
-  if ((thiserror != 0) ||
-           (request_data.retcode < 200) ||
-           (request_data.retcode > 301))
-         {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-           
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           free(url);
-           free(path);
-           
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-         }
-         
-  if (request_data.retcode == 301)
-    {
-       if (debugmode) syslog(LOG_DEBUG, "301 detected");
-
-       len = strlen(url);
-      
-       if ((request_data.location[0] != '\0') &&
-          (len + 1 == strlen(request_data.location)) &&
-          (request_data.location[len] == '/') &&
-          (strncmp(url, request_data.location, len) == 0))
-        {
-          free(url);
-          url = strdup(request_data.location);
-          request_data.url = url;
-                  
-          thiserror = perform_request(&request_data, &fuse_ctx);
-
-          if ((thiserror != 0) ||
-              (request_data.retcode < 200) ||
-              ((request_data.retcode > 299) && (request_data.retcode != 403)))
-            {
-              if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-           
-              if (thiserror != 0) anyerror = thiserror;
-              else                anyerror = request_data.retcode;
-
-              free(url);
-              free(path);
-              return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-            }
-            
-          stbuf->st_mode  = S_IFDIR | 0755;  /* this is a directory */
-
-          free(path);
-          asprintf(&path, "%s/", rawpath);
-        }
-      else 
-        {
-          free(url);
-          free(path);
-          return -ENOENT;
-        }
-    }
-
-  if (request_data.length_set) stbuf->st_size  = request_data.length;
-  else stbuf->st_size = 0;
-  
-  if (request_data.modified_set)
-    {
-      stbuf->st_mtime = request_data.modified;
-      stbuf->st_ctime = request_data.modified;
-    }
-
-  stbuf->st_atime = now;
-
-  write_headers_to_cache(&fuse_ctx, path, stbuf->st_size, stbuf->st_mtime);
-
-  free(url);
-  free(path);
-  return 0;
-}
-
-int write_block_to_cache(struct fuse_context *fuse_ctx, char *filename,  
-                         off_t start, off_t finish)
-{
-  int          anyerror = 0, thiserror, i, fd;
-  char        *s, *url, *tempfile, *encoded_filename, *p,
-              *newdir, *new_filename, errorbuffer[CURL_ERROR_SIZE+1] = "";
-  struct       stat statbuf;
-  struct       grst_request request_data;
-  FILE        *fp;
-
-  asprintf(&tempfile, "%s/blocks-XXXXXX", GRST_SLASH_TMP);
-  fd = mkstemp(tempfile);
-
-  if (fd == -1)
-    {
-      free(tempfile);
-      return -EIO;
-    }
-
-  fp = fdopen(fd, "w");
-
-  if (strncmp(filename, "/http/", 6) == 0)
-    asprintf(&url, "http://%s", &filename[6]);
-  else if (strncmp(filename, "/https/", 7) == 0)
-    asprintf(&url, "https://%s", &filename[7]);
-  else return -ENOENT;
-
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = fwrite;
-  request_data.writedata     = (void *) fp;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_GET;
-  request_data.start         = start;
-  request_data.finish        = finish;
-
-  if (debugmode) syslog(LOG_DEBUG, "Get block %ld-%ld from URL %s\n",
-                                   (long) start, (long) finish, url);
-  
-  thiserror = perform_request(&request_data, fuse_ctx);
-
-  free(url);
-
-  fclose(fp);  
-
-  if ((thiserror != 0) ||
-           (request_data.retcode <  200) ||
-           (request_data.retcode >= 300))
-         {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-         }
-
-  encoded_filename = GRSThttpUrlMildencode(filename);
-
-// need to protect against .. ?
-// can optimise by checking for existing of filename as a dir at the start
-
-  for (p = encoded_filename; ; ++p)
-     {  
-       if ((*p != '/') && (*p != '\0')) continue;
-     
-       if (*p == '/') 
-         {
-           *p = '\0';
-           asprintf(&newdir, "%s/%d%s", 
-                    GRST_SLASH_BLOCKS, fuse_ctx->uid, encoded_filename);
-           *p = '/';
-         }
-       else asprintf(&newdir, "%s/%d%s", 
-                     GRST_SLASH_BLOCKS, fuse_ctx->uid, encoded_filename);
-           
-       if (stat(newdir, &statbuf) != 0)
-                                   mkdir(newdir, S_IRUSR | S_IWUSR | S_IXUSR);
-       free(newdir);
-       
-       if (*p == '\0') break;
-     }
-
-  asprintf(&new_filename, "%s/%d%s/%ld-%ld", GRST_SLASH_BLOCKS, fuse_ctx->uid,
-                           encoded_filename, (long) start, (long) finish);
-
-  free(encoded_filename);
-  
-  rename(tempfile, new_filename);
-
-  if (debugmode) syslog(LOG_DEBUG, "Added %s to block cache", new_filename);
-
-  free(tempfile);
-  free(new_filename);
-
-  return 0;
-}
-
-int drop_cache_blocks(struct fuse_context *fuse_ctx, char *filename)
-/* drop ALL the blocks cached for this file, and delete the directory in
-   the blocks cache for this file */
-{
-  int   ret;
-  char *encoded_filename, *dirname, *blockname;
-  DIR *blocksDIR;
-  struct dirent *blocks_ent;
-
-  encoded_filename = GRSThttpUrlMildencode(filename);
-  
-  asprintf(&dirname, "%s/%d%s", 
-                     GRST_SLASH_BLOCKS, fuse_ctx->uid, encoded_filename);
-
-  free(encoded_filename);
-
-  blocksDIR = opendir(dirname);
-  
-  if (blocksDIR == NULL) /* no directory to delete (probably) */
-    {
-      free(dirname);
-      return 1;
-    }
-    
-  while ((blocks_ent = readdir(blocksDIR)) != NULL)
-       {
-         asprintf(&blockname, "%s/%s", dirname, blocks_ent->d_name);
-         remove(blockname);
-         free(blockname);
-       }  
-  
-  closedir(blocksDIR);
-    
-  ret = rmdir(dirname);
-  free(dirname);  
-
-  return ret ? 1 : 0; /* return 1 on error, 0 on rmdir() success */
-}
-
-static int slashgrid_read(const char *path, char *buf, 
-                          size_t size, off_t offset,
-                          struct fuse_file_info *fi)
-{
-  (void) offset;
-  (void) fi;
-
-  int          anyerror = 0, thiserror, i, ilast, fd;
-  char        *s, *url, *disk_filename, *encoded_filename, *localpath;
-  off_t        block_start, block_finish, block_i, len;
-  struct       grst_body_text   rawbody;
-  struct       grst_request request_data;
-  struct       tm               modified_tm;
-  struct       stat             statbuf;
-  time_t                        now;
-  GRSTgaclPerm perm;
-  struct fuse_context fuse_ctx;
-
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-  
-  if (debugmode) syslog(LOG_DEBUG, "in slashgrid_read size=%ld offset=%ld",
-                                    (long) size, (long) offset);
-
-  if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0))
-    {
-      asprintf(&localpath, "%s/%s", local_root, &path[7]);
-      
-      perm = get_gaclPerm(&fuse_ctx, localpath);
-      
-      if (GRSTgaclPermHasRead(perm))
-        {
-          fd = open(localpath, O_RDONLY);
-
-          if (lseek(fd, offset, SEEK_SET) < 0) size = -1;
-          else size = read(fd, buf, size);
-
-          close(fd);                  
-        }
-      else size = -1;
-      
-      free(localpath);
-      
-      return size;
-    }
-
-  if ((strncmp(path, "/http/",  6) != 0) &&
-      (strncmp(path, "/https/", 7) != 0)) return -ENOENT;
-
-  block_start  = GRST_SLASH_BLOCK_SIZE * (offset / GRST_SLASH_BLOCK_SIZE);
-  block_finish = GRST_SLASH_BLOCK_SIZE *
-                                ((offset + size - 1) / GRST_SLASH_BLOCK_SIZE);
-
-  encoded_filename = GRSThttpUrlMildencode((char *) path);
-  time(&now);
- 
-  for (block_i = block_start; block_i <= block_finish; block_i += GRST_SLASH_BLOCK_SIZE)
-     {     
-       asprintf(&disk_filename, "%s/%d%s/%ld-%ld", 
-                 GRST_SLASH_BLOCKS, fuse_ctx.uid, encoded_filename, 
-                 (long) block_i, (long) (block_i + GRST_SLASH_BLOCK_SIZE - 1));
-
-       if (debugmode) syslog(LOG_DEBUG, "disk_filename=%s", disk_filename);
-                 
-       if ((stat(disk_filename, &statbuf) != 0) ||
-           (statbuf.st_mtime < now - GRST_SLASH_HEADERS_EXPIRE))
-         {
-           write_block_to_cache(&fuse_ctx, (char *) path, 
-                            block_i, block_i + GRST_SLASH_BLOCK_SIZE - 1);
-         }
-
-// need to worry about cached copy being deleted (invalidated by a writing
-// thread?) between write_block_to_cache() and these reads?
-// maybe return fd from write_block_to_cache() itself???
-// the initial stat() needs to be part of this too
-
-       if ((fd = open(disk_filename, O_RDONLY)) != -1)
-         {
-           if (block_i == block_start)              
-             {
-               lseek(fd, offset - block_start, SEEK_SET);
-               read(fd, buf, 
-                        (offset - block_start + size < GRST_SLASH_BLOCK_SIZE) 
-                       ? size : GRST_SLASH_BLOCK_SIZE - offset + block_start);
-             }
-           else if (block_i == block_finish)
-             {
-               read(fd, buf + (block_i - block_start),
-                        offset + size - block_i);
-             }
-           else 
-             {
-               read(fd, buf + (block_i - block_start), 
-                        GRST_SLASH_BLOCK_SIZE);
-             }
-             
-           close(fd);
-         }        
-       else syslog(LOG_ERR, "Failed to open %s in cache", disk_filename);
-     }
-
-  free(disk_filename);
-  free(encoded_filename);
-
-  return size;
-}
-
-static int slashgrid_write(const char *path, const char *buf, 
-                           size_t size, off_t offset,
-                           struct fuse_file_info *fi)
-{
-  int          anyerror = 0, thiserror, i, fd;
-  char        *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = "", *localpath;
-  GRSTgaclPerm perm;
-
-  struct grst_read_data read_data;
-  struct grst_request request_data;
-  struct fuse_context fuse_ctx;
-  
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));  
-
-  if (debugmode) syslog(LOG_DEBUG, "in slashgrid_write, path=%s, UID=%d\n",
-                                   path, fuse_ctx.uid);
-                         
-  if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0))
-    {
-      asprintf(&localpath, "%s/%s", local_root, &path[7]);      
-      perm = get_gaclPerm(&fuse_ctx, localpath);
-      
-      if (GRSTgaclPermHasWrite(perm))
-        {
-          fd = open(localpath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
-
-          if (lseek(fd, offset, SEEK_SET) < 0) size = -1;
-          else size = write(fd, buf, size);
-
-          fchown(fd, local_uid, local_gid);
-          close(fd);                  
-        }
-      else size = -1;
-      
-      free(localpath);
-      
-      return size;
-    }
-
-  if (strncmp(path, "/http/", 6) == 0)
-    asprintf(&url, "http://%s", &path[6]);
-  else if (strncmp(path, "/https/", 7) == 0)
-    asprintf(&url, "https://%s", &path[7]);
-  else return -ENOENT;
-
-  read_data.buf     = buf;
-  read_data.sent    = 0;
-  read_data.maxsent = size;
-
-  if (debugmode) syslog(LOG_DEBUG, "Put block %ld-%ld to URL %s", 
-                                   (long) offset, (long) offset+size-1, url);
-
-  drop_cache_blocks(&fuse_ctx, (char *) path); /* we drop all read-cache blocks first */
-  
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = null_callback;
-  request_data.readfunction  = read_data_callback;
-  request_data.readdata      = &read_data;
-  request_data.infilesize    = size;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_PUT;
-  request_data.start         = offset;
-  request_data.finish        = (off_t) (offset + size - 1);
-
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  free(url);
-
-  if ((thiserror != 0) ||
-      (request_data.retcode <  200) ||
-      (request_data.retcode >= 300))
-    {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-           
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-    }
-
-  return size;
-}
-
-int slashgrid_rename(const char *oldpath, const char *newpath)
-{
-  int          anyerror = 0, thiserror, i, fd, ret;
-  char        *s, *url, *p, *destination, errorbuffer[CURL_ERROR_SIZE+1] = "",
-              *oldlocalpath, *newlocalpath;
-
-  struct grst_read_data read_data;
-  struct fuse_context fuse_ctx;
-  struct grst_request request_data;
-  GRSTgaclPerm oldperm, newperm;
-
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if ((local_root != NULL) && 
-      ((strncmp(oldpath, "/local/", 7) == 0) ||
-       (strncmp(newpath, "/local/", 7) == 0)))
-    {
-      if (strncmp(oldpath, newpath, 7) != 0)
-        {
-          return -EXDEV; /* not on same filesystem */
-        }
-    
-      asprintf(&oldlocalpath, "%s/%s", local_root, &oldpath[7]);
-      asprintf(&newlocalpath, "%s/%s", local_root, &newpath[7]);
-      
-      oldperm = get_gaclPerm(&fuse_ctx, oldlocalpath);
-      newperm = get_gaclPerm(&fuse_ctx, newlocalpath);
-      
-      if (GRSTgaclPermHasWrite(oldperm) &&
-          GRSTgaclPermHasWrite(newperm))
-        {
-          ret = rename(oldlocalpath, newlocalpath);
-          free(oldlocalpath);
-          free(newlocalpath);
-          
-          return (ret == 0) ? 0 : -errno;
-        }
-
-      free(oldlocalpath);
-      free(newlocalpath);
-      return -EACCES;
-    }
-  else if (strncmp(oldpath, "/http/", 6) == 0)
-    {
-      if (strncmp(newpath, "/http/", 6) != 0) return -EXDEV;
-
-      asprintf(&url,         "http://%s", &oldpath[6]);
-      asprintf(&destination, "http://%s", &newpath[6]);
-    }
-  else if (strncmp(oldpath, "/https/", 7) == 0)
-    {
-      if (strncmp(newpath, "/https/", 7) != 0) return -EXDEV;
-
-      asprintf(&url,         "https://%s", &oldpath[7]);
-      asprintf(&destination, "https://%s", &newpath[7]);
-    }
-  else return -ENOENT;
-
-  read_data.buf     = "";
-  read_data.sent    = 0;
-  read_data.maxsent = 0;
-
-  if (debugmode) syslog(LOG_DEBUG, "MOVE URL %s to %s", url, destination);
-  
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = null_callback;
-  request_data.readfunction  = read_data_callback;
-  request_data.readdata      = &read_data;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_MOVE;
-  request_data.destination   = destination;
-
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  free(url);
-  free(destination);
-
-  if ((thiserror != 0) ||
-      (request_data.retcode <  200) ||
-      (request_data.retcode >= 300))
-    {
-      if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-
-      if (thiserror != 0) anyerror = thiserror;
-      else                anyerror = request_data.retcode;
-
-      if (request_data.retcode == 403) return -EACCES;
-      else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-    }
-
-  return 0;
-}
-
-int slashgrid_unlink(const char *path)
-{
-  int   anyerror = 0, thiserror, i, fd, ret;
-  char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = "",
-              *localpath;
-
-  struct grst_read_data read_data;
-  struct fuse_context fuse_ctx;
-  struct grst_request request_data;
-  GRSTgaclPerm perm;
-
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_unlink called for %s", path);
-  
-  if (strncmp(path, "/http/", 6) == 0)
-    asprintf(&url, "http://%s", &path[6]);
-  else if (strncmp(path, "/https/", 7) == 0)
-    asprintf(&url, "https://%s", &path[7]);
-  else if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0))
-    {
-      asprintf(&localpath, "%s/%s", local_root, &path[7]);
-      
-      perm = get_gaclPerm(&fuse_ctx, localpath);
-      
-      if (GRSTgaclPermHasWrite(perm))
-        {
-          ret = remove(localpath);
-          free(localpath);
-          
-          return (ret == 0) ? 0 : -errno;
-        }
-
-      free(localpath);
-      return -EACCES;
-    }
-  else return -ENOENT;
-
-  read_data.buf     = "";
-  read_data.sent    = 0;
-  read_data.maxsent = 0;
-
-  if (debugmode) syslog(LOG_DEBUG, "DELETE URL %s", url);
-  
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = null_callback;
-  request_data.readfunction  = read_data_callback;
-  request_data.readdata      = &read_data;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_DELETE;
-
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  free(url);
-
-  if ((thiserror != 0) ||
-           (request_data.retcode <  200) ||
-           (request_data.retcode >= 300))
-         {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-         }
-
-  return 0;
-}
-
-int slashgrid_rmdir(const char *path)
-{
-  int   ret;
-  char *pathwithslash, *localpath;
-
-  asprintf(&pathwithslash, "%s/", path);
-  ret = slashgrid_unlink(pathwithslash);  
-  free(pathwithslash);
-
-/* error on GridSite side still??? */
-  
-  return ret;
-}
-
-int slashgrid_mknod(const char *path, mode_t mode, dev_t dev)
-{
-  int ret;
-
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_mknod called for %s", path);
-  
-  ret = slashgrid_write(path, "", 0, 0, NULL);
-
-  return (ret < 0) ? ret : 0;
-}
-
-int slashgrid_mkdir(const char *path, mode_t mode)
-{
-  int   ret;
-  char *pathwithslash, *localpath;
-  struct fuse_context fuse_ctx;
-  GRSTgaclPerm perm;
-  
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_mkdir, for %s", path);
-                                  
-  if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0))
-    {
-      asprintf(&localpath, "%s/%s", local_root, &path[7]);
-      
-      perm = get_gaclPerm(&fuse_ctx, localpath);
-      
-      if (GRSTgaclPermHasWrite(perm))
-        {
-          ret = mkdir(localpath, S_IRUSR | S_IWUSR | S_IXUSR);
-          chown(localpath, local_uid, local_gid);
-          free(localpath);
-          
-          return (ret == 0) ? 0 : -errno;
-        }
-
-      free(localpath);
-      return -EACCES;
-    }
-
-  asprintf(&pathwithslash, "%s/", path);
-  ret = slashgrid_write(pathwithslash, "", 0, 0, NULL);
-  free(pathwithslash);
-
-  return (ret < 0) ? ret : 0;
-}
-
-int slashgrid_chown(const char *path, uid_t uid, gid_t gid)
-{
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_chown - NOP");
-  return 0;
-}
-
-int slashgrid_chmod(const char *path, mode_t mode)
-{
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_chmod - NOP");
-  return 0;
-}
-
-int slashgrid_truncate(const char *path, off_t offset)
-{
-  int   anyerror = 0, thiserror, i, fd, ret;
-  char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = "", *localpath;
-  GRSTgaclPerm perm;
-
-  struct grst_read_data read_data;
-  struct fuse_context fuse_ctx;
-  struct grst_request request_data;
-
-  memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
-
-  if (debugmode) syslog(LOG_DEBUG, "slashgrid_truncate, for %s (%d)",
-                                  path, offset);
-
-  if (strncmp(path, "/http/", 6) == 0)
-    asprintf(&url, "http://%s", &path[6]);
-  else if (strncmp(path, "/https/", 7) == 0)
-    asprintf(&url, "https://%s", &path[7]);
-  else if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0))
-    {
-      asprintf(&localpath, "%s/%s", local_root, &path[7]);
-      
-      perm = get_gaclPerm(&fuse_ctx, localpath);
-      
-      if (GRSTgaclPermHasWrite(perm))
-        {
-          ret = truncate(localpath, offset);
-          free(localpath);
-          
-          return (ret == 0) ? 0 : -errno;
-        }
-
-      free(localpath);
-      return -EACCES;
-    }
-  else return -ENOENT;
-
-  read_data.buf     = "";
-  read_data.sent    = 0;
-  read_data.maxsent = 0;
-
-  if (debugmode) syslog(LOG_DEBUG, "Truncate URL %s to %ld\n", 
-                                   url, (long) offset);
-  
-  bzero(&request_data, sizeof(struct grst_request));
-  request_data.writefunction = null_callback;
-  request_data.readfunction  = read_data_callback;
-  request_data.readdata      = &read_data;
-  request_data.errorbuffer   = errorbuffer;
-  request_data.url           = url;
-  request_data.method        = GRST_SLASH_TRUNC;
-  request_data.finish        = offset;
-
-  thiserror = perform_request(&request_data, &fuse_ctx);
-
-  free(url);
-
-  if ((thiserror != 0) ||
-           (request_data.retcode <  200) ||
-           (request_data.retcode >= 300))
-         {
-           if (debugmode)
-                syslog(LOG_DEBUG, "... curl error: %s (%d), HTTP error: %d\n",
-                       errorbuffer, thiserror, request_data.retcode);
-
-           if (thiserror != 0) anyerror = thiserror;
-           else                anyerror = request_data.retcode;
-
-           if (request_data.retcode == 403) return -EACCES;
-           else return -ENOENT; 
-/* memory clean up still needed here!!!!!! */
-         }
-
-  return 0;
-}
-
-int slashgrid_statfs(const char *path, struct statfs *fs)
-{
-  /* statfs() on /local not used in practice, since not mounted separately */
-
-  if ((strncmp(path, "/local/", 7) == 0) ||
-      (strcmp(path, "/local") == 0))
-       return statfs(local_root, fs);
-  else return statfs(GRST_SLASH_BLOCKS, fs);
-}
-
-void *slashgrid_init(void)
-{
-  FILE *fp;
-  struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY };
-  
-  if ((fp = fopen(GRST_SLASH_PIDFILE, "w")) != NULL)
-    {
-      fprintf(fp, "%d\n", (int) getpid());
-      fclose(fp);
-    }
-
-  if (debugmode)
-    {
-      chdir("/var/tmp"); /* fuse changes to / in demonize: undo this */
-      setrlimit(RLIMIT_CORE, &unlimited);
-    }
-
-  return NULL;
-}
-
-void slashgrid_destroy(void *p)
-{
-  unlink(GRST_SLASH_PIDFILE);
-}
-
-static struct fuse_operations slashgrid_oper = {
-  .getattr	= slashgrid_getattr,
-  .chown	= slashgrid_chown,    
-  .chmod	= slashgrid_chmod,
-  .truncate	= slashgrid_truncate,    
-  .readdir	= slashgrid_readdir,
-  .write	= slashgrid_write,
-  .read		= slashgrid_read,
-  .mknod	= slashgrid_mknod,
-  .mkdir	= slashgrid_mkdir,
-  .unlink	= slashgrid_unlink,
-  .rmdir	= slashgrid_rmdir,
-  .rename	= slashgrid_rename,
-  .statfs	= slashgrid_statfs,
-  .init		= slashgrid_init,
-  .destroy	= slashgrid_destroy
-};
-
-void slashgrid_logfunc(char *file, int line, int level, char *fmt, ...)
-{
-  char *mesg;
-  va_list ap;
-
-  va_start(ap, fmt);
-  vasprintf(&mesg, fmt, ap);
-  va_end(ap);
-  
-  syslog(level, "%s(%d) %s", file, line, mesg);
-  
-  free(mesg);
-}
-
-int main(int argc, char *argv[])
-{
-  char *fuse_argv[] = { "slashgrid", "/grid", "-o", "allow_other",
-                        "-s", "-d" };
-  int   i, ret, fuse_argc = 4; /* by default, ignore the final 2 args */
-  struct passwd *pw;
-  
-  for (i=1; i < argc; ++i)
-     {
-       if (strcmp(argv[i], "--debug") == 0) 
-         {
-           debugmode = 1;
-         }
-       else if (strcmp(argv[i], "--foreground") == 0) 
-         {
-           debugmode = 1;
-           fuse_argc = 6;
-         }
-       else if ((strcmp(argv[i], "--domain") == 0) && (i + 1 < argc))
-         {
-           sitecast_domain = argv[i+1];
-           sitecast_domain_len = strlen(sitecast_domain);
-           ++i;
-         }
-       else if ((strcmp(argv[i], "--groups") == 0) && (i + 1 < argc))
-         {
-           sitecast_groups = argv[i+1];
-           ++i;
-         }          
-       else if ((strcmp(argv[i], "--local-root") == 0) && (i + 1 < argc))
-         {
-           local_root = argv[i+1];
-           ++i;
-         }          
-       else if ((strcmp(argv[i], "--local-user") == 0) && (i + 1 < argc))
-         {
-           if ((pw = getpwnam(argv[i+1])) == NULL)
-             {
-               fprintf(stderr, "unable to find user %s\n", argv[i+1]);
-               return 1;
-             }
-            
-           local_uid = pw->pw_uid;
-           local_gid = pw->pw_gid;
-           ++i;           
-         }
-       else if ((strcmp(argv[i], "--gridmapdir") == 0) && (i + 1 < argc))
-         {
-           gridmapdir = argv[i+1];
-           ++i;
-         }          
-       else
-         {
-           fprintf(stderr, "argument %s not recognised\n", argv[i]);
-           return 1;
-         }
-     }              
-
-  if ((local_root != NULL) && 
-      ((local_uid == 0) || (local_gid == 0)))
-    {
-      fprintf(stderr, "if --local-root is given, "
-                "--local-user must be given too and not be the root user\n");
-      return 1;
-    }
-
-  openlog("slashgrid", 0, LOG_DAEMON);
-    
-  umount("/grid"); /* in case of previous crash - will fail if still busy */
-
-  for (i=0; i < GRST_SLASH_MAX_HANDLES; ++i)
-     {
-       pthread_mutex_init(&(handles[i].mutex), NULL);
-       handles[i].curl_handle = NULL;
-       handles[i].proxyfile   = NULL;
-       handles[i].last_used   = 0;
-     }
-
-//  GRSTerrorLogFunc = slashgrid_logfunc;
- 
-  GRSTgaclInit();
- 
-  ret = fuse_main(fuse_argc, fuse_argv, &slashgrid_oper);
-
-  return ret;
-}
diff --git a/org.gridsite.core/src/slashgrid.init b/org.gridsite.core/src/slashgrid.init
deleted file mode 100755
index f83b43e..0000000
--- a/org.gridsite.core/src/slashgrid.init
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-#
-# slashgrid        Startup script for the SlashGrid client-side server
-#
-# chkconfig: - 90 10
-# description: Filesystem extension for access to HTTP(S) file servers
-# processname: slashgrid
-# config: /etc/sysconfig/slashgrid
-# pidfile: /var/run/slashgrid.pid
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Examples of useful overrides of default settings:
-#
-# OPTIONS=--debug			# to turn on LOG_DEBUG in syslog
-# SLASHGRID=/usr/local/sbin/slashgrid	# if slashgrid not in /usr/sbin
-# PATH=$PATH:/usr/local/bin		# if fusermount not on old $PATH
-#
-if [ -f /etc/sysconfig/slashgrid ] ; then
- . /etc/sysconfig/slashgrid
-fi
-
-slashgrid=${SLASHGRID-/usr/sbin/slashgrid}
-pidfile=${PIDFILE-/var/run/slashgrid.pid}
-lockfile=${LOCKFILE-/var/lock/subsys/slashgrid}
-prog=slashgrid
-RETVAL=0
-
-start() {
-        echo -n $"Starting $prog: "
-        modprobe fuse
-        sleep 1
-        daemon $slashgrid $OPTIONS
-        RETVAL=$?
-        echo
-        [ $RETVAL = 0 ] && touch ${lockfile}
-        return $RETVAL
-}
-
-stop() {
-	echo -n $"Stopping $prog: "
-	killproc $slashgrid
-	RETVAL=$?
-	echo
-	[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
-}
-
-# Invoke the right function
-
-case "$1" in
-  start)
-	start
-	;;
-  stop)
-	stop
-	;;
-  restart)
-	stop
-	start
-	;;
-  *)
-	echo $"Usage: $prog {start|stop|restart|help}"
-	exit 1
-esac
-
-exit $RETVAL
diff --git a/org.gridsite.core/src/urlencode.c b/org.gridsite.core/src/urlencode.c
deleted file mode 100644
index bea36a9..0000000
--- a/org.gridsite.core/src/urlencode.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-   Copyright (c) 2002-3, Andrew McNab, University of Manchester
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or
-   without modification, are permitted provided that the following
-   conditions are met:
-
-     o Redistributions of source code must retain the above
-       copyright notice, this list of conditions and the following
-       disclaimer. 
-     o Redistributions in binary form must reproduce the above
-       copyright notice, this list of conditions and the following
-       disclaimer in the documentation and/or other materials
-       provided with the distribution. 
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-   POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*---------------------------------------------------------------*
- * For more about GridSite: http://www.gridsite.org/             *
- *---------------------------------------------------------------*/
-
-#include 
-#include 
-
-#include "gridsite.h"
-
-int main(int argn, char *argv[])
-{
-  int    i;
-
-  if (argn == 1)
-    {
-      puts("urlencode [-m|-d] string-to-encode-or-decode");
-      return 0;
-    }
-
-  if      (strcmp(argv[1], "-d") == 0) /* decode */
-   for (i = 2; i < argn; ++i) 
-      {
-        if (i > 2) fputs(" ", stdout);
-        fputs(GRSThttpUrlDecode(argv[i]), stdout);
-      }
-  else if (strcmp(argv[1], "-m") == 0) /* mild encode */
-   for (i = 2; i < argn; ++i) 
-      {
-        if (i > 2) fputs("%20", stdout);
-        fputs(GRSThttpUrlMildencode(argv[i]), stdout);
-      }
-  else /* standard encode */
-   for (i = 1; i < argn; ++i) 
-      {
-        if (i > 1) fputs("%20", stdout);
-        fputs(GRSThttpUrlEncode(argv[i]), stdout);
-      }
-
-  puts("");
-
-  return 0;
-}
diff --git a/org.gridsite.core/src/xacmlexample.c b/org.gridsite.core/src/xacmlexample.c
deleted file mode 100644
index af914b9..0000000
--- a/org.gridsite.core/src/xacmlexample.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-   Copyright (c) 2005, Andrew McNab and Shiv Kaushal, University of Manchester
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or
-   without modification, are permitted provided that the following
-   conditions are met:
-
-     o Redistributions of source code must retain the above
-       copyright notice, this list of conditions and the following
-       disclaimer. 
-     o Redistributions in binary form must reproduce the above
-       copyright notice, this list of conditions and the following
-       disclaimer in the documentation and/or other materials
-       provided with the distribution. 
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-   POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*---------------------------------------------------------------*
- * For more about GridSite: http://www.gridsite.org/             *
- *---------------------------------------------------------------*/
-
-/*
-   Example program using XACML
-
-   Build with:
-   
-    gcc -o xacmlexample xacmlexample.c -L. -I. -lgridsite -lxml2 -lz -lm
-*/
-
-#include 
-#include 
-#include 
-#include 
-
-int main()
-{
-  GRSTgaclCred  *cred, *usercred;
-  GRSTgaclEntry *entry;
-  GRSTgaclAcl   *acl1, *acl2;
-  GRSTgaclUser  *user;
-  GRSTgaclPerm   perm0, perm1, perm2;
-  FILE          *fp;
-
-  /* must initialise GACL before using XACML functions */
-
-  GRSTgaclInit();
-
-  /* build up an ACL, starting with a credential */
-
-  cred = GRSTgaclCredNew("person");
-
-  GRSTgaclCredAddValue(cred, "dn", "/O=Grid/CN=Mr Grid Person");
-
-  /* create an entry to put it in */
-
-  entry = GRSTgaclEntryNew();
-
-  /* add the credential to it */
-
-  GRSTgaclEntryAddCred(entry, cred);
-
-  /* add another credential */
-
-  cred = GRSTgaclCredNew("dn-list");
-  GRSTgaclCredAddValue(cred, "url", "example-dn-list");
-  GRSTgaclEntryAddCred(entry, cred);
-
-  fp = fopen("example-dn-list", "w");
-  fputs("/O=Grid/CN=Mr Grid Person\n", fp);
-  fclose(fp);
-
-  /* associate some permissions and denials to the credential */
-
-  GRSTgaclEntryAllowPerm( entry, GRST_PERM_READ);
-  GRSTgaclEntryAllowPerm( entry, GRST_PERM_WRITE);
-  GRSTgaclEntryAllowPerm( entry, GRST_PERM_ADMIN);
-  GRSTgaclEntryDenyPerm(  entry, GRST_PERM_ADMIN);
-  GRSTgaclEntryDenyPerm(  entry, GRST_PERM_LIST);
-
-  perm0 = GRST_PERM_READ | GRST_PERM_WRITE;
-
-  printf("test perm should be %d\n", perm0);
-
-  /* create a new ACL and add the entry to it */
-
-  acl1 = GRSTgaclAclNew();
-
-  GRSTgaclAclAddEntry(acl1, entry);
-
-  /* create a GRSTgaclUser to compare with the ACL */
-
-  usercred = GRSTgaclCredNew("person");
-
-  GRSTgaclCredAddValue(usercred, "dn", "/O=Grid/CN=Mr Grid Person");
-
-  user = GRSTgaclUserNew(usercred);
-
-  GRSTgaclUserSetDNlists(user, getcwd(NULL, 0));
-  printf("DN Lists dir %s\n", getcwd(NULL, 0));
-
-//  putenv("GRST_DN_LISTS=.");
-
-  perm1 = GRSTgaclAclTestUser(acl1, user);
-
-  printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm1);
-
-  /* print and save the whole ACL */
-
-  GRSTgaclAclPrint(acl1, stdout);
-
-  GRSTxacmlAclSave(acl1, "example.xacml");
-
-  puts("gridacl.out saved");
-
-  puts("");
-
-  /* load the ACL back off the disk, print and test it */
-
-  acl2 = GRSTxacmlAclLoadFile("example.xacml");
-
-  puts("gridacl.out loaded");
-
-  if (acl2 != NULL) GRSTgaclAclPrint(acl2, stdout); else puts("acl2 is NULL");
-
-  perm2 = GRSTgaclAclTestUser(acl2, user);
-
-  printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm2);
-
-  if (perm1 != perm0) return 1;
-  if (perm2 != perm0) return 2;
-
-  return 0;
-}
-
-- 
1.8.2.3