Sprout from master 2004-12-10 13:01:20 UTC Aleš Křenek <ljocha@ics.muni.cz> 'imported statistics counting'
Cherrypick from master 2005-06-10 09:43:14 UTC Andrew McNab <andrew.mcnab@manchester.ac.uk> 'Tidy up for tag':
org.glite.deployment.lb/build.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/lxscript-rpm.xsl
org.glite.security.gsoap-plugin/LICENSE
org.glite.security.gsoap-plugin/examples/calc.h.S
org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c
org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c
org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c
org.glite.security.gsoap-plugin/interface/glite_gsplugin.h
org.glite.security.gsoap-plugin/interface/glite_gss.h
org.glite.security.gsoap-plugin/project/build.properties
org.glite.security.gsoap-plugin/project/properties.xml
org.glite.security.gsoap-plugin/project/tar_exclude
org.glite.security.gsoap-plugin/src/glite_gss.c
org.gridsite.core/CHANGES
org.gridsite.core/VERSION
org.gridsite.core/build.xml
org.gridsite.core/doc/config.html
org.gridsite.core/doc/gsexec.8
org.gridsite.core/doc/httpd-fileserver.conf
org.gridsite.core/doc/httpd-webserver.conf
org.gridsite.core/interface/gridsite.h
org.gridsite.core/project/build.number
org.gridsite.core/project/configure.properties.xml
org.gridsite.core/project/version.properties
org.gridsite.core/src/Makefile
org.gridsite.core/src/gridsite.spec
org.gridsite.core/src/grst-delegation.c
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_gacl.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
org.gridsite.core/src/mod_gridsite.c
org.gridsite.core/src/showx509exts.c
org.gridsite.core/src/xacmlexample.c
Cherrypick from master 2005-07-08 13:18:40 UTC Alberto Di Meglio <alberto.di.meglio@cern.ch> 'Merged from branch 1.2.2':
org.glite.deployment.lb/LICENSE
org.glite.deployment.lb/project/properties.xml
Cherrypick from master 2005-02-15 09:29:04 UTC Jiří Škrábal <nykolas@ics.muni.cz> '- files lb_gss.* renamed to glite_gss.*':
org.glite.security.gsoap-plugin/test/test_gss.cpp
Cherrypick from glite-lb-client-interface_branch_1_0_0 2005-04-13 11:41:09 UTC Jiří Škrábal <nykolas@ics.muni.cz> '- do not distribute fake library header files':
org.glite.lb.client-interface/Makefile
org.glite.lb.client-interface/build.xml
org.glite.lb.client-interface/interface/CountRef.h
org.glite.lb.client-interface/interface/Event.h.T
org.glite.lb.client-interface/interface/Job.h
org.glite.lb.client-interface/interface/JobStatus.h.T
org.glite.lb.client-interface/interface/LoggingExceptions.h
org.glite.lb.client-interface/interface/Notification.h
org.glite.lb.client-interface/interface/ServerConnection.h
org.glite.lb.client-interface/interface/consumer.h
org.glite.lb.client-interface/interface/context.h
org.glite.lb.client-interface/interface/events.h.T
org.glite.lb.client-interface/interface/jobstat.h.T
org.glite.lb.client-interface/interface/notification.h
org.glite.lb.client-interface/interface/notifid.h
org.glite.lb.client-interface/interface/producer.h.T
org.glite.lb.client-interface/interface/statistics.h
org.glite.lb.client-interface/project/build.number
org.glite.lb.client-interface/project/configure.properties.xml
org.glite.lb.client-interface/project/version.properties
Cherrypick from glite-lb-client_branch_1_0_0 2005-07-07 17:22:40 UTC Aleš Křenek <ljocha@ics.muni.cz> 'fix for double connection close crash':
org.glite.lb.client/Makefile
org.glite.lb.client/build.xml
org.glite.lb.client/doc/README-acl
org.glite.lb.client/doc/README-fake
org.glite.lb.client/doc/README-notify
org.glite.lb.client/examples/abort_job.c
org.glite.lb.client/examples/change_acl.c
org.glite.lb.client/examples/job_log.c
org.glite.lb.client/examples/job_log_fake.cpp
org.glite.lb.client/examples/job_status.c
org.glite.lb.client/examples/producer_fake.c
org.glite.lb.client/examples/purge_test
org.glite.lb.client/project/build.number
org.glite.lb.client/project/version.properties
org.glite.lb.client/src/ServerConnection.cpp
org.glite.lb.client/src/connection.c
org.glite.lb.client/src/logevent.c.T
org.glite.lb.client/src/producer.c
org.glite.lb.client/src/uiwrap.c.T
Cherrypick from glite-security-proxyrenewal_branch_1_0_0_RC1 2005-04-08 02:14:05 UTC Master Builder <glbuilder@cern.ch> 'Incremented build number [GLBUILDER]':
org.glite.security.proxyrenewal/Makefile
org.glite.security.proxyrenewal/build.xml
org.glite.security.proxyrenewal/config/startup
org.glite.security.proxyrenewal/interface/renewal.h
org.glite.security.proxyrenewal/project/build.number
org.glite.security.proxyrenewal/project/version.properties
org.glite.security.proxyrenewal/src/acstack.h
org.glite.security.proxyrenewal/src/api.c
org.glite.security.proxyrenewal/src/commands.c
org.glite.security.proxyrenewal/src/common.c
org.glite.security.proxyrenewal/src/newformat.h
org.glite.security.proxyrenewal/src/renew.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
Cherrypick from glite-lb-common_branch_1_1_0 2005-07-07 17:20:50 UTC Aleš Křenek <ljocha@ics.muni.cz> 'fix for double connection close crash':
org.glite.lb.common/Makefile
org.glite.lb.common/build.xml
org.glite.lb.common/interface/lb_gss.h
org.glite.lb.common/project/build.number
org.glite.lb.common/project/version.properties
org.glite.lb.common/src/context.c
org.glite.lb.common/src/events.c.T
org.glite.lb.common/src/il_log.c
org.glite.lb.common/src/lb_gss.c
org.glite.lb.common/src/param.c
Cherrypick from glite-lb-server_branch_1_0_0 2005-06-08 05:24:47 UTC Master Builder <glbuilder@cern.ch> 'Incremented build number [GLBUILDER]':
org.glite.lb.server/Makefile
org.glite.lb.server/build.xml
org.glite.lb.server/project/build.number
org.glite.lb.server/project/configure.properties.xml
org.glite.lb.server/project/version.properties
org.glite.lb.server/src/dump.c
org.glite.lb.server/src/notification.c
org.glite.lb.server/src/server_state.c
org.glite.lb.server/src/srv_purge.c
org.glite.lb.server/src/store.c.T
Cherrypick from glite-lb-logger_branch_1_0_0 2005-07-07 06:30:51 UTC Master Builder <glbuilder@cern.ch> 'Incremented build number [GLBUILDER]':
org.glite.lb.logger/build.xml
org.glite.lb.logger/project/build.number
org.glite.lb.logger/project/version.properties
org.glite.lb.logger/src/event_queue.c
org.glite.lb.logger/src/event_store.c
org.glite.lb.logger/src/il_master.c
org.glite.lb.logger/src/interlogd.h
org.glite.lb.logger/src/logd_proto.c
org.glite.lb.logger/src/queue_thread.c
Cherrypick from glite-security-gsoap-plugin_branch_1_1_0 2005-06-02 11:00:51 UTC Jiří Škrábal <nykolas@ics.muni.cz> '- clean connection on unsuccessfull connect':
org.glite.security.gsoap-plugin/Makefile
org.glite.security.gsoap-plugin/build.xml
org.glite.security.gsoap-plugin/project/build.number
org.glite.security.gsoap-plugin/project/configure.properties.xml
org.glite.security.gsoap-plugin/project/version.properties
org.glite.security.gsoap-plugin/src/glite_gsplugin.c
org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.c
Cherrypick from glite-deployment-lb_branch_2_0_0 2005-07-22 09:14:26 UTC Master Builder <glbuilder@cern.ch> 'Incremented build number [GLBUILDER]':
org.glite.deployment.lb/CHANGELOG
org.glite.deployment.lb/config/scripts/glite-lb-config.py
org.glite.deployment.lb/config/templates/glite-lb.cfg.xml
org.glite.deployment.lb/project/build.number
org.glite.deployment.lb/project/glite-lb.sdf.xml.template
org.glite.deployment.lb/project/version.properties
Cherrypick from glite-lb-ws-interface_branch_1_0_0 2005-04-03 16:29:31 UTC Alberto Di Meglio <alberto.di.meglio@cern.ch> 'Increased revision number':
org.glite.lb.ws-interface/Makefile
org.glite.lb.ws-interface/build.xml
org.glite.lb.ws-interface/project/build.number
org.glite.lb.ws-interface/project/version.properties
org.glite.lb.ws-interface/src/LB.xml.T
org.glite.lb.ws-interface/src/puke-ug.xsl
Cherrypick from glite-lb_branch_1_0_0_RC1 2005-07-07 17:31:17 UTC Aleš Křenek <ljocha@ics.muni.cz> 'Tagged dependencies properties file [GLBUILDER]':
org.glite.lb/build.xml
org.glite.lb/project/build.number
org.glite.lb/project/dependencies.properties
org.glite.lb/project/events.T
org.glite.lb/project/types.T
org.glite.lb/project/version.properties
Cherrypick from glite-wms-utils-exception_branch_1_0_0 2005-04-04 00:48:20 UTC Alberto Di Meglio <alberto.di.meglio@cern.ch> 'Increased revision number':
org.glite.wms-utils.exception/build.xml
org.glite.wms-utils.exception/configure.ac
org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h
org.glite.wms-utils.exception/project/build.number
org.glite.wms-utils.exception/project/version.properties
org.glite.wms-utils.exception/src/Exception.cpp
Cherrypick from glite-lb-server-bones_branch_1_0_0 2005-04-14 14:02:40 UTC Aleš Křenek <ljocha@ics.muni.cz> 'do not distribute srvbones.h (Makefile rev. 1.5.2.1)':
org.glite.lb.server-bones/Makefile
org.glite.lb.server-bones/build.xml
org.glite.lb.server-bones/project/build.number
org.glite.lb.server-bones/project/version.properties
Cherrypick from glite-wms-utils-jobid_branch_1_0_0 2005-04-03 01:12:39 UTC Master Builder <glbuilder@cern.ch> 'Incremented build number [GLBUILDER]':
org.glite.wms-utils.jobid/build.xml
org.glite.wms-utils.jobid/project/build.number
org.glite.wms-utils.jobid/project/version.properties
Delete:
org.glite.deployment.lb/project/glite-lb.spec
org.glite.jp.common/.cvsignore
org.glite.jp.common/Makefile
org.glite.jp.common/build.xml
org.glite.jp.common/interface/context.h
org.glite.jp.common/interface/strmd5.h
org.glite.jp.common/interface/types.h
org.glite.jp.common/project/build.properties
org.glite.jp.common/project/configure.properties.xml
org.glite.jp.common/project/properties.xml
org.glite.jp.common/project/tar_exclude
org.glite.jp.common/project/version.properties
org.glite.jp.common/src/context.c
org.glite.jp.common/src/strmd5.c
org.glite.jp.index/.cvsignore
org.glite.jp.index/Makefile
org.glite.jp.index/build.xml
org.glite.jp.index/project/JobProvenanceIS.wsdl
org.glite.jp.index/project/build.properties
org.glite.jp.index/project/configure.properties.xml
org.glite.jp.index/project/properties.xml
org.glite.jp.index/project/tar_exclude
org.glite.jp.index/project/version.properties
org.glite.jp.index/src/simple_server.c
org.glite.jp.index/src/soap_ops.c
org.glite.jp.index/src/typemap.dat
org.glite.jp.primary/.cvsignore
org.glite.jp.primary/Makefile
org.glite.jp.primary/build.xml
org.glite.jp.primary/examples/jpps-test.c
org.glite.jp.primary/project/build.properties
org.glite.jp.primary/project/configure.properties.xml
org.glite.jp.primary/project/properties.xml
org.glite.jp.primary/project/tar_exclude
org.glite.jp.primary/project/version.properties
org.glite.jp.primary/src/backend.h
org.glite.jp.primary/src/feed.c
org.glite.jp.primary/src/feed.h
org.glite.jp.primary/src/ftp_backend.c
org.glite.jp.primary/src/is_client.c
org.glite.jp.primary/src/jptype_map.h
org.glite.jp.primary/src/simple_server.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/typemap.dat
org.glite.jp.ws-interface/.cvsignore
org.glite.jp.ws-interface/LICENSE
org.glite.jp.ws-interface/Makefile
org.glite.jp.ws-interface/build.xml
org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl
org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl
org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl
org.glite.jp.ws-interface/project/build.properties
org.glite.jp.ws-interface/project/configure.properties.xml
org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec
org.glite.jp.ws-interface/project/properties.xml
org.glite.jp.ws-interface/project/tar_exclude
org.glite.jp.ws-interface/project/version.properties
org.glite.jp/.cvsignore
org.glite.jp/build.xml
org.glite.jp/project/build.properties
org.glite.jp/project/dependencies.properties
org.glite.jp/project/glite.jp.csf.xml
org.glite.jp/project/properties.xml
org.glite.jp/project/run-workspace
org.glite.jp/project/taskdefs.xml
org.glite.jp/project/version.properties
org.glite.lb.client/examples/log_usertag_proxy.c
org.gridsite.core/src/real-gridsite-admin.cgi
--- /dev/null
+DATE: 08-07-2005 15:20\r
+[dimeglio] Increased major version because of interface changes in the config scripts\r
+\r
+DATE: 08-07-2005 15:20\r
+[dimeglio] Merged from branch 1.2.2\r
+\r
+DATE: 25-05-2005 20:00\r
+[dimeglio] Merged from branch 1.2.2\r
+\r
+DATE: 21-03-2005 17:21\r
+[dimeglio] Implemented status method\r
+\r
+DATE: 21-03-2005 00:32\r
+[dimeglio] Added PERL5LIB env var\r
+\r
+DATE: 17-03-2005 17:33\r
+[gdiez] Stopping and starting the database before the index creation (just after the database is created and the user granted)\r
+\r
+DATE: 09-03-2005 23:05\r
+[dimeglio] Moved creation of indices inside database creation (if database\r
+ exists indices are not recreated)\r
+\r
+DATE: 02-03-2005 11:05\r
+[dimeglio] Started CHANGELOG\r
+[dimeglio] Fixed formatting, improved display of message using glib.printXxxMessage functions\r
+[dimeglio] Fixed some problems when starting/stopping services\r
+[dimeglio] GLITE_USER parameter not exposed anymore in config file, use same user parameters\r
+ as WMS to allow installation on same node\r
+[dimeglio] Increased module version number to 1.2.0
\ No newline at end of file
-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
-<email address>.
-
-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/
-
-
+LICENSE file for EGEE Middleware\r
+================================\r
+\r
+Copyright (c) 2004 on behalf of the EU EGEE Project: \r
+The European Organization for Nuclear Research (CERN), \r
+Istituto Nazionale di Fisica Nucleare (INFN), Italy\r
+Datamat Spa, Italy\r
+Centre National de la Recherche Scientifique (CNRS), France\r
+CS Systeme d'Information (CSSI), France\r
+Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden\r
+Universiteit van Amsterdam (UvA), Netherlands\r
+University of Helsinki (UH.HIP), Finlan\r
+University of Bergen (UiB), Norway\r
+Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are\r
+met: \r
+\r
+1. Redistributions of source code must retain the above copyright\r
+notice, this list of conditions and the following disclaimer.\r
+\r
+2. Redistributions in binary form must reproduce the above copyright\r
+notice, this list of conditions and the following disclaimer in the\r
+documentation and/or other materials provided with the distribution.\r
+\r
+3. The end-user documentation included with the redistribution, if\r
+any, must include the following acknowledgment: "This product includes\r
+software developed by The EU EGEE Project (http://cern.ch/eu-egee/)."\r
+Alternatively, this acknowledgment may appear in the software itself, if\r
+and wherever such third-party acknowledgments normally appear.\r
+\r
+4. The names EGEE and the EU EGEE Project must not be\r
+used to endorse or promote products derived from this software without\r
+prior written permission. For written permission, please contact\r
+<email address>.\r
+\r
+5. You are under no obligation whatsoever to provide anyone with any\r
+bug fixes, patches, or upgrades to the features, functionality or\r
+performance of the Software ("Enhancements") that you may develop over\r
+time; however, if you choose to provide your Enhancements to The EU\r
+EGEE Project, or if you choose to otherwise publish or distribute your\r
+Enhancements, in source code form without contemporaneously requiring\r
+end users of The EU EGEE Proejct to enter into a separate written license\r
+agreement for such Enhancements, then you hereby grant The EU EGEE Project\r
+a non-exclusive, royalty-free perpetual license to install, use, copy,\r
+modify, prepare derivative works, incorporate into the EGEE Middleware\r
+or any other computer software, distribute, and sublicense your\r
+Enhancements or derivative works thereof, in binary and source code\r
+form (if any), whether developed by The EU EGEE Project or third parties.\r
+\r
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED\r
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE\r
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\r
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+This software consists of voluntary contributions made by many\r
+individuals on behalf of the EU EGEE Prject. For more information on The\r
+EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on\r
+EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/\r
+\r
+\r
Revision history:
$Log$
+ Revision 1.5 2004/10/17 22:34:39 dimeglio
+ Use new installer script format
+ Use global filters
+ Use RH standard expat rpm in sdf template
+
Revision 1.4 2004/10/14 16:07:53 dimeglio
Removed wms.thirdparty-globus-ssl-utils
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
# For license conditions see the license file or http://eu-egee.org/license.html
#
################################################################################
-# glite-lb-config v. 0.2.0
+# glite-lb-config v. 2.0.0
#
# Post-installation script for configuring the gLite Logging and Bookkeping Server
# Robert Harakaly < robert.harakaly@cern.ch >
# Version info: $Id$
#
# Usage: python glite-lb-config [-c|-v|-h|--help]
-# -c print configuration
-# -v print version
-# -h,--help print usage info
+# -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
+import os,string,pwd
import sys, posix, getopt,time
sys.path.append(".")
from gLiteInstallerLib import gLib
+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 = "0.2.0"
+ self.version = "2.0.0"
self.name = "glite-lb"
self.friendly_name = "gLite Logging and Bookkeeping"
+ params['module.version'] = self.version
#-------------------------------------------------------------------------------
# Banner
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'
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
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
+ #-------------------------------------------------------------------
+
+ pid = glib.getPID('rgma-servicetool')
+ if (pid != 0):
+ print 'The gLite R-GMA Servicetool service is already running. Restarting...'
+ rgmaServicetool.stop()
+ else:
+ print "Starting the gLite R-GMA Servicetool service"
+
+ rgmaServicetool.start()
+
+
+ # Check that the daemon is running
+
+ pid = glib.getPID('rgma-servicetool')
+
+ if (pid != 0):
+ print "The gLite R-GMA Servicetool service has been started ",
+ glib.printOkMessage()
+ else:
+ glib.printErrorMessage("Could not start the gLite R-GMA Servicetool service")
+ glib.printErrorMessage("Please verify and re-run the script "),
+ glib.printFailedMessage()
+ return 1
return 0
def stop(self):
- os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION'])
+
+ 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()
+ else:
+ print 'The LB Server service has been stopped ',
+ glib.printOkMessage()
+
self.mysql.stop()
+
+ #-------------------------------------------------------------------
+ # Stop the servicetool
+ #-------------------------------------------------------------------
+
+ pid = glib.getPID('rgma-servicetool')
+ if (pid != 0):
+ rgmaServicetool.stop()
+
+ pid = glib.getPID('rgma-servicetool')
+ if (pid != 0):
+ print 'Could not stop the R-GMA Servicetool service ',
+ glib.printFailedMessage()
+ else:
+ print 'The R-GMA Servicetool service has been stopped ',
+ glib.printOkMessage()
return 0
+ 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
+
+ return error_level
+
def configure(self):
- # Create all directories needed
- if params.has_key('dirlist'):
- dirlist = string.split(params['dirlist'],',')
- for d in dirlist:
- glib.check_dir(d,0777)
- glib.check_dir(params['GLITE_CERT_DIR'])
-
+
+ #--------------------------------------------------------
+ # Installs the Security Utilities
+ #--------------------------------------------------------
+
+ if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()):
+ print "\nInstalling gLite Security Utilities ",
+ glib.printFailedMessage()
+ return 1
+
+ print "\nInstalling gLite Security Utilities ",
+ glib.printOkMessage()
+
# Create the GLITE_USER if it doesn't exists
- print "Creating/Verifying the GLITE_USER account %s" % params['GLITE_USER']
- glib.add_user(params['GLITE_USER'],params['GLITE_USER'])
- (uid,gid) = glib.get_user_info(params['GLITE_USER'])
+ 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)
- glib.check_dir("/home/%s/.certs" % params['GLITE_USER'],0755, uid, gid)
- lb_cert_path = pwd.getpwnam(params['GLITE_USER'])[5] + "/" + params['user.certificate.path']
+ 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
+ print "\nVerify CA certificates directory ",
+ glib.check_dir(os.environ['GLITE_CERT_DIR'])
+ glib.printOkMessage()
+
# Copy certificates
- glib.check_dir( lb_cert_path, 0755, uid, gid)
+ 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)
- glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % lb_cert_path)
- glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % lb_cert_path)
-
+ os.chmod("%s/hostkey.pem" % lb_cert_path, 0400)
+ glib.printOkMessage()
+
# Create the MySQL database
+ print "\nCreate/Verify the %s database" % params['lb.database.name']
self.mysql.stop()
time.sleep(5)
self.mysql.start()
- print '#-------------------------------------------------------------------'
- print ('Creating MySQL %s database.' % params['lb.database.name'])
- print '#-------------------------------------------------------------------'
-
- os.system('/usr/bin/mysqlaccess %s %s' % (params['lb.database.username'], params['lb.database.name']))
- file = open('/tmp/mysql_ct', 'w')
- text = ['CREATE DATABASE %s;\n' % params['lb.database.name'],
- 'GRANT ALL PRIVILEGES ON %s.* TO %s@localhost IDENTIFIED BY "";\n' % (params['lb.database.name'],params['lb.database.username']),
- '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 < /tmp/mysql_ct')
- os.system('/bin/rm /tmp/mysql_ct')
if not os.path.exists('/tmp/mysql.sock'):
os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock')
+
+ # Check if database exists
+ if self.mysql.existsDB(params['lb.database.name']) != 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')
+ text = ['CREATE DATABASE %s;\n' % params['lb.database.name'],
+ 'GRANT ALL PRIVILEGES ON %s.* TO %s@localhost IDENTIFIED BY "";\n' \
+ % (params['lb.database.name'],params['lb.database.username']),
+ '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 < /tmp/mysql_ct')
+ 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
+ #-------------------------------------------------------------------
+
+ print "Configuring the R-GMA Servicetool..."
+
+ if rgmaServicetool.configure(glib):
+ # error in configuring services
+ print "Configuring the R-GMA Servicetool... ",
+ glib.printFailedMessage()
+ return 1
+
+ print "Configuring the R-GMA Servicetool... ",
+ glib.printOkMessage()
+
return 0
#-------------------------------------------------------------------------------
if not os.path.exists(os.environ['GLITE_LOCATION_TMP']):
os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755)
- (uid,gid) = glib.add_user(params['GLITE_USER'])
- lb_cert_path = pwd.getpwnam(params['GLITE_USER'])[5] + "/" + params['user.certificate.path']
+ 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('GLOBUS_LOCATION',params['GLOBUS_LOCATION'])
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/externals/bin:%s/bin" % (os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION']))
+ 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()
if __name__ == '__main__':
- # Command line opts if any
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','stop','start'])
- except getopt.GetoptError:
- usage(msg = "Unknown options(s)")
- sys.exit(1)
-
# The script must be run as root
if not os.geteuid()==0:
print '"\nThis script must be run as root\n'
# Load parameters
params = {}
+ try:
+ opts, args = getopt.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(),params):
- print "Configuration files not found.\nPlease verify if the configuration files are copied from the templates directory\n"
+ print "An error occurred while configuring the service"
sys.exit(1)
verbose = 0
# 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 = getopt.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 == "--stop":
- service.stop()
- sys.exit(0)
- if o == "--start":
- service.start()
- sys.exit(0)
- # Check certificates
- if params.has_key('glite.installer.checkcerts'):
- if params['glite.installer.checkcerts'] == "true":
- if glib.check_certs(params) != 0:
- print "Certificate files are not found\n"
- sys.exit(1)
-
- # Print configuration parameters
- if verbose:
- glib.print_params(params)
+ if o == "--configure":
- service.copyright()
- service.showVersion()
- service.banner()
-
- # Configure the service
- if service.configure() == 0:
- print "%s configuration successfully completed\n" % service.friendly_name
- else:
- print "An error occurred while configuring the %s" % service.friendly_name
- sys.exit(1)
+ # 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)
- # Start the service
- # service.stop()
- if service.start() != 0:
- print "An error occurred while starting the %s" % service.friendly_name
- sys.exit(1)
+ 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())
+
<!-- User-defined parameters - Please change them -->
<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
- <!-- gLite configuration -->
+ <!-- gLite services user accounts -->
+ <glite.user.name
+ description="Name of the user account used to run the gLite services
+ on this LB node"
+ value="changeme"/>
+
+ <glite.user.group
+ description="Group of the user specified in the 'glite.user.name'
+ parameter. Leave it empty of comment it out to use the same as 'glite.user.name'"
+ value="changeme"/>
+
+ <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+ <!-- Advanced parameters - Change them if you know what you're doing -->
+ <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+
+ <!-- Installer configuration -->
<glite.installer.verbose
description="Enable verbose output"
value="true"/>
description="Enable check of host certificates"
value="true"/>
- <GLITE_USER
- description="The account used to run the LB daemons"
- value="changeme"/>
-
- <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
- <!-- Optimization parameters - Change them if you know what you're doing -->
- <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
-
<!-- MySQL DB -->
<lb.database.name
description="The mySQL database name to create for storing LB data
- Now it must be set to the default value"
+ In this version it must be set to the given value"
value="lbserver20"/>
+
+ <lb.index.list
+ description="Definitions of indices on all the currently supported indexed system attributes">
+
+ <value>owner</value>
+ <value>location</value>
+ <value>destination</value>
+
+ </lb.index.list>
<lb.database.username
description="The username to be used to access the local mySQL server
- Now it must be set to the default value"
+ In this version it must be set to the given value"
value="lbserver"/>
- <GLOBUS_LOCATION
- description="The location of the Globus Toolkit"
- value="/opt/globus"/>
-
<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
<!-- System parameters - You should leave these alone -->
<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
- <dirlist value='/opt/glite/var'/>
+
</parameters>
-</config>
\ No newline at end of file
+
+ <!--RGMA service publishing: log server -->
+ <instance name="lb.rgma" service="rgma-servicetool">
+ <parameters>
+
+ <rgma.servicetool.enable
+ description="Publish log server via RGMA servicetool. If this variable is set to 'false': the other
+ values of this instance are not taken into account.[Example: 'true'] [Type: 'boolean']"
+
+ value="true"/>
+
+ <rgma.servicetool.service_type
+ description="The service type. This should be uniquely defined for each service type.
+ The recommended format is the service namespace in
+ reversed domain name format [Type: 'string']"
+ value="org.glite.lb.lbserver"/>
+
+ <rgma.servicetool.name
+ description="Name of the service. This should be globally unique.
+ [Example: 'HOSTANME_LB_LocalLogger'] [Type: 'String']"
+ value="${HOSTNAME}_${rgma.servicetool.service_type}"/>
+
+ <rgma.servicetool.url_endpoint
+ description="URL to contact the service at.
+ This should be unique for each service. Use example and adapt host.
+ Example: http://your.host.name/LB/LBServer
+ [Type: 'string']"
+ value="not available"/>
+
+ <rgma.servicetool.service_version
+ description="Service version in the form 'major.minor.patch'
+ Example: 1.2.3
+ [Type: 'string']"
+ value="${module.version}"/>
+
+ <rgma.servicetool.publish_interval
+ description="How often to check and publish service information.
+ Example: 3600 [Type: 'string'] [Unit: 'seconds']"
+ value="3600"/>
+
+ <rgma.servicetool.status_script
+ description="Script to run when determining the service status.
+ This script should return an exit code of 0 to indicate the service is OK, other values
+ should indicate an error. The first line of the standard output should be a brief message
+ describing the service status (e.g. 'Accepting connections')
+ Example: ${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd status
+ [Type: 'string']"
+ value="${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd status"/>
+
+ <rgma.servicetool.status_interval
+ description="How often to check and publish service status.
+ Example: 60 [Type: 'string'] [Unit: 'seconds']"
+ value="30"/>
+
+ <rgma.servicetool.url_wsdl
+ description="URL of a WSDL document for the service (leave blank if the
+ service has no WSDL).
+ Example: http://example.rl.ac.uk/service?WSDL
+ [Type: 'string']"
+ value="not available"/>
+
+ <rgma.servicetool.url_semantics
+ description="URL of a document containing a detailed description of the service
+ and how it should be used.
+ Example: http://example.rl.ac.uk/service/semantics.html
+ [Type: 'string']"
+ value="not available"/>
+
+ </parameters>
+ </instance>
+
+</config>
{font-family:Times;
panose-1:2 2 6 3 5 4 5 2 3 4;}
@font-face
- {font-family:"Univers \(W1\)";
- panose-1:0 0 0 0 0 0 0 0 0 0;}
+ {font-family:"Univers \(W1\)";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin-top:2.0pt;
<h1><span lang=FR>1. </span><span lang=FR>Release Description</span></h1>
<p class=MsoNormal>This release contains the gLite Logging & Bookkeeping
-Server module v. 0.2.0. The following sections provide additional information about
+Server module v. 1.2.3. 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. </p>
-<h1>2. Release contents</h1>
+<h1><span lang=FR>2. </span><span lang=FR>Changes in this Release</span></h1>
-<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 0.2.0 is
+<p class=MsoNormal>This release introduces the following changes:</p>
+
+<p class=MsoNormal> </p>
+
+<ul style='margin-top:0mm' type=disc>
+ <li class=MsoNormal style='text-align:left'>All R-GMA service publishing
+ instances in the configuration template now have default values</li>
+ <li class=MsoNormal>Bug fixes (see below for the complete lists)</li>
+</ul>
+
+<h1>3. Release contents</h1>
+
+<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 1.2.3 is
composed of the following gLite components:</p>
<p class=MsoNormal> </p>
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=634
- style='width:475.4pt;border-collapse:collapse;border:none'>
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=621
+ style='width:466.1pt;border-collapse:collapse;border:none'>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Component name</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Component name</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Version</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Version</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border:solid windowtext 1.0pt;
+ <td width=415 valign=top style='width:310.95pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>File</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>File</span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>org.glite.deployment.lb</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.deployment.lb</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.2.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.2.3</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-lb_installer.sh">http://glite.web.cern.ch/glite/packages/I20041210/installers/glite-lb_installer.sh</a>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-lb_installer.sh">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-lb_installer.sh</a>
</span></p>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite-lb-config-0.2.0-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite-lb-config-0.2.0-1.noarch.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.3-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.3-1.noarch.rpm</a></span></span></p>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt;color:windowtext;text-decoration:none'>apt-get install
+ glite-lb-config</span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>org.glite.deployment.config</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.deployment.config</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.3.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.1.1</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite-%20config-0.3.0-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite-
- config-0.3.0-1.noarch.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-config-1.1.1-3.noarch.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-config-1.1.1-3.noarch.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>glite-lb-client-interface</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.lb.client-interface</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>0.3.1</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.3</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.1-2.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.1-2.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.3-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.3-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>glite-lb-common</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>common</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>0.4.1</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.1.4</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=FR style='font-size:
- 10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-common-0.4.1-2.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-common-0.4.1-2.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-logger</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>logger</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.4.1</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=FR style='font-size:
- 10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-logger-0.4.1-3.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-logger-0.4.1-3.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=IT style='font-size:
+ 8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm"><span
+ lang=FR>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm</span></a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>glite-lb-server</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.server</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>0.6.2</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>1.0.1</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=FR style='font-size:
- 10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-server-0.6.2-4.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-server-0.6.2-4.i386.rpm</a></span></span></p>
+ 8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>server-bones</span></p>
+ </td>
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>ws-interface</span></p>
+ </td>
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-server-bones</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.security.proxyrenewal</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.13</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.13-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.13-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-ws-interface</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.wms-utils.exception</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-ws-interface-0.1.0-0.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-ws-interface-0.1.0-0.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-security-proxyrenewal</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.wms-utils.jobid</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.1</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.1-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-wms-utils-exception</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.security.voms</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.2</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.2.32</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-wms-utils-jobid</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.gridsite.core</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.2</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.1.5</span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm</a></span></span></p>
</td>
</tr>
</table>
<p class=MsoNormal><span lang=EN-US> </span></p>
-<h1>3. Dependencies</h1>
+<h1>4. Dependencies</h1>
-<p class=MsoNormal>The gLite Logging & Bookkeeping Server module has the
-following dependencies:</p>
+<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 1.2.2 module
+has the following dependencies:</p>
<p class=MsoNormal> </p>
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=640
- style='width:480.3pt;border-collapse:collapse;border:none'>
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=621
+ style='width:466.1pt;border-collapse:collapse;border:none'>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>Component name</span></p>
+ 8.0pt'>Component name</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Version</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Version</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border:solid windowtext 1.0pt;
+ <td width=398 valign=top style='width:298.25pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>RPM file name</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>RPM file name</span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span lang=EN-US
+ style='font-size:8.0pt'>gLite Security Utilities</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-security-utils_installer.sh">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-security-utils_installer.sh</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span lang=EN-US
- style='font-size:10.0pt'>gLite Security Utilities</span></p>
+ style='font-size:8.0pt'>gLite </span><span style='font-size:8.0pt'>R-GMA </span><span
+ lang=EN-US style='font-size:8.0pt'>Service Publisher</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.2.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>4.2.0</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041210/installers/glite-security-utils_installer.sh">http://glite.web.cern.ch/glite/packages/I20041210/installers/glite-security-utils_installer.sh</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-rgma-servicetool_installer.sh">http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-rgma-servicetool_installer.sh</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>GPT</span></p>
+ 8.0pt'>GPT</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>VDT 1.2.0</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>VDT 1.2.2</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-<span
- lang=EN-GB>VDT1.2.0rh9</span>-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-<span
+ lang=EN-GB>VDT1.2.2rh9</span>-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>VDT Globus Essentials</span></p>
+ 8.0pt'>VDT Globus Essentials</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>VDT 1.2.0</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>VDT 1.2.2</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-<span
- lang=EN-GB>VDT1.2.0rh9</span>-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-<span
+ lang=EN-GB>VDT1.2.2rh9</span>-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>MySQL-server</span></p>
+ 8.0pt'>MySQL-server</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>4.0.20</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>4.0.20</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
+ style='font-size:8.0pt'><a
href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-<span
lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>MySQL-client</span></p>
+ 8.0pt'>MySQL-client</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>4.0.20</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>4.0.20</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
+ style='font-size:8.0pt'><a
href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-<span
lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>ares</span></p>
+ 8.0pt'>ares</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.1.1</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.1.1</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
+ style='font-size:8.0pt'><a
href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-<span
lang=EN-GB>1.1.1</span>-EGEE.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>myproxy</span></p>
+ 8.0pt'>myproxy</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.14</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.14</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
+ style='font-size:8.0pt'><a
href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-<span
lang=EN-GB>1.14</span>-EGEE.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>perl-Expect.pm</span></p>
+ 8.0pt'>perl-Expect.pm</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.01</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.01</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
+ style='font-size:8.0pt'><a
href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-<span
lang=EN-GB>1.01</span>-9.i386.rpm</a></span></span></p>
</td>
</tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>Java SDK/JRE</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.4.2</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'>http://java.sun.com/j2se/1.4.2/download.html</span></span></p>
+ </td>
+ </tr>
</table>
<p class=MsoNormal> </p>
-<h1>4. Known bugs and issues</h1>
+<h1>5. Known bugs and issues</h1>
<p class=MsoNormal align=left style='text-align:left'>This release has the
following bugs and issues. Bug numbers refer to the gLite Bug Tracking system
<p class=MsoNormal align=left style='text-align:left'> </p>
+<ul style='margin-top:0mm' type=disc>
+ <li class=MsoNormal style='text-align:left'>If the mysql root password is set
+ and it is not specified in the mysql.conf file, the configuration script
+ fails. This bug will be fixed in the next release</li>
+ <li class=MsoNormal style='text-align:left'>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.</li>
+</ul>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<p class=MsoNormal align=left style='text-align:left'>Known open bugs:</p>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
style='border-collapse:collapse;border:none'>
<tr>
- <td width=106 valign=top style='width:79.3pt;border:solid windowtext 1.0pt;
+ <td width=59 valign=top style='width:44.35pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
</td>
- <td width=513 valign=top style='width:385.1pt;border:solid windowtext 1.0pt;
+ <td width=543 valign=top style='width:407.6pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
</td>
+ <td width=17 valign=top style='width:12.45pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
</tr>
<tr>
- <td width=106 valign=top style='width:79.3pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5125"><span
- style='color:windowtext;text-decoration:none'> #5125</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053"><span
+ style='color:windowtext;text-decoration:none'> #7053</span></a></span></p>
</td>
- <td width=513 valign=top style='width:385.1pt;border-top:none;border-left:
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5125"><span
- style='color:windowtext;text-decoration:none'>glite-lb-bkserverd
- start/stop/status displays usage options</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053"><span
+ style='color:windowtext;text-decoration:none'>LB configuration fails if the
+ mysql root pwd is set</span></a> </span></p>
+ </td>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5202"><span
- style='color:windowtext;text-decoration:none'> #5202</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237"><span
+ style='color:windowtext;text-decoration:none'> #7237</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5202"><span
- style='color:windowtext;text-decoration:none'>no RPM provides the
- lb-local-logger daemon - </span></a> </span></p>
- </td>
- </tr>
- <tr>
- <td width=106 valign=top style='width:79.3pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5248"><span
- style='color:windowtext;text-decoration:none'> #5248</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237"><span
+ style='color:windowtext;text-decoration:none'>Intermittent errors with job
+ submission</span></a> </span></p>
</td>
- <td width=513 valign=top style='width:385.1pt;border-top:none;border-left:
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5248"><span
- style='color:windowtext;text-decoration:none'>When running
- "glite-lb-bkserverd start", glite-lb-bkserverd doesn't start in
- background</span></a> </span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5833"><span
- style='color:windowtext;text-decoration:none'> #5833</span></a></span></p>
- </td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5833"><span
- style='color:windowtext;text-decoration:none'>all jobs in SUBMITTED after a
- job storm</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300"><span
+ style='color:windowtext;text-decoration:none'> #7300</span></a></span></p>
</td>
- </tr>
- <tr>
- <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5903"><span
- style='color:windowtext;text-decoration:none'> #5903</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300"><span
+ style='color:windowtext;text-decoration:none'>update of the lb instructions
+ at the end of the installer script </span></a> </span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5903"><span
- style='color:windowtext;text-decoration:none'>glite-lb-bkserverd script gives
- bash: /root/.bashrc: Permission denied error </span></a> </span></p>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5904"><span
- style='color:windowtext;text-decoration:none'> #5904</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305"><span
+ style='color:windowtext;text-decoration:none'> #7305</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5904"><span
- style='color:windowtext;text-decoration:none'>glite-lb-bkserverd does not
- check default location for credentials</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305"><span
+ style='color:windowtext;text-decoration:none'>lb.database.username paramenter
+ in config file</span></a> </span></p>
+ </td>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5926"><span
- style='color:windowtext;text-decoration:none'> #5926</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307"><span
+ style='color:windowtext;text-decoration:none'> #7307</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5926"><span
- style='color:windowtext;text-decoration:none'>Default user should not be used
- in the init.d scripts</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307"><span
+ style='color:windowtext;text-decoration:none'>lb config script does _not_
+ fail if mysql root password is set</span></a> </span></p>
+ </td>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5932"><span
- style='color:windowtext;text-decoration:none'> #5932</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324"><span
+ style='color:windowtext;text-decoration:none'> #7324</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5932"><span
- style='color:windowtext;text-decoration:none'>credential file created in
- /var/tmp is unnecessary</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324"><span
+ style='color:windowtext;text-decoration:none'>lb-bkserver is running with no
+ pid</span></a> </span></p>
+ </td>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5934"><span
- style='color:windowtext;text-decoration:none'> #5934</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389"><span
+ style='color:windowtext;text-decoration:none'> #7389</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=543 valign=top style='width:407.6pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5934"><span
- style='color:windowtext;text-decoration:none'>service start and stop notifications
- are inconsistent for glite-lb-bkserverd init,d script</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389"><span
+ style='color:windowtext;text-decoration:none'>LB server and WMS local logger
+ related issues</span></a> </span></p>
+ </td>
+ <td width=17 valign=top style='width:12.45pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
</table>
-<p class=MsoNormal align=left style='text-align:left'> </p>
-
-<p class=MsoNormal align=left style='text-align:left'>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.</p>
-
-<p class=MsoNormal align=left style='margin:0mm;margin-bottom:.0001pt;
-text-align:left;text-autospace:none'><span lang=EN-US style='font-size:10.0pt;
-font-family:"Courier New"'> </span></p>
-
-<h1>5. Bugs closed since last release</h1>
+<p class=MsoNormal> </p>
-<p class=MsoNormal align=left style='text-align:left'>This release fixes the
-following bugs and issues. Since there are no previous public releases, this
-list refers to the previous development release. Bug numbers refer to the gLite
-Bug Tracking system database hosted on the CERN Savannah system at <a
-href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
- </p>
+<p class=MsoNormal>Bugs fixed in this or previous releases, but not yet officially
+tested:</p>
-<p class=MsoNormal align=left style='text-align:left'> </p>
+<p class=MsoNormal> </p>
<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
style='border-collapse:collapse;border:none'>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=57 valign=top style='width:43.05pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border:solid windowtext 1.0pt;
+ <td width=536 valign=top style='width:401.8pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
</td>
+ <td width=26 valign=top style='width:19.55pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
</tr>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=4627"><span
- style='color:windowtext;text-decoration:none'> #4627</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412"><span
+ style='color:windowtext;text-decoration:none'> #6412</span></a></span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=4627"><span
- style='color:windowtext;text-decoration:none'>no licence found in lb packages</span></a> </span></p>
- </td>
- </tr>
- <tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5236"><span
- style='color:windowtext;text-decoration:none'> #5236</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412"><span
+ style='color:windowtext;text-decoration:none'>--start and --stop options not
+ documented in glite-ce-config.py, glite-lb-config.py</span></a> </span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5236"><span
- style='color:windowtext;text-decoration:none'>LB install/config documentation
- has some errors</span></a> </span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5912"><span
- style='color:windowtext;text-decoration:none'> #5912</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722"><span
+ style='color:windowtext;text-decoration:none'> #6722</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5912"><span
- style='color:windowtext;text-decoration:none'>glite-lb-bkserver daemon looks
- hangs is /tmp/mysql.sock is not present</span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722"><span
+ style='color:windowtext;text-decoration:none'>glite-job-status -all doesn't
+ work</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
<td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5930"><span
- style='color:windowtext;text-decoration:none'> #5930</span></a></span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7151"><span
+ style='color:windowtext;text-decoration:none'> #7151</span></a></span></p>
</td>
- <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
- border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5930"><span
- style='color:windowtext;text-decoration:none'>running start on started
- service is not an error. </span></a> </span></p>
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7151"><span
+ style='color:windowtext;text-decoration:none'>There are conflicts when
+ installing WMS and LB on the same node</span></a> </span></p>
</td>
- </tr>
-</table>
-
-<p class=MsoNormal align=left style='text-align:left'> </p>
-
-<h1>6. Previous Releases</h1>
-
-<h2>6.1. Release 0.1.0</h2>
-
-<h3><span lang=FR>6.1.1. </span><span lang=FR>Release Description</span></h3>
-
-<p class=MsoNormal>This release contains the gLite Logging & Bookkeeping
-Server module v. 0.1.0. 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. </p>
-
-<h3>6.1.2. <span lang=FR>Release</span> contents</h3>
-
-<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 0.1.0 is
-composed of the following gLite components:</p>
-
-<p class=MsoNormal> </p>
-
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=634
- style='width:475.4pt;border-collapse:collapse;border:none'>
- <tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Component name</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border:solid windowtext 1.0pt;
- border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Version</span></p>
- </td>
- <td width=393 valign=top style='width:294.9pt;border:solid windowtext 1.0pt;
- border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>File</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>org.glite.deployment.lb</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7180"><span
+ style='color:windowtext;text-decoration:none'> #7180</span></a></span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-lb_installer.sh">http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-lb_installer.sh</a>
- </span></p>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite-lb-config-0.1.0-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite-lb-config-0.1.0-1.noarch.rpm</a></span></span></p>
- </td>
- </tr>
- <tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>org.glite.deployment.config</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
- padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7180"><span
+ style='color:windowtext;text-decoration:none'>Logging & Bookkeping UI </span></a> </span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite-ce-config-0.1.0-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite-
- config-0.1.0-1.noarch.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>glite-lb-client-interface</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>0.3.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7321"><span
+ style='color:windowtext;text-decoration:none'> #7321</span></a></span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.0-2.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.0-2.i386.rpm</a></span></span></p>
- </td>
- </tr>
- <tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-logger</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
- padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.3.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7321"><span
+ style='color:windowtext;text-decoration:none'>creation of indices fails
+ randomly</span></a> </span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=FR style='font-size:
- 10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-logger-0.3.0-3.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-logger-0.3.0-3.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-common</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.3.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7884"><span
+ style='color:windowtext;text-decoration:none'> #7884</span></a></span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-common-0.3.0-2.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-common-0.3.0-2.i386.rpm</a></span></span></p>
- </td>
- </tr>
- <tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-server</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
- padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.5.2</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7884"><span
+ style='color:windowtext;text-decoration:none'>local header files distributed
+ in RPMs. </span></a> </span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-0.5.2-4.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-0.5.2-4.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-lb-server-bones</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7910"><span
+ style='color:windowtext;text-decoration:none'> #7910</span></a></span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=536 valign=top style='width:401.8pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm</a></span></span></p>
- </td>
- </tr>
- <tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-wms-utils-jobid</span></p>
- </td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
- padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.2</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7910"><span
+ style='color:windowtext;text-decoration:none'>Duplicate apostroph in MySQL
+ calls</span></a> </span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
</td>
</tr>
+</table>
+
+<p class=MsoNormal align=left style='margin:0mm;margin-bottom:.0001pt;
+text-align:left;text-autospace:none'><span lang=EN-US style='font-size:10.0pt;
+font-family:"Courier New"'> </span></p>
+
+<h1>6. Bugs closed since last release</h1>
+
+<p class=MsoNormal align=left style='text-align:left'>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 <a
+href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
+ </p>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
+ style='border-collapse:collapse;border:none'>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-wms-utils-exception</span></p>
+ <td width=87 valign=top style='width:64.95pt;border:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
+ </td>
+ <td width=533 valign=top style='width:399.45pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.2</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5850"><span
+ style='color:windowtext;text-decoration:none'> #5850</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5850"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py has
+ glite.location and globus.location not set in params[]</span></a> </span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
+ </tr>
+ <tr>
+ <td width=87 valign=top style='width:64.95pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5901"><span
+ style='color:windowtext;text-decoration:none'> #5901</span></a></span></p>
+ </td>
+ <td width=533 valign=top style='width:399.45pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5901"><span
+ style='color:windowtext;text-decoration:none'>mysqlaccess command fails with
+ Broken pipe if mysql socket file is in /tmp </span></a> </span></p>
</td>
</tr>
<tr>
- <td width=177 valign=top style='width:133.0pt;border:solid windowtext 1.0pt;
- border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>glite-security-proxyrenewal</span></p>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5908"><span
+ style='color:windowtext;text-decoration:none'> #5908</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5908"><span
+ style='color:windowtext;text-decoration:none'>Environment variables set via
+ the configuration script are not passed to daemon startup scripts</span></a> </span></p>
</td>
- <td width=63 valign=top style='width:47.5pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.1.0</span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6057"><span
+ style='color:windowtext;text-decoration:none'> #6057</span></a></span></p>
</td>
- <td width=393 valign=top style='width:294.9pt;border-top:none;border-left:
- none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6057"><span
+ style='color:windowtext;text-decoration:none'>glite-lb configuration scripts
+ has missing dependency (CGI.pm)</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.0-1.i386.rpm</a></span></span></p>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6075"><span
+ style='color:windowtext;text-decoration:none'> #6075</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6075"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py crashes with
+ KeyError: GLITE_CERT_DIR</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6190"><span
+ style='color:windowtext;text-decoration:none'> #6190</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6190"><span
+ style='color:windowtext;text-decoration:none'>LB local logger doesn't start
+ on the CE node</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6366"><span
+ style='color:windowtext;text-decoration:none'> #6366</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6366"><span
+ style='color:windowtext;text-decoration:none'>LB install script:: Fails but
+ no error reported</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6415"><span
+ style='color:windowtext;text-decoration:none'> #6415</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6415"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-bkserver does not
+ start and blocks execution of glite-lb-config.py</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7296"><span
+ style='color:windowtext;text-decoration:none'> #7296</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7296"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py crashes with
+ a TypeError exception</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7753"><span
+ style='color:windowtext;text-decoration:none'> #7753</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7753"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py fails with
+ an indentation error</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7976"><span
+ style='color:windowtext;text-decoration:none'> #7976</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7976"><span
+ style='color:windowtext;text-decoration:none'>edg-job-status not working with
+ voms proxies</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=8094"><span
+ style='color:windowtext;text-decoration:none'> #8094</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=8094"><span
+ style='color:windowtext;text-decoration:none'>interlogd on the WMS doesn't
+ restart</span></a> </span></p>
</td>
</tr>
</table>
-<p class=MsoNormal><span lang=EN-US> </span></p>
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<b><span style='font-size:12.0pt;font-family:Arial;text-transform:uppercase;
+layout-grid-mode:line'><br clear=all style='page-break-before:always'>
+</span></b>
+
+<h1>7. Previous Releases</h1>
+
+<h2>7.1. Release 1.2.2</h2>
+
+<h3><span lang=FR>7.1.1. </span><span lang=FR>Release Description</span></h3>
+
+<p class=MsoNormal>This release contains the gLite Logging & Bookkeeping
+Server module v. 1.2.2. 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. </p>
+
+<h3><span lang=FR>7.1.2. </span><span lang=FR>Changes in this Release</span></h3>
+
+<p class=MsoNormal>This release introduces the following changes:</p>
+
+<p class=MsoNormal> </p>
+
+<ul style='margin-top:0mm' type=disc>
+ <li class=MsoNormal>Implemented status method</li>
+ <li class=MsoNormal>Added definition of PERL5LIB env var</li>
+ <li class=MsoNormal>Stopping and starting the database before the index
+ creation (just after the database is created and the user granted) to fix
+ access denied error</li>
+ <li class=MsoNormal>Moved creation of indices inside database creation (if
+ database exists indices must not be recreated)</li>
+ <li class=MsoNormal>GLITE_USER parameter is not exposed anymore in the
+ configuration file; instead the module uses the same user parameters as
+ WMS to allow installation on same node</li>
+ <li class=MsoNormal>LB admin tools are now installed in sbin, not in bin</li>
+ <li class=MsoNormal>Bug fixes (see below for the complete lists)</li>
+</ul>
-<h3>6.1.3. <span lang=FR>Dependencies</span></h3>
+<h3>7.1.3. Release contents</h3>
-<p class=MsoNormal>The gLite Logging & Bookkeeping Server module has the
-following dependencies:</p>
+<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 1.2.2 is
+composed of the following gLite components:</p>
<p class=MsoNormal> </p>
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=640
- style='width:480.3pt;border-collapse:collapse;border:none'>
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=621
+ style='width:466.1pt;border-collapse:collapse;border:none'>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>Component name</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Component name</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Version</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Version</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border:solid windowtext 1.0pt;
+ <td width=415 valign=top style='width:310.95pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>RPM file name</span></p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>File</span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span lang=EN-US
- style='font-size:10.0pt'>gLite Security Utilities</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.deployment.lb</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span lang=EN-US style='font-size:10.0pt'>0.2.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.2.2</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-lb_installer.sh">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-lb_installer.sh</a>
+ </span></p>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'>http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-security-utils_installer.sh</span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.2-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.2-1.noarch.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>GPT</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.deployment.config</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>VDT 1.2.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-<span
- lang=EN-GB>VDT1.2.0rh9</span>-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-config-1.0.0-1.noarch.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-config-1.0.0-1.noarch.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>VDT Globus Essentials</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.client-interface</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>VDT 1.2.0</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.2</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-<span
- lang=EN-GB>VDT1.2.0rh9</span>-1.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.2-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.2-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>MySQL-server</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>common</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>4.0.20</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.1.4</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-<span
- lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>MySQL-client</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>logger</span></p>
+ </td>
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=IT style='font-size:
+ 8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm"><span
+ lang=FR>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm</span></a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.server</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>1.0.1</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=FR style='font-size:
+ 8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>server-bones</span></p>
+ </td>
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>4.0.20</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-<span
- lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>ares</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.lb.</span><span
+ lang=EN-US style='font-size:8.0pt'>ws-interface</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.1.1</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-<span
- lang=EN-GB>1.1.1</span>-EGEE.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>myproxy</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.security.proxyrenewal</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.14</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.11</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-<span
- lang=EN-GB>1.14</span>-EGEE.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.11-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.11-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=187 valign=top style='width:140.1pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
- 10.0pt'>perl-Expect.pm</span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.wms-utils.exception</span></p>
</td>
- <td width=66 valign=top style='width:49.6pt;border-top:none;border-left:none;
- border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>1.01</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.1</span></p>
</td>
- <td width=387 valign=top style='width:290.6pt;border-top:none;border-left:
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
<p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
- style='font-size:10.0pt'><a
- href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-<span
- lang=EN-GB>1.01</span>-9.i386.rpm</a></span></span></p>
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm</a></span></span></p>
</td>
</tr>
-</table>
-
-<p class=MsoNormal> </p>
-
-<h3>6.1.4. Known bugs and issues</h3>
-
-<p class=MsoNormal align=left style='text-align:left'>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 <a
-href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
-.</p>
-
-<p class=MsoNormal align=left style='text-align:left'> </p>
-
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
- style='border-collapse:collapse;border:none'>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.glite.wms-utils.jobid</span></p>
+ </td>
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border:solid windowtext 1.0pt;
- border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5125"><span
- style='color:windowtext;text-decoration:none'> #5125</span></a></span></p>
+ <p class=MsoNormal><span lang=FR style='font-size:8.0pt'>org.glite.security.voms</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5125"><span
- style='color:windowtext;text-decoration:none'>glite-lb-bkserverd
- start/stop/status displays usage options</span></a> </span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.2.32</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=153 valign=top style='width:115.0pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5248"><span
- style='color:windowtext;text-decoration:none'> #5248</span></a></span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>org.gridsite.core</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=54 valign=top style='width:40.15pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><span style='font-size:10.0pt'><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5248"><span
- style='color:windowtext;text-decoration:none'>When running
- "glite-lb-bkserverd start", glite-lb-bkserverd doesn't start in
- background</span></a> </span></p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.1.5</span></p>
+ </td>
+ <td width=415 valign=top style='width:310.95pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm</a></span></span></p>
</td>
</tr>
</table>
-<p class=MsoNormal align=left style='text-align:left'> </p>
-
-<p class=MsoNormal align=left style='text-align:left'>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.</p>
-
-<p class=MsoNormal align=left style='margin:0mm;margin-bottom:.0001pt;
-text-align:left;text-autospace:none'><span lang=EN-US style='font-size:10.0pt;
-font-family:"Courier New"'> </span></p>
+<p class=MsoNormal><span lang=EN-US> </span></p>
-<h3>6.1.5. Bugs closed since last release</h3>
+<h3>7.1.4. Dependencies</h3>
-<p class=MsoNormal align=left style='text-align:left'>This release fixes the
-following bugs and issues. Since there are no previous public releases, this
-list refers to the previous development release. Bug numbers refer to the gLite
-Bug Tracking system database hosted on the CERN Savannah system at <a
-href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
- </p>
+<p class=MsoNormal>The gLite Logging & Bookkeeping Server v. 1.2.2 module
+has the following dependencies:</p>
-<p class=MsoNormal align=left style='text-align:left'> </p>
+<p class=MsoNormal> </p>
-<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
- style='border-collapse:collapse;border:none'>
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width=621
+ style='width:466.1pt;border-collapse:collapse;border:none'>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal>Bug number</p>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>Component name</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>Version</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border:solid windowtext 1.0pt;
+ <td width=398 valign=top style='width:298.25pt;border:solid windowtext 1.0pt;
border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal>Description</p>
+ <p class=MsoNormal><span style='font-size:8.0pt'>RPM file name</span></p>
</td>
</tr>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=4627"><span
- style='color:windowtext;text-decoration:none'> #4627</span></a></p>
+ <p class=MsoNormal align=left style='text-align:left'><span lang=EN-US
+ style='font-size:8.0pt'>gLite Security Utilities</span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=4627"><span
- style='color:windowtext;text-decoration:none'>no licence found in lb packages</span></a> </p>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>1.0.0</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-security-utils_installer.sh">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-security-utils_installer.sh</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span lang=EN-US
+ style='font-size:8.0pt'>gLite </span><span style='font-size:8.0pt'>R-GMA </span><span
+ lang=EN-US style='font-size:8.0pt'>Service Publisher</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=EN-US style='font-size:8.0pt'>4.1.5</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-rgma-servicetool_installer.sh">http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-rgma-servicetool_installer.sh</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>GPT</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>VDT 1.2.2</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-<span
+ lang=EN-GB>VDT1.2.2rh9</span>-1.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>VDT Globus Essentials</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>VDT 1.2.2</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-<span
+ lang=EN-GB>VDT1.2.2rh9</span>-1.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>MySQL-server</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>4.0.20</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-<span
+ lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>MySQL-client</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>4.0.20</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-<span
+ lang=EN-GB>4.0.20</span>-0.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>ares</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.1.1</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-<span
+ lang=EN-GB>1.1.1</span>-EGEE.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>myproxy</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.14</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-<span
+ lang=EN-GB>1.14</span>-EGEE.i386.rpm</a></span></span></p>
</td>
</tr>
<tr>
- <td width=121 valign=top style='width:90.45pt;border:solid windowtext 1.0pt;
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5236"><span
- style='color:windowtext;text-decoration:none'> #5236</span></a></p>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>perl-Expect.pm</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.01</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'><a
+ href="http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm">http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-<span
+ lang=EN-GB>1.01</span>-9.i386.rpm</a></span></span></p>
+ </td>
+ </tr>
+ <tr>
+ <td width=158 valign=top style='width:118.6pt;border:solid windowtext 1.0pt;
+ border-top:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal align=left style='text-align:left'><span style='font-size:
+ 8.0pt'>Java SDK/JRE</span></p>
+ </td>
+ <td width=66 valign=top style='width:49.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:8.0pt'>1.4.2</span></p>
+ </td>
+ <td width=398 valign=top style='width:298.25pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span class=MsoHyperlink><span lang=EN-US
+ style='font-size:8.0pt'>http://java.sun.com/j2se/1.4.2/download.html</span></span></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal> </p>
+
+<h3>7.1.5. Known bugs and issues</h3>
+
+<p class=MsoNormal align=left style='text-align:left'>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 <a
+href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
+.</p>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<ul style='margin-top:0mm' type=disc>
+ <li class=MsoNormal style='text-align:left'>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.</li>
+</ul>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<p class=MsoNormal align=left style='text-align:left'>Known open bugs:</p>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
+ style='border-collapse:collapse;border:none'>
+ <tr>
+ <td width=59 valign=top style='width:44.05pt;border:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
+ </td>
+ <td width=534 valign=top style='width:400.8pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412"><span
+ style='color:windowtext;text-decoration:none'> #6412</span></a></span></p>
+ </td>
+ <td width=534 valign=top style='width:400.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412"><span
+ style='color:windowtext;text-decoration:none'>--start and --stop options not
+ documented in glite-ce-config.py, glite-lb-config.py</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053"><span
+ style='color:windowtext;text-decoration:none'> #7053</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053"><span
+ style='color:windowtext;text-decoration:none'>LB configuration fails if the
+ mysql root pwd is set</span></a> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7180"><span
+ style='color:windowtext;text-decoration:none'> #7180</span></a></span></p>
+ </td>
+ <td width=534 valign=top style='width:400.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7180"><span
+ style='color:windowtext;text-decoration:none'>Logging & Bookkeping UI </span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237"><span
+ style='color:windowtext;text-decoration:none'> #7237</span></a></span></p>
+ </td>
+ <td width=534 valign=top style='width:400.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237"><span
+ style='color:windowtext;text-decoration:none'>Intermittent errors with job
+ submission</span></a> </span></p>
</td>
- <td width=499 valign=top style='width:373.95pt;border-top:none;border-left:
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
padding:0mm 5.4pt 0mm 5.4pt'>
- <p class=MsoNormal><a
- href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5236"><span
- style='color:windowtext;text-decoration:none'>LB install/config documentation
- has some errors</span></a> </p>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300"><span
+ style='color:windowtext;text-decoration:none'> #7300</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300"><span
+ style='color:windowtext;text-decoration:none'>update of the lb instructions
+ at the end of the installer script </span></a> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305"><span
+ style='color:windowtext;text-decoration:none'> #7305</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305"><span
+ lang=IT style='color:windowtext;text-decoration:none'>lb.database.username
+ paramenter in config file</span></a></span><span lang=IT style='font-size:
+ 10.0pt'> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span lang=IT style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307"><span
+ lang=IT style='color:windowtext;text-decoration:none'> </span><span
+ style='color:windowtext;text-decoration:none'>#7307</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307"><span
+ style='color:windowtext;text-decoration:none'>lb config script does _not_
+ fail if mysql root password is set</span></a> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7321"><span
+ style='color:windowtext;text-decoration:none'> #7321</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7321"><span
+ style='color:windowtext;text-decoration:none'>creation of indices fails
+ randomly</span></a> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324"><span
+ style='color:windowtext;text-decoration:none'> #7324</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324"><span
+ style='color:windowtext;text-decoration:none'>lb-bkserver is running with no
+ pid</span></a> </span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389"><span
+ style='color:windowtext;text-decoration:none'> #7389</span></a></span></p>
+ </td>
+ <td width=534 valign=top style='width:400.8pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389"><span
+ style='color:windowtext;text-decoration:none'>LB server and WMS local logger
+ related issues</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal> </p>
+
+<p class=MsoNormal>Bugs fixed in this or previous releases, but not yet
+officially tested:</p>
+
+<p class=MsoNormal> </p>
+
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
+ style='border-collapse:collapse;border:none'>
+ <tr>
+ <td width=58 valign=top style='width:43.3pt;border:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5850"><span
+ style='color:windowtext;text-decoration:none'> #5850</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5850"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py has
+ glite.location and globus.location not set in params[]</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5908"><span
+ style='color:windowtext;text-decoration:none'> #5908</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5908"><span
+ style='color:windowtext;text-decoration:none'>Environment variables set via
+ the configuration script are not passed to daemon startup scripts</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6075"><span
+ style='color:windowtext;text-decoration:none'> #6075</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6075"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py crashes with
+ KeyError: GLITE_CERT_DIR</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6366"><span
+ style='color:windowtext;text-decoration:none'> #6366</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6366"><span
+ style='color:windowtext;text-decoration:none'>LB install script:: Fails but
+ no error reported</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6415"><span
+ style='color:windowtext;text-decoration:none'> #6415</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6415"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-bkserver does not
+ start and blocks execution of glite-lb-config.py</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6689"><span
+ style='color:windowtext;text-decoration:none'> #6689</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6689"><span
+ style='color:windowtext;text-decoration:none'>glite-proxy-renewd starts the
+ daemon glite-proxy-renewd as GLITE_USER which is glite-lb i.e. wrong</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722"><span
+ style='color:windowtext;text-decoration:none'> #6722</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722"><span
+ style='color:windowtext;text-decoration:none'>glite-job-status -all doesn't
+ work</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7296"><span
+ style='color:windowtext;text-decoration:none'> #7296</span></a></span></p>
+ </td>
+ <td width=535 valign=top style='width:401.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7296"><span
+ style='color:windowtext;text-decoration:none'>glite-lb-config.py crashes with
+ a TypeError exception</span></a> </span></p>
+ </td>
+ <td width=26 valign=top style='width:19.55pt;border-top:none;border-left:
+ none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal align=left style='margin:0mm;margin-bottom:.0001pt;
+text-align:left;text-autospace:none'><span lang=EN-US style='font-size:10.0pt;
+font-family:"Courier New"'> </span></p>
+
+<h3>7.1.6. Bugs closed since last release</h3>
+
+<p class=MsoNormal align=left style='text-align:left'>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 <a
+href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bugs/?group=jra1mdw</a>
+ </p>
+
+<p class=MsoNormal align=left style='text-align:left'> </p>
+
+<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
+ style='border-collapse:collapse;border:none'>
+ <tr>
+ <td width=103 valign=top style='width:77.45pt;border:solid windowtext 1.0pt;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Bug number</span></p>
+ </td>
+ <td width=516 valign=top style='width:386.95pt;border:solid windowtext 1.0pt;
+ border-left:none;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'>Description</span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5833"><span
+ style='color:windowtext;text-decoration:none'> #5833</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5833"><span
+ style='color:windowtext;text-decoration:none'>all jobs in SUBMITTED after a
+ job storm</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5897"><span
+ style='color:windowtext;text-decoration:none'> #5897</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5897"><span
+ style='color:windowtext;text-decoration:none'>I20041203 LB installation
+ script has a missing dependency </span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5910"><span
+ style='color:windowtext;text-decoration:none'> #5910</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5910"><span
+ style='color:windowtext;text-decoration:none'>glite-lb configuration scripts
+ don't set GLITE_USER environment</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5925"><span
+ style='color:windowtext;text-decoration:none'> #5925</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=5925"><span
+ style='color:windowtext;text-decoration:none'>Running glite-lb script removes
+ mysql.sock file </span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6416"><span
+ style='color:windowtext;text-decoration:none'> #6416</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6416"><span
+ style='color:windowtext;text-decoration:none'>the BKserver on the LB machine
+ needs a symlink and the script doesn't check for it</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7032"><span
+ style='color:windowtext;text-decoration:none'> #7032</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7032"><span
+ style='color:windowtext;text-decoration:none'>The LB installer fails with an
+ RPM not found message</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7152"><span
+ style='color:windowtext;text-decoration:none'> #7152</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7152"><span
+ style='color:windowtext;text-decoration:none'>The LB installer tries to
+ install gridsite with a wrong rpm name</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7351"><span
+ style='color:windowtext;text-decoration:none'> #7351</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7351"><span
+ style='color:windowtext;text-decoration:none'>Star/restart of LB services </span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7401"><span
+ style='color:windowtext;text-decoration:none'> #7401</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7401"><span
+ style='color:windowtext;text-decoration:none'>The first time the LB config
+ script is run it fails creating the db indices</span></a> </span></p>
+ </td>
+ </tr>
+ <tr>
+ <td valign=top style='border:solid windowtext 1.0pt;border-top:none;
+ padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7423"><span
+ style='color:windowtext;text-decoration:none'> #7423</span></a></span></p>
+ </td>
+ <td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;
+ border-right:solid windowtext 1.0pt;padding:0mm 5.4pt 0mm 5.4pt'>
+ <p class=MsoNormal><span style='font-size:10.0pt'><a
+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7423"><span
+ style='color:windowtext;text-decoration:none'>'/etc/rc.d/init.d/gLite status'
+ not working correctly in LB</span></a> </span></p>
</td>
</tr>
</table>
--- /dev/null
+#Fri Jul 22 11:14:22 CEST 2005
+module.build=246
<service name="glite-lb-service">
<components>
<component name="glite-config"
- version="0.3.0"
- age="1"
- build="1"
+ version="@org.glite.deployment.config.info.version@"
+ age="@org.glite.deployment.config.info.age@"
+ build="@org.glite.deployment.config.info.build@"
arch="noarch"/>
<component name="glite-lb-config"
arch="noarch"/>
<component name="glite-lb-client-interface"
- version="@org.glite.lb.client-interface.version@"
- age="@org.glite.lb.client-interface.age@"
- build="@org.glite.lb.client-interface.build@"
+ version="@org.glite.lb.client-interface.info.version@"
+ age="@org.glite.lb.client-interface.info.age@"
+ build="@org.glite.lb.client-interface.info.build@"
arch="i386"/>
<component name="glite-lb-ws-interface"
- version="@org.glite.lb.ws-interface.version@"
- age="@org.glite.lb.ws-interface.age@"
- build="@org.glite.lb.ws-interface.build@"
+ version="@org.glite.lb.ws-interface.info.version@"
+ age="@org.glite.lb.ws-interface.info.age@"
+ build="@org.glite.lb.ws-interface.info.build@"
arch="i386"/>
<component name="glite-lb-logger"
- version="@org.glite.lb.logger.version@"
- age="@org.glite.lb.logger.age@"
- build="@org.glite.lb.logger.build@"
+ version="@org.glite.lb.logger.info.version@"
+ age="@org.glite.lb.logger.info.age@"
+ build="@org.glite.lb.logger.info.build@"
arch="i386"/>
<component name="glite-lb-common"
- version="@org.glite.lb.common.version@"
- age="@org.glite.lb.common.age@"
- build="@org.glite.lb.common.build@"
+ version="@org.glite.lb.common.info.version@"
+ age="@org.glite.lb.common.info.age@"
+ build="@org.glite.lb.common.info.build@"
arch="i386"/>
<component name="glite-lb-server"
- version="@org.glite.lb.server.version@"
- age="@org.glite.lb.server.age@"
- build="@org.glite.lb.server.build@"
+ version="@org.glite.lb.server.info.version@"
+ age="@org.glite.lb.server.info.age@"
+ build="@org.glite.lb.server.info.build@"
arch="i386"/>
<component name="glite-lb-server-bones"
- version="@org.glite.lb.server-bones.version@"
- age="@org.glite.lb.server-bones.age@"
- build="@org.glite.lb.server-bones.build@"
+ version="@org.glite.lb.server-bones.info.version@"
+ age="@org.glite.lb.server-bones.info.age@"
+ build="@org.glite.lb.server-bones.info.build@"
arch="i386"/>
<component name="glite-wms-utils-jobid"
- version="@org.glite.wms-utils.jobid.version@"
- age="@org.glite.wms-utils.jobid.age@"
- build="@org.glite.wms-utils.jobid.build@"
+ version="@org.glite.wms-utils.jobid.info.version@"
+ age="@org.glite.wms-utils.jobid.info.age@"
+ build="@org.glite.wms-utils.jobid.info.build@"
arch="i386"/>
<component name="glite-wms-utils-exception"
- version="@org.glite.wms-utils.exception.version@"
- age="@org.glite.wms-utils.exception.age@"
- build="@org.glite.wms-utils.exception.build@"
- arch="i386"/>
-
- <component name="glite-security-proxyrenewal"
- version="@org.glite.security.proxyrenewal.version@"
- age="@org.glite.security.proxyrenewal.age@"
- build="@org.glite.security.proxyrenewal.build@"
+ version="@org.glite.wms-utils.exception.info.version@"
+ age="@org.glite.wms-utils.exception.info.age@"
+ build="@org.glite.wms-utils.exception.info.build@"
arch="i386"/>
+ <component name="glite-security-voms-api-c"
+ version="@org.glite.security.voms-api-c.info.version@"
+ age="@org.glite.security.voms-api-c.info.age@"
+ build="@org.glite.security.voms-api-c.info.build@"
+ arch="i386"/>
+
+ <component name="gridsite"
+ version="@org.gridsite.core.info.version@"
+ age="@org.gridsite.core.info.age@"
+ build="@org.gridsite.core.info.build@"
+ arch="i386"/>
</components>
<dependencies>
- <external name="MySQL-server"
- version="4.0.20"
- age="0"
- arch="i386"/>
- <external name="MySQL-client"
- version="4.0.20"
- age="0"
- arch="i386"/>
- <external name="ares"
- version="1.1.1"
- age="EGEE"
- arch="i386"/>
- <external name="vdt_globus_essentials"
- version="VDT1.2.0rh9"
- age="1"
- arch="i386"/>
- <external name="gpt"
- version="VDT1.2.0rh9"
- age="1"
- arch="i386"/>
- <external name="myproxy"
- version="1.14"
- age="EGEE"
- arch="i386"/>
- <external name="perl-Expect.pm"
- version="1.01"
- age="9"
- arch="i386"/>
+ <external name="@ext.mysql-server.rpm.name@"
+ version="@ext.mysql-server.version@"
+ age="@ext.mysql-server.rpm.age@"
+ arch="@ext.mysql-server.platform@"/>
+ <external name="@ext.mysql-client.rpm.name@"
+ version="@ext.mysql-client.version@"
+ age="@ext.mysql-client.rpm.age@"
+ arch="@ext.mysql-client.platform@"/>
+ <external name="@ext.ares.rpm.name@"
+ version="@ext.ares.version@"
+ age="@ext.ares.rpm.age@"
+ arch="@ext.ares.platform@"/>
+ <external name="@ext.globus-essentials.rpm.name@"
+ version="@ext.globus-essentials.rpm.version@"
+ age="@ext.globus-essentials.rpm.age@"
+ arch="@ext.globus-essentials.platform@"/>
+ <external name="@ext.gpt.rpm.name@"
+ version="@ext.gpt.rpm.version@"
+ age="@ext.gpt.rpm.age@"
+ arch="@ext.gpt.rpm.platform@"/>
+ <external name="@ext.myproxy.rpm.name@"
+ version="@ext.myproxy.rpm.version@"
+ age="@ext.myproxy.rpm.age@"
+ arch="@ext.myproxy.rpm.platform@"/>
+ <external name="@ext.perl-expect-pm.rpm.name@"
+ version="@ext.perl-expect-pm.version@"
+ age="@ext.perl-expect-pm.rpm.age@"
+ arch="@ext.perl-expect-pm.platform@"/>
</dependencies>
</service>
+
+ <!-- Security Utilities -->
+ <service name="glite-security-utils">
+ <subservice name="glite-security-utils"/>
+ </service>
+ <!-- RGMA servicetool -->
+ <service name="glite-rgma-servicetool">
+ <subservice name="glite-rgma-servicetool"/>
+ </service>
</services>
<dependencies>
- <!-- glite service tool -->
</dependencies>
</node>
+++ /dev/null
-Summary:gLite LB node installation package
-Name:glite-lb-config
-Version:@MODULE.VERSION@
-Release:@MODULE.BUILD@
-Copyright:Open Source EGEE License
-Vendor:EU EGEE project
-Group:System/Application
-Prefix:/opt/glite
-BuildArch:noarch
-BuildRoot:%{_builddir}/%{name}-%{version}
-Requires: glite-lb-common, glite-lb-logger, glite-lb-server, glite-security-proxyrenewal, glite-lb-client-interface, MySQL-server, MySQL-client, expat, ares,vdt_globus_essentials, glite-wms-utils-jobid, glite-wms-utils-exception, myproxy, perl-Expect.pm
-
-AutoReqProv:no
-Source:glite-lb.tar.gz
-%define debug_package %{nil}
-
-%description
-gLite Logging and Bookkeeping node installation package
-
-%prep
-
-
-%setup -c
-
-%build
-
-
-%install
-
-
-%clean
-
-%pre
-%post
-#echo "post install script"
-%preun
-%postun
-%files
-%attr(755,root,root) %{prefix}/etc/config/scripts/glite-lb-config.py
-%attr(644,root,root) %{prefix}/etc/config/templates/glite-lb.cfg.xml
-%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.doc
-%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.pdf
-%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.html
-
-%changelog
-
omit-xml-declaration="yes"/>
<!-- Definition of variables and parameters -->
+ <xsl:param name="installers"/>
<xsl:param name="repository"/>
<xsl:param name="ext-repository"/>
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
<xsl:for-each select="node/services/service">
+ # Download <xsl:value-of select="@name"/> scripts from repository
+ <xsl:for-each select=".">
+ <xsl:apply-templates select="subservice">
+ <xsl:with-param name="install">true</xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:for-each>
+
+
# Download <xsl:value-of select="@name"/> dependencies RPMS from repository
<xsl:for-each select="dependencies">
<xsl:apply-templates>
</xsl:for-each>
</xsl:for-each>
+
+ # Download and install subservices
+ parseScriptList
+
# Install all RPMS
echo
echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo
parseRPMList
- rpm -Uvh $RPMLIST
- echo
- echo Done!
+ 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 file /opt/glite/etc/config/glite-lb.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
+ 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 or to the gLite web site \(http:\/\/www.glite.org\)
- echo Please report problems and comments to the gLite Team at project-eu-egee-middleware-integration-support@cern.ch
+ 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 project-eu-egee-glite-bugs@cern.ch
cd ..
}
echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo
rpm -ev $RPMLIST
- echo
- echo Done!
+ 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
}
###############################################################################
exit 0
</xsl:template>
+ <xsl:template name="subservices" match="subservice">
+ <xsl:param name="install"/>
+ <xsl:variable name="package"><xsl:value-of select="@name"/>_installer.sh</xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$install = 'true'">
+wget -N --non-verbose <xsl:value-of select="$installers"/><xsl:value-of select="$package"/>
+if [ ! -f "<xsl:value-of select="$package"/>" ]
+then
+ echo
+ echo ERROR: <xsl:value-of select="$package"/> could not be downloaded!
+ exit 1
+fi
+chmod u+x <xsl:value-of select="$package"/>
+SCRIPTLIST="$SCRIPTLIST ./<xsl:value-of select="$package"/>"
+ </xsl:when>
+ <xsl:otherwise>
+SCRIPTLISTUn="$SCRIPTLISTUn ./<xsl:value-of select="$package"/> -u "
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
<xsl:template name="dependencies" match="external">
<xsl:param name="install"/>
<xsl:variable name="package"><xsl:value-of select="@name"/>-<xsl:value-of select="@version"/>-<xsl:value-of select="@age"/>.<xsl:value-of select="@arch"/>.rpm</xsl:variable>
Revision history:
$Log$
+ Revision 1.1 2004/10/06 09:19:24 dimeglio
+ First version of this file
+
-->
<project name="gLite LB Server Deployment Unit common properties">
Define extra properties here ...
====================================================== -->
+ <property name="build.package.summary" value="gLite Logging and Bookkeeping node configuration files" />
+ <property name="build.package.description" value="gLite Logging and Bookkeeping node configuration files" />
+ <property name="build.package.files" value="
+%attr(755,root,root) %{prefix}/etc/config/scripts/glite-lb-config.py\n
+%attr(644,root,root) %{prefix}/etc/config/templates/glite-lb.cfg.xml\n
+%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.doc\n
+%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.pdf\n
+%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.html\n"
+ />
+
</project>
-#Thu Dec 09 08:14:11 CET 2004
-module.version=0.2.0
-module.build=68
-module.age=1
+
+module.version = 2.0.0
+module.age = 1
+
\ No newline at end of file
+++ /dev/null
-# defaults
-top_srcdir=.
-builddir=build
-top_builddir=${top_srcdir}/${builddir}
-stagedir=.
-distdir=.
-globalprefix=glite
-lbprefix=lb
-package=glite-jp-common
-version=0.0.0
-PREFIX=/opt/glite
-
-glite_location=/opt/glite
-globus_prefix=/opt/globus
-nothrflavour=gcc32
-thrflavour=gcc32pthr
-expat_prefix=/opt/expat
-ares_prefix=/opt/ares
-gsoap_prefix=/software/gsoap-2.6
-
-CC=gcc
-
--include Makefile.inc
-
-
-VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/project:${jpproject}
-
-GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour}
-
-
-DEBUG:=-g -O0
-CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${stagedir}/include \
- ${GLOBUSINC}
-
-LINK:=libtool --mode=link ${CC} ${LDFLAGS} -rpath ${stagedir}/lib
-LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS}
-INSTALL:=libtool --mode=install install
-COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
-
-HDRS:=types.h context.h strmd5.h
-
-SRCS:=context.c strmd5.c
-OBJS:=${SRCS:.c=.lo}
-
-commonlib:= libglite_jp_common.la
-
-default all: compile
-
-compile: ${commonlib}
-
-${commonlib}: ${OBJS}
- ${LINK} -o $@ ${OBJS}
-
-check:
- -echo nothing yet
-
-doc:
-
-stage: compile
- $(MAKE) install PREFIX=${stagedir}
-
-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} ${PREFIX}/lib
-
-dist: distsrc distbin
-
-# FIXME: just copied from LB
-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
-
-clean:
-
-%.lo: %.c
- ${COMPILE} -o $@ -c $<
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Build file for the GLite JP Common module
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.1.1.1 2004/10/15 09:49:02 akrenek
--->
-
-<project name="common" default="dist">
-
- <!-- =========================================
- Builds the GLite JP Primary Module
- ========================================= -->
-
- <!-- =========================================
- Import properties (order is important)
- ========================================= -->
-
- <!-- import baseline & user properties -->
- <import file="../org.glite/project/baseline.properties.xml" />
-
- <!-- import component build properties,
- component properties &
- component common properties -->
- <import file="./project/properties.xml"/>
-
- <!-- import subsystem build properties,
- subsystem properties &
- subsystem common properties -->
- <import file="${subsystem.properties.file}"/>
-
- <!-- import global build properties &
- global properties -->
- <import file="${global.properties.file}" />
-
- <!-- =========================================
- Load dependency property files (order is important)
- ========================================= -->
- <property file="${user.dependencies.file}"/>
- <property file="${component.dependencies.file}" />
- <property file="${subsystem.dependencies.file}" />
- <property file="${global.dependencies.file}"/>
-
- <!-- =========================================
- Load configure options (order is important)
- ========================================= -->
- <import file="${global.configure.options.file}"/>
- <import file="${component.configure.options.file}"/>
-
- <!-- =========================================
- Import task definitions (order is important)
- ========================================= -->
- <import file="${subsystem.taskdefs.file}" />
- <import file="${global.taskdefs.file}" />
-
- <!-- =========================================
- Load common targets
- ========================================= -->
- <import file="${global.targets-simple_make.file}" />
-
- <!-- =========================================
- Load version file
- ========================================= -->
- <property file="${module.version.file}"/>
-
- <!-- ==============================================
- Local private targets
- ============================================== -->
-
- <target name="localinit"
- description="Module specific initialization tasks">
-
- <antcall target="lbmakefiles" />
- </target>
-
- <target name="localcompile"
- description="Module specific compile tasks">
- </target>
-
- <target name="localclean"
- description="Module specific cleaning tasks">
- </target>
-
-</project>
+++ /dev/null
-#ifndef __GLITE_JP_CONTEXT
-#define __GLITE_JP_CONTEXT
-
-int glite_jp_init_context(glite_jp_context_t *);
-void glite_jp_free_query_rec(glite_jp_query_rec_t *);
-
-char *glite_jp_peer_name(glite_jp_context_t);
-char *glite_jp_error_chain(glite_jp_context_t);
-
-int glite_jp_stack_error(glite_jp_context_t, const glite_jp_error_t *);
-int glite_jp_clear_error(glite_jp_context_t);
-
-int glite_jp_add_deferred(glite_jp_context_t,int (*)(glite_jp_context_t,void *),void *);
-int glite_jp_run_deferred(glite_jp_context_t);
-
-
-#endif
+++ /dev/null
-#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 */
+++ /dev/null
-#ifndef __GLITE_JP_TYPES
-#define __GLITE_JP_TYPES
-
-#include <sys/time.h>
-
-typedef struct _glite_jp_error_t {
- int code;
- char *desc;
- char *source;
- struct _glite_jp_error_t *reason;
-} glite_jp_error_t;
-
-typedef struct _glite_jp_context {
- glite_jp_error_t *error;
- int (**deferred_func)(struct _glite_jp_context *,void *);
- void **deferred_arg;
- void *feeds;
- struct soap *other_soap;
-} *glite_jp_context_t;
-
-typedef enum {
- GLITE_JP_FILECLASS_UNDEF,
- GLITE_JP_FILECLASS_INPUT,
- GLITE_JP_FILECLASS_OUTPUT,
- GLITE_JP_FILECLASS_LBLOG,
- GLITE_JP_FILECLASS_TAGS,
- GLITE_JP_FILECLASS__LAST
-} glite_jp_fileclass_t;
-
-typedef struct {
- char *name;
- int sequence;
- time_t timestamp;
- int binary;
- size_t size;
- char *value;
-} glite_jp_tagval_t;
-
-typedef enum {
- GLITE_JP_ATTR_UNDEF,
- GLITE_JP_ATTR_OWNER,
- GLITE_JP_ATTR_TIME,
- GLITE_JP_ATTR_TAG,
- GLITE_JP_ATTR__LAST
-} glite_jp_attrtype_t;
-
-typedef struct {
- glite_jp_attrtype_t type;
- char *name;
-} glite_jp_attr_t;
-
-typedef struct {
- glite_jp_attr_t attr;
- union {
- char *s;
- int i;
- struct timeval time;
- glite_jp_tagval_t tag;
- } value;
-} glite_jp_attrval_t;
-
-
-typedef enum {
- GLITE_JP_QUERYOP_UNDEF,
- GLITE_JP_QUERYOP_EQUAL,
- GLITE_JP_QUERYOP_UNEQUAL,
- GLITE_JP_QUERYOP_LESS,
- GLITE_JP_QUERYOP_GREATER,
- GLITE_JP_QUERYOP_WITHIN,
- GLITE_JP_QUERYOP__LAST,
-} glite_jp_queryop_t;
-
-typedef struct {
- glite_jp_attr_t attr;
- glite_jp_queryop_t op;
- union _glite_jp_query_rec_val {
- char *s;
- int i;
- struct timeval time;
- } value,value2;
-} glite_jp_query_rec_t;
-
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Configuration options for the gLite JP Common module
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.2 2004/11/22 13:36:42 dimeglio
- First version of this file
-
- Revision 1.1.1.1 2004/10/15 09:49:02 akrenek
--->
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
- <project name="JP Common configuration options">
- <target name="lbmakefiles">
- <exec executable="ln" failonerror="true">
- <arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
- </exec>
- <echo file="${module.build.dir}/Makefile.inc">
-top_srcdir=..
-builddir=build
-stagedir=${stage.abs.dir}
-distdir=${dist.dir}
-globalprefix=${global.prefix}
-jpprefix=${subsystem.prefix}
-package=${module.package.name}
-PREFIX=${install.dir}
-version=${module.version}
-glite_location=${with.glite.location}
-globus_prefix=${with.globus.prefix}
-expat_prefix=${with.expat.prefix}
-gsoap_prefix=${with.gsoap.prefix}
-ares_prefix=${with.ares.prefix}
-thrflavour=${with.globus.thr.flavor}
-nothrflavour=${with.globus.nothr.flavor}
-cppunit=${with.cppunit.prefix}
-jpproject=${subsystem.project.dir}
-project=${component.project.dir}
- </echo>
- </target>
- </project>
+++ /dev/null
-#Fri Dec 10 13:33:53 CET 2004
-module.version=0.1.0
-module.build=3
-module.age=1
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-
-#include "types.h"
-#include "context.h"
-
-int glite_jp_init_context(glite_jp_context_t *ctx)
-{
- *ctx = calloc(1,sizeof **ctx);
-}
-
-char *glite_jp_peer_name(glite_jp_context_t ctx)
-{
- return strdup("unknown");
-}
-
-char *glite_jp_error_chain(glite_jp_context_t ctx)
-{
- char *ret = NULL,indent[300] = "";
- int len = 0,add;
- char buf[2000];
-
- glite_jp_error_t *ep = ctx->error;
-
- do {
- add = snprintf(buf,sizeof buf,"%s%s: %s (%s)\n",
- indent,
- ep->source,
- strerror(ep->code),
- ep->desc ? ep->desc : "");
- ret = realloc(ret,len + add + 1);
- strncpy(ret + len,buf,add); ret[len += add] = 0;
- strcat(indent," ");
- } while (ep = ep->reason);
-
- return ret;
-}
-
-int glite_jp_stack_error(glite_jp_context_t ctx, const glite_jp_error_t *err)
-{
- glite_jp_error_t *reason = ctx->error;
-
- ctx->error = calloc(1,sizeof *ctx->error);
- ctx->error->code = err->code;
- ctx->error->desc = err->desc ? strdup(err->desc) : NULL;
- ctx->error->source = err->source ? strdup(err->source) : NULL;
- ctx->error->reason = reason;
-
- return err->code;
-}
-
-int glite_jp_clear_error(glite_jp_context_t ctx)
-{
- glite_jp_error_t *e = ctx->error, *r;
-
- while (e) {
- r = e->reason;
- free(e->source);
- free(e->desc);
- free(e);
- e = r;
- }
- ctx->error = NULL;
- return 0;
-}
-
-
-void glite_jp_free_query_rec(glite_jp_query_rec_t *q)
-{
- free(q->attr.name); q->attr.name = NULL;
- switch (q->attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TAG:
- free(q->value.s); q->value.s = NULL;
- if (q->op == GLITE_JP_QUERYOP_WITHIN) {
- free(q->value2.s);
- q->value2.s = NULL;
- }
- break;
- default: break;
- }
-}
-
-int glite_jp_attr_copy(glite_jp_attr_t *dst,const glite_jp_attr_t *src)
-{
- dst->name = src->name ? strdup(src->name) : NULL;
- dst->type = src->type;
- return 0;
-}
-
-int glite_jp_queryrec_copy(glite_jp_query_rec_t *dst, const glite_jp_query_rec_t *src)
-{
- glite_jp_attr_copy(&dst->attr,&src->attr);
- dst->op = src->op;
- switch (src->attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TAG:
- dst->value.s = strdup(src->value.s);
- if (dst->op == GLITE_JP_QUERYOP_WITHIN)
- dst->value2.s = strdup(src->value2.s);
- break;
- case GLITE_JP_ATTR_TIME:
- memcpy(&dst->value.time,&src->value.time,sizeof dst->value.time);
- if (dst->op == GLITE_JP_QUERYOP_WITHIN)
- memcpy(&dst->value2.time,&src->value2.time,sizeof dst->value2.time);
- break;
- }
- return 0;
-}
-
-int glite_jp_run_deferred(glite_jp_context_t ctx)
-{
- int i,cnt,ret;
-
- if (!ctx->deferred_func) return 0;
-
- glite_jp_clear_error(ctx);
- for (cnt=0;ctx->deferred_func[cnt];cnt++);
- for (i=0; i<cnt; i++) {
- if (ret = (*ctx->deferred_func)(ctx,*ctx->deferred_arg)) {
- glite_jp_error_t err;
- char desc[100];
-
- sprintf(desc,"calling func #%d, %p",i,*ctx->deferred_func);
- err.code = ret;
- err.desc = desc;
- err.source = "glite_jp_run_deferred()";
-
- glite_jp_stack_error(ctx,&err);
- return ret;
- }
- else {
- memmove(ctx->deferred_func,ctx->deferred_func+1,
- (cnt-i) * sizeof *ctx->deferred_func);
- memmove(ctx->deferred_arg,ctx->deferred_arg+1,
- (cnt-i) * sizeof *ctx->deferred_arg);
- }
- }
- free(ctx->deferred_func); ctx->deferred_func = NULL;
- free(ctx->deferred_arg); ctx->deferred_arg = NULL;
- return 0;
-}
-
-int glite_jp_add_deferred(
- glite_jp_context_t ctx,
- int (*func)(glite_jp_context_t, void *),
- void *arg
-)
-{
- int (**v)(glite_jp_context_t, void *) = ctx->deferred_func;
- int i;
-
- for (i=0; v && *v; i++);
-
- ctx->deferred_func = realloc(ctx->deferred_func, (i+1) * sizeof *ctx->deferred_func);
- ctx->deferred_func[i] = func;
- ctx->deferred_func[i+1] = NULL;
-
- ctx->deferred_arg = realloc(ctx->deferred_arg,(i+1) * sizeof *ctx->deferred_arg);
- ctx->deferred_arg[i] = arg;
- ctx->deferred_arg[i+1] = NULL;
-
- return 0;
-}
+++ /dev/null
-#include <openssl/md5.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "strmd5.h"
-
-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);
-}
+++ /dev/null
-# defaults
-top_srcdir=.
-builddir=build
-top_builddir=${top_srcdir}/${builddir}
-stagedir=.
-distdir=.
-globalprefix=glite
-lbprefix=lb
-package=glite-lb-server
-version=0.0.0
-PREFIX=/opt/glite
-
-glite_location=/opt/glite
-globus_prefix=/opt/globus
-nothrflavour=gcc32
-thrflavour=gcc32pthr
-expat_prefix=/opt/expat
-ares_prefix=/opt/ares
-gsoap_prefix=/software/gsoap-2.6
-
-CC=gcc
-
--include Makefile.inc
-
-
-VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${jpproject}
-
-GLOBUS_LIBS:=-L${globus_prefix}/lib \
- -lglobus_common_${nothrflavour} \
- -lglobus_gssapi_gsi_${nothrflavour}
-
-DEBUG:=-g -O0 -DDEBUG
-
-CFLAGS:=${DEBUG} -I. -I${gsoap_prefix}/include -I${stagedir}/include
-LDFLAGS:=-L${stagedir}/lib
-
-LINK:=libtool --mode=link ${CC} ${LDFLAGS}
-LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS}
-INSTALL:=libtool --mode=install install
-
-
-daemon:=glite-jp-indexd
-example:=jpis-test
-soap_prefix:=jpis_
-
-SRCS:= simple_server.c soap_ops.c \
- ${soap_prefix}C.c \
- ${soap_prefix}Server.c
-
-EXA_SRCS:=jpis-test.c ${soap_prefix}C.c ${soap_prefix}Client.c
-
-
-OBJS:=${SRCS:.c=.o} stdsoap2.o
-EXA_OBJS:=${EXA_SRCS:.c=.o} stdsoap2.o
-
-COMMONLIB:=-lglite_jp_common
-
-default all: compile
-
-compile: ${daemon} ${example}
-
-${daemon}: ${OBJS}
- ${LINK} -o $@ ${OBJS} ${COMMONLIB} ${GLOBUS_LIBS}
-
-${example}: ${EXA_OBJS}
- ${LINK} -o $@ ${EXA_OBJS}
-
-JobProvenanceIS.xh: JobProvenanceIS.wsdl JobProvenanceTypes.wsdl typemap.dat
- cp ${jpproject}/JobProvenanceTypes.wsdl .
- ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $<
- rm -f JobProvenanceTypes.wsdl
-
-${soap_prefix}C.c ${soap_prefix}H.h: JobProvenanceIS.xh
- ${gsoap_prefix}/bin/soapcpp2 -w -c -p ${soap_prefix} JobProvenanceIS.xh
-
-#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh
-# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh
-#
-#LB.xh: LB.wsdl typemap.dat
-# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl
-#
-
-
-check:
- -echo nothing yet
-
-doc:
-
-stage: compile
- ${INSTALL} -m 755 ${daemon} ${stagedir}/bin
-
-dist: distsrc distbin
-
-# FIXME: just copied from LB
-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}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d
- for p in bkserverd bkindex; do \
- ${INSTALL} -m 755 "glite_lb_$$p" "${PREFIX}/bin/glite-lb-$$p"; \
- done
-
- for f in dbsetup.sql index.conf.template; do \
- ${INSTALL} -m 644 ${top_srcdir}/config/"glite-lb-$$f" ${PREFIX}/etc; \
- done
-
- ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-lb-bkserverd
-
-clean:
-
-soap_ops.o jpis-test.o simple_server.o: ${soap_prefix}H.h
-
-# we have no real config.h but have to force gSoap not to use
-# linux ftime with broken (aka obsolete) DST information
-
-stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c
- test -f config.h || touch config.h
- @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless'
- ${CC} -o $@ -c -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Build file for the gLite JP Index module
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.1.1.1 2004/10/15 09:49:13 akrenek
--->
-
-<project name="index" default="dist">
-
- <!-- =========================================
- Builds the GLite JP Index Module
- ========================================= -->
-
- <!-- =========================================
- Import properties (order is important)
- ========================================= -->
-
- <!-- import baseline & user properties -->
- <import file="../org.glite/project/baseline.properties.xml" />
-
- <!-- import component build properties,
- component properties &
- component common properties -->
- <import file="./project/properties.xml"/>
-
- <!-- import subsystem build properties,
- subsystem properties &
- subsystem common properties -->
- <import file="${subsystem.properties.file}"/>
-
- <!-- import global build properties &
- global properties -->
- <import file="${global.properties.file}" />
-
- <!-- =========================================
- Load dependency property files (order is important)
- ========================================= -->
- <property file="${user.dependencies.file}"/>
- <property file="${component.dependencies.file}" />
- <property file="${subsystem.dependencies.file}" />
- <property file="${global.dependencies.file}"/>
-
- <!-- =========================================
- Load configure options (order is important)
- ========================================= -->
- <import file="${global.configure.options.file}"/>
- <import file="${component.configure.options.file}"/>
-
- <!-- =========================================
- Import task definitions (order is important)
- ========================================= -->
- <import file="${subsystem.taskdefs.file}" />
- <import file="${global.taskdefs.file}" />
-
- <!-- =========================================
- Load common targets
- ========================================= -->
- <import file="${global.targets-simple_make.file}" />
-
- <!-- =========================================
- Load version file
- ========================================= -->
- <property file="${module.version.file}"/>
-
- <!-- ==============================================
- Local private targets
- ============================================== -->
-
- <target name="localinit"
- description="Module specific initialization tasks">
-
- <antcall target="lbmakefiles" />
- </target>
-
- <target name="localcompile"
- description="Module specific compile tasks">
- </target>
-
- <target name="localclean"
- description="Module specific cleaning tasks">
- </target>
-
-</project>
+++ /dev/null
-<WSDL:definitions
- xmlns:tns="http://glite.org/wsdl/services/jp"
- xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:jp="http://glite.org/wsdl/types/jp"
- xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- targetNamespace="http://glite.org/wsdl/services/jp"
- name="JobProvenance">
-
- <WSDL:types>
- <schema
- targetNamespace="http://glite.org/wsdl/types/jp"
- xmlns="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="unqualified" attributeFormDefault="unqualified">
- <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
-
- <simpleType name="Attribute">
- <restriction base="xsd:string">
- </restriction>
- </simpleType>
- <simpleType name="UploadClass">
- <restriction base="xsd:string">
- <enumeration value="INPUT-SANDBOX"/>
- <enumeration value="OUTPUT-SANDBOX"/>
- <enumeration value="JOB-LOG"/>
- </restriction>
- </simpleType>
- <simpleType name="QueryOp">
- <restriction base="xsd:string">
- <enumeration value="EQUAL"/>
- <enumeration value="UNEQUAL"/>
- <enumeration value="LESS"/>
- <enumeration value="GREATER"/>
- <enumeration value="WITHIN"/>
- </restriction>
- </simpleType>
- <complexType name="TagValue">
- <sequence>
- <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="true"/>
- <element name="sequence" type="xsd:int" minOccurs="0" maxOccurs="1"/>
- <element name="timestamp" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="stringValue" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="blobValue" type="xsd:base64Binary" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="Attributes">
- <sequence>
- <element name="item" type="jp:Attribute" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="GenericJPFaultType">
- <sequence>
- <element name="source" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="code" type="xsd:int" minOccurs="1" maxOccurs="1"/>
- <element name="text" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
- <element name="reason" type="jp:GenericJPFaultType" minOccurs="0" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="PrimaryQueryElement">
- <sequence>
- <element name="attr" type="jp:Attribute" minOccurs="1" maxOccurs="1"/>
- <element name="op" type="jp:QueryOp" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="PrimaryQuery">
- <sequence>
- <element name="item" type="jp:PrimaryQueryElement" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="IndexQueryRecord">
- <sequence>
- <element name="op" type="jp:QueryOp" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="IndexQueryElement">
- <sequence>
- <element name="attr" type="jp:Attribute" minOccurs="1" maxOccurs="1"/>
- <element name="record" type="jp:IndexQueryRecord" minOccurs="1" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="IndexQuery">
- <sequence>
- <element name="item" type="jp:IndexQueryElement" minOccurs="1" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="JobRecord">
- <sequence>
- <element name="jobid" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="PSContact" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="JobRecords">
- <sequence>
- <element name="record" type="jp:JobRecord" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
-
- <complexType name="AttrUpdate">
- <sequence>
- <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="0" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="AttrUpdates">
- <sequence>
- <element name="item" type="jp:AttrUpdate" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="JobUpdate">
- <sequence>
- <element name="jobid" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="attributes" type="jp:AttrUpdates" minOccurs="1" maxOccurs="1"/>
- <element name="tags" type="jp:AttrUpdates" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="UpdateJobsData">
- <sequence>
- <element name="job" type="jp:JobUpdate" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
-
- <complexType name="FeedIndexResponse">
- <sequence>
- <element name="feedId" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="expires" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="GetJobResponse">
- <sequence>
- <element name="jobLog" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="inputSandbox" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="outputSandbox" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="tags" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="StartUploadResponse">
- <sequence>
- <element name="destination" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="commitBefore" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <element name="GenericJPFault" type="jp:GenericJPFaultType"/>
- </schema>
- </WSDL:types>
- <message name="RegisterJobRequest">
- <part name="x" type="xsd:string"/>
- </message>
- <message name="StartUploadRequest">
- <part name="uclass" type="jp:UploadClass"/>
- <part name="commitTimeout" type="xsd:duration"/>
- <part name="contentType" type="xsd:string"/>
- </message>
- <message name="StartUploadResponse">
- <part name="destination" type="xsd:string"/>
- <part name="commitBefore" type="xsd:dateTime"/>
- </message>
- <message name="CommitUploadRequest">
- <part name="destination" type="xsd:string"/>
- </message>
- <message name="RecordTagRequest">
- <part name="jobid" type="xsd:string"/>
- <part name="tag" type="jp:TagValue"/>
- </message>
- <message name="FeedIndexRequest">
- <part name="destination" type="xsd:string"/>
- <part name="attributes" type="jp:Attributes"/>
- <part name="conditions" type="jp:PrimaryQuery"/>
- <part name="continuous" type="xsd:boolean"/>
- </message>
- <message name="FeedIndexResponse">
- <part name="feedId" type="xsd:string"/>
- <part name="expires" type="xsd:dateTime"/>
- </message>
- <message name="FeedIndexRefreshRequest">
- <part name="feedId" type="xsd:string"/>
- </message>
- <message name="GetJobRequest">
- <part name="jobid" type="xsd:string"/>
- </message>
- <message name="GetJobResponse">
- <part name="jobLog" type="xsd:string"/>
- <part name="inputSandbox" type="xsd:string"/>
- <part name="outputSandbox" type="xsd:string"/>
- <part name="tags" type="xsd:string"/>
- </message>
- <message name="GenericJPFault">
- <part name="fault" element="jp:GenericJPFault"/>
- </message>
- <message name="EmptyResponse"/>
- <portType name="JobProvenancePS_PortType">
- <operation name="RegisterJob">
- <documentation>Register job with JP primary storage.
-Job registration in LB is propagated to JP immediately so that JP is aware of the job,
-despite no furhter information is available in it.
-
-Input: JobId
-
-Output: N/A
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:RegisterJobRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="StartUpload">
- <documentation>Initiate upload of of sandbox/dump of job life log from LB.
-WM component responsible for job sandbox management and LB server call JP to declare
-intention to upload intput/output sandbox and job life log.
-
-Input:
-
-uclass: type of the upload - INPUT_SANDBOX, OUTPUT_SANDBOX, JOB_LOG
-
-commitTimeout: upper limit on time for which JP waits for committing this upload transaction
-
-contentType: MIME type of the uploaded file
-
-Output:
-
-destination: URL where the client should upload the file
-
-commitBefore: acutual time when the upload transaction times out
-
-Faults: GenericJPFault
-
-
-Initiate upload of of sandbox/dump of job life log from LB.</documentation>
- <input message="tns:StartUploadRequest"/>
- <output message="tns:StartUploadResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="CommitUpload">
- <documentation>Confirm upload.
-Should be called after a file upload initiaded with StartUpload is finished.
-
-Input:
-
-destination: Upload destination URL (to match with the original request)
-
-Output:
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:CommitUploadRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="RecordTag">
- <documentation>Record a value of user tag.
-JP tags are either standalone or override values of their LB counterparts.
-However, JP tag values are still distinguishable those inherited from LB.
-JP tags may be either strings or blobs.
-
-Input:
-
-jobid:
-
-tag: structure containing name, timestamp, optional sequence number to order tag values
-without relying on timestamps, and string or blob value.
-
-Output: N/A
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:RecordTagRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="FeedIndex">
- <documentation>Start feeding JP index server.
-Called by the index server to start batch feed, and optionally also subscribe for incremental feed.
-
-JP index server subscribes with JP primary storage using a query
-containing conditions on primary metadata and a list of queryable attributes
-of the index server (i.e. data which should be sent to the index server).
-
-When a matching job record is created or modified within the primary storage
-the job record data are sent to the subscribed index server.
-
-The subscription is soft-state, it expires after certain time unless refreshed by the client explicitely.
-
-In the batch mode the query has the same form
-with additional flag asking for all matching records (i.e.\ not only
-arriving afterwards).
-
-Input:
-
-destination: where to send the job record data
-
-attributes: which job record attributes should be sent to the requesting index server
-
-conditions: list of query conditions. Each conditions has the form Attribute Operator Value,
-where Attribute is any of job record attributes and Operator is one of EQUAL, UNEQUAL, LESS, GREATER, WITHIN.
-
-continuous: flag determining that the query is incremental (not batch)
-
-Output:
-
-feedId: unique Id of the feed request, to be used in refresh, cancelation etc.
-
-expires: when the feed times out. Must be refreshed before this time.
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:FeedIndexRequest"/>
- <output message="tns:FeedIndexResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="FeedIndexRefresh">
- <documentation>Extend batch feed subscription (used by index server)
-
-Input: feedId returned previously by FeedIndex
-
-Output: the same as for FeedIndex
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:FeedIndexRefreshRequest"/>
- <output message="tns:FeedIndexResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="GetJob">
- <documentation>Retrieve job record URL's when jobid is known
-Used either to bypass JP index server query for this specific case, or after the index server query to
-retrieve actual job record.
-
-Input: jobid
-
-Output:
-
-jobLog, inputSandbox, outputSandbox, tags: URL's to components of the job record.
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:GetJobRequest"/>
- <output message="tns:GetJobResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- </portType>
- <binding name="JobProvenancePS" type="tns:JobProvenancePS_PortType">
- <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
- <operation name="RegisterJob">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="StartUpload">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="CommitUpload">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="RecordTag">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="FeedIndex">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="FeedIndexRefresh">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="GetJob">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- </binding>
- <service name="JobProvenancePS">
- <documentation>Job Provenance Primary Storage service</documentation>
- <port name="JobProvenancePS" binding="tns:JobProvenancePS">
- <SOAP:address location="http://localhost:10001"/>
- </port>
- </service>
-
- <message name="QueryJobsRequest">
- <part name="conditions" type="jp:IndexQuery"/>
- </message>
-
- <message name="QueryJobsResponse">
- <part name="jobs" type="jp:JobRecords"/>
- </message>
-
- <message name="UpdateJobsRequest">
- <part name="feedId" type="xsd:string"/>
- <part name="data" type="jp:UpdateJobsData"/>
- <part name="feedDone" type="xsd:boolean"/>
- </message>
-
- <portType name="JobProvenanceIS_PortType">
- <operation name="UpdateJobs">
- <documentation>Store or update information on jobs within the JP index server.
-Called directly by the primary storage, used for both batch and incremental feed.
-
-Input:
-
-data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values.
-
-feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation
-the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.)
-
-Output: N/A
-
-Faults: GenericJPFault
-
-
- </documentation>
- <input message="tns:UpdateJobsRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="QueryJobs">
- <documentation>Retrieve pointers to job records of jobs matching a query.
-Input: conditions - list of lists of query conditions.
- Elements of the inner lists refer to a single job attribute, the conditions are or-ed.
- Elements of the outer list may refer to different job attributes, they are and-ed.
-
-Output:
-
-jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:QueryJobsRequest"/>
- <output message="tns:QueryJobsResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- </portType>
-
- <binding name="JobProvenanceIS" type="tns:JobProvenanceIS_PortType">
- <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
- <operation name="UpdateJobs">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="QueryJobs">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- </binding>
-
- <service name="JobProvenanceIS">
- <documentation>Job Provenance Index service</documentation>
- <port name="JobProvenanceIS" binding="tns:JobProvenanceIS">
- <SOAP:address location="http://localhost:10001"/>
- </port>
- </service>
-
-
-</WSDL:definitions>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Configuration options for the gLite JP Index module
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.2 2004/11/22 14:00:37 dimeglio
- Updated to use standard files
- Fixed names (was using common instead of real module name)
-
- Revision 1.1.1.1 2004/10/15 09:49:13 akrenek
--->
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
- <project name="JP Common configuration options">
- <target name="lbmakefiles">
- <exec executable="ln" failonerror="true">
- <arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
- </exec>
- <echo file="${module.build.dir}/Makefile.inc">
-top_srcdir=..
-builddir=build
-stagedir=${stage.abs.dir}
-distdir=${dist.dir}
-globalprefix=${global.prefix}
-lbprefix=${subsystem.prefix}
-package=${module.package.name}
-PREFIX=${install.dir}
-version=${module.version}
-glite_location=${with.glite.location}
-globus_prefix=${with.globus.prefix}
-expat_prefix=${with.expat.prefix}
-gsoap_prefix=${with.gsoap.prefix}
-ares_prefix=${with.ares.prefix}
-thrflavour=${with.globus.thr.flavor}
-nothrflavour=${with.globus.nothr.flavor}
-cppunit=${with.cppunit.prefix}
-jpproject=${subsystem.project.dir}
-project=${component.project.dir}
- </echo>
- </target>
- </project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Common build properties file for the gLite JP Index component
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.1.1.1 2004/10/15 09:49:13 akrenek
--->
-
-<project name="JP Index component common properties">
-
- <!-- Include build properties to allow overwriting
- of properties for subsystem -->
- <property file="project/build.properties" />
-
- <!-- ======================================================
- Define corresponding subsystem properties
- ====================================================== -->
-
- <!-- Subsystem name -->
- <property name="subsystem.name" value="${jp.subsystem.name}"/>
-
- <!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${jp.subsystem.prefix}"/>
-
- <!-- ======================================================
- Define component properties
- ====================================================== -->
-
- <!-- Component name prefix -->
- <property name="component.prefix" value="index" />
-
- <!-- ======================================================
- Define general component properties
- ====================================================== -->
-
- <import file="${component.general.properties.file}" />
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
-
-</project>
+++ /dev/null
-tar_exclude
-CVS
-build.xml
-build
-build.properties
-properties.xml
-configure.properties.xml
-.cvsignore
-.project
-.cdtproject
+++ /dev/null
-#Fri Dec 10 13:35:33 CET 2004
-module.version=0.1.0
-module.build=2
-module.age=1
+++ /dev/null
-#include "glite/jp/types.h"
-#include "glite/jp/context.h"
-
-#include "jpis_H.h"
-
-int main() {
- struct soap soap;
- int i, m, s; // master and slave sockets
-
- glite_jp_context_t ctx;
-
- soap_init(&soap);
- glite_jp_init_context(&ctx);
- soap.user = (void *) ctx;
-
- srand48(time(NULL)); /* feed id generation */
-
- m = soap_bind(&soap, NULL, 8902, 100);
- if (m < 0)
- soap_print_fault(&soap, stderr);
- else
- {
- fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
- for (i = 1; ; i++) {
- s = soap_accept(&soap);
- if (s < 0) {
- soap_print_fault(&soap, stderr);
- break;
- }
- soap_serve(&soap); // process RPC request
- soap_destroy(&soap); // clean up class instances
- soap_end(&soap); // clean up everything and close socket
- glite_jp_run_deferred(ctx);
- }
- }
- soap_done(&soap); // close master socket
-
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "glite/jp/types.h"
-#include "glite/jp/context.h"
-
-#include "jpis_H.h"
-#include "JobProvenanceIS.nsmap"
-
-static struct jptype__GenericJPFaultType *jp2s_error(struct soap *soap,
- const glite_jp_error_t *err)
-{
- struct jptype__GenericJPFaultType *ret = NULL;
- if (err) {
- ret = soap_malloc(soap,sizeof *ret);
- memset(ret,0,sizeof *ret);
- ret->code = err->code;
- ret->source = soap_strdup(soap,err->source);
- ret->text = soap_strdup(soap,strerror(err->code));
- ret->description = soap_strdup(soap,err->desc);
- ret->reason = jp2s_error(soap,err->reason);
- }
- return ret;
-}
-
-static void err2fault(const glite_jp_context_t ctx,struct soap *soap)
-{
- char *et;
- struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail);
- struct _GenericJPFault *f = soap_malloc(soap,sizeof *f);
-
-
- f->jptype__GenericJPFault = jp2s_error(soap,ctx->error);
-
- detail->__type = SOAP_TYPE__GenericJPFault;
- detail->value = f;
- detail->__any = NULL;
-
- soap_receiver_fault(soap,"Oh, shit!",NULL);
- if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail;
- else soap->fault->detail = detail;
-}
-
-static void s2jp_tag(const struct jptype__TagValue *stag,glite_jp_tagval_t *jptag)
-{
- memset(jptag,0,sizeof *jptag);
- jptag->name = strdup(stag->name);
- jptag->sequence = stag->sequence ? *stag->sequence : 0;
- jptag->timestamp = stag->timestamp ? *stag->timestamp : 0;
- if (stag->stringValue) jptag->value = strdup(stag->stringValue);
- else if (stag->blobValue) {
- jptag->binary = 1;
- jptag->size = stag->blobValue->__size;
- jptag->value = (char *) stag->blobValue->__ptr;
- }
-}
-
-#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user)
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__UpdateJobs(
- struct soap *soap,
- char *feed_id,
- struct jptype__UpdateJobsData *jobs,
- enum xsd__boolean done
-)
-{
- printf("%s items %d jobid %s\n",__FUNCTION__,jobs->__sizejob,
- jobs->job[0]->jobid);
- return SOAP_OK;
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__QueryJobs(
- struct soap *soap,
- struct jptype__IndexQuery *query,
- struct jpsrv__QueryJobsResponse *resp
-)
-{
- puts(__FUNCTION__);
- return SOAP_OK;
-}
-
+++ /dev/null
-jpsrv = http://glite.org/wsdl/services/jp
-jptype = http://glite.org/wsdl/types/jp
+++ /dev/null
-# defaults
-top_srcdir=.
-builddir=build
-top_builddir=${top_srcdir}/${builddir}
-stagedir=.
-distdir=.
-globalprefix=glite
-jpprefix=jp
-package=glite-jp-primary
-version=0.0.0
-PREFIX=/opt/glite
-
-glite_location=/opt/glite
-globus_prefix=/opt/globus
-nothrflavour=gcc32
-thrflavour=gcc32pthr
-expat_prefix=/opt/expat
-ares_prefix=/opt/ares
-gsoap_prefix=/software/gsoap-2.6
-
-CC=gcc
-
--include Makefile.inc
-
-
-VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${stagedir}/interface
-
-GLOBUS_LIBS:=-L${globus_prefix}/lib \
- -lglobus_common_${nothrflavour} \
- -lglobus_gssapi_gsi_${nothrflavour}
-
-DEBUG:=-g -O0 -DDEBUG
-
-CFLAGS:=${DEBUG} -I. -I${top_srcdir}/src -I${gsoap_prefix}/include -I${stagedir}/include
-LDFLAGS:=-L${stagedir}/lib
-
-LINK:=libtool --mode=link ${CC} ${LDFLAGS}
-LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS}
-INSTALL:=libtool --mode=install install
-
-
-daemon:=glite-jp-primarystoraged
-example:=jpps-test
-ps_prefix:=jpps_
-is_prefix:=jpis_
-
-gsoap_version=`${gsoap_prefix}/bin/soapcpp2 -version 2>&1 | cut -d' ' -f4 | perl -F\\\\. -nae '$$F[2] =~ s/\D*$$//; print $$F[2]+100*$$F[1]+10000*$$F[0]'`
-
-CFLAGS+=-DGSOAP_VERSION=${gsoap_version}
-
-
-SRCS:= simple_server.c soap_ops.c \
- ftp_backend.c \
- feed.c tags.c\
- is_client.c \
- ${ps_prefix}ServerLib.c \
- ${is_prefix}ClientLib.c jpps_C.c
-# env_C.c
-
-EXA_SRCS:=jpps-test.c ${ps_prefix}C.c ${ps_prefix}Client.c
-
-
-OBJS:=${SRCS:.c=.o}
-EXA_OBJS:=${EXA_SRCS:.c=.o}
-
-COMMONLIB:=-lglite_jp_common
-GSOAPLIB:=-L${gsoap_prefix}/lib -lgsoap${GSOAP_DEBUG}
-
-default all: compile
-
-compile: ${daemon} ${example}
-
-${daemon}: ${OBJS}
- ${LINK} -o $@ ${OBJS} ${COMMONLIB} ${GSOAPLIB} ${GLOBUS_LIBS}
-
-${example}: ${EXA_OBJS}
- ${LINK} -o $@ ${EXA_OBJS} ${GSOAPLIB}
-
-JobProvenanceIS.xh JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat
- cp ${stagedir}/interface/JobProvenanceTypes.wsdl .
- ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $<
- rm -f JobProvenanceTypes.wsdl
-
-${ps_prefix}Client.c ${ps_prefix}ClientLib.c \
-${ps_prefix}Server.c ${ps_prefix}ServerLib.c \
-${ps_prefix}C.c ${ps_prefix}H.h: JobProvenancePS.xh
- ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${ps_prefix} JobProvenancePS.xh
-
-${is_prefix}ClientLib.c ${is_prefix}Client.c \
-${is_prefix}C.c ${is_prefix}H.h: JobProvenanceIS.xh
- ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${is_prefix} JobProvenanceIS.xh
-
-env_C.c env_Server.c:
- touch env.xh
- cp ${jpproject}/JobProvenanceTypes.wsdl .
- ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o env.xh JobProvenanceTypes.wsdl
- rm -f JobProvenanceTypes.wsdl
- ${gsoap_prefix}/bin/soapcpp2 -w -c -p env_ env.xh
-
-#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh
-# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh
-#
-#LB.xh: LB.wsdl typemap.dat
-# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl
-#
-
-
-simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h
-
-check:
- -echo nothing yet
-
-doc:
-
-stage: compile
- ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install
-
-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}/bin ${PREFIX}/etc ${PREFIX}/examples ${PREFIX}/etc/init.d
- ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin
- ${INSTALL} -m 755 jpps-test ${PREFIX}/examples/glite-jp-primary-test
-
-
-clean:
-
-simple_server.o soap_ops.o jpps-test.o: ${ps_prefix}H.h
-
-# we have no real config.h but have to force gSoap not to use
-# linux ftime with broken (aka obsolete) DST information
-
-stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c
- test -f config.h || touch config.h
- @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless'
- ${CC} -o $@ -c -DWITH_NONAMESPACES -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Build file for the GLite JP Primary module
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.2 2004/11/22 13:55:30 dimeglio
- First version of this file
- Use central subsystem definition
-
- Revision 1.1.1.1 2004/10/15 09:49:24 akrenek
--->
-
-<project name="primary" default="dist">
-
- <!-- =========================================
- Builds the gLite JP Primary Module
- ========================================= -->
-
- <!-- =========================================
- Import properties (order is important)
- ========================================= -->
-
- <!-- import baseline & user properties -->
- <import file="../org.glite/project/baseline.properties.xml" />
-
- <!-- import component build properties,
- component properties &
- component common properties -->
- <import file="./project/properties.xml"/>
-
- <!-- import subsystem build properties,
- subsystem properties &
- subsystem common properties -->
- <import file="${subsystem.properties.file}"/>
-
- <!-- import global build properties &
- global properties -->
- <import file="${global.properties.file}" />
-
- <!-- =========================================
- Load dependency property files (order is important)
- ========================================= -->
- <property file="${user.dependencies.file}"/>
- <property file="${component.dependencies.file}" />
- <property file="${subsystem.dependencies.file}" />
- <property file="${global.dependencies.file}"/>
-
- <!-- =========================================
- Load configure options (order is important)
- ========================================= -->
- <import file="${global.configure.options.file}"/>
- <import file="${component.configure.options.file}"/>
-
- <!-- =========================================
- Import task definitions (order is important)
- ========================================= -->
- <import file="${subsystem.taskdefs.file}" />
- <import file="${global.taskdefs.file}" />
-
- <!-- =========================================
- Load common targets
- ========================================= -->
- <import file="${global.targets-simple_make.file}" />
-
- <!-- =========================================
- Load version file
- ========================================= -->
- <property file="${module.version.file}"/>
-
- <!-- ==============================================
- Local private targets
- ============================================== -->
-
- <target name="localinit"
- description="Module specific initialization tasks">
-
- <antcall target="lbmakefiles" />
- </target>
-
- <target name="localcompile"
- description="Module specific compile tasks">
- </target>
-
- <target name="localclean"
- description="Module specific cleaning tasks">
- </target>
-
-</project>
+++ /dev/null
-#include <stdio.h>
-#include <sysexits.h>
-#include <string.h>
-#include <assert.h>
-
-#include "jpps_H.h"
-#include "jpps_.nsmap"
-
-#include "jptype_map.h"
-
-static void usage(const char *me)
-{
- fprintf(stderr,"%s: [-s server-url] operation args \n\n"
- " operations are:\n"
- " RegisterJob jobid\n"
- " StartUpload jobid class(0,1,2) commit_before mimetype\n"
- " CommitUpload destination\n"
- " RecordTag jobid tagname sequence stringvalue\n"
- " GetJob jobid\n"
- " FeedIndex destination query_number history continuous\n"
- " FeedIndexRefresh feedid\n"
- ,me);
-
- exit (EX_USAGE);
-}
-
-static int check_fault(struct soap *soap,int err) {
- struct SOAP_ENV__Detail *detail;
- struct jptype__GenericJPFaultType *f;
- char *reason,indent[200] = " ";
-
- switch(err) {
- case SOAP_OK: puts("OK");
- break;
- case SOAP_FAULT:
- case SOAP_SVR_FAULT:
- if (soap->version == 2) {
- detail = soap->fault->SOAP_ENV__Detail;
- reason = soap->fault->SOAP_ENV__Reason;
- }
- else {
- detail = soap->fault->detail;
- reason = soap->fault->faultstring;
- }
- fputs(reason,stderr);
- putc('\n',stderr);
- assert(detail->__type == SOAP_TYPE__GenericJPFault);
-#if GSOAP_VERSION >=20700
- f = ((struct _GenericJPFault *) detail->fault)
-#else
- f = ((struct _GenericJPFault *) detail->value)
-#endif
- -> jptype__GenericJPFault;
-
- while (f) {
- fprintf(stderr,"%s%s: %s (%s)\n",indent,
- f->source,f->text,f->description);
- f = f->reason;
- strcat(indent," ");
- }
- return -1;
-
- default: soap_print_fault(soap,stderr);
- return -1;
- }
- return 0;
-}
-
-static struct jptype__Attribute sample_attr[] = {
- { OWNER, NULL },
- { TIME, "submitted" },
- { TAG, "test" },
-};
-
-static struct jptype__PrimaryQueryElement sample_query[][5] = {
- {
- { sample_attr+OWNER, EQUAL, "unknown", NULL },
- { NULL, 0, NULL, NULL }
- },
-};
-
-int main(int argc,char *argv[])
-{
- char *server = "http://localhost:8901";
- int opt;
- struct soap *soap = soap_new();
-
- if (argc < 2) usage(argv[0]);
-
- soap_init(soap);
- soap_set_namespaces(soap, jpps__namespaces);
-
- while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) {
- case 's': server = optarg;
- argv += 2;
- break;
- case '?': usage(argv[0]);
- }
-
- if (!strcasecmp(argv[1],"RegisterJob")) {
- struct jpsrv__RegisterJobResponse r;
-
- if (argc != 3) usage(argv[0]);
- check_fault(soap,
- soap_call_jpsrv__RegisterJob(soap,server,"",argv[2],&r));
- } else if (!strcasecmp(argv[1], "StartUpload")) {
- struct jpsrv__StartUploadResponse r;
-
- if (argc != 6) usage(argv[0]);
- if (!check_fault(soap,
- soap_call_jpsrv__StartUpload(soap, server, "",
- argv[2], atoi(argv[3]), atoi(argv[4]), argv[5], &r))) {
- printf("Destination: %s\nCommit before: %s\n", r.destination, ctime(&r.commitBefore));
- }
- } else if (!strcasecmp(argv[1], "CommitUpload")) {
- struct jpsrv__CommitUploadResponse r;
-
- if (argc != 3) usage(argv[0]);
- if (!check_fault(soap,
- soap_call_jpsrv__CommitUpload(soap, server, "",
- argv[2], &r))) {
- /* OK */
- }
- } else if (!strcasecmp(argv[1], "RecordTag")) {
- struct jpsrv__RecordTagResponse r;
- struct jptype__TagValue tagval;
-
- if (argc != 6) usage(argv[0]);
-
- tagval.name = argv[3];
- tagval.sequence = NULL;
- tagval.timestamp = NULL;
- tagval.stringValue = argv[5];
- tagval.blobValue = NULL;
-
- if (!check_fault(soap,
- soap_call_jpsrv__RecordTag(soap, server, "",
- argv[2], &tagval, &r))) {
- /* OK */
- }
- } else if (!strcasecmp(argv[1],"FeedIndex")) {
- struct jpsrv__FeedIndexResponse r;
- struct jptype__Attribute *ap[2];
- struct jptype__Attributes attr = { 2, ap };
- struct jptype__PrimaryQueryElement *qp[100];
- struct jptype__PrimaryQuery qry = { 0, qp };
-
- int i,j,qi = atoi(argv[3])-1;
-
- if (argc != 6) usage(argv[0]);
-
- for (i=0; i<attr.__sizeitem; i++) ap[i] = sample_attr+i;
-
- for (i=0; sample_query[qi][i].attr; i++)
- qp[i] = &sample_query[qi][i];
- qry.__sizeitem = i;
-
- if (!check_fault(soap,soap_call_jpsrv__FeedIndex(soap,server,"",
- argv[2],&attr,&qry,!strcasecmp(argv[4],"true"),
- !strcasecmp(argv[5],"true"),
- &r)))
- {
- printf("FeedId: %s\nExpires: %s\n",r.feedId,ctime(&r.expires));
- }
- } else if (!strcasecmp(argv[1], "FeedIndexRefresh")) {
- struct jpsrv__FeedIndexRefreshResponse r;
-
- if (argc != 3) usage(argv[0]);
- if (!check_fault(soap,
- soap_call_jpsrv__FeedIndexRefresh(soap, server, "",
- argv[2], &r))) {
- printf("FeedId: %s\nExpires: %s\n",r.feedId,ctime(&r.expires));
- }
- } else if (!strcasecmp(argv[1],"GetJob")) {
- struct jpsrv__GetJobResponse r;
-
- if (argc != 3) usage(argv[0]);
-
- if (!check_fault(soap,soap_call_jpsrv__GetJob(soap,server,"",
- argv[2],&r)))
- {
- printf("JobLog:\t%s\nInput:\t%s\nOutput:\t%s\nTags:\t%s\n",
- r.jobLog,r.inputSandbox,r.outputSandbox,r.tags);
- }
-
- }
- else usage(argv[0]);
-
- return 0;
-}
-
-
-/* XXX: we don't use it */
-SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} };
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Common build properties file for the gLite JP Primary component
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
--->
-
-<project name="JP Primary component common properties">
-
- <!-- Include build properties to allow overwriting
- of properties for subsystem -->
- <property file="project/build.properties" />
-
- <!-- ======================================================
- Define corresponding subsystem properties
- ====================================================== -->
-
- <!-- Subsystem name -->
- <property name="subsystem.name" value="${jp.subsystem.name}"/>
-
- <!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${jp.subsystem.prefix}"/>
-
- <!-- ======================================================
- Define component properties
- ====================================================== -->
-
- <!-- Component name prefix -->
- <property name="component.prefix" value="primary" />
-
- <!-- ======================================================
- Define general component properties
- ====================================================== -->
-
- <import file="${component.general.properties.file}" />
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
-
-</project>
+++ /dev/null
-tar_exclude
-CVS
-build.xml
-build
-build.properties
-properties.xml
-configure.properties.xml
-.cvsignore
-.project
-.cdtproject
+++ /dev/null
-#Fri Dec 10 13:37:05 CET 2004
-module.version=0.1.0
-module.build=3
-module.age=1
+++ /dev/null
-#ifndef __GLITE_JP_BACKEND
-#define __GLITE_JP_BACKEND
-
-#include <sys/types.h>
-#include <unistd.h>
-
-int glite_jppsbe_init(
- glite_jp_context_t ctx,
- int *argc,
- char *argv[]
-);
-
-int glite_jppsbe_init_slave(
- glite_jp_context_t ctx
-);
-
-int glite_jppsbe_register_job(
- glite_jp_context_t ctx,
- const char *job,
- const char *owner
-);
-
-int glite_jppsbe_start_upload(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- const char *content_type,
- char **destination_out,
- time_t *commit_before_inout
-);
-
-int glite_jppsbe_commit_upload(
- glite_jp_context_t ctx,
- const char *destination
-);
-
-int glite_jppsbe_destination_info(
- glite_jp_context_t ctx,
- const char *destination,
- char **job_out,
- glite_jp_fileclass_t *class_out
-);
-
-int glite_jppsbe_get_job_url(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- char **url_out
-);
-
-int glite_jppsbe_open_file(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- int mode,
- void **handle_out
-);
-
-int glite_jppsbe_close_file(
- glite_jp_context_t ctx,
- void *handle
-);
-
-int glite_jppsbe_pread(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes,
- off_t offset,
- ssize_t *nbytes_ret
-);
-
-int glite_jppsbe_pwrite(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes,
- off_t offset
-);
-
-int glite_jppsbe_append(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes
-);
-
-int glite_jppsbe_get_job_metadata(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_attrval_t attrs_inout[]
-);
-
-int glite_jppsbe_query(
- glite_jp_context_t ctx,
- const glite_jp_query_rec_t query[],
- const glite_jp_attrval_t metadata[],
- int (*callback)(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_attrval_t metadata[]
- )
-);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "glite/jp/types.h"
-#include "glite/jp/strmd5.h"
-#include "feed.h"
-
-
-/*
- * seconds before feed expires: should be
- * XXX: should be configurable, default for real deployment sort of 1 hour
- */
-#define FEED_TTL 120
-
-static int check_qry_item(
- glite_jp_context_t ctx,
- const glite_jp_query_rec_t *qry,
- const glite_jp_attrval_t *attr
-)
-{
- int cmp,cmp2;
- long scmp,ucmp;
-
- switch (qry->attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TAG:
- cmp = strcmp(attr->value.s,qry->value.s);
- break;
- case GLITE_JP_ATTR_TIME:
- scmp = (ucmp = attr->value.time.tv_usec - qry->value.time.tv_usec) > 0 ? 0 : -1;
- ucmp -= 1000000 * scmp;
- scmp += attr->value.time.tv_sec - qry->value.time.tv_sec;
- cmp = scmp ? scmp : ucmp;
- break;
- }
- switch (qry->op) {
- case GLITE_JP_QUERYOP_EQUAL: return !cmp;
- case GLITE_JP_QUERYOP_UNEQUAL: return cmp;
- case GLITE_JP_QUERYOP_LESS: return cmp < 0;
- case GLITE_JP_QUERYOP_GREATER: return cmp > 0;
-
- case GLITE_JP_QUERYOP_WITHIN:
- switch (qry->attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TAG:
- cmp2 = strcmp(attr->value.s,qry->value2.s);
- break;
- case GLITE_JP_ATTR_TIME:
- scmp = (ucmp = attr->value.time.tv_usec - qry->value2.time.tv_usec) > 0 ? 0 : -1;
- ucmp -= 1000000 * scmp;
- scmp += attr->value.time.tv_sec - qry->value2.time.tv_sec;
- cmp2 = scmp ? scmp : ucmp;
- break;
- }
- return cmp >= 0 && cmp2 <= 0;
- }
-}
-
-/* XXX: limit on query size -- I'm lazy to malloc() */
-#define QUERY_MAX 100
-
-static int match_feed(
- glite_jp_context_t ctx,
- const struct jpfeed *feed,
- const char *job,
- const glite_jp_attrval_t attrs[] /* XXX: not checked for correctness */
-)
-{
- int i;
- int attri[GLITE_JP_ATTR__LAST];
- int qi[QUERY_MAX];
-
- glite_jp_attrval_t *newattr = NULL;
-
- glite_jp_clear_error(ctx);
-
- for (i=0; i<GLITE_JP_ATTR__LAST; i++) attri[i] = -1;
- for (i=0; attrs[i].attr.type; i++) attri[attrs[i].attr.type] = i;
-
- if (feed->qry) {
- int j,complete = 1;
-
- memset(qi,0,sizeof qi);
- for (i=0; feed->qry[i].attr.type; i++) {
- assert(i<QUERY_MAX);
- if ((j=attri[feed->qry[i].attr.type]) >=0) {
- if (check_qry_item(ctx,feed->qry+i,attrs+j))
- qi[i] = 1; /* matched */
- else return 0; /* can't be satisfied */
- }
- else complete = 0;
- }
-
- /* not all attributes in query are known from input
- * we have to retrieve job metadata from the backend
- */
- if (!complete) {
- glite_jp_attrval_t meta[GLITE_JP_ATTR__LAST+1];
- int qai[GLITE_JP_ATTR__LAST];
-
- memset(meta,0,sizeof meta);
- j=0;
- for (i=0; feed->qry[i].attr.type; i++) if (!qi[i]) {
- meta[j].attr.type = feed->qry[i].attr.type;
- meta[j].attr.name = feed->qry[i].attr.name;
- qai[feed->qry[i].attr.type] = i;
- j++;
- }
-
- if (glite_jppsbe_get_job_metadata(ctx,job,meta)) {
- glite_jp_error_t err;
- err.code = EIO;
- err.source = __FUNCTION__;
- err.desc = "complete query";
- return glite_jp_stack_error(ctx,&err);
- }
-
- for (i=0; j=meta[i].attr.type; i++)
- if (!check_qry_item(ctx,feed->qry+qai[j],meta+i))
- return 0;
- }
- }
-
- /* matched completely */
- return glite_jpps_single_feed(ctx,feed->destination,job,attrs);
- return 0;
-}
-
-int glite_jpps_match_attr(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_attrval_t attrs[]
-)
-{
- struct jpfeed *f = (struct jpfeed *) ctx->feeds;
- int i,j;
- int attri[GLITE_JP_ATTR__LAST];
-
- glite_jp_clear_error(ctx);
-
- for (i=0; i<GLITE_JP_ATTR__LAST; i++) attri[i] = -1;
- for (i=0; attrs[i].attr.type; i++) {
- if (attrs[i].attr.type >= GLITE_JP_ATTR__LAST ||
- attrs[i].attr.type <= 0)
- {
- glite_jp_error_t err;
- err.code = EINVAL;
- err.source = __FUNCTION__;
- err.desc = "unknown attribute";
- return glite_jp_stack_error(ctx,&err);
- }
- if (attri[attrs[i].attr.type] >= 0) {
- glite_jp_error_t err;
- err.code = EINVAL;
- err.source = __FUNCTION__;
- err.desc = "double attribute change";
- return glite_jp_stack_error(ctx,&err);
- }
-
- attri[attrs[i].attr.type] = i;
- }
-
- for (;f; f = f->next) {
- for (i=0; f->attrs[i].type && attri[f->attrs[i].type] == -1; i++);
- /* XXX: ignore any errors */
- if (f->attrs[i].type) match_feed(ctx,f,job,attrs);
- }
-
- return glite_jp_clear_error(ctx);
-}
-
-int glite_jpps_match_file(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class
-)
-{
- fprintf(stderr,"%s: \n",__FUNCTION__);
- return 0;
-}
-
-int glite_jpps_match_tag(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_tagval_t *tag
-)
-{
- fprintf(stderr,"%s: \n",__FUNCTION__);
- return 0;
-}
-
-static char *generate_feedid(void)
-{
- char hname[200],buf[1000];
-
- gethostname(hname,sizeof hname);
- snprintf(buf,sizeof buf,"%s%d%ld",hname,getpid(),lrand48());
- buf[sizeof buf-1] = 0;
- return str2md5base64(buf);
-}
-
-
-int glite_jpps_run_feed(
- glite_jp_context_t ctx,
- const char *destination,
- const glite_jp_attr_t *attrs,
- const glite_jp_query_rec_t *qry,
- char **feed_id)
-{
- fprintf(stderr,"%s: \n",__FUNCTION__);
- return 0;
-}
-
-static int register_feed_deferred(glite_jp_context_t ctx,void *feed)
-{
- struct jpfeed *f = feed;
-
- f->next = ctx->feeds;
- ctx->feeds = f;
- return 0;
-}
-
-/* FIXME:
- * - volatile implementation: should store the registrations in a file
- * and recover after restart
- * - should communicate the data among all server slaves
- */
-int glite_jpps_register_feed(
- glite_jp_context_t ctx,
- const char *destination,
- const glite_jp_attr_t *attrs,
- const glite_jp_query_rec_t *qry,
- char **feed_id,
- time_t *expires)
-{
- int i;
- struct jpfeed *f = calloc(1,sizeof *f);
-
- if (!*feed_id) *feed_id = generate_feedid();
- time(expires); *expires += FEED_TTL;
-
- f->id = strdup(*feed_id);
- f->destination = strdup(destination);
- f->expires = *expires;
- for (i=0; attrs[i].type; i++) {
- f->attrs = realloc(f->attrs,(i+2) * sizeof *f->attrs);
- glite_jp_attr_copy(f->attrs+i,attrs+i);
- memset(f->attrs+i+1,0,sizeof *f->attrs);
- }
- for (i=0; qry[i].attr.type; i++) {
- f->qry = realloc(f->qry,(i+2) * sizeof *f->qry);
- glite_jp_queryrec_copy(f->qry+i,qry+i);
- memset(f->qry+i+1,0,sizeof *f->qry);
- }
-
- glite_jp_add_deferred(ctx,register_feed_deferred,f);
-
- return 0;
-}
-
+++ /dev/null
-#ifndef __GLITE_JP_FEED
-#define __GLITE_JP_FEED
-
-
-struct jpfeed {
- char *id,*destination;
- time_t expires;
- glite_jp_attr_t *attrs;
- glite_jp_query_rec_t *qry;
- struct jpfeed *next;
-};
-
-
-int glite_jpps_match_attr(glite_jp_context_t,const char *,const glite_jp_attrval_t[]);
-int glite_jpps_match_file(glite_jp_context_t,const char *,glite_jp_fileclass_t);
-int glite_jpps_match_tag(glite_jp_context_t,const char *,const glite_jp_tagval_t *);
-int glite_jpps_run_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **);
-int glite_jpps_register_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **,time_t *);
-
-#endif
-
+++ /dev/null
-#ident "$Header$"
-
-#include <getopt.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <limits.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "glite/jp/types.h"
-#include "glite/jp/context.h"
-#include "glite/jp/strmd5.h"
-
-#include "tags.h"
-#include "backend.h"
-
-#define UPLOAD_SUFFIX ".upload"
-#define LOCK_SUFFIX ".lock"
-
-struct ftpbe_config {
- char *internal_path;
- char *external_path;
- char *gridmap;
- char *logname;
-};
-
-static struct ftpbe_config *config = NULL;
-
-struct fhandle_rec {
- int fd;
- int fd_append;
-};
-typedef struct fhandle_rec *fhandle;
-
-static struct option ftpbe_opts[] = {
- { "ftp-internal-path", 1, NULL, 'I' },
- { "ftp-external-path", 1, NULL, 'E' },
- { "ftp-gridmap", 1, NULL, 'G' },
- { NULL, 0, NULL, 0 }
-};
-
-static struct {
- glite_jp_fileclass_t type;
- char * fname;
- } class_to_fname_tab[] = {
- { GLITE_JP_FILECLASS_INPUT, "input" },
- { GLITE_JP_FILECLASS_OUTPUT, "output" },
- { GLITE_JP_FILECLASS_LBLOG, "lblog" },
- { GLITE_JP_FILECLASS_TAGS, "tags" },
- { GLITE_JP_FILECLASS_UNDEF, NULL }
- };
-
-static char *class_to_fname(glite_jp_fileclass_t type)
-{
- int i;
-
- for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++)
- if (type == class_to_fname_tab[i].type)
- return class_to_fname_tab[i].fname;
-
- return NULL;
-}
-
-static glite_jp_fileclass_t fname_to_class(char* fname)
-{
- int i;
-
- for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++)
- if (!strcmp(fname, class_to_fname_tab[i].fname))
- return class_to_fname_tab[i].type;
-
- return GLITE_JP_FILECLASS_UNDEF;
-}
-
-static int config_check(
- glite_jp_context_t ctx,
- struct ftpbe_config *config)
-{
- return config == NULL ||
- config->internal_path == NULL ||
- config->external_path == NULL ||
- config->gridmap == NULL ||
- config->logname == NULL;
-
- /* XXX check reality */
-}
-
-static int jobid_unique_pathname(glite_jp_context_t ctx, const char *job,
- char **unique, char **ju_path, int get_path)
-{
- char *p;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- p = strrchr(job, '/');
- if (!p) {
- err.code = EINVAL;
- err.desc = "Malformed jobid";
- return glite_jp_stack_error(ctx,&err);
- }
- /* XXX thorough checks */
- if (!(*unique = strdup(p+1))) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- if (get_path) {
- if (!(*ju_path = strdup(p+1))) {
- free(*unique);
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- *(*ju_path + 10) = '\0';
- }
- return 0;
-}
-
-static int mkdirpath(const char* path, int prefixlen)
-{
- char *wpath, *p;
- int goout, ret;
-
- wpath = strdup(path);
- if (!wpath) {
- errno = ENOMEM;
- return -1;
- }
-
- p = wpath + prefixlen;
- goout = 0;
- while (!goout) {
- while (*p == '/') p++;
- while (*p != '/' && *p != '\0') p++;
- goout = (*p == '\0');
- *p = '\0';
- ret = mkdir(wpath, S_IRUSR | S_IWUSR | S_IXUSR);
- if (ret < 0 && errno != EEXIST) break;
- *p = '/';
- }
- free(wpath);
- return goout ? 0 : ret;
-}
-
-static long regtime_trunc(long tv_sec)
-{
- return tv_sec / (86400*7);
-}
-
-static long regtime_ceil(long tv_sec)
-{
- return (tv_sec % (86400*7)) ? tv_sec/(86400*7)+1 : tv_sec/(86400*7) ;
-}
-
-/********************************************************************************/
-int glite_jppsbe_init(
- glite_jp_context_t ctx,
- int *argc,
- char *argv[]
-)
-{
- glite_jp_error_t err;
- int opt;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- config = (struct ftpbe_config *) calloc(1, sizeof *config);
- if (!config) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
-
- config->logname = getlogin();
-
- while ((opt = getopt_long(*argc, argv, "I:E:G:", ftpbe_opts, NULL)) != EOF) {
- switch (opt) {
- case 'I': config->internal_path = optarg; break;
- case 'E': config->external_path = optarg; break;
- case 'G': config->gridmap = optarg; break;
- default: break;
- }
- }
-
- if (config_check(ctx, config)) {
- err.code = EINVAL;
- err.desc = "Invalid FTP backend configuration";
- return glite_jp_stack_error(ctx,&err);
- }
-
- return 0;
-}
-
-int glite_jppsbe_init_slave(
- glite_jp_context_t ctx
-)
-{
- /* Nothing to do */
-}
-
-int glite_jppsbe_register_job(
- glite_jp_context_t ctx,
- const char *job,
- const char *owner
-)
-{
- glite_jp_error_t err;
- char *int_dir = NULL;
- char *int_fname = NULL;
- char *data_dir = NULL;
- char *data_fname = NULL;
- char *ju = NULL;
- char *ju_path = NULL;
- char *ownerhash = NULL;
- FILE *regfile = NULL;
- struct timeval reg_tv;
- long reg_tv_trunc;
- struct stat statbuf;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- assert(job != NULL);
- assert(owner != NULL);
-
- gettimeofday(®_tv, NULL);
- reg_tv_trunc = regtime_trunc(reg_tv.tv_sec);
-
- if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) {
- err.code = ctx->error->code;
- err.desc = "Cannot obtain jobid unique path/name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&int_dir, "%s/regs/%s",
- config->internal_path, ju_path) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (mkdirpath(int_dir, strlen(config->internal_path)) < 0 &&
- errno != EEXIST) {
- free(int_dir);
- err.code = errno;
- err.desc = "Cannot mkdir jobs's reg directory";
- return glite_jp_stack_error(ctx,&err);
- }
- free(int_dir);
-
- if (asprintf(&int_fname, "%s/regs/%s/%s.info",
- config->internal_path, ju_path, ju) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (stat(int_fname, &statbuf) < 0) {
- if (errno != ENOENT) {
- err.code = errno;
- err.desc = "Cannot stat jobs's reg info file";
- goto error_out;
- }
- } else {
- err.code = EEXIST;
- err.desc = "Job already registered";
- goto error_out;
- }
-
- regfile = fopen(int_fname, "w");
- if (regfile == NULL) {
- err.code = errno;
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
-
- ownerhash = str2md5(owner); /* static buffer */
-
- if (fprintf(regfile, "%d %ld.%06ld %s %s %d %s\n", 1,
- (long)reg_tv.tv_sec, (long)reg_tv.tv_usec, job,
- ownerhash, strlen(owner), owner) < 1 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot write jobs's reg info file";
- goto error_out;
- }
- if (fclose(regfile) != 0 ) {
- err.code = errno;
- err.desc = "Cannot close(write) jobs's reg info file";
- goto error_out;
- }
-
- if (asprintf(&data_dir, "%s/data/%s/%d/%s",
- config->internal_path, ownerhash, regtime_trunc(reg_tv.tv_sec), ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (asprintf(&data_fname, "%s/_info", data_dir) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (mkdirpath(data_dir, strlen(config->internal_path)) < 0 &&
- errno != EEXIST) {
- err.code = errno;
- err.desc = "Cannot mkdir jobs's data directory";
- goto error_out;
- }
-
- if (link(int_fname, data_fname) < 0) {
- err.code = errno;
- err.desc = "Cannot link job's reg and data info files";
- goto error_out;
- }
-
-error_out:
- free(int_fname);
- free(data_fname);
- if (err.code && data_dir) rmdir(data_dir);
- free(data_dir);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-static int add_to_gridmap(glite_jp_context_t ctx, const char *dn)
-{
- FILE *gridmap = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- gridmap = fopen(config->gridmap, "a");
- if (!gridmap) {
- err.code = errno;
- err.desc = "Cannot open gridmap file";
- return glite_jp_stack_error(ctx,&err);
- }
- if (fprintf(gridmap, "\"%s\" %s\n", dn, config->logname) < 6 ||
- ferror(gridmap)) {
- err.code = EIO;
- err.desc = "Cannot write to gridmap file";
- fclose(gridmap);
- return glite_jp_stack_error(ctx,&err);
- }
- fclose(gridmap);
- return 0;
-}
-
-static int remove_from_gridmap(glite_jp_context_t ctx, const char *dn)
-{
- FILE *gridmap = NULL;
- char *temp_name = NULL;
- FILE *temp_file = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- /* XXX */
- return 0;
-}
-
-int glite_jppsbe_start_upload(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- const char *content_type,
- char **destination_out,
- time_t *commit_before_inout
-)
-{
- char *int_fname = NULL;
- char *lock_fname = NULL;
- FILE *lockfile = NULL;
- FILE *regfile = NULL;
- char *fname = NULL;
- char *data_dir = NULL;
- char *data_lock = NULL;
- char *ju = NULL;
- char *ju_path = NULL;
- char *peername = NULL;
- int info_version;
- long reg_time;
- char ownerhash[33];
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- assert(job!=NULL);
- assert(destination_out!=NULL);
-
- fname = class_to_fname(class);
- assert(fname!=NULL);
-
- if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) {
- err.code = ctx->error->code;
- err.desc = "Cannot obtain jobid unique path/name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- peername = glite_jp_peer_name(ctx);
-
- if (asprintf(&int_fname, "%s/regs/%s/%s.info",
- config->internal_path, ju_path, ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- regfile = fopen(int_fname, "r");
- if (regfile == NULL) {
- err.code = errno;
- if (errno == ENOENT)
- err.desc = "Job not registered";
- else
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
- if (fscanf(regfile, "%d %ld.%*ld %*s %s ", &info_version,
- ®_time, ownerhash) < 3 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- fclose(regfile);
-
- /* XXX authorization */
-
- if (asprintf(&data_dir, "%s/data/%s/%d/%s",
- config->internal_path, ownerhash, regtime_trunc(reg_time), ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- if (asprintf(&lock_fname, "%s/%s" LOCK_SUFFIX,
- data_dir, fname) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- if (commit_before_inout != NULL)
- *commit_before_inout = (time_t) LONG_MAX; /* XXX no timeout enforced */
-
- lockfile = fopen(lock_fname, "w");
- if (lockfile == NULL) {
- err.code = errno;
- err.desc = "Cannot open uploads's lock file";
- goto error_out;
- }
-
- if (fprintf(lockfile, "%ld %d %s\n", (long)*commit_before_inout,
- peername ? peername : 0,
- peername ? peername : "") < 1 || ferror(regfile)) {
- fclose(lockfile);
- err.code = errno;
- err.desc = "Cannot write upload's lock file";
- goto error_out;
- }
- if (fclose(lockfile) != 0 ) {
- err.code = errno;
- err.desc = "Cannot close(write) upload's lock file";
- goto error_out;
- }
-
- if (asprintf(destination_out, "%s/data/%s/%d/%s/%s" UPLOAD_SUFFIX,
- config->external_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- if (add_to_gridmap(ctx, peername)) {
- err.code = EIO;
- err.desc = "Cannot add peer DN to ftp server authorization file";
- goto error_out;
- }
-
-error_out:
- free(int_fname);
- free(data_dir);
- if (err.code && data_lock) unlink(data_lock);
- free(data_lock);
- free(ju); free(ju_path);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_commit_upload(
- glite_jp_context_t ctx,
- const char *destination
-)
-{
- size_t dest_len;
- size_t suff_len;
- size_t extp_len;
- long commit_before;
- int lockpeerlen;
- char *lockpeername = NULL;
- char *peername = NULL;
- char *dest_rw = NULL;
- char *dest_rw_suff = NULL;
- char *dest_rw_lock = NULL;
- FILE *lockfile = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- assert(destination != NULL);
-
- suff_len = strlen(UPLOAD_SUFFIX);
- dest_len = strlen(destination);
- extp_len = strlen(config->external_path);
-
- if (dest_len < suff_len ||
- strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) ||
- strncmp(destination, config->external_path, extp_len)) {
- err.code = EINVAL;
- err.desc = "Forged destination path";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&dest_rw_suff, "%s%s", config->internal_path,
- destination + extp_len) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- dest_rw = strdup(dest_rw_suff);
- if (!dest_rw) {
- err.code = ENOMEM;
- goto error_out;
- }
- *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0';
-
- if (asprintf(&dest_rw_lock, "%s" LOCK_SUFFIX, dest_rw) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- lockfile = fopen(dest_rw_lock, "r");
- if (lockfile == NULL) {
- err.code = errno;
- err.desc = "Cannot open upload's lock file";
- goto error_out;
- }
- if (fscanf(lockfile, "%ld %d ", &commit_before, &lockpeerlen) < 2 || ferror(lockfile)) {
- fclose(lockfile);
- err.code = errno;
- err.desc = "Cannot read upload's lock file";
- goto error_out;
- }
- if (lockpeerlen) {
- lockpeername = (char*) calloc(1, lockpeerlen+1);
- if (!lockpeername) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (fgets(lockpeername, lockpeerlen+1, lockfile) == NULL) {
- fclose(lockfile);
- err.code = errno;
- err.desc = "Cannot read upload's lock file";
- goto error_out;
- }
- }
- fclose(lockfile);
-
- peername = glite_jp_peer_name(ctx);
- if (lockpeername && (!peername || strcmp(lockpeername, peername))) {
- err.code = EPERM;
- err.desc = "Upload started by client of different identity";
- goto error_out;
- }
-
- if (rename(dest_rw_suff, dest_rw) < 0) {
- err.code = errno;
- err.desc = "Cannot move upload file to the final place";
- goto error_out;
- }
-
- if (unlink(dest_rw_lock) < 0) {
- err.code = errno;
- err.desc = "Cannot unlink upload's lock file";
- goto error_out;
- }
-
-error_out:
- free(dest_rw);
- free(dest_rw_suff);
- free(dest_rw_lock);
- free(peername);
- free(lockpeername);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_destination_info(
- glite_jp_context_t ctx,
- const char *destination,
- char **job,
- glite_jp_fileclass_t *class
-)
-{
- size_t dest_len;
- size_t suff_len;
- size_t extp_len;
- char *dest_rw = NULL;
- char *dest_rw_suff = NULL;
- char *dest_rw_info = NULL;
- FILE *infofile = NULL;
- char *classname = NULL;
- char jobstr[256+1];
- glite_jp_error_t err;
-
- assert(destination != NULL);
- assert(job != NULL);
- assert(class != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- suff_len = strlen(UPLOAD_SUFFIX);
- dest_len = strlen(destination);
- extp_len = strlen(config->external_path);
-
- if (dest_len < suff_len ||
- strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) ||
- strncmp(destination, config->external_path, extp_len)) {
- err.code = EINVAL;
- err.desc = "Forged destination path";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&dest_rw_suff, "%s%s", config->internal_path,
- destination + extp_len) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- dest_rw = strdup(dest_rw_suff);
- if (!dest_rw) {
- err.code = ENOMEM;
- goto error_out;
- }
- *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0';
-
- classname = strrchr(dest_rw,'/');
- if (classname == NULL) {
- err.code = EINVAL;
- err.desc = "Forged destination path";
- goto error_out;
- }
- *classname++ ='\0';
- *class = fname_to_class(classname);
- if (!class == GLITE_JP_FILECLASS_UNDEF) {
- err.code = EINVAL;
- err.desc = "Forged destination path";
- goto error_out;
- }
-
- if (asprintf(&dest_rw_info, "%s/_info", dest_rw) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- infofile = fopen(dest_rw_info, "r");
- if (infofile == NULL) {
- err.code = errno;
- err.desc = "Cannot open _info file";
- goto error_out;
- }
- if (fscanf(infofile, "%*d %*ld.%*ld %256s ", jobstr) < 1 || ferror(infofile)) {
- fclose(infofile);
- err.code = errno;
- err.desc = "Cannot read _info file";
- goto error_out;
- }
- *job = strdup(jobstr);
- fclose(infofile);
-
-error_out:
- free(dest_rw);
- free(dest_rw_suff);
- free(dest_rw_info);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-
-int glite_jppsbe_get_job_url(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- char **url_out
-)
-{
- FILE *regfile = NULL;
- char *int_fname = NULL;
- char *fname = NULL;
- char *ju = NULL;
- char *ju_path = NULL;
- int info_version;
- long reg_time;
- char ownerhash[33];
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- assert(job!=NULL);
- assert(class != GLITE_JP_FILECLASS_UNDEF);
- assert(url_out != NULL);
-
- fname = class_to_fname(class);
- assert(fname!=NULL);
-
- if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) {
- err.code = ctx->error->code;
- err.desc = "Cannot obtain jobid unique path/name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&int_fname, "%s/regs/%s/%s.info",
- config->internal_path, ju_path, ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- regfile = fopen(int_fname, "r");
- if (regfile == NULL) {
- err.code = errno;
- if (errno == ENOENT)
- err.desc = "Job not registered";
- else
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
- if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version,
- ®_time, ownerhash) < 3 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- fclose(regfile);
-
- if (asprintf(url_out, "%s/data/%s/%d/%s/%s",
- config->external_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
-error_out:
- free(int_fname);
- free(ju); free(ju_path);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-static int get_job_fname(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- char **fname_out
-)
-{
- FILE *regfile = NULL;
- char *fname = NULL;
- char *int_fname = NULL;
- char *ju = NULL;
- char *ju_path = NULL;
- int info_version;
- long reg_time;
- char ownerhash[33];
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- assert(job!=NULL);
- assert(class != GLITE_JP_FILECLASS_UNDEF);
- assert(fname_out != NULL);
-
- fname = class_to_fname(class);
- assert(fname!=NULL);
-
- if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) {
- err.code = ctx->error->code;
- err.desc = "Cannot obtain jobid unique path/name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&int_fname, "%s/regs/%s/%s.info",
- config->internal_path, ju_path, ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- regfile = fopen(int_fname, "r");
- if (regfile == NULL) {
- err.code = errno;
- if (errno == ENOENT)
- err.desc = "Job not registered";
- else
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
- if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version,
- ®_time, ownerhash) < 3 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- fclose(regfile);
-
- if (asprintf(fname_out, "%s/data/%s/%d/%s/%s",
- config->internal_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
-
-error_out:
- free(int_fname);
- free(ju); free(ju_path);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_open_file(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_fileclass_t class,
- int mode,
- void **handle_out
-)
-{
- fhandle handle = NULL;
- char* fname = NULL;
- glite_jp_error_t err;
-
- assert(handle_out != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (get_job_fname(ctx, job, class, &fname)) {
- err.code = ctx->error->code;
- err.desc = "Cannot construct internal filename";
- return glite_jp_stack_error(ctx,&err);
- }
-
- handle = (fhandle) calloc(1,sizeof(*handle));
- if (handle == NULL) {
- err.code = ENOMEM;
- goto error_out;
- }
-
- handle->fd = open(fname, mode, S_IRUSR | S_IWUSR);
- if (handle->fd < 0) {
- err.code = errno;
- err.desc = "Cannot open requested file";
- free(handle);
- goto error_out;
- }
- handle->fd_append = open(fname, mode | O_APPEND, S_IRUSR | S_IWUSR);
- if (handle->fd_append < 0) {
- err.code = errno;
- err.desc = "Cannot open requested file for append";
- close(handle->fd);
- free(handle);
- goto error_out;
- }
- *handle_out = (void*) handle;
-
-error_out:
- free(fname);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_close_file(
- glite_jp_context_t ctx,
- void *handle
-)
-{
- glite_jp_error_t err;
-
- assert(handle != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (close(((fhandle)handle)->fd_append) < 0) {
- err.code = errno;
- err.desc = "Error closing file descriptor (fd_append)";
- goto error_out;
- }
- if (close(((fhandle)handle)->fd) < 0) {
- err.code = errno;
- err.desc = "Error closing file descriptor";
- goto error_out;
- }
-
-error_out:
- free(handle);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_pread(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes,
- off_t offset,
- ssize_t *nbytes_ret
-)
-{
- ssize_t ret;
- glite_jp_error_t err;
-
- assert(handle != NULL);
- assert(buf != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if ((ret = pread(((fhandle)handle)->fd, buf, nbytes, offset)) < 0) {
- err.code = errno;
- err.desc = "Error in pread()";
- return glite_jp_stack_error(ctx,&err);
- }
- *nbytes_ret = ret;
-
- return 0;
-}
-
-int glite_jppsbe_pwrite(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes,
- off_t offset
-)
-{
- glite_jp_error_t err;
-
- assert(handle != NULL);
- assert(buf != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (pwrite(((fhandle)handle)->fd, buf, nbytes, offset) < 0) {
- err.code = errno;
- err.desc = "Error in pwrite()";
- return glite_jp_stack_error(ctx,&err);
- }
-
- return 0;
-}
-
-int glite_jppsbe_append(
- glite_jp_context_t ctx,
- void *handle,
- void *buf,
- size_t nbytes
-)
-{
- glite_jp_error_t err;
-
- assert(handle != NULL);
- assert(buf != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (write(((fhandle)handle)->fd_append, buf, nbytes) < 0) {
- err.code = errno;
- err.desc = "Error in write()";
- return glite_jp_stack_error(ctx,&err);
- }
-
- return 0;
-}
-
-static int get_job_info(
- glite_jp_context_t ctx,
- const char *job,
- char **owner,
- struct timeval *tv_reg
-)
-{
- char *ju = NULL;
- char *ju_path = NULL;
- FILE *regfile = NULL;
- long reg_time_sec;
- long reg_time_usec;
- int ownerlen = 0;
- int info_version;
- char *int_fname = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) {
- err.code = ctx->error->code;
- err.desc = "Cannot obtain jobid unique path/name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (asprintf(&int_fname, "%s/regs/%s/%s.info",
- config->internal_path, ju_path, ju) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- regfile = fopen(int_fname, "r");
- if (regfile == NULL) {
- err.code = errno;
- if (errno == ENOENT)
- err.desc = "Job not registered";
- else
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
- if (fscanf(regfile, "%d %ld.%ld %*s %*s %d ", &info_version,
- ®_time_sec, ®_time_usec, &ownerlen) < 4 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- if (ownerlen) {
- *owner = (char *) calloc(1, ownerlen+1);
- if (!*owner) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (fgets(*owner, ownerlen+1, regfile) == NULL) {
- fclose(regfile);
- free(*owner);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- }
- fclose(regfile);
-
- tv_reg->tv_sec = reg_time_sec;
- tv_reg->tv_usec = reg_time_usec;
-
-error_out:
- free(int_fname);
- free(ju);
- free(ju_path);
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-static int get_job_info_int(
- glite_jp_context_t ctx,
- const char *int_fname,
- char **jobid,
- char **owner,
- struct timeval *tv_reg
-)
-{
- FILE *regfile = NULL;
- long reg_time_sec;
- long reg_time_usec;
- int ownerlen = 0;
- int info_version;
- char jobid_buf[256];
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- regfile = fopen(int_fname, "r");
- if (regfile == NULL) {
- err.code = errno;
- err.desc = "Cannot open jobs's reg info file";
- goto error_out;
- }
- if (fscanf(regfile, "%d %ld.%ld %s %*s %d ", &info_version,
- ®_time_sec, ®_time_usec, jobid_buf, &ownerlen) < 5 || ferror(regfile)) {
- fclose(regfile);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- *jobid = strdup(jobid_buf);
- if (ownerlen) {
- *owner = (char *) calloc(1, ownerlen+1);
- if (!*owner) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (fgets(*owner, ownerlen+1, regfile) == NULL) {
- fclose(regfile);
- free(*owner);
- err.code = errno;
- err.desc = "Cannot read jobs's reg info file";
- goto error_out;
- }
- }
- fclose(regfile);
-
- tv_reg->tv_sec = reg_time_sec;
- tv_reg->tv_usec = reg_time_usec;
-
-error_out:
- if (err.code) {
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-
-int glite_jppsbe_get_job_metadata(
- glite_jp_context_t ctx,
- const char *job,
- glite_jp_attrval_t attrs_inout[]
-)
-{
- int got_info = 0;
- struct timeval tv_reg;
- char *owner = NULL;
- int got_tags = 0;
- void *tags_handle = NULL;
- glite_jp_tagval_t* tags = NULL;
- int i,j;
- glite_jp_error_t err;
-
- assert(job != NULL);
- assert(attrs_inout != NULL);
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- for (i = 0; attrs_inout[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) {
- switch (attrs_inout[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TIME:
- if (!got_info) {
- if (get_job_info(ctx, job, &owner, &tv_reg)) {
- err.code = ctx->error->code;
- err.desc = "Cannot retrieve job info";
- goto error_out;
- }
- got_info = 1;
- }
- break;
- case GLITE_JP_ATTR_TAG:
- if (!got_tags) {
- if (glite_jppsbe_open_file(ctx, job, GLITE_JP_FILECLASS_TAGS,
- O_RDONLY, &tags_handle)) {
- err.code = ctx->error->code;
- err.desc = "Cannot open tag file";
- goto error_out;
- }
- if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) {
- err.code = ctx->error->code;
- err.desc = "Cannot read tags";
- glite_jppsbe_close_file(ctx, tags_handle);
- goto error_out;
- }
- glite_jppsbe_close_file(ctx, tags_handle);
- got_tags = 1;
- }
- break;
- default:
- err.code = EINVAL;
- err.desc = "Invalid attribute type";
- goto error_out;
- break;
- }
-
- switch (attrs_inout[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- attrs_inout[i].value.s = strdup(owner);
- if (!attrs_inout[i].value.s) {
- err.code = ENOMEM;
- err.desc = "Cannot copy owner string";
- goto error_out;
- }
- break;
- case GLITE_JP_ATTR_TIME:
- attrs_inout[i].value.time = tv_reg;
- break;
- case GLITE_JP_ATTR_TAG:
- for (j = 0; tags[j].name != NULL; j++) {
- if (!strcmp(tags[j].name, attrs_inout[i].attr.name)) {
- if (glite_jpps_tagval_copy(ctx, &tags[j],
- &attrs_inout[i].value.tag)) {
- err.code = ENOMEM;
- err.desc = "Cannot copy tag value";
- goto error_out;
- }
- break;
- }
- }
- if (!tags[j].name) attrs_inout[i].value.tag.name = NULL;
- break;
- default:
- break;
- }
- }
-
-error_out:
- free(owner);
- if (tags) for (j = 0; tags[j].name != NULL; j++) {
- free(tags[j].name);
- free(tags[j].value);
- }
- free(tags);
-
- if (err.code) {
- while (i > 0) {
- i--;
- switch (attrs_inout[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- free(attrs_inout[i].value.s);
- break;
- case GLITE_JP_ATTR_TAG:
- free(attrs_inout[i].value.tag.name);
- free(attrs_inout[i].value.tag.value);
- default:
- break;
- }
- }
- return glite_jp_stack_error(ctx,&err);
- } else {
- return 0;
- }
-}
-static int compare_timeval(struct timeval a, struct timeval b)
-{
- if (a.tv_sec < b.tv_sec) return -1;
- if (a.tv_sec > b.tv_sec) return 1;
- if (a.tv_usec < b.tv_usec) return -1;
- if (a.tv_usec > b.tv_usec) return 1;
- return 0;
-}
-
-static int query_phase2(
- glite_jp_context_t ctx,
- const char *ownerhash,
- long regtime_tr,
- int q_tags,
- int md_tags,
- const glite_jp_query_rec_t query[],
- glite_jp_attrval_t metadata[],
- int (*callback)(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_attrval_t metadata[]
- )
-);
-
-static int query_phase2(
- glite_jp_context_t ctx,
- const char *ownerhash,
- long regtime_tr,
- int q_tags,
- int md_tags,
- const glite_jp_query_rec_t query[],
- glite_jp_attrval_t metadata[],
- int (*callback)(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_attrval_t metadata[]
- )
-)
-{
- char *time_dirname = NULL;
- DIR *time_dirp = NULL;
- struct dirent *jobent;
- char *info_fname = NULL;
- char *jobid = NULL;
- char *owner = NULL;
- struct timeval tv_reg;
- void *tags_handle = NULL;
- int matching;
- int i, j;
- glite_jp_tagval_t* tags = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- if (asprintf(&time_dirname, "%s/data/%s/%d", config->internal_path,
- ownerhash, regtime_tr) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- time_dirp = opendir(time_dirname);
- if (!time_dirp) {
- free(time_dirname);
- return 0; /* found nothing */
- }
- while ((jobent = readdir(time_dirp)) != NULL) {
- if (!strcmp(jobent->d_name, ".")) continue;
- if (!strcmp(jobent->d_name, "..")) continue;
- if (asprintf(&info_fname, "%s/%s/_info", time_dirname,
- jobent->d_name) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- if (get_job_info_int(ctx, info_fname, &jobid, &owner, &tv_reg)) {
- err.code = EIO;
- err.desc = "Cannot retrieve job info";
- goto error_out;
- }
- if (q_tags || md_tags) {
- if (glite_jppsbe_open_file(ctx, jobid, GLITE_JP_FILECLASS_TAGS,
- O_RDONLY, &tags_handle)) {
- err.code = ctx->error->code;
- err.desc = "Cannot open tag file";
- goto error_out;
- }
- if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) {
- err.code = ctx->error->code;
- err.desc = "Cannot read tags";
- glite_jppsbe_close_file(ctx, tags_handle);
- goto error_out;
- }
- glite_jppsbe_close_file(ctx, tags_handle);
- tags_handle = NULL;
- }
-
- matching = 1;
- for (i = 0; matching && query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) {
- switch (query[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- if (query[i].value.s == NULL ||
- strcmp(query[i].value.s, owner)) matching = 0;
- break;
- case GLITE_JP_ATTR_TIME:
- switch (query[i].op) {
- case GLITE_JP_QUERYOP_EQUAL:
- matching = !compare_timeval(tv_reg, query[i].value.time);
- break;
- case GLITE_JP_QUERYOP_UNEQUAL:
- matching = compare_timeval(tv_reg, query[i].value.time);
- break;
- case GLITE_JP_QUERYOP_LESS:
- matching = compare_timeval(tv_reg, query[i].value.time) < 0;
- break;
- case GLITE_JP_QUERYOP_GREATER:
- matching = compare_timeval(tv_reg, query[i].value.time) > 0;
- break;
- case GLITE_JP_QUERYOP_WITHIN:
- matching = compare_timeval(tv_reg, query[i].value.time) >= 0
- && compare_timeval(tv_reg, query[i].value2.time) <= 0;
- break;
- }
- break;
- case GLITE_JP_ATTR_TAG:
- if (!tags) {
- matching = 0;
- break;
- }
- for (j = 0; tags[j].name != NULL; j++) {
- if (!strcmp(tags[j].name, query[i].attr.name)) {
- switch (query[i].op) {
- case GLITE_JP_QUERYOP_EQUAL:
- matching = !strcmp(tags[j].value, query[i].value.s);
- break;
- case GLITE_JP_QUERYOP_UNEQUAL:
- matching = strcmp(tags[j].value, query[i].value.s);
- break;
- case GLITE_JP_QUERYOP_LESS:
- matching = strcmp(tags[j].value, query[i].value.s) < 0;
- break;
- case GLITE_JP_QUERYOP_GREATER:
- matching = strcmp(tags[j].value, query[i].value.s) > 0;
- break;
- case GLITE_JP_QUERYOP_WITHIN:
- matching = strcmp(tags[j].value, query[i].value.s) >= 0 \
- && strcmp(tags[j].value, query[i].value2.s) <= 0 ;
- break;
- default:
- break;
- }
- }
- }
- break;
- default:
- break;
- }
- }
- if (!matching) {
- free(info_fname); info_fname = NULL;
- free(jobid); jobid = NULL;
- if (tags) for (j = 0; tags[j].name != NULL; j++) {
- free(tags[j].name);
- free(tags[j].value);
- }
- free(tags); tags = NULL;
- continue;
- }
-
- for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) {
- switch (metadata[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- metadata[i].value.s = owner;
- break;
- case GLITE_JP_ATTR_TIME:
- metadata[i].value.time = tv_reg;
- break;
- case GLITE_JP_ATTR_TAG:
- for (j = 0; tags[j].name != NULL; j++) {
- if (!strcmp(tags[j].name, metadata[i].attr.name)) {
- if (glite_jpps_tagval_copy(ctx, &tags[j],
- &metadata[i].value.tag)) {
- err.code = ENOMEM;
- err.desc = "Cannot copy tag value";
- goto error_out;
- }
- break;
- }
- }
- if (!tags[j].name) {
- metadata[i].value.tag.name = NULL;
- metadata[i].value.tag.value = NULL;
- }
- break;
- default:
- break;
- }
- }
- (*callback)(ctx, jobid, metadata);
- free(jobid); jobid = NULL;
- while (i > 0) {
- i--;
- switch (metadata[i].attr.type) {
- case GLITE_JP_ATTR_TAG:
- free(metadata[i].value.tag.name);
- free(metadata[i].value.tag.value);
- default:
- break;
- }
- }
- }
-
-error_out:
- if (tags) for (j = 0; tags[j].name != NULL; j++) {
- free(tags[j].name);
- free(tags[j].value);
- }
- if (tags_handle) glite_jppsbe_close_file(ctx, tags_handle);
- free(info_fname);
- free(owner);
- free(jobid);
- closedir(time_dirp);
- free(time_dirname);
- if (err.code) {
- while (i > 0) {
- i--;
- switch (metadata[i].attr.type) {
- case GLITE_JP_ATTR_TAG:
- free(metadata[i].value.tag.name);
- free(metadata[i].value.tag.value);
- default:
- break;
- }
- }
- return glite_jp_stack_error(ctx,&err);
- } else
- return 0;
-}
-
-int glite_jppsbe_query(
- glite_jp_context_t ctx,
- const glite_jp_query_rec_t query[],
- const glite_jp_attrval_t metadata[],
- int (*callback)(
- glite_jp_context_t ctx,
- const char *job,
- const glite_jp_attrval_t metadata[]
- )
-)
-{
- /* XXX clone metadata */
- int i;
- char *q_exact_owner = NULL;
- char *ownerhash = NULL;
- long q_min_time = 0;
- long q_max_time = LONG_MAX;
- long q_min_time_tr;
- long q_max_time_tr;
- int q_with_tags = 0;
- int md_info = 0;
- int md_tags = 0;
- char *owner_dirname = NULL;
- DIR *owner_dirp = NULL;
- struct dirent *ttimeent;
- char *data_dirname = NULL;
- DIR *data_dirp = NULL;
- struct dirent *ownerent;
- long ttime = 0;
- glite_jp_attrval_t *metadata_templ = NULL;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- for (i = 0; query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) {
- if (query[i].attr.type == GLITE_JP_ATTR_OWNER && query[i].op == GLITE_JP_QUERYOP_EQUAL) {
- q_exact_owner = query[i].value.s;
- }
- if (query[i].attr.type == GLITE_JP_ATTR_TIME) {
- switch (query[i].op) {
- case GLITE_JP_QUERYOP_EQUAL:
- q_min_time = query[i].value.time.tv_sec;
- q_max_time = query[i].value.time.tv_sec + 1;
- break;
- case GLITE_JP_QUERYOP_LESS:
- if (q_max_time > query[i].value.time.tv_sec + 1)
- q_max_time = query[i].value.time.tv_sec + 1;
- break;
- case GLITE_JP_QUERYOP_WITHIN:
- if (q_max_time > query[i].value2.time.tv_sec + 1)
- q_max_time = query[i].value2.time.tv_sec + 1;
- /* fallthrough */
- case GLITE_JP_QUERYOP_GREATER:
- if (q_min_time < query[i].value.time.tv_sec)
- q_min_time = query[i].value.time.tv_sec;
- break;
- default:
- err.code = EINVAL;
- err.desc = "Invalid query op";
- return glite_jp_stack_error(ctx,&err);
- break;
- }
- }
- if (query[i].attr.type == GLITE_JP_ATTR_TAG)
- q_with_tags = 1;
-
- }
-
- for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) {
- switch (metadata[i].attr.type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TIME:
- md_info = 1;
- break;
- case GLITE_JP_ATTR_TAG:
- md_tags = 1;
- break;
- default:
- err.code = EINVAL;
- err.desc = "Invalid attribute type in metadata parameter";
- return glite_jp_stack_error(ctx,&err);
- break;
- }
- }
- metadata_templ = (glite_jp_attrval_t *) calloc(i + 1, sizeof(glite_jp_attrval_t));
- if (!metadata_templ) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- memcpy(metadata_templ, metadata, (i + 1) * sizeof(glite_jp_attrval_t));
-
- q_min_time_tr = regtime_trunc(q_min_time);
- q_max_time_tr = regtime_ceil(q_max_time);
-
- if (q_exact_owner) {
- ownerhash = str2md5(q_exact_owner); /* static buffer */
- if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path, ownerhash) == -1) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- owner_dirp = opendir(owner_dirname);
- free(owner_dirname);
- if (!owner_dirp) {
- free(metadata_templ);
- return 0; /* found nothing */
- }
- while ((ttimeent = readdir(owner_dirp)) != NULL) {
- if (!strcmp(ttimeent->d_name, ".")) continue;
- if (!strcmp(ttimeent->d_name, "..")) continue;
- ttime = atol(ttimeent->d_name);
- if (ttime >= q_min_time_tr && ttime < q_max_time_tr) {
- if (query_phase2(ctx, ownerhash, ttime, q_with_tags, md_tags,
- query, metadata_templ, callback)) {
- err.code = EIO;
- err.desc = "query_phase2() error";
- goto error_out;
- }
- }
- }
- } else { /* !q_exact_owner */
- if (asprintf(&data_dirname, "%s/data", config->internal_path) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- data_dirp = opendir(data_dirname);
- if (!data_dirp) {
- err.code = EIO;
- err.desc = "Cannot open data directory";
- goto error_out;
- }
- while ((ownerent = readdir(data_dirp)) != NULL) {
- if (!strcmp(ownerent->d_name, ".")) continue;
- if (!strcmp(ownerent->d_name, "..")) continue;
- if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path,
- ownerent->d_name) == -1) {
- err.code = ENOMEM;
- goto error_out;
- }
- owner_dirp = opendir(owner_dirname);
- free(owner_dirname);
- if (!owner_dirp) {
- err.code = EIO;
- err.desc = "Cannot open owner data directory";
- goto error_out;
- }
- while ((ttimeent = readdir(owner_dirp)) != NULL) {
- if (!strcmp(ttimeent->d_name, ".")) continue;
- if (!strcmp(ttimeent->d_name, "..")) continue;
- ttime = atol(ttimeent->d_name);
- if (ttime >= q_min_time_tr && ttime < q_max_time_tr) {
- if (query_phase2(ctx, ownerent->d_name, ttime, q_with_tags, md_tags,
- query, metadata_templ, callback)) {
- err.code = EIO;
- err.desc = "query_phase2() error";
- goto error_out;
- }
- }
- }
- closedir(owner_dirp); owner_dirp = NULL;
- }
- closedir(data_dirp); data_dirp = NULL;
- }
- return 0;
-
-error_out:
- if (owner_dirp) closedir(owner_dirp);
- if (data_dirp) closedir(data_dirp);
- free(data_dirname);
- free(metadata_templ);
- return glite_jp_stack_error(ctx,&err);
-}
-
-/* XXX:
-- no primary authorization yet
-- no concurrency control yet
-- partial success in pwrite,append
-- "unique" part of jobid is assumed to be unique across bookkeeping servers
-- repository versioning not fully implemented yet
-*/
+++ /dev/null
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "glite/jp/types.h"
-
-#include "feed.h"
-#include "jpis_H.h"
-#include "jpis_.nsmap"
-
-int glite_jpps_single_feed(
- glite_jp_context_t ctx,
- const char *destination,
- const char *job,
- const glite_jp_attrval_t attrs[]
-)
-{
- /* TODO: really call JP Index server (via interlogger) */
- printf("feed to %s, job %s\n",destination,job);
-
- if (soap_call_jpsrv__UpdateJobs(ctx->other_soap,destination,"",
- /* FIXME: feedId */ "",
- /* FIXME: UpdateJobsData */ NULL,
- 0,
- NULL
- )) fprintf(stderr,"UpdateJobs: %s %s\n",ctx->other_soap->fault->faultcode,
- ctx->other_soap->fault->faultstring);
-
- return 0;
-}
+++ /dev/null
-#if GSOAP_VERSION >= 20700
-#define INPUT_SANDBOX jptype__UploadClass__INPUT_SANDBOX
-#define OUTPUT_SANDBOX jptype__UploadClass__OUTPUT_SANDBOX
-#define JOB_LOG jptype__UploadClass__JOB_LOG
-
-#define OWNER jptype__AttributeType__OWNER
-#define TIME jptype__AttributeType__TIME
-#define TAG jptype__AttributeType__TAG
-
-#define EQUAL jptype__QueryOp__EQUAL
-#define UNEQUAL jptype__QueryOp__UNEQUAL
-#define LESS jptype__QueryOp__LESS
-#define GREATER jptype__QueryOp__GREATER
-#define WITHIN jptype__QueryOp__WITHIN
-#endif
-
+++ /dev/null
-#include <stdio.h>
-
-#include "glite/jp/types.h"
-#include "glite/jp/context.h"
-
-#include "jpps_H.h"
-
-extern SOAP_NMAC struct Namespace jpis__namespaces[],jpps__namespaces[];
-
-int main(int argc, char *argv[]) {
- struct soap soap;
- int i, m, s; // master and slave sockets
-
- glite_jp_context_t ctx;
-
- soap_init(&soap);
- soap_set_namespaces(&soap, jpps__namespaces);
-
- glite_jp_init_context(&ctx);
-
- if (glite_jppsbe_init(ctx, &argc, argv)) {
- /* XXX log */
- fputs(glite_jp_error_chain(ctx), stderr);
- exit(1);
- }
-
- soap.user = (void *) ctx;
-
- ctx->other_soap = soap_new();
- soap_init(ctx->other_soap);
- soap_set_namespaces(ctx->other_soap,jpis__namespaces);
-
- srand48(time(NULL)); /* feed id generation */
-
- m = soap_bind(&soap, NULL, 8901, 100);
- if (m < 0)
- soap_print_fault(&soap, stderr);
- else
- {
- fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
- for (i = 1; ; i++) {
- s = soap_accept(&soap);
- if (s < 0) {
- soap_print_fault(&soap, stderr);
- break;
- }
- jpps__serve(&soap); // process RPC request
- soap_destroy(&soap); // clean up class instances
- soap_end(&soap); // clean up everything and close socket
- glite_jp_run_deferred(ctx);
- }
- }
- soap_done(&soap); // close master socket
-
- return 0;
-}
-
-/* XXX: we don't use it */
-SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} };
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "glite/jp/types.h"
-#include "glite/jp/context.h"
-
-#include "feed.h"
-
-#include "jpps_H.h"
-/* #include "JobProvenancePS.nsmap" */
-#include "jpps_.nsmap"
-
-#include "jptype_map.h"
-
-static struct jptype__GenericJPFaultType *jp2s_error(struct soap *soap,
- const glite_jp_error_t *err)
-{
- struct jptype__GenericJPFaultType *ret = NULL;
- if (err) {
- ret = soap_malloc(soap,sizeof *ret);
- memset(ret,0,sizeof *ret);
- ret->code = err->code;
- ret->source = soap_strdup(soap,err->source);
- ret->text = soap_strdup(soap,strerror(err->code));
- ret->description = soap_strdup(soap,err->desc);
- ret->reason = jp2s_error(soap,err->reason);
- }
- return ret;
-}
-
-static void err2fault(const glite_jp_context_t ctx,struct soap *soap)
-{
- char *et;
- struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail);
- struct _GenericJPFault *f = soap_malloc(soap,sizeof *f);
-
-
- f->jptype__GenericJPFault = jp2s_error(soap,ctx->error);
-
- detail->__type = SOAP_TYPE__GenericJPFault;
-#if GSOAP_VERSION >= 20700
- detail->fault = f;
-#else
- detail->value = f;
-#endif
- detail->__any = NULL;
-
- soap_receiver_fault(soap,"Oh, shit!",NULL);
- if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail;
- else soap->fault->detail = detail;
-}
-
-static glite_jp_fileclass_t s2jp_fileclass(enum jptype__UploadClass class)
-{
- switch (class) {
- case INPUT_SANDBOX: return GLITE_JP_FILECLASS_INPUT;
- case OUTPUT_SANDBOX: return GLITE_JP_FILECLASS_OUTPUT;
- case JOB_LOG: return GLITE_JP_FILECLASS_LBLOG;
- default: return GLITE_JP_FILECLASS_UNDEF;
- }
-}
-
-static void s2jp_tag(const struct jptype__TagValue *stag,glite_jp_tagval_t *jptag)
-{
- memset(jptag,0,sizeof *jptag);
- jptag->name = strdup(stag->name);
- jptag->sequence = stag->sequence ? *stag->sequence : 0;
- jptag->timestamp = stag->timestamp ? *stag->timestamp : 0;
- if (stag->stringValue) jptag->value = strdup(stag->stringValue);
- else if (stag->blobValue) {
- jptag->binary = 1;
- jptag->size = stag->blobValue->__size;
- jptag->value = (char *) stag->blobValue->__ptr;
- }
-}
-
-#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user)
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__RegisterJob(
- struct soap *soap,
- char *job,
- struct jpsrv__RegisterJobResponse *response)
-{
- CONTEXT_FROM_SOAP(soap,ctx);
- char *owner = glite_jp_peer_name(ctx);
- glite_jp_attrval_t owner_val[2];
-
- if (glite_jppsbe_register_job(ctx,job,owner)) {
- err2fault(ctx,soap);
- free(owner);
- return SOAP_FAULT;
- }
-
- owner_val[0].attr.type = GLITE_JP_ATTR_OWNER;
- owner_val[0].value.s = owner;
- owner_val[1].attr.type = GLITE_JP_ATTR_UNDEF;
-
-/* XXX: errrors should be ingored but not silently */
- glite_jpps_match_attr(ctx,job,owner_val);
- free(owner);
-
- return SOAP_OK;
-}
-
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__StartUpload(
- struct soap *soap,
- char *job,
- enum jptype__UploadClass class,
- time_t commit_before,
- char *content_type,
- struct jpsrv__StartUploadResponse *response)
-{
- CONTEXT_FROM_SOAP(soap,ctx);
- glite_jp_fileclass_t jclass = s2jp_fileclass(class);
- char *destination;
-
- if (glite_jppsbe_start_upload(ctx,job,jclass,content_type,&destination,&commit_before)) {
- err2fault(ctx,soap);
- return SOAP_FAULT;
- }
-
- response->destination = soap_strdup(soap,destination);
- free(destination);
- response->commitBefore = commit_before;
-
- return SOAP_OK;
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__CommitUpload(
- struct soap *soap,
- char *destination,
- struct jpsrv__CommitUploadResponse *response)
-{
- CONTEXT_FROM_SOAP(soap,ctx);
- char *job = NULL;
- glite_jp_fileclass_t class;
-
- if (glite_jppsbe_commit_upload(ctx,destination)) {
- err2fault(ctx,soap);
- return SOAP_FAULT;
- }
-
- /* XXX: should not fail when commit_upload was OK */
- glite_jppsbe_destination_info(ctx,destination,&job,&class);
-
- /* XXX: ignore errors but don't fail silenty */
- glite_jpps_match_file(ctx,job,class);
-
- return SOAP_OK;
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__RecordTag(
- struct soap *soap,
- char *job,
- struct jptype__TagValue *tag,
- struct jpsrv__RecordTagResponse *response)
-{
- CONTEXT_FROM_SOAP(soap,ctx);
- void *tagfile;
-
- glite_jp_tagval_t mytag;
-
- if (glite_jppsbe_open_file(ctx,job,GLITE_JP_FILECLASS_TAGS,
- O_WRONLY|O_CREAT,&tagfile))
- {
- err2fault(ctx,soap);
- return SOAP_FAULT;
- }
-
- if (glite_jpps_tag_append(ctx,tagfile,&mytag)) {
- err2fault(ctx,soap);
- glite_jppsbe_close_file(ctx,tagfile);
- return SOAP_FAULT;
- }
-
- if (glite_jppsbe_close_file(ctx,tagfile)) {
- err2fault(ctx,soap);
- return SOAP_FAULT;
- }
-
- /* XXX: ignore errors but don't fail silenty */
-
- s2jp_tag(tag,&mytag);
- glite_jpps_match_tag(ctx,job,&mytag);
-
- return SOAP_OK;
-}
-
-static void s2jp_attr(const struct jptype__Attribute *in,glite_jp_attr_t *out)
-{
- switch (in->type) {
- case OWNER: out->type = GLITE_JP_ATTR_OWNER; break;
- case TIME: out->type = GLITE_JP_ATTR_TIME;
- out->name = strdup(in->name);
- break;
- case TAG: out->type = GLITE_JP_ATTR_TAG;
- out->name = strdup(in->name);
- break;
- default: break;
- }
-}
-
-static void s2jp_queryval(
- const char *in,
- glite_jp_attrtype_t type,
- union _glite_jp_query_rec_val *out)
-{
- switch (type) {
- case GLITE_JP_ATTR_OWNER:
- case GLITE_JP_ATTR_TAG:
- out->s = strdup(in);
- break;
- case GLITE_JP_ATTR_TIME:
- out->time.tv_sec = atoi(in);
- break;
- }
-}
-
-static void s2jp_query(const struct jptype__PrimaryQueryElement *in, glite_jp_query_rec_t *out)
-{
- s2jp_attr(in->attr,&out->attr);
-
- switch (in->op) {
- case EQUAL: out->op = GLITE_JP_QUERYOP_EQUAL; break;
- case UNEQUAL: out->op = GLITE_JP_QUERYOP_UNEQUAL; break;
- case LESS: out->op = GLITE_JP_QUERYOP_LESS; break;
- case GREATER: out->op = GLITE_JP_QUERYOP_GREATER; break;
- case WITHIN:
- out->op = GLITE_JP_QUERYOP_WITHIN;
- s2jp_queryval(in->value2,out->attr.type,&out->value2);
- break;
- }
-
- s2jp_queryval(in->value,out->attr.type,&out->value);
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__FeedIndex(
- struct soap *soap,
- char *destination,
- struct jptype__Attributes *attributes,
- struct jptype__PrimaryQuery *query,
- enum xsd__boolean history,
- enum xsd__boolean continuous,
- struct jpsrv__FeedIndexResponse *response)
-{
-
-/* deferred processing: return feed_id to the index server first,
- * start feeding it afterwards -- not before the index server actually
- * knows feed_id and is ready to accept the feed.
- *
- * Has to be done within the same server slave,
- * passed through the context */
-
- CONTEXT_FROM_SOAP(soap,ctx);
- char *feed_id = NULL;
- time_t expires = 0;
- int ret = SOAP_OK;
-
- glite_jp_attr_t *attrs = calloc(attributes->__sizeitem+1,sizeof *attrs);
- glite_jp_query_rec_t *qry = calloc(query->__sizeitem+1,sizeof *qry);
- int i;
-
- glite_jp_clear_error(ctx);
-
- for (i = 0; i<attributes->__sizeitem; i++) s2jp_attr(attributes->item[i],attrs+i);
- for (i = 0; i<query->__sizeitem; i++) s2jp_query(query->item[i],qry+i);
-
- if (history) {
- if (glite_jpps_run_feed(ctx,destination,attrs,qry,&feed_id)) {
- err2fault(ctx,soap);
- ret = SOAP_FAULT;
- goto cleanup;
- }
- }
-
- if (continuous) {
- if (glite_jpps_register_feed(ctx,destination,attrs,qry,&feed_id,&expires)) {
- err2fault(ctx,soap);
- ret = SOAP_FAULT;
- goto cleanup;
- }
- }
-
- if (!history && !continuous) {
- glite_jp_error_t err;
- err.code = EINVAL;
- err.source = __FUNCTION__;
- err.desc = "at least one of <history> and <continous> must be true";
- glite_jp_stack_error(ctx,&err);
- err2fault(ctx,soap);
- ret = SOAP_FAULT;
- goto cleanup;
- }
-
- response->expires = expires;
- response->feedId = soap_strdup(soap,feed_id);
-
-cleanup:
- free(feed_id);
- for (i=0; attrs[i].type; i++) free(attrs[i].name);
- free(attrs);
- for (i=0; qry[i].attr.type; i++) glite_jp_free_query_rec(qry+i);
- free(qry);
-
- return ret;
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__FeedIndexRefresh(
- struct soap *soap,
- char *feed_id,
- struct jpsrv__FeedIndexRefreshResponse *response)
-{
- fprintf(stderr,"%s: not implemented\n",__FUNCTION__);
- abort();
-}
-
-SOAP_FMAC5 int SOAP_FMAC6 jpsrv__GetJob(
- struct soap *soap,
- char *job,
- struct jpsrv__GetJobResponse *response)
-{
- CONTEXT_FROM_SOAP(soap,ctx);
- char *url;
-
- struct {
- glite_jp_fileclass_t type;
- char **url;
- char *name;
- } tab[] = {
- { GLITE_JP_FILECLASS_INPUT, &response->inputSandbox, "input sandbox" },
- { GLITE_JP_FILECLASS_OUTPUT, &response->outputSandbox, "output sandbox" },
- { GLITE_JP_FILECLASS_LBLOG, &response->jobLog, "L&B log" },
- { GLITE_JP_FILECLASS_TAGS, &response->tags, "JP tags" },
- { GLITE_JP_FILECLASS_UNDEF, NULL, NULL }
- };
-
- int i,gotone = 0;
- glite_jp_error_t err;
-
- for (i=0; tab[i].type; i++) {
- glite_jp_clear_error(ctx);
- switch (glite_jppsbe_get_job_url(ctx,job,tab[i].type,&url)) {
- case 0: *tab[i].url = soap_strdup(soap,url);
- free(url);
- gotone = 1;
- break;
- case ENOENT:
- *tab[i].url = NULL;
- break;
- default:
- err.code = ctx->error->code;
- err.source = "jpsrv__GetJob()";
- err.desc = tab[i].name;
- glite_jp_stack_error(ctx,&err);
- err2fault(ctx,soap);
- glite_jp_clear_error(ctx);
- return SOAP_FAULT;
- }
- }
-
- if (!gotone) {
- glite_jp_clear_error(ctx);
- err.code = ENOENT;
- err.source = __FUNCTION__;
- err.desc = "No file found for this job";
- glite_jp_stack_error(ctx,&err);
- err2fault(ctx,soap);
- glite_jp_clear_error(ctx);
- return SOAP_FAULT;
- }
- return SOAP_OK;
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <glite/jp/types.h>
-#include "tags.h"
-#include "backend.h"
-
-/* magic name_len value_len binary sequence timestamp */
-#define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#"
-#define HEADER_SIZE 48
-
-int glite_jpps_tag_append(
- glite_jp_context_t ctx,
- void *handle,
- const glite_jp_tagval_t *tag
-)
-{
- char hdr[HEADER_SIZE+1];
- glite_jp_error_t err;
-
- unsigned long vlen = tag->binary ? tag->size :
- (tag->value ? strlen(tag->value) : 0);
- int nlen;
-
- memset(&err,0,sizeof err);
- err.source = "glite_jpps_tag_append()";
-
- if (!tag->name) {
- err.code = EINVAL;
- err.desc = "tag name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- nlen = strlen(tag->name);
-
- assert(sprintf(hdr,HEADER,nlen,vlen,
- tag->binary ? "B" : "S",
- tag->sequence, tag->timestamp) == HEADER_SIZE);
-
- if (glite_jppsbe_append(ctx,handle,hdr,HEADER_SIZE)) {
- err.code = EIO;
- err.desc = "write tag header";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (glite_jppsbe_append(ctx,handle,tag->name,nlen)) {
- err.code = EIO;
- err.desc = "write tag name";
- return glite_jp_stack_error(ctx,&err);
- }
-
- if (glite_jppsbe_append(ctx,handle,tag->value,vlen)) {
- err.code = EIO;
- err.desc = "write tag value";
- return glite_jp_stack_error(ctx,&err);
- }
-
- return 0;
-}
-
-int glite_jpps_tagval_copy(
- glite_jp_context_t ctx,
- glite_jp_tagval_t *from,
- glite_jp_tagval_t *to
-)
-{
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- to->name = strdup(from->name);
- if (!to->name) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- to->sequence = from->sequence;
- to->timestamp = from->timestamp;
- to->binary = from->binary;
- to->size = from->size;
- to->value = (char *) malloc(to->size);
- if (!to->value) {
- free(to->name);
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- memcpy(from->value, to->value, to->size);
-
- return 0;
-}
-
-int glite_jpps_tag_read(
- glite_jp_context_t ctx,
- void *handle,
- off_t offset,
- glite_jp_tagval_t *tagvalue,
- size_t *shift
-)
-{
- char hdr[HEADER_SIZE+1];
- unsigned int nlen;
- unsigned long vlen;
- char binary;
- unsigned sequence;
- unsigned timestamp;
- char * name = NULL;
- char * value = NULL;
- ssize_t ret;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- hdr[HEADER_SIZE] = '\0';
- if (glite_jppsbe_pread(ctx, handle, hdr, HEADER_SIZE, offset, &ret)) {
- err.code = EIO;
- err.desc = "Cannot read tag header";
- goto error_out;
- }
- if (ret == 0) {
- err.code = ENOENT;
- err.desc = "No more tags in the file";
- goto error_out;
- }
- /* #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";
- goto error_out;
- }
- name = (char*) malloc(nlen + 1);
- if (!name) {
- err.code = ENOMEM;
- goto error_out;
- }
- name[nlen] = '\0';
- value = (char*) malloc(vlen + 1);
- if (!value) {
- err.code = ENOMEM;
- goto error_out;
- }
- value[vlen] = '\0';
- if (glite_jppsbe_pread(ctx, handle, name, nlen, offset + HEADER_SIZE, &ret)) {
- err.code = EIO;
- err.desc = "Cannot read tag name";
- goto error_out;
- }
- if (glite_jppsbe_pread(ctx, handle, value, vlen, offset + HEADER_SIZE + nlen, &ret)) {
- err.code = EIO;
- err.desc = "Cannot read tag value";
- goto error_out;
- }
-
- tagvalue->name = name;
- tagvalue->sequence = sequence;
- tagvalue->timestamp = timestamp;
- tagvalue->binary = (binary == 'B') ? 1 : 0;
- tagvalue->size = vlen;
- tagvalue->value = value;
-
- *shift = HEADER_SIZE + nlen + vlen;
-
- return 0;
-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(
- glite_jp_context_t ctx,
- void *handle,
- glite_jp_tagval_t **tags_out
-)
-{
- glite_jp_tagval_t * tags = NULL;
- void * newspace;
- int ntags = 0;
- int ntagspace = 0;
- off_t offset = 0;
- int ret;
- size_t shift;
- glite_jp_error_t err;
-
- glite_jp_clear_error(ctx);
- memset(&err,0,sizeof err);
- err.source = __FUNCTION__;
-
- ntagspace = 1;
- tags = (glite_jp_tagval_t *) calloc(ntagspace + 1, sizeof(*tags));
- if (!tags) {
- err.code = ENOMEM;
- return glite_jp_stack_error(ctx,&err);
- }
- while (!(ret = glite_jpps_tag_read(ctx, handle, offset, &tags[ntags], &shift))) {
- offset += shift;
- ntags++;
- if (ntagspace <= ntags) {
- ntagspace += 1;
- newspace = realloc(tags, (ntagspace + 1) * sizeof(*tags));
- if (!newspace) {
- err.code = ENOMEM;
- goto error_out;
- }
- tags = (glite_jp_tagval_t *) newspace;
- }
- }
- if (ret == ENOENT) {
- *tags_out = tags;
- return 0;
- } else {
- err.code = EIO;
- err.desc = "Error reading tag value";
- }
-
-error_out:
- for (; ntags-- ;) {
- free(tags[ntags].name);
- free(tags[ntags].value);
- }
- free(tags);
- return glite_jp_stack_error(ctx,&err);
-}
+++ /dev/null
-int glite_jpps_tag_append(glite_jp_context_t,void *,const glite_jp_tagval_t *);
+++ /dev/null
-jpsrv = http://glite.org/wsdl/services/jp
-jptype = http://glite.org/wsdl/types/jp
+++ /dev/null
-.project
-.cdtproject
\ No newline at end of file
+++ /dev/null
-# Default values
-top_srcdir=.
-builddir=build
-top_builddir=${top_srcdir}/${builddir}
-stagedir=.
-distdir=.
-globalprefix=glite
-package=glite-jp-ws-interface
-version=0.0.0
-PREFIX=/opt/glite
-
--include Makefile.inc
-
-VPATH=${top_srcdir}/interface
-STAGETO=interface
-
-WSDL=JobProvenancePS.wsdl JobProvenanceTypes.wsdl
-
-all compile:
-
-check:
- @echo No unit test required for interface-only module.
-
-stage:
- $(MAKE) install PREFIX=${stagedir}
-
-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=${top_srcdir}/tmpbuilddir
- cd ${top_srcdir}/tmpbuilddir && tar -czf ${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *
- rm -rf ${top_srcdir}/tmpbuilddir
-
-install:
- -mkdir -p ${PREFIX}/${STAGETO}
- -mkdir -p ${PREFIX}/share/doc/${package}-${version}
- install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
- cd ${top_srcdir}/interface && install -m 644 ${WSDL} ${PREFIX}/${STAGETO}
-
-clean:
- rm -f *.h
-
+++ /dev/null
-<WSDL:definitions
- xmlns:tns="http://glite.org/wsdl/services/jp"
- xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:jp="http://glite.org/wsdl/types/jp"
- xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- targetNamespace="http://glite.org/wsdl/services/jp"
- name="JobProvenanceIS">
-
- <import namespace="http://glite.org/wsdl/types/jp" location="JobProvenanceTypes.wsdl"/>
-
- <message name="GenericJPFault">
- <part name="fault" element="jp:GenericJPFault"/>
- </message>
-
- <message name="QueryJobsRequest">
- <part name="conditions" type="jp:IndexQuery"/>
- </message>
-
- <message name="QueryJobsResponse">
- <part name="jobs" type="jp:JobRecords"/>
- </message>
-
- <message name="UpdateJobsRequest">
- <part name="feedId" type="xsd:string"/>
- <part name="data" type="jp:UpdateJobsData"/>
- <part name="feedDone" type="xsd:boolean"/>
- </message>
- <message name="EmptyResponse"/>
-
- <portType name="JobProvenanceIS_PortType">
- <operation name="UpdateJobs">
- <documentation>Store or update information on jobs within the JP index server.
-Called directly by the primary storage, used for both batch and incremental feed.
-
-Input:
-
-data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values.
-
-feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation
-the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.)
-
-Output: N/A
-
-Faults: GenericJPFault
-
-
- </documentation>
- <input message="tns:UpdateJobsRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="QueryJobs">
- <documentation>Retrieve pointers to job records of jobs matching a query.
-Input: conditions - list of lists of query conditions.
- Elements of the inner lists refer to a single job attribute, the conditions are or-ed.
- Elements of the outer list may refer to different job attributes, they are and-ed.
-
-Output:
-
-jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:QueryJobsRequest"/>
- <output message="tns:QueryJobsResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- </portType>
-
- <binding name="JobProvenanceIS" type="tns:JobProvenanceIS_PortType">
- <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
- <operation name="UpdateJobs">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="QueryJobs">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- </binding>
-
- <service name="JobProvenanceIS">
- <documentation>Job Provenance Index service</documentation>
- <port name="JobProvenanceIS" binding="tns:JobProvenanceIS">
- <SOAP:address location="http://localhost:10001"/>
- </port>
- </service>
-
-
-</WSDL:definitions>
+++ /dev/null
-<WSDL:definitions
- xmlns:tns="http://glite.org/wsdl/services/jp"
- xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:jp="http://glite.org/wsdl/types/jp"
- xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- targetNamespace="http://glite.org/wsdl/services/jp"
- name="JobProvenancePS">
-
- <import namespace="http://glite.org/wsdl/types/jp" location="JobProvenanceTypes.wsdl"/>
-
- <message name="RegisterJobRequest">
- <part name="job" type="xsd:string"/>
- </message>
- <message name="StartUploadRequest">
- <part name="job" type="xsd:string"/>
- <part name="uclass" type="jp:UploadClass"/>
- <part name="commitBefore" type="xsd:dateTime"/>
- <part name="contentType" type="xsd:string"/>
- </message>
- <message name="StartUploadResponse">
- <part name="destination" type="xsd:string"/>
- <part name="commitBefore" type="xsd:dateTime"/>
- </message>
- <message name="CommitUploadRequest">
- <part name="destination" type="xsd:string"/>
- </message>
- <message name="RecordTagRequest">
- <part name="jobid" type="xsd:string"/>
- <part name="tag" type="jp:TagValue"/>
- </message>
- <message name="FeedIndexRequest">
- <part name="destination" type="xsd:string"/>
- <part name="attributes" type="jp:Attributes"/>
- <part name="conditions" type="jp:PrimaryQuery"/>
- <part name="history" type="xsd:boolean"/>
- <part name="continuous" type="xsd:boolean"/>
- </message>
- <message name="FeedIndexResponse">
- <part name="feedId" type="xsd:string"/>
- <part name="expires" type="xsd:dateTime"/>
- </message>
- <message name="FeedIndexRefreshRequest">
- <part name="feedId" type="xsd:string"/>
- </message>
- <message name="GetJobRequest">
- <part name="jobid" type="xsd:string"/>
- </message>
- <message name="GetJobResponse">
- <part name="jobLog" type="xsd:string"/>
- <part name="inputSandbox" type="xsd:string"/>
- <part name="outputSandbox" type="xsd:string"/>
- <part name="tags" type="xsd:string"/>
- </message>
- <message name="GenericJPFault">
- <part name="fault" element="jp:GenericJPFault"/>
- </message>
- <message name="EmptyResponse"/>
- <portType name="JobProvenancePS_PortType">
- <operation name="RegisterJob">
- <documentation>Register job with JP primary storage.
-Job registration in LB is propagated to JP immediately so that JP is aware of the job,
-despite no furhter information is available in it.
-
-Input: JobId
-
-Output: N/A
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:RegisterJobRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="StartUpload">
- <documentation>Initiate upload of of sandbox/dump of job life log from LB.
-WM component responsible for job sandbox management and LB server call JP to declare
-intention to upload intput/output sandbox and job life log.
-
-Input:
-
-uclass: type of the upload - INPUT_SANDBOX, OUTPUT_SANDBOX, JOB_LOG
-
-commitTimeout: upper limit on time for which JP waits for committing this upload transaction
-
-contentType: MIME type of the uploaded file
-
-Output:
-
-destination: URL where the client should upload the file
-
-commitBefore: acutual time when the upload transaction times out
-
-Faults: GenericJPFault
-
-
-Initiate upload of of sandbox/dump of job life log from LB.</documentation>
- <input message="tns:StartUploadRequest"/>
- <output message="tns:StartUploadResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="CommitUpload">
- <documentation>Confirm upload.
-Should be called after a file upload initiaded with StartUpload is finished.
-
-Input:
-
-destination: Upload destination URL (to match with the original request)
-
-Output:
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:CommitUploadRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="RecordTag">
- <documentation>Record a value of user tag.
-JP tags are either standalone or override values of their LB counterparts.
-However, JP tag values are still distinguishable those inherited from LB.
-JP tags may be either strings or blobs.
-
-Input:
-
-jobid:
-
-tag: structure containing name, timestamp, optional sequence number to order tag values
-without relying on timestamps, and string or blob value.
-
-Output: N/A
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:RecordTagRequest"/>
- <output message="tns:EmptyResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="FeedIndex">
- <documentation>Start feeding JP index server.
-Called by the index server to start batch feed, and optionally also subscribe for incremental feed.
-
-JP index server subscribes with JP primary storage using a query
-containing conditions on primary metadata and a list of queryable attributes
-of the index server (i.e. data which should be sent to the index server).
-
-When a matching job record is created or modified within the primary storage
-the job record data are sent to the subscribed index server.
-
-The subscription is soft-state, it expires after certain time unless refreshed by the client explicitely.
-
-In the batch mode the query has the same form
-with additional flag asking for all matching records (i.e.\ not only
-arriving afterwards).
-
-Input:
-
-destination: where to send the job record data
-
-attributes: which job record attributes should be sent to the requesting index server
-
-conditions: list of query conditions. Each conditions has the form Attribute Operator Value,
-where Attribute is any of job record attributes and Operator is one of EQUAL, UNEQUAL, LESS, GREATER, WITHIN.
-
-continuous: flag determining that the query is incremental (not batch)
-
-Output:
-
-feedId: unique Id of the feed request, to be used in refresh, cancelation etc.
-
-expires: when the feed times out. Must be refreshed before this time.
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:FeedIndexRequest"/>
- <output message="tns:FeedIndexResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="FeedIndexRefresh">
- <documentation>Extend batch feed subscription (used by index server)
-
-Input: feedId returned previously by FeedIndex
-
-Output: the same as for FeedIndex
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:FeedIndexRefreshRequest"/>
- <output message="tns:FeedIndexResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- <operation name="GetJob">
- <documentation>Retrieve job record URL's when jobid is known
-Used either to bypass JP index server query for this specific case, or after the index server query to
-retrieve actual job record.
-
-Input: jobid
-
-Output:
-
-jobLog, inputSandbox, outputSandbox, tags: URL's to components of the job record.
-
-Faults: GenericJPFault
- </documentation>
- <input message="tns:GetJobRequest"/>
- <output message="tns:GetJobResponse"/>
- <fault name="f" message="tns:GenericJPFault"/>
- </operation>
- </portType>
- <binding name="JobProvenancePS" type="tns:JobProvenancePS_PortType">
- <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
- <operation name="RegisterJob">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="StartUpload">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="CommitUpload">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="RecordTag">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="FeedIndex">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="FeedIndexRefresh">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- <operation name="GetJob">
- <SOAP:operation style="rpc"/>
- <input>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </input>
- <output>
- <SOAP:body use="literal" namespace="http://glite.org/wsdl/services/jp"/>
- </output>
- <fault name="f">
- <SOAP:fault name="f" use="literal"/>
- </fault>
- </operation>
- </binding>
-
- <service name="JobProvenancePS">
- <documentation>Job Provenance Primary Storage service</documentation>
- <port name="JobProvenancePS" binding="tns:JobProvenancePS">
- <SOAP:address location="http://localhost:10001"/>
- </port>
- </service>
-</WSDL:definitions>
+++ /dev/null
-<?xml version="1.0"?>
-<WSDL:definitions
- xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- xmlns:jp="http://glite.org/wsdl/types/jp"
- targetNamespace="http://glite.org/wsdl/types/jp"
- name="JobProvenanceTypes">
-
-
-<WSDL:types>
-
-<schema
- targetNamespace="http://glite.org/wsdl/types/jp"
- xmlns="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="unqualified" attributeFormDefault="unqualified">
- <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
-
- <simpleType name="AttributeType">
- <restriction base="xsd:string">
- <enumeration value="OWNER"/>
- <enumeration value="TIME"/>
- <enumeration value="TAG"/>
- </restriction>
- </simpleType>
- <simpleType name="UploadClass">
- <restriction base="xsd:string">
- <enumeration value="INPUT-SANDBOX"/>
- <enumeration value="OUTPUT-SANDBOX"/>
- <enumeration value="JOB-LOG"/>
- </restriction>
- </simpleType>
- <simpleType name="QueryOp">
- <restriction base="xsd:string">
- <enumeration value="EQUAL"/>
- <enumeration value="UNEQUAL"/>
- <enumeration value="LESS"/>
- <enumeration value="GREATER"/>
- <enumeration value="WITHIN"/>
- </restriction>
- </simpleType>
- <complexType name="TagValue">
- <sequence>
- <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="true"/>
- <element name="sequence" type="xsd:int" minOccurs="0" maxOccurs="1"/>
- <element name="timestamp" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="stringValue" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="blobValue" type="xsd:base64Binary" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="Attribute">
- <sequence>
- <element name="type" type="jp:AttributeType" minOccurs="1" maxOccurs="1"/>
- <element name="name" type="xsd:string" minOccurs="0" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="Attributes">
- <sequence>
- <element name="item" type="jp:Attribute" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="GenericJPFaultType">
- <sequence>
- <element name="source" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="code" type="xsd:int" minOccurs="1" maxOccurs="1"/>
- <element name="text" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
- <element name="reason" type="jp:GenericJPFaultType" minOccurs="0" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="PrimaryQueryElement">
- <sequence>
- <element name="attr" type="jp:Attribute" minOccurs="1" maxOccurs="1"/>
- <element name="op" type="jp:QueryOp" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="value2" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="PrimaryQuery">
- <sequence>
- <element name="item" type="jp:PrimaryQueryElement" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="IndexQueryRecord">
- <sequence>
- <element name="op" type="jp:QueryOp" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="IndexQueryElement">
- <sequence>
- <element name="attr" type="jp:Attribute" minOccurs="1" maxOccurs="1"/>
- <element name="record" type="jp:IndexQueryRecord" minOccurs="1" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="IndexQuery">
- <sequence>
- <element name="item" type="jp:IndexQueryElement" minOccurs="1" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
- <complexType name="JobRecord">
- <sequence>
- <element name="jobid" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="PSContact" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="JobRecords">
- <sequence>
- <element name="record" type="jp:JobRecord" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
-
- <complexType name="AttrUpdate">
- <sequence>
- <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="value" type="xsd:string" minOccurs="0" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="AttrUpdates">
- <sequence>
- <element name="item" type="jp:AttrUpdate" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="JobUpdate">
- <sequence>
- <element name="jobid" type="xsd:string" minOccurs="1" maxOccurs="1"/>
- <element name="attributes" type="jp:AttrUpdates" minOccurs="1" maxOccurs="1"/>
- <element name="tags" type="jp:AttrUpdates" minOccurs="1" maxOccurs="1"/>
- </sequence>
- </complexType>
- <complexType name="UpdateJobsData">
- <sequence>
- <element name="job" type="jp:JobUpdate" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- </complexType>
-
- <complexType name="FeedIndexResponse">
- <sequence>
- <element name="feedId" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="expires" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="GetJobResponse">
- <sequence>
- <element name="jobLog" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="inputSandbox" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="outputSandbox" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="tags" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <complexType name="StartUploadResponse">
- <sequence>
- <element name="destination" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
- <element name="commitBefore" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable="true"/>
- </sequence>
- </complexType>
- <element name="GenericJPFault" type="jp:GenericJPFaultType"/>
-</schema>
-
-</WSDL:types>
-</WSDL:definitions>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Configuration build properties file for the GLite jp ws-interface component
-
- Authors: Joachim Flammer <Joachim.Flammer@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.3 2004/07/20 16:08:30 flammer
- Changed incorrect my_... instead of .._template entries for subsystem and component.
-
- Revision 1.2 2004/07/16 14:56:55 flammer
- Corrected input path of build.properties.
-
- Revision 1.1 2004/07/06 20:43:19 flammer
- Update of configure & targets.
-
-
-
--->
-<project name="jp ws-interface component configuration properties">
-
-<target name="lbmakefiles">
- <exec executable="ln" failonerror="true">
- <arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
- </exec>
- <echo file="${module.build.dir}/Makefile.inc">
-top_srcdir=..
-builddir=build
-stagedir=${stage.abs.dir}
-distdir=${dist.dir}
-globalprefix=${global.prefix}
-jpprefix=${subsystem.prefix}
-package=${module.package.name}
-PREFIX=${install.dir}
-version=${module.version}
-glite_location=${with.glite.location}
- </echo>
- </target>
-</project>
+++ /dev/null
-Summary:Change me !!!
-Name:glite-jp-ws-interface
-Version:0.0.0
-Release:0
-Copyright:Open Source EGEE License
-Vendor:EU EGEE project
-Group:System/Application
-Prefix:/opt/glite
-BuildArch:x86_64
-BuildRoot:%{_builddir}/%{name}-%{version}
-Source:glite-jp-ws-interface-0.0.0_bin.tar.gz
-
-%define debug_package %{nil}
-
-%description
-Change me !!!
-
-%prep
-
-
-%setup -c
-
-%build
-
-
-%install
-
-
-%clean
-
-%pre
-%post
-%preun
-%postun
-%files
-%defattr(-,root,root)
-%{prefix}/interface/JobProvenancePS.wsdl
-%{prefix}/interface/JobProvenanceTypes.wsdl
-%{prefix}/share/doc/glite-jp-ws-interface-0.0.0/LICENSE
-
-%changelog
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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 build properties file for the GLite jp ws-interface component
-
- Authors: Joachim Flammer <Joachim.Flammer@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.4 2004/07/20 16:08:30 flammer
- Changed incorrect my_... instead of .._template entries for subsystem and component.
-
- Revision 1.3 2004/07/16 14:56:55 flammer
- Corrected input path of build.properties.
-
- Revision 1.2 2004/07/16 14:36:49 flammer
-
- Corrected build.properties include.
-
- Revision 1.1.1.1 2004/06/18 12:40:17 flammer
- Added general component template.
-
-
--->
-
-<project name="jp ws-interface component common properties">
-
- <!-- Include build properties to allow overwriting
- of properties for subsystem -->
- <property file="project/build.properties" />
-
- <!-- ======================================================
- Define corresponding subsystem properties
- ====================================================== -->
-
- <!-- Subsystem name -->
- <property name="subsystem.name" value="${jp.subsystem.name}"/>
-
- <!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${jp.subsystem.prefix}"/>
-
- <!-- ======================================================
- Define component properties
- ====================================================== -->
-
- <!-- Component name prefix -->
- <property name="component.prefix" value="ws-interface" />
-
- <!-- ======================================================
- Define general component properties
- ====================================================== -->
-
- <import file="${component.general.properties.file}" />
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
-
-</project>
+++ /dev/null
-module.version = 0.0.0
-module.build = 0
-module.age = 0
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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
-
- Build file for the GLite Middleware Job Provenance Subsystem
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.2 2004/12/01 18:36:00 zsalvet
- Add component targets.
-
- Revision 1.1 2004/11/22 13:21:49 dimeglio
- First version of this file
-
--->
-
-<project name="jp" default="dist">
-
- <description>
- Ant build file to build the GLite Job Provenance Subsystem
- </description>
-
- <!-- =========================================
- Builds the GLite JP subsystem
- ========================================= -->
-
- <!-- Import baseline & user properties -->
- <import file="../org.glite/project/baseline.properties.xml" />
-
- <!-- Import subsystem build properties,
- subsystem properties &
- subsystem common properties -->
- <import file="./project/properties.xml" />
-
- <!-- Import global build properties and global properties -->
- <import file="${global.properties.file}" />
-
- <!-- =========================================
- Load dependencies properties files (order is important)
- ========================================= -->
- <property file="${user.dependencies.file}"/>
- <property file="${subsystem.dependencies.file}"/>
- <property file="${global.dependencies.file}"/>
-
- <!-- =========================================
- Load configure options
- ========================================= -->
- <import file="${global.configure.options.file}"/>
-
- <!-- =========================================
- Import global task definitions
- ========================================= -->
- <import file="${global.taskdefs.file}" />
-
- <!-- =========================================
- Import global compiler definitions
- ========================================= -->
- <import file="${global.compilerdefs.file}" />
-
- <!-- =========================================
- Import targets
- ========================================= -->
- <import file="${global.targets-common.file}"/>
-
- <!-- =========================================
- Load version file
- ========================================= -->
- <property file="${module.version.file}"/>
-
- <!-- ===============================================
- Public common targets
- =============================================== -->
-
- <target name="localinit" depends="envcheck">
-
- <echo> Preparing directories ... </echo>
-
- <mkdir dir="${stage.bin.dir}" />
- <mkdir dir="${stage.lib.dir}" />
- <mkdir dir="${stage.java.dir}" />
- <mkdir dir="${stage.inc.dir}" />
- <mkdir dir="${stage.int.dir}" />
-
- <mkdir dir="${dist.dir}" />
-
- </target>
-
- <target name="init" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="init"/>
- </antcall>
- </target>
-
- <target name="checkstyle" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="checkstyle"/>
- </antcall>
- </target>
-
- <target name="compile" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="compile"/>
- </antcall>
- </target>
-
- <target name="compiletest" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="compiletest"/>
- </antcall>
- </target>
-
- <target name="unittest" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="unittest"/>
- </antcall>
- </target>
-
- <target name="unitcoverage" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="unitcoverage"/>
- </antcall>
- </target>
-
- <target name="stage" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="stage"/>
- </antcall>
- </target>
-
- <target name="dist" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="dist"/>
- </antcall>
- </target>
-
- <target name="install" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="install"/>
- </antcall>
- </target>
-
- <target name="doc" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="doc"/>
- </antcall>
- </target>
-
- <target name="all" depends="localinit">
- <antcall target="buildmodules">
- <param name="target" value="all"/>
- </antcall>
- </target>
-
- <target name="clean" depends="envcheck">
-
- <property name="offline.repository" value="true" />
- <antcall target="buildmodules">
- <param name="target" value="clean"/>
- </antcall>
-
- <delete dir="${module.bin.dir}" />
- <delete dir="${module.lib.dir}" />
- <delete dir="${module.autosrc.dir}" />
- <delete dir="${module.autodoc.dir}" />
- <delete dir="${module.test.reports.dir}" />
-
- </target>
-
- <target name="cleanAll" depends="clean"/>
-
- <!-- ===============================================
- Private targets
- =============================================== -->
-
- <!-- ===============================================
- Modules proxy targets
- =============================================== -->
-
- <!-- component targets definitions tag = do not remove = -->
-
- <target name="ws-interface" unless="setenvonly" depends="envset" >
- <if>
- <isset property="small.memory" />
- <then>
- <exec dir="${jp.subsystem.dir}.ws-interface" executable="${antExec}" failonerror="${failonerror}">
- <arg line="${target} "-Dsmall.memory=true" "-Dbootstrap=${bootstrap}" "-Dfailonerror=${failonerror}" "-Ddo.cvs.tag=${do.cvs.tag}""/>
- </exec>
- </then>
- <else>
- <ant dir="${jp.subsystem.dir}.ws-interface"
- target="${target}"
- inheritall="false" />
- </else>
- </if>
- </target>
-
- <target name="common" unless="setenvonly" depends="envset" >
- <if>
- <isset property="small.memory" />
- <then>
- <exec dir="${jp.subsystem.dir}.common" executable="${antExec}" failonerror="${failonerror}">
- <arg line="${target} "-Dsmall.memory=true" "-Dbootstrap=${bootstrap}" "-Dfailonerror=${failonerror}" "-Ddo.cvs.tag=${do.cvs.tag}""/>
- </exec>
- </then>
- <else>
- <ant dir="${jp.subsystem.dir}.common"
- target="${target}"
- inheritall="false" />
- </else>
- </if>
- </target>
-
- <target name="index" unless="setenvonly" depends="envset, common" >
- <if>
- <isset property="small.memory" />
- <then>
- <exec dir="${jp.subsystem.dir}.index" executable="${antExec}" failonerror="${failonerror}">
- <arg line="${target} "-Dsmall.memory=true" "-Dbootstrap=${bootstrap}" "-Dfailonerror=${failonerror}" "-Ddo.cvs.tag=${do.cvs.tag}""/>
- </exec>
- </then>
- <else>
- <ant dir="${jp.subsystem.dir}.index"
- target="${target}"
- inheritall="false" />
- </else>
- </if>
- </target>
-
- <target name="primary" unless="setenvonly" depends="envset, ws-interface, common" >
- <if>
- <isset property="small.memory" />
- <then>
- <exec dir="${jp.subsystem.dir}.primary" executable="${antExec}" failonerror="${failonerror}">
- <arg line="${target} "-Dsmall.memory=true" "-Dbootstrap=${bootstrap}" "-Dfailonerror=${failonerror}" "-Ddo.cvs.tag=${do.cvs.tag}""/>
- </exec>
- </then>
- <else>
- <ant dir="${jp.subsystem.dir}.primary"
- target="${target}"
- inheritall="false" />
- </else>
- </if>
- </target>
-
- <!-- Main proxy -->
- <target name="buildmodules" depends="envset,
- ws-interface,
- common,
- index,
- primary">
- <echo append="true" file="${global.project.dir}/cruisecontrol-stub.xml">
- <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/>
- </echo>
- </target>
-
-</project>
+++ /dev/null
-###################################################################
-# System dependencies
-###################################################################
-
-org.glite.version = HEAD
-org.glite.jp.version = HEAD
-
-# Component dependencies tag = do not remove this line =
-org.glite.jp.ws-interface.version = HEAD
-org.glite.jp.common.version = HEAD
-org.glite.jp.index.version = HEAD
-org.glite.jp.primary.version = HEAD
+++ /dev/null
-<?xml version="1.0"?>
-<!--
- 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 Middleware Job Provenance Configuration Specification File
-
- Authors: Alberto Di Meglio <alberto.di.meglio@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
- Revision 1.2 2004/12/01 18:24:25 zsalvet
- common, index, and primary components defined
-
- Revision 1.1 2004/11/22 13:21:49 dimeglio
- First version of this file
-
--->
-
-
-<project name="GLite Middleware JP CSF" default="all">
-
- <!-- ===============================================
- Determine workspace directory
- =============================================== -->
-
- <!-- Relative workspace root directory -->
- <property name="workspace.dir" value="../.." />
-
- <!-- ===============================================
- Load properties
- =============================================== -->
-
- <!-- load baseline and user properties -->
- <import file="${workspace.dir}/org.glite/project/baseline.properties.xml" />
-
- <!-- define build properties file location since we are already in project dir -->
- <property name="subsystem.build.properties.file" value="./build.properties" />
-
- <!-- Load subsystem-specific property file -->
- <property file="./properties.xml"/>
-
- <!-- load global properties -->
- <import file="${global.properties.file}" />
-
- <!-- ===============================================
- Load dependencies
- =============================================== -->
-
- <!-- Load user dependencies file -->
- <property file="${user.dependencies.file}" />
-
- <!-- Load subsystem dependencies file -->
- <property file="./dependencies.properties" />
-
- <!-- Load global dependencies file -->
- <property file="${global.dependencies.file}" />
-
- <!-- ===============================================
- Load targets
- =============================================== -->
- <import file="${global.targets-envchecks.file}" />
- <import file="${global.targets-external-dependencies.file}" />
-
- <!-- ===============================================
- Evaluate CVS tags
- =============================================== -->
-
- <target name="evaluate.cvs.tags" description="Figure out if we need tagged CVS checkout">
-
- <condition property="glite.head">
- <and>
- <equals arg1="${org.glite.version}" arg2="HEAD" />
- <or>
- <istrue value="${update}" />
- <not>
- <available file="${global.dependencies.file}" type="file" />
- </not>
- </or>
- </and>
- </condition>
-
- <condition property="glite.tag">
- <and>
- <not>
- <equals arg1="${org.glite.version}" arg2="HEAD" />
- </not>
- <or>
- <istrue value="${update}" />
- <not>
- <available file="${global.dependencies.file}" type="file" />
- </not>
- </or>
- </and>
- </condition>
-
- <condition property="glite-jp.head">
- <and>
- <equals arg1="${org.glite.jp.version}" arg2="HEAD" />
- <istrue value="${update}" />
- </and>
- </condition>
-
- <condition property="glite-jp.tag">
- <and>
- <not>
- <equals arg1="${org.glite.jp.version}" arg2="HEAD" />
- </not>
- <istrue value="${update}" />
- </and>
- </condition>
-
- <!-- condition property tag = do not remove = -->
-
- <condition property="common.head">
- <equals arg1="${org.glite.jp.common.version}" arg2="HEAD" />
- </condition>
-
- <condition property="ws-interface.head">
- <equals arg1="${org.glite.jp.ws-interface.version}" arg2="HEAD" />
- </condition>
-
- <condition property="index.head">
- <equals arg1="${org.glite.jp.index.version}" arg2="HEAD" />
- </condition>
-
- <condition property="primary.head">
- <equals arg1="${org.glite.jp.primary.version}" arg2="HEAD" />
- </condition>
-
- </target>
-
- <presetdef name="cvs-co">
- <cvs command="checkout" dest="${workspace.dir}" />
- </presetdef>
-
- <!-- =====================================================
- Self-update if required
- ===================================================== -->
-
- <!-- Update main GLite module -->
- <target name="org.glite" depends="get.glite.head, get.glite.tag"/>
-
- <target name="get.glite.head" if="glite.head">
- <cvs-co package="org.glite" />
- </target>
-
- <target name="get.glite.tag" if="glite.tag">
- <cvs-co package="org.glite"
- tag="${org.glite.version}" />
- </target>
-
- <!-- Update the current module -->
- <target name="org.glite.jp" depends="get.glite-jp.head,
- get.glite-jp.tag"/>
-
- <target name="get.glite-jp.head" if="glite-jp.head">
- <cvs-co package="org.glite.jp" />
- <fail>The org.glite and org.glite.jp modules have been updated, please rerun the configuration file</fail>
- </target>
-
- <target name="get.glite-jp.tag" if="glite-jp.tag">
- <cvs-co package="org.glite.jp"
- tag="${org.glite.jp.version}" />
- <fail>The org.glite and org.glite.jp modules have been updated, please rerun the configuration file</fail>
- </target>
-
- <!-- *****************************************************-->
- <!-- Development tools -->
- <!-- *****************************************************-->
-
- <!-- All development tools -->
- <target name="devtools" depends="oscheck,
- junitcheck,
- junit,
- chkstyle,
- jalopy,
- ant-contrib,
- cpptasks,
- log4j,
- egee-ant-ext"
- description="Get development tools into repository."/>
-
- <!-- =====================================================
- External libraries
- ===================================================== -->
-
- <!-- All external libraries -->
- <target name="external"
- description="Install external packages" depends="oscheck"/>
-
- <!-- =====================================================
- GLite Middleware jp modules
- ===================================================== -->
-
- <!-- component targets tag = do not remove = -->
-
- <!-- ws-interface -->
- <target name="ws-interface" depends="evaluate.cvs.tags, get.ws-interface.head, get.ws-interface.tag"/>
- <target name="get.ws-interface.head" if="ws-interface.head">
- <cvs-co package="org.glite.jp.ws-interface" />
- </target>
- <target name="get.ws-interface.tag" unless="ws-interface.head">
- <cvs-co package="org.glite.jp.ws-interface"
- tag="${org.glite.jp.ws-interface.version}" />
- </target>
-
- <!-- common -->
- <target name="common" depends="evaluate.cvs.tags, get.common.head, get.common.tag"/>
- <target name="get.common.head" if="common.head">
- <cvs-co package="org.glite.jp.common" />
- </target>
- <target name="get.common.tag" unless="common.head">
- <cvs-co package="org.glite.jp.common"
- tag="${org.glite.jp.common.version}" />
- </target>
-
- <!-- index -->
- <target name="index" depends="evaluate.cvs.tags, get.index.head, get.index.tag"/>
- <target name="get.index.head" if="index.head">
- <cvs-co package="org.glite.jp.index" />
- </target>
- <target name="get.index.tag" unless="index.head">
- <cvs-co package="org.glite.jp.index"
- tag="${org.glite.jp.index.version}" />
- </target>
-
- <!-- primary -->
- <target name="primary" depends="evaluate.cvs.tags, get.primary.head, get.primary.tag"/>
- <target name="get.primary.head" if="primary.head">
- <cvs-co package="org.glite.jp.primary" />
- </target>
- <target name="get.primary.tag" unless="primary.head">
- <cvs-co package="org.glite.jp.primary"
- tag="${org.glite.jp.primary.version}" />
- </target>
-
- <!-- All project modules -->
- <target name="project" depends="ws-interface,
- common,
- index,
- primary" />
-
- <!-- ====================================================
- Checkout all
- ==================================================== -->
-
- <!-- All libraries -->
- <target name="all" depends="oscheck,
- evaluate.cvs.tags,
- defaultenvchecks,
- org.glite,
- org.glite.jp,
- devtools,
- external,
- project" />
-
- <!-- ====================================================
- Print dependecies to console
- ==================================================== -->
-
- <target name="dependencies">
- <concat>
- <fileset dir="." includes="dependencies.properties" />
- </concat>
- </target>
-
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Common build properties file for the gLite JP modules
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Alberto Di Meglio <alberto.di.meglio@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
--->
-
-<project name="Job Provenance subsystem common properties">
-
- <!-- Include build properties to allow overwriting
- of properties for subsystem -->
- <property name="subsystem.build.properties.file" value="./project/build.properties" />
- <property file="${subsystem.build.properties.file}" />
-
- <!-- ======================================================
- Define subsystem properties
- ====================================================== -->
-
- <!-- Subsystem name -->
- <property name="subsystem.name" value="${jp.subsystem.name}"/>
-
- <!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${jp.subsystem.prefix}"/>
-
- <!-- ======================================================
- Define general subsystem properties
- ====================================================== -->
-
- <!-- Include common subsystem properties -->
- <import file="${subsystem.general.properties.file}" />
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
-
-</project>
+++ /dev/null
-#!/bin/sh
-
-cd ../..
-
-cvs co org.glite
-cvs co org.glite.jp
-
-cd org.glite.jp/project
-ant -f glite.jp.csf.xml
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Common Ant task definition file for the gLite Job Provenance modules
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Alberto Di Meglio <alberto.di.meglio@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
--->
-
-<project name="Job Provenance subsystem common tasks and types definitions">
-
- <!-- ======================================================
- Subsystem task definitions
- ====================================================== -->
-
-</project>
\ No newline at end of file
+++ /dev/null
-#Fri Dec 10 13:38:38 CET 2004
-module.version=0.1.0
-module.build=3
-module.age=1
STAGETO=include/${globalprefix}/${lbprefix}
STATIC_H=consumer.h context.h dump.h load.h notification.h notifid.h purge.h \
Notification.h CountRef.h Job.h LoggingExceptions.h ServerConnection.h \
- consumer_fake.h producer_fake.h statistics.h
+ statistics.h
+FAKE_H=consumer_fake.h producer_fake.h
GEN_H=events.h jobstat.h producer.h Event.h JobStatus.h interface_version.h
interface_version.h: ${top_srcdir}/project/version.properties
echo "#define GLITE_LB_CLIENT_INTERFACE \"${version}\"" >$@
stage: generate
- $(MAKE) install PREFIX=${top_srcdir}/${stagedir}
+ $(MAKE) install PREFIX=${top_srcdir}/${stagedir} DOSTAGE=yes
dist: distsrc distbin
doxygen C.dox
doxygen CPP.dox
-install:
+install: generate doc
-mkdir -p ${PREFIX}/${STAGETO}
-mkdir -p ${PREFIX}/share/doc/${package}-${version}
install -m 644 ${GEN_H} ${PREFIX}/${STAGETO}
install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
cd ${top_srcdir}/interface && install -m 644 ${STATIC_H} ${PREFIX}/${STAGETO}
+ cd ${top_srcdir}/doc && cp -r C CPP ${PREFIX}/share/doc/${package}-${version}
+ if [ x${DOSTAGE} = xyes ]; then \
+ cd ${top_srcdir}/interface && install -m 644 ${FAKE_H} ${PREFIX}/${STAGETO} ; \
+ fi
+
clean:
rm -f *.h
Revision history:
$Log$
+ Revision 1.6 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.5 2004/08/05 15:22:34 dimeglio
Changed default target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_COUNTREF_HPP__
#define __EDG_WORKLOAD_LOGGING_CLIENT_COUNTREF_HPP__
+/**
+ * Switching into glite.lb namespace (couple with EWL_END_NAMESPACE).
+ */
#define EWL_BEGIN_NAMESPACE namespace glite { namespace lb {
+
+/**
+ * Leave the glite.lb namespace.
+ */
#define EWL_END_NAMESPACE } }
-EWL_BEGIN_NAMESPACE;
+EWL_BEGIN_NAMESPACE
+/** Class implementing simple reference counting mechanism.
+ *
+ * This class is used instead of simple pointers to enable sharing of
+ * objects using simple reference counting mechanism. It encapsulates
+ * the given (pointer to) object and remembers the number of
+ * references to it. Taking and getting rid of the reference to
+ * encapsulated object is explicit by calling member functions use()
+ * and release().
+ */
template<typename T>
class CountRef {
public:
- CountRef(void *);
+ CountRef(void *);
// CountRef(void *,void (*)(void *));
- void use(void);
+ void use(void);
void release(void);
- void *ptr;
+ void *ptr; /**< Pointer to the encapsulated object. */
+
private:
int count;
// void (*destroy)(void *);
};
+/**
+ * Encapsulate the given object and set reference count to 1.
+ *
+ */
template <typename T>
CountRef<T>::CountRef(void *p)
{
count = 1;
}
+/** Decrease the reference count, possibly deallocating the
+ * encapsulated object.
+ *
+ * This method should be called when the holder no longer plans to use
+ * the encapsulated object, instead of deleting it.
+ */
template <typename T>
void CountRef<T>::release(void)
{
}
}
+/** Increase the number of references to the object.
+ *
+ * This method should be called every time the pointer (ie. this
+ * instance) is copied.
+ */
template <typename T>
void CountRef<T>::use(void)
{
count++;
}
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
#include "glite/lb/events.h"
#include "glite/lb/notifid.h"
-EWL_BEGIN_NAMESPACE;
-
+EWL_BEGIN_NAMESPACE
+
+/** Class representing one event in the L&B database.
+ *
+ * This class represents a L&B event, which is basically list of
+ * attribute -- value pairs. For each particular event type (returned
+ * by name()) there is a list of allowed attributes (returned by
+ * getAttrs()). The Event class provides methods for reading these
+ * attributes, but no means of changing the
+ * event are provided; this class is used as a result of L&B queries.
+ */
class Event {
friend class Job;
friend class ServerConnection;
friend class CountRef<Event>;
public:
- /** Event type codes.
- * Identify which of the event fields are valid.
+ /** Event type codes
+ * identify which of the event fields are valid.
*/
-
enum Type {
- UNDEF = 0,
+ UNDEF = 0, /**< Undefined event type. */
@@@{
for my $e ($event->getTypesOrdered) {
my $u = uc $e;
gen "\t\t$u,\t/**< $c */\n";
}
@@@}
- TYPE_MAX
+ TYPE_MAX /**< Limit for checking type validity. */
};
- /** Event attribute symbolic identifier. */
+ /** Event attribute symbolic identifier.
+ * These symbols provide symbolic names for event
+ * attributes. In braces are shown the event types for which the
+ * attribute is defined, for each event type the attribute
+ * meaning is described.
+ */
enum Attr {
@@@{
for (sort {$a cmp $b} getAllFields $event) {
selectType $event $t;
my $cc = getFieldComment $event $_;
$t = 'common' if $t eq '_common_';
- $c .= "\t * $t: $cc\n";
+ $c .= "\t * \\n\[$t\] $cc\n";
}
$c .= "\t */\n";
gen "$c\t\t$u,\n";
}
@@@}
- ATTR_MAX
+ ATTR_MAX /**< Limit for checking attribute code
+ validity. */
};
@@@{
my $ff;
my $ut;
my $utf;
+ my $fc;
if ($t eq '_common_') {
$ff = $f;
$ut = '';
$utf = '';
+ $fc = '';
}
else {
selectType $event $t;
$ff = getField $event;
$ut = uc $t . '_';
$utf = ucfirst $t;
+ $fc = $event->getFieldComment($f);
}
if ($ff->{codes}) {
gen qq{
+! /** $fc */
! enum ${utf}Code \{
};
for (@{$ff->{codes}}) {
}
@@@}
- enum AttrType { INT_T, STRING_T, TIMEVAL_T, PORT_T, LOGSRC_T, JOBID_T, NOTIFID_T };
+ /** Symbolic names for types of attribute values. */
+ enum AttrType { INT_T, /**< Integer value. */
+ STRING_T, /**< String value. */
+ TIMEVAL_T, /**< Time value (ie. struct
+ timeval). */
+ PORT_T, /**< Service port (integer). */
+ LOGSRC_T, /**< Source of the event
+ (integer). */
+ JOBID_T, /**< JobId value. */
+ NOTIFID_T /**< NotifId value. */
+ };
- Type type;
+ Type type; /**< Type of the event as defined by Type. */
+ /** Default constructor.
+ *
+ * Initializes an empty event.
+ */
Event(void);
+
+ /** Constructor from corresponding C type.
+ *
+ * Initializes the object from the corresponding C struct, in
+ * fact holding the pointer to it.
+ */
Event(edg_wll_Event *);
+
+ /** Copy constructor.
+ *
+ * Creates a copy of the object by sharing the C struct
+ * with the original.
+ */
Event(const Event &);
+
+ /** Destructor.
+ *
+ * Releases the C struct (possibly deallocating it).
+ */
~Event(void);
- /** Assign new Event to an existing instance. */
+ /** Assign new Event to an existing instance.
+ *
+ * The original data are released and new ones are made
+ * accessible.
+ * \returns Reference to this object.
+ */
Event & operator= (const Event &);
- /** String representation of the event type */
+ /** String representation of the event type.
+ *
+ * Returns string representing the event type.
+ * \returns Name of the event.
+ * \throw Exception Invalid event type.
+ */
const std::string & name(void) const;
- /** Retrieve integer attribute */
- int getValInt(Attr) const;
-
- /** Retrieve string attribute */
- std::string getValString(Attr) const;
+ /** Retrieve integer attribute.
+ *
+ * Retrieves value for attributes of integer type.
+ * \param[in] name Name of the attribute to retrieve.
+ * \returns Integer value of the attribute.
+ * \throw Exception Invalid event type or attribute not
+ * defined for this event.
+ */
+ int getValInt(Attr name) const;
+
+ /** Retrieve string attribute.
+ *
+ * Retrieves value for attributes of string type.
+ * \param[in] name Name of the attribute to retrieve.
+ * \returns String value of the attribute.
+ * \throw Exception Invalid event type or attribute not
+ * defined for this event.
+ */
+ std::string getValString(Attr name) const;
- /** Retrieve time attribute */
- struct timeval getValTime(Attr) const;
+ /** Retrieve time attribute.
+ *
+ * Retrieves value for attributes of timeval type.
+ * \param[in] name Name of the attribute to retrieve.
+ * \returns struct timeval value of the attribute.
+ */
+ struct timeval getValTime(Attr name) const;
- /** Retrieve jobid attribute */
- const glite::wmsutils::jobid::JobId getValJobId(Attr) const;
-
- /** Attribute name */
- const std::string & getAttrName(Attr) const;
+ /** Retrieve jobid attribute
+ *
+ * Retrieves value for attributes of JobId type.
+ * \param[in] name Name of the attribute to retrieve.
+ * \returns JobId value of the attribute.
+ * \throw Exception Invalid event type or attribute not
+ * defined for this event.
+ */
+ const glite::wmsutils::jobid::JobId getValJobId(Attr name) const;
+
+ /** Attribute name.
+ *
+ * Retrieves string representation of the attribute name.
+ * \param[in] name Symbolic name of the attribute.
+ * \returns String name of the attribute.
+ * \throw Exception Invalid event type or attribute not
+ * defined for this event.
+ */
+ const std::string & getAttrName(Attr name) const;
- /** List of attributes and types valid for this instance */
+ /** List of attributes and types valid for this instance.
+ *
+ * Retrieves description of all attributes defined for this event.
+ * \returns Vector of Attr -- AttrType pairs.
+ * \throw Exception Invalid event type.
+ */
const std::vector<std::pair<Attr,AttrType> > & getAttrs(void) const;
private:
CountRef<Event> *flesh;
};
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
* @version $Revision$
*/
-EWL_BEGIN_NAMESPACE;
+EWL_BEGIN_NAMESPACE
-/** L&B job.
- * Implementation of L&B job-specific calls.
- * Connection to the server is maintained transparently.
-*/
-
+/** Class encapsulating the job info stored in the L&B database.
+ *
+ * This class is the primary interface for getting information about
+ * jobs stored in the L&B database. It is constructed from known job
+ * id, which uniquely identifies the job as well as the bookkeeping
+ * server where the job data is stored. The Job class provides methods
+ * for obtaining the data from the bookkeeping server and for setting
+ * various parameters of the connection to the bookkeeping server.
+ *
+ * All query methods have their counterpart in C functions taking
+ * taking edg_wll_Context and edg_wll_JobId as their first parameters
+ * (in fact, those functions are used to do the actual work).
+ */
class Job {
public:
- Job(void);
- Job(const glite::wmsutils::jobid::JobId &);
- ~Job();
-
- /** Assign new JobId to an existing instance.
- * Connection to server is preserved if possible.
- */
+
+ /** Default constructor.
+ *
+ * Initializes the job as empty, not representing anything.
+ */
+ Job(void);
+
+ /** Constructor from job id.
+ *
+ * Initializes the job to obtain information for the given job id.
+ * \param[in] jobid The job id of the job this object will
+ * represent.
+ * \throws Exception Could not copy the job id.
+ */
+ Job(const glite::wmsutils::jobid::JobId &jobid);
+
+
+ /** Destructor.
+ *
+ * All the actual work is done by member destructors, namely ServerConnection.
+ */
+ ~Job();
- Job & operator= (const glite::wmsutils::jobid::JobId &);
+ /** Assign new job id to an existing instance.
+ *
+ * Redirect this instance to obtain information about
+ * different job; connection to the server is preserved, if
+ * possible.
+ * \param[in] jobid New job id.
+ * \returns Reference to this object.
+ * \throws Exception Could not copy the job id.
+ */
+ Job & operator= (const glite::wmsutils::jobid::JobId &jobid);
-/**
- * Status retrieval bitmasks. Used ORed as Job::status() argument,
- * determine which status fields are actually retrieved.
- */
- static const int STAT_CLASSADS; /**< various job description fields */
- static const int STAT_CHILDREN; /**< list of subjob JobId's */
- static const int STAT_CHILDSTAT; /**< apply the flags recursively to subjobs */
+ /*
+ * Status retrieval bitmasks. Used ORed as Job::status() argument,
+ * determine which status fields are actually retrieved.
+ */
+ static const int STAT_CLASSADS; /**< Include the job
+ * description in the
+ * query result. */
+ static const int STAT_CHILDREN; /**< Include the list of
+ * subjob id's in the
+ * query result. */
+ static const int STAT_CHILDSTAT; /**< Apply the flags
+ * recursively to
+ * subjobs. */
- /** Return job status */
- JobStatus status(int) const;
+ /** Return job status.
+ *
+ * Obtain the job status (as JobStatus) from the bookkeeping
+ * server.
+ * \param[in] flags Specify details of the query.
+ * \returns Status of the job.
+ * \throws Exception Could not query the server.
+ * \see STAT_CLASSADS, STAT_CHILDREN, STAT_CHILDSTAT
+ */
+ JobStatus status(int flags) const;
- /** Return all events corresponding to this job */
- void log(std::vector<Event> &) const;
- const std::vector<Event> log(void) const;
+ /** Return all events corresponding to this job
+ *
+ * Obtain all events corresponding to the job that are stored
+ * in the bookkeeping server database. The maximum number of
+ * returned events can be set by calling setParam().
+ * \param[out] events Vector of events (of type Event).
+ * \throws Exception Could not query the server.
+ */
+ void log(std::vector<Event> &events) const;
+
+ /** Return all events corresponding to this job
+ *
+ * Obtain all events corresponding to the job that are stored
+ * in the bookkeeping server database. The maximum number of
+ * returned events can be set by calling setParam().
+ * \returns Vector of events (of type Event).
+ * \throws Exception Could not query the server.
+ */
+ const std::vector<Event> log(void) const;
- /** Return last known address of a listener associated to the job.
- * \param name name of the listener
- * \return hostname and port number
- */
- const std::pair<std::string,uint16_t> queryListener(const std::string & name) const;
+ /** Return last known address of a listener associated to the job.
+ *
+ * Obtains the information about last listener that has been
+ * registered for this job in the bookkeeping server database.
+ * \param[in] name Name of the listener.
+ * \returns Hostname and port number of the registered
+ * listener.
+ * \throws Exception Could not query the server.
+ */
+ const std::pair<std::string,uint16_t> queryListener(const std::string &name) const;
- /** Manipulate LB parameters, the same as for edg_wll_Context in C */
- void setParam(edg_wll_ContextParam, int);
- void setParam(edg_wll_ContextParam, const std::string);
- void setParam(edg_wll_ContextParam, const struct timeval &);
-
- int getParamInt(edg_wll_ContextParam) const;
- std::string getParamString(edg_wll_ContextParam) const;
- struct timeval getParamTime(edg_wll_ContextParam) const;
+ /**
+ * Manipulate LB parameters.
+ *
+ * This method sets integer typed parameters for the server connection.
+ *
+ * \param[in] ctx Symbolic name of the parameter to change.
+ * \param[in] val New value of the parameter.
+ */
+ void setParam(edg_wll_ContextParam ctx, int val);
+
+ /**
+ * Manipulate LB parameters.
+ *
+ * This method sets string typed parameters for the server connection.
+ *
+ * \param[in] ctx Symbolic name of the parameter to change.
+ * \param[in] val New value of the parameter.
+ */
+ void setParam(edg_wll_ContextParam ctx, const std::string val);
+
+ /**
+ * Manipulate LB parameters.
+ *
+ * This method sets timeval typed parameters for the server connection.
+ *
+ * \param[in] ctx Symbolic name of the parameter to change.
+ * \param[in] val New value of the parameter.
+ */
+ void setParam(edg_wll_ContextParam ctx, const struct timeval &val);
+
+ /**
+ * Get LB parameters.
+ *
+ * Obtain value of the named integer parameter.
+ *
+ * \param[in] ctx Symbolic name of the paramater to obtain.
+ * \return Value of the parameter.
+ */
+ int getParamInt(edg_wll_ContextParam ctx) const;
+
+ /**
+ * Get LB parameters.
+ *
+ * Obtain value of the named string parameter.
+ *
+ * \param[in] ctx Symbolic name of the paramater to obtain.
+ * \return Value of the parameter.
+ */
+ std::string getParamString(edg_wll_ContextParam ctx) const;
+
+ /**
+ * Get LB parameters.
+ *
+ * Obtain value of the named timeval parameter.
+ *
+ * \param[in] ctx Symbolic name of the paramater to obtain.
+ * \return Value of the parameter.
+ */
+ struct timeval getParamTime(edg_wll_ContextParam ctx) const;
private:
ServerConnection server;
glite::wmsutils::jobid::JobId jobId;
};
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
EWL_BEGIN_NAMESPACE;
-/**
- * Description of job status.
- * The status is computed from a sequence of logged events
+/** Class representing status of job.
+ *
+ * This class is used to represent all information about the job status
+ * as computed and stored in the bookkeeping server's database. Job
+ * status is, like Event, list of attribute -- value pairs. One of the
+ * attributes is the job's state as seen by the L&B, ie. something
+ * like <tt>RUNNING</tt> or * <tt>DONE</tt>, other attributes contain
+ * more information about the job.
+ *
+ * The JobStatus class provides methods for reading values of these
+ * attributes and it is used as a result of server queries.
*/
-
-
class JobStatus {
friend class Job;
friend class CountRef<JobStatus>;
public:
+
+ /** Symbolic names of job states. */
enum Code {
- UNDEF = 0, /**< indicates invalid, i.e. uninitialized instance */
+ UNDEF = 0, /**< Indicates invalid, i.e. uninitialized instance. */
@@@{
for my $stat ($status->getTypesOrdered)
{
};
}
@@@}
- CODE_MAX
+ CODE_MAX /**< Limit for range checking. */
};
+ /** Symbolic names of attributes.
+ *
+ * These constants are used for naming individual attributes
+ * when invoking their access methods.
+ */
enum Attr {
@@@{
selectType $status '_common_';
gen "\t/** $f->{comment} */\n\t\t$u,\n";
}
@@@}
- ATTR_MAX
+ ATTR_MAX /**< Limit for range checking. */
};
@@@{
}
}
@@@}
- enum AttrType { INT_T,
- STRING_T,
- TIMEVAL_T,
- BOOL_T,
- JOBID_T,
- INTLIST_T,
- STRLIST_T,
- TAGLIST_T,
- STSLIST_T
+ /** Symbolic names of attribute types.
+ *
+ * These constants are used to name the various attribute
+ * types.
+ */
+ enum AttrType { INT_T, /**< Integer type. */
+ STRING_T, /**< String type. */
+ TIMEVAL_T, /**< <tt>struct timeval</tt> type. */
+ BOOL_T, /**< Boolean type (true or false). */
+ JOBID_T, /**< Job id type. */
+ INTLIST_T, /**< List of integer values. */
+ STRLIST_T, /**< List of string values. */
+ TAGLIST_T, /**< List of user tags. */
+ STSLIST_T /**< List of states. */
};
- /** Numeric status code */
+ /** Numeric status code.
+ *
+ * This code represents the state of the job.
+ * \see Code.
+ */
Code status;
- /** String representation of the status code */
+ /** Get state name.
+ *
+ * Returns string representation of the job's state.
+ */
const std::string & name(void) const;
- /** Retrieve integer attribute */
- int getValInt(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve integer value of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ int getValInt(Attr name) const;
- /** Retrieve string attribute */
- std::string getValString(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve string value of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ std::string getValString(Attr name) const;
- /** Retrieve time attribute */
- struct timeval getValTime(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve <tt>struct timeval</tt> value of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ struct timeval getValTime(Attr name) const;
- /** Retrieve jobid attribute */
- const glite::wmsutils::jobid::JobId getValJobId(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve JobId value of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const glite::wmsutils::jobid::JobId getValJobId(Attr name) const;
- /** Retrieve bool attribute */
- bool getValBool(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve <tt>bool</tt> value of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ bool getValBool(Attr name) const;
- /** Retrieve int list attribute */
- const std::vector<int> getValIntList(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve integer values of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const std::vector<int> getValIntList(Attr name) const;
- /** Retrieve string list attribute */
- const std::vector<std::string> getValStringList(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve string values of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const std::vector<std::string> getValStringList(Attr name) const;
- /** Retrieve tag list attribute */
- const std::vector<std::pair<std::string,std::string> > getValTagList(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve user tags values of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const std::vector<std::pair<std::string,std::string> > getValTagList(Attr name) const;
- /** Retrieve job status list attribute */
- const std::vector<JobStatus> getValJobStatusList(Attr) const;
+ /** Access method for attribute values.
+ *
+ * Retrieve status values of named attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Value of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const std::vector<JobStatus> getValJobStatusList(Attr name) const;
- /** Attribute name */
- const std::string& getAttrName(Attr) const;
+ /** Get name of attribute.
+ *
+ * Retrieve string representation of symbolic name of attribute.
+ * \param[in] name Symbolic name of attribute.
+ * \returns Name of attribute.
+ * \throws LoggingException Invalid attribute name.
+ */
+ const std::string& getAttrName(Attr name) const;
- /** List of attributes and types valid for this instance */
+ /** List of attributes and their types valid for this
+ * instance.
+ *
+ * Returns the vector of (attribute, attribute type) pairs
+ * that this instance of JobStatus contains.
+ * \returns List of attributes.
+ */
const std::vector<std::pair<Attr,AttrType> >& getAttrs(void) const;
+ /** Default constructor.
+ *
+ * Initializes an empty instance.
+ */
JobStatus(void);
- JobStatus(const JobStatus &);
- JobStatus & operator=(const JobStatus &);
- JobStatus(const edg_wll_JobStat &);
- JobStatus & operator=(const edg_wll_JobStat&);
+
+ /** Copy constructor.
+ *
+ * Creates identical copy of the original object.
+ * The underlying C struct edg_wll_JobStatus is shared using
+ * the CountRef mechanism.
+ * \param[in] orig Original.
+ */
+ JobStatus(const JobStatus &orig);
+
+ /** Assignment operator.
+ *
+ * Creates identical copy of the original object.
+ * The underlying C struct edg_wll_JobStatus is shared using
+ * the CountRef mechanism.
+ * \param[in] orig Original.
+ */
+ JobStatus & operator=(const JobStatus &orig);
+
+ /** Constructor from the C type.
+ *
+ * Encapsulates the given struct.
+ * \param[in] src C struct that holds the status.
+ */
+ JobStatus(const edg_wll_JobStat &src);
+
+ /** Assignment from the C type.
+ *
+ * Encapsulates the given struct.
+ * \param[in] src C struct that holds the status.
+ */
+ JobStatus & operator=(const edg_wll_JobStat& src);
+
+ /** Destructor.
+ *
+ * Releases the encapsulated C struct.
+ */
virtual ~JobStatus();
protected:
#include <pthread.h>
-EWL_BEGIN_NAMESPACE;
-
+EWL_BEGIN_NAMESPACE
+
+/** Base class for all exceptions thrown by the L&B C++ classes.
+ *
+ * This class serves as a common base for all exceptions thrown by the
+ * L&B C++ API classes. In case when the exception is constructed from
+ * another exception (creating chained exception list), the error
+ * message is created by concatenating the error message of the
+ * original exception and the new error message. All the other
+ * functionality (printing error message, logging it, printing stack
+ * trace) is inherited from the base class glite::wmsutils::exception::Exception.
+ */
class Exception: public glite::wmsutils::exception::Exception {
public:
- /* constructor for mandatory fields */
+ /** Constructor for mandatory fields.
+ *
+ * Updates all the mandatory fields and names the exception.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ */
Exception(const std::string& source,
int line_number,
const std::string& method,
int code,
const std::string& exception)
: glite::wmsutils::exception::Exception(source,
- line_number,
- method,
- code,
- "glite::lb::Exception")
+ line_number,
+ method,
+ code,
+ "glite::lb::Exception")
{ error_message = exception; };
- /* constructor for mandatory fields AND exception chain */
+ /** Constructor for mandatory fields and the exception chain.
+ *
+ * Updates all the mandatory fields, names the exception and
+ * adds the original exception's error message to the current
+ * one.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ * \param[in] exc Originally raised exception.
+ */
Exception(const std::string& source,
int line_number,
const std::string& method,
const std::string& exception,
const glite::wmsutils::exception::Exception &exc)
: glite::wmsutils::exception::Exception(source,
- line_number,
- method,
- code,
- "glite::lb::Exception")
+ line_number,
+ method,
+ code,
+ "glite::lb::Exception")
{ error_message = exception + ": " + exc.what(); };
};
+/** Exception encapsulating error states originating in the L&B.
+ *
+ * This class is simple child of the base Exception class, adding no
+ * new functionality. Its purpose is to differentiate the error
+ * conditions originating in the L&B subsystem from other errors (such
+ * as system ones).
+ */
class LoggingException: public Exception {
public:
- /* constructor for mandatory fields */
+ /** Constructor for mandatory fields.
+ *
+ * Updates all the mandatory fields and names the exception.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ */
LoggingException(const std::string& source,
int line_number,
const std::string& method,
: Exception(source, line_number, method, code, exception)
{};
- /* constructor for mandatory fields AND exception chain */
+ /** Constructor for mandatory fields and the exception chain.
+ *
+ * Updates all the mandatory fields, names the exception and
+ * adds the original exception's error message to the current
+ * one.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ * \param[in] exc Originally raised exception.
+ */
LoggingException(const std::string& source,
int line_number,
const std::string& method,
};
+/** Exceptions caused by system errors.
+ *
+ * This class represents error conditions caused by failing system
+ * calls. The error message is augmented with the system error message
+ * obtained by calling strerror().
+ */
class OSException: public Exception {
public:
- /* constructor for mandatory fields */
+ /** Constructor for mandatory fields.
+ *
+ * Updates all the mandatory fields and names the exception.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ */
OSException(const std::string& source,
int line_number,
const std::string& method,
exception + ": " + strerror(code))
{};
- /* constructor for mandatory fields AND exception chain */
+ /** Constructor for mandatory fields and the exception chain.
+ *
+ * Updates all the mandatory fields, names the exception and
+ * adds the original exception's error message to the current
+ * one.
+ * \param[in] source Source filename where the exception was raised.
+ * \param[in] line_number Line in the source that caused the exception.
+ * \param[in] method Name of the method that raised the exception.
+ * \param[in] code Error code giving the reason for exception.
+ * \param[in] exception Error message describing the exception.
+ * \param[in] exc Originally raised exception.
+ */
OSException(const std::string& source,
int line_number,
const std::string& method,
};
+/** Mandatory exception fields.
+ *
+ * This defines the mandatory parameters for all exception
+ * constructors (filename, line, method name).
+ */
#define EXCEPTION_MANDATORY \
__FILE__, \
__LINE__, \
std::string(CLASS_PREFIX) + __FUNCTION__
+/** Stacking exceptions.
+ *
+ * This was originally used for creating the exception chain; now the
+ * same result is achieved by adding the nested exception to the
+ * constructor parameter list.
+ */
#define STACK_ADD
-/* note: we can use __LINE__ several times in macro, it is expanded into one row */
+/** Utility macro to throw LoggingException.
+ *
+ * This macro is used to obtain the L&B error message and throw the
+ * appropriate exception.
+ * Note: we can use __LINE__ several times in macro, it is expanded into
+ * one row.
+ */
#define throw_exception(context, exception) \
{ STACK_ADD; \
{ \
} \
}
+/** Utility macro to check result of L&B calls.
+ *
+ * Checks return value of L&B calls and throws exception if the code
+ * failed.
+ */
#define check_result(code, context, desc) \
if((code)) throw_exception((context), desc)
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
#include "glite/lb/JobStatus.h"
-EWL_BEGIN_NAMESPACE;
+EWL_BEGIN_NAMESPACE
/** Manage LB notifications.
*/
Notification();
- /** Create from server,port pair
+ /** Create from server host,port pair
* to be used for new notifications, i.e. with Register()
- * \param host
- * \param port
+ * \param[in] host host
+ * \param[in] port port
*/
- Notification(const std::string,const u_int16_t);
+ Notification(const std::string host,const u_int16_t port);
/** Create from NotifId
* to be used for existing notifications, i.e. with Bind()
- * \param notifId
+ * \param[in] notifId NotifId
*/
- Notification(const std::string);
+ Notification(const std::string notifId);
~Notification();
/** Add this job to the list.
* Local operation only, Register() has to be called
* to propagate changes to server
+ * \param[in] jobId JobId
*/
- void addJob(const glite::wmsutils::jobid::JobId &);
+ void addJob(const glite::wmsutils::jobid::JobId &jobId);
- /** Remove job from the list, local op again. */
- void removeJob(const glite::wmsutils::jobid::JobId &);
+ /** Remove job from the list, local op again.
+ * \param[in] jobId JobId
+ */
+ void removeJob(const glite::wmsutils::jobid::JobId &jobId);
/** Get jobs on the list */
std::string getJobs();
/** Bind to the existing notification at the server
* i.e. change the receiving local address
- * \param address_override
+ * \param[in] address address override
*/
- void Bind(const std::string);
+ void Bind(const std::string address);
/** Receive notification.
* Blocks at most the specified timeout (maybe 0 for local polling).
};
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
#include "glite/lb/JobStatus.h"
#include "glite/lb/consumer.h"
-EWL_BEGIN_NAMESPACE;
-
-/** Auxiliary class to hold an atomic query condition. */
+EWL_BEGIN_NAMESPACE
+
+/** Auxiliary class to hold atomic query condition.
+ *
+ * This class is used to construct queries to the L&B database. Each
+ * query is composed of multiple atomic conditions in the form of
+ * 'attribute' 'predicate' 'value'. QueryRecord represents such an
+ * atomic condition.
+ */
class QueryRecord {
public:
friend class ServerConnection;
friend edg_wll_QueryRec *convertQueryVector(const std::vector<QueryRecord> &in);
/* IMPORTANT: must match lbapi.h */
+ /** Symbolic names of queryable attributes.
+ *
+ * The queryable attributes correspond to the table columns in
+ * the bookkeeping server database, they relate both to the
+ * event records and job records.
+ * \see Event::Attr
+ */
enum Attr {
UNDEF=0, /**< Not-defined value, used to terminate lists etc. */
- JOBID, /**< Job Id \see _edg_wll_QueryRec */
- OWNER, /**< Job owner \see _edg_wll_QueryRec */
- STATUS, /**< Current job status */
- LOCATION, /**< Where is the job processed */
- DESTINATION, /**< Destination CE */
- DONECODE, /**< Minor done status (OK,fail,cancel) */
- USERTAG, /**< User tag (not implemented yet) */
- TIME, /**< Timestamp \see _edg_wll_QueryRec */
- LEVEL, /**< Logging level (see "dglog.h") * \see _edg_wll_QueryRec */
- HOST, /**< Where the event was generated */
- SOURCE, /**< Source component */
- INSTANCE, /**< Instance of the source component */
- EVENT_TYPE, /**< Event type \see _edg_wll_QueryRec */
- CHKPT_TAG, /**< Checkpoint tag */
+ JOBID, /**< Job id. */
+ OWNER, /**< Job owner (certificate subject). */
+ STATUS, /**< Current job status code. */
+ LOCATION, /**< Where is the job being processed. */
+ DESTINATION, /**< Destination CE. */
+ DONECODE, /**< Minor done status (OK,fail,cancel). */
+ USERTAG, /**< User tag. */
+ TIME, /**< Timestamp of the event. */
+ LEVEL, /**< Logging level. */
+ HOST, /**< Hostname where the event was generated. */
+ SOURCE, /**< Source component that sent the event. */
+ INSTANCE, /**< Instance of the source component. */
+ EVENT_TYPE, /**< Event type. */
+ CHKPT_TAG, /**< Checkpoint tag. */
RESUBMITTED, /**< Job was resubmitted */
- PARENT, /**< Job was resubmitted */
- EXITCODE, /**< Unix exit code */
+ PARENT, /**< Id of the parent job. */
+ EXITCODE, /**< Job system exit code. */
};
+ /** Symbolic names of predicates.
+ *
+ * These are the predicates used for creating atomic query
+ * conditions.
+ */
enum Op {
- EQUAL=EDG_WLL_QUERY_OP_EQUAL,
- LESS=EDG_WLL_QUERY_OP_LESS,
- GREATER=EDG_WLL_QUERY_OP_GREATER,
- WITHIN=EDG_WLL_QUERY_OP_WITHIN,
- UNEQUAL=EDG_WLL_QUERY_OP_UNEQUAL
+ EQUAL=EDG_WLL_QUERY_OP_EQUAL, /**< Equal. */
+ LESS=EDG_WLL_QUERY_OP_LESS, /**< Less than. */
+ GREATER=EDG_WLL_QUERY_OP_GREATER, /**< Greater than. */
+ WITHIN=EDG_WLL_QUERY_OP_WITHIN, /**< Within the
+ range. */
+ UNEQUAL=EDG_WLL_QUERY_OP_UNEQUAL /**< Not equal. */
};
+
+ /** Default constructor.
+ *
+ * Initializes empty query condition.
+ */
QueryRecord();
- /* copy and assignment */
- QueryRecord(const QueryRecord &);
- QueryRecord& operator=(const QueryRecord &);
+ /** Copy constructor
+ *
+ * Initializes an exact copy of the object.
+ * \param[in] src Original object.
+ */
+ QueryRecord(const QueryRecord &src);
+
+ /** Assignment operator.
+ *
+ * Initializes an exact copy of the object.
+ * \param[in] src Original object.
+ * \returns Reference to this object.
+ */
+ QueryRecord& operator=(const QueryRecord &src);
+
+ /** Constructor for condition on string typed value.
+ *
+ * Initializes the object to hold condition on string typed
+ * attribute value.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value Actual value.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const std::string &value);
+
+ /** Constructor for condition on integer typed value.
+ *
+ * Initializes the object to hold condition on integer typed
+ * attribute value.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value Actual value.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const int value);
+
+ /** Constructor for condition on timeval typed value.
+ *
+ * Initializes the object to hold condition on timeval typed
+ * attribute value.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value Actual value.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const struct timeval &value);
+
+ /** Constructor for condition on JobId typed value.
+ *
+ * Initializes the object to hold condition on JobId typed
+ * attribute value.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value Actual value.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const glite::wmsutils::jobid::JobId &value);
- /* constructors for simple attribute queries */
- QueryRecord(const Attr, const Op, const std::string &);
- QueryRecord(const Attr, const Op, const int);
- QueryRecord(const Attr, const Op, const struct timeval &);
- QueryRecord(const Attr, const Op, const glite::wmsutils::jobid::JobId&);
/* this one is for attr==TIME and particular state */
- QueryRecord(const Attr, const Op, const int, const struct timeval &);
+ /** Constructor for condition on timeval typed value.
+ *
+ * Initializes the object to hold condition on the time the job
+ * stays in given state.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] state State of thet job.
+ * \param[in] value Actual value.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const int state, const struct timeval &value);
/* constructors for WITHIN operator */
- QueryRecord(const Attr, const Op, const std::string &, const std::string &);
- QueryRecord(const Attr, const Op, const int, const int);
- QueryRecord(const Attr, const Op, const struct timeval &, const struct timeval &);
- QueryRecord(const Attr, const Op, const int, const struct timeval &, const struct timeval &);
+ /** Constructor for condition on string typed interval.
+ *
+ * Initializes the object to hold condition on string typed
+ * attribute interval.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value_min Low interval boundary.
+ * \param[in] value_max High interval boundary.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const std::string &value_min, const std::string &value_max);
+
+ /** Constructor for condition on integer typed interval.
+ *
+ * Initializes the object to hold condition on integer typed
+ * attribute interval.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value_min Low interval boundary.
+ * \param[in] value_max High interval boundary.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const int value_min, const int value_max);
+
+ /** Constructor for condition on timeval typed interval.
+ *
+ * Initializes the object to hold condition on timeval typed
+ * attribute interval.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value_min Low interval boundary.
+ * \param[in] value_max High interval boundary.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const struct timeval &value_min, const struct timeval &value_max);
+
+ /** Constructor for condition on timeval typed interval for
+ * given state.
+ *
+ * Initializes the object to hold condition on the time job
+ * stayed in given state.
+ * \param[in] name Name of the attribute.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] state State of thet job.
+ * \param[in] value_min Low interval boundary.
+ * \param[in] value_max High interval boundary.
+ * \throw Exception Invalid value type for given attribute.
+ */
+ QueryRecord(const Attr name, const Op op, const int state, const struct timeval &value_min, const struct timeval &value_max);
/* convenience for user tags */
- QueryRecord(const std::string &, const Op, const std::string &);
- QueryRecord(const std::string &, const Op, const std::string &, const std::string &);
+ /** Convenience constructor for condition on user tags.
+ *
+ * Initializes the object to hold condition on the value of
+ * user tag.
+ * \param[in] tag Name of the tag.
+ * \param[in] op Symbolic name of the predicate.
+ * \param[in] value Value of the tag.
+ */
+ QueryRecord(const std::string &tag, const Op op, const std::string &value);
+
+ /** Convenience constructor for condition on user tags.
+ *
+ * Initializes the object to hold condition on the value of
+ * user tag.
+ * \param[in] tag Name of the tag.
+ * \param[in] op Symbolic namen of the predicate.
+ * \param[in] value_min Minimal value of the tag.
+ * \param[in] value_max Maximal value of the tag.
+ * \throws Exception Predicate is not WITHIN.
+ */
+ QueryRecord(const std::string &tag, const Op op, const std::string &value_min, const std::string &value_max);
+ /** Destructor.
+ *
+ * The actual work is done by member destructors.
+ */
~QueryRecord();
- static const std::string AttrName(const Attr) ;
+ /** Return the string representation of symbolic attribute
+ * name.
+ * \param[in] attr Symbolic attribute name.
+ * \returns Printable attribute name.
+ */
+ static const std::string AttrName(const Attr attr) ;
protected:
};
-/** Supported aggregate operations */
+/** Supported aggregate operations. */
enum AggOp { AGG_MIN=1, AGG_MAX, AGG_COUNT };
/**
- * Connection to the L&B server.
- * Maintain connection to the server.
- * Implement non job-specific API calls
+ * Class representing a connection to the L&B server.
+ *
+ * This class serves as an interface for queries not related to
+ * particular job. The address of the bookkeeping server to query can
+ * be set arbitrarily during the lifetime of this object, connection
+ * to the server is maintained automatically by the underlying C API
+ * layer. This class can be thought of also as an encapsulation of
+ * edg_wll_Context from L&B C API.
+ *
+ * ServerConnection's methods correlate to the L&B C API functions
+ * taking edg_wll_Context as their first argument and not having
+ * edg_wll_JobId as the second argument.
+ * \see edg_wll_Context
*/
-
class ServerConnection {
public:
+ /** \defgroup query Methods for querying the bookkeeping
+ * server.
+ *
+ * These methods serve for obtaining data from the bookkeeping
+ * server. The L&B service queries come in two flavors:
+ * \li conjunctive query, as in <tt>(cond1) or (cond2)</tt>
+ * \li conjunction of disjunctive queries, as in <tt>( (cond1)
+ * or (cond2) ) and ( (cond3) or (cond4) )</tt>
+ * Methods for both query flavors are provided.
+ *
+ * Query methods actually do communicate with the server and
+ * they are synchronous; their completion can take some time
+ * not exceeding the query timeout.
+ */
+
+ /** \defgroup property Methods for setting and getting
+ * connection properties.
+ *
+ * These methods are used for setting and obtaining various
+ * parameters of the communication (timeouts, user
+ * certificates, limits). Both general methods (taking the
+ * symbolic name of the parameter as an argument) and
+ * convenience methods (for some parameters) are provided.
+ *
+ * The methods are local, no communication takes place.
+ */
+
friend class Job;
+ /** Default constructor.
+ *
+ * Initializes the context to default values.
+ * \throws OSException Initialization failed.
+ */
ServerConnection(void);
- /* DEPRECATED: do not use
- * connections are now handled automagically inside the implementation
+ /** DEPRECATED.
+ *
+ * \throws Exception Always.
*/
ServerConnection(const std::string &);
- /** Open connection to a given server */
+ /** DEPRECATED.
+ *
+ * \throws Exception Always.
+ */
void open(const std::string &);
- /** Close the current connection */
+ /** DEPRECATED.
+ *
+ * \throws Exception Always.
+ */
void close(void);
/* END DEPRECATED */
/* set & get parameter methods */
- /* consumer parameter settings */
- void setQueryServer(const std::string&, int);
- void setQueryTimeout(int);
-
- void setX509Proxy(const std::string&);
- void setX509Cert(const std::string&, const std::string&);
-
+ /** Set bookkeeping server address.
+ * \ingroup property
+ *
+ * Directs the instance to query the given bookkeping server.
+ * \param[in] host Hostname of the server.
+ * \param[in] port Service port.
+ * \throws LoggingException Setting parameters failed.
+ */
+ void setQueryServer(const std::string& host, int port);
+
+ /** Set query timeout.
+ * \ingroup property
+ *
+ * Sets the time interval to wait for server response.
+ * \param[in] time Time in seconds before the query expires.
+ * \throws LoggingException Setting parameters failed.
+ */
+ void setQueryTimeout(int time);
+
+ /** Set user's proxy certificate.
+ * \ingroup property
+ *
+ * Instructs the instance to authenticate to the server using
+ * user's X509 proxy certificate.
+ * \param[in] proxy Name of file containing the user's proxy certificate.
+ * \throws LoggingException Setting paramater failed.
+ */
+ void setX509Proxy(const std::string& proxy);
+
+ /** Set user's certificate.
+ * \ingroup property
+ *
+ * Instructs the instance to authenticate to the server using
+ * users's full X509 certificate (which is not a good thing).
+ * \param[in] cert Name of file containing the user's certificate.
+ * \param[in] key Name of file containing the user's private
+ * key.
+ * \throws LoggingException Setting parameters failed.
+ */
+ void setX509Cert(const std::string& cert, const std::string& key);
+
+ /** Get address of the bookkeeping server.
+ * \ingroup property
+ *
+ * Returns address of the bookkeeping server this instance is
+ * bound to.
+ * \returns Address (hostname,port).
+ * \throws LoggingException Getting parameter failed.
+ */
std::pair<std::string, int> getQueryServer() const;
+
+ /** Get query timeout.
+ * \ingroup property
+ *
+ * Returns the time interval this instance waits for server
+ * response.
+ * \returns Number of seconds to wait.
+ * \throws LoggingException Getting parameter failed.
+ */
int getQueryTimeout() const;
+ /** Get user's proxy.
+ * \ingroup property
+ *
+ * Returns filename of the user's X509 proxy certificate used
+ * to authenticate to the server.
+ * \returns Filename of the proxy certificate.
+ * \throws LoggingException Getting parameter failed.
+ */
std::string getX509Proxy() const;
+
+ /** Get user's X509 certificate.
+ * \ingroup property
+ *
+ * Returns filenames of the user's full X509 certificate used
+ * to authenticate to the server.
+ * \returns Pair of (certificate, key) filenames.
+ * \throws LoggingException Getting parameter failed.
+ */
std::pair<std::string, std::string> getX509Cert() const;
/* end of set & get */
+ /** Destructor.
+ *
+ * Closes the connections and frees the context.
+ */
virtual ~ServerConnection();
/* consumer API */
/** Retrieve the set of single indexed attributes.
- * outer vector elements correspond to indices
- * inner vector elements correspond to index columns
- * if .first of the pair is USERTAG, .second is its name
- * if .first is TIME, .second is state name
- * otherwise .second is meaningless (empty string anyway)
+ * \ingroup query
+ *
+ * Returns the set of attributes that are indexed on the
+ * server. Every query must contain at least one indexed
+ * attribute for performance reason; exception to this rule
+ * requires setting appropriate paramater on the server and is
+ * not advised.
+ *
+ * In the vector returned, outer elements correspond to indices,
+ * inner vector elements correspond to index
+ * columns.
+ * If <tt>.first</tt> of the pair is USERTAG, <tt>.second</tt> is its name;
+ * if <tt>.first</tt> is TIME, <tt>.second</tt> is state name
+ * otherwise <tt>.second</tt> is meaningless (empty string anyway).
*/
std::vector<std::vector<std::pair<QueryRecord::Attr,std::string> > >
getIndexedAttrs(void);
- /** Retrieve hard and soft result set size limit */
- std::pair<int,int> getLimits(void) const;
-
- /** Set the soft result set size limit */
- void setQueryJobsLimit(int);
- void setQueryEventsLimit(int);
+ /* Retrieve hard and soft result set size limit.
+ * \ingroup property
+ *
+ * Returns both the hard and soft limit on the number of
+ * results returned by the bookkeeping server.
+ * \returns Pair (hard, soft) of limits.
+ * \throws
+ */
+ // std::pair<int,int> getLimits(void) const;
+
+ /** Set the soft result set size limit.
+ * \ingroup property
+ *
+ * Sets the maximum number of results this instance is willing
+ * to obtain when querying for jobs.
+ * \param max Maximum number of results.
+ * \throws LoggingException Setting parameter failed.
+ */
+ void setQueryJobsLimit(int max);
+
+ /** Set the soft result set size limit.
+ * \ingroup property
+ *
+ * Sets the maximum number of results this instance is willing
+ * to obtain when querying for Events.
+ * \param max Maximum number of results.
+ * \throws LoggingException Setting parameter failed.
+ */
+ void setQueryEventsLimit(int max);
- /** Retrieve all events satisfying the query records
- * @param job_cond, event_cond - vectors of conditions to be satisfied
- * by jobs as a whole or particular events, conditions are ANDed
- * @param events vector of returned events
+ /** Retrieve all events satisfying the query records.
+ * \ingroup query
+ *
+ * Returns all events belonging to the jobs specified by \arg
+ * job_cond and in addition satisfying the \arg event_cond.
+ * \param[in] job_cond Conjunctive query on jobs.
+ * \param[in] event_cond Conjunctive query on events.
+ * \param[out] events Vector of Event objects representing L&B
+ * events.
+ * \throws LoggingException Query failed.
*/
void queryEvents(const std::vector<QueryRecord>& job_cond,
const std::vector<QueryRecord>& event_cond,
- std::vector<Event>&) const;
+ std::vector<Event>& events) const;
+ /** Convenience form of queryEvents.
+ *
+ */
const std::vector<Event> queryEvents(const std::vector<QueryRecord>& job_cond,
const std::vector<QueryRecord>& event_cond) const;
+ /** Another modification of queryEvents.
+ *
+ * The same method, but the results are returned as a list
+ * instead of vector.
+ */
const std::list<Event> queryEventsList(const std::vector<QueryRecord>& job_cond,
const std::vector<QueryRecord>& event_cond) const;
- /** The same as queryEvents but return only an aggregate.
- * @param job_cond, event_cond - vectors of conditions to be satisfied
- * by jobs as a whole or particular events, conditions are ANDed
- * @param op aggregate operator to apply
- * @param attr attribute to apply the operation to
+ /** NOT IMPLEMENTED.
+ * \param[in] job_cond
+ * \param[in] event_cond Vectors of conditions to be satisfied
+ * by jobs as a whole or particular events.
+ * \param[in] op Aggregate operator to apply.
+ * \param[in] attr Attribute to apply the operation to.
*/
std::string queryEventsAggregate(const std::vector<QueryRecord>& job_cond,
const std::vector<QueryRecord>& event_cond,
std::string const attr) const;
- /** Retrieve all events satisfying the query records
- * @param job_cond, event_cond - vectors of vectors of job or event conditions,
- * respectively. The inner vectors are logically ANDed, the outer are ORed
- * (cond1 AND cond2 AND ...) OR (condN AND ...)
- * @param events vector of returned events
+ /** Retrieve all events satisfying the conjunctive-disjunctive
+ * query.
+ *
+ * Returns all events belonging to the jobs specified by
+ * <tt>job_cond</tt> and satisfying <tt>query_cond</tt>. The
+ * conditions are given in conjunctive-disjunctive form
+ * <tt>((cond1 OR cond2 OR ...) AND ...)</tt>
+ * \param[in] job_cond Vector of conditions on jobs.
+ * \param[in] event_cond Vector of coditions on events.
+ * \param[out] eventList Returned Event's.
+ * \throws LoggingException Query failed.
*/
void queryEvents(const std::vector<std::vector<QueryRecord> >& job_cond,
const std::vector<std::vector<QueryRecord> >& event_cond,
- std::vector<Event>&) const;
+ std::vector<Event>& eventList) const;
+ /** Convenience form of queryEvents.
+ *
+ * The same as previous, but the resulting vector is passed as
+ * a return value.
+ */
const std::vector<Event>
queryEvents(const std::vector<std::vector<QueryRecord> >& job_cond,
const std::vector<std::vector<QueryRecord> >& event_cond) const;
- /** Retrieve jobs satisfying the query records, including their states
- * @param query vector of Query records that are anded to form the
- * query
- * @param ids vector of returned job id's
- * @param states vector of returned job states
+ /** Retrieve jobs satisfying the query.
+ *
+ * Finds all jobs (represented as JobId's) satisfying given
+ * query.
+ * \param[in] query Query in conjunctive form.
+ * \param[out] jobList List of job id's.
+ * \throws LoggingException Query failed.
*/
-
void queryJobs(const std::vector<QueryRecord>& query,
- std::vector<glite::wmsutils::jobid::JobId>& ids) const;
-
+ std::vector<glite::wmsutils::jobid::JobId>& jobList) const;
+
+ /** Convenience form of queryJobs.
+ *
+ * The same as above, but job id's are passed as a return
+ * value.
+ */
const std::vector<glite::wmsutils::jobid::JobId>
queryJobs(const std::vector<QueryRecord>& query) const;
- /** Retrieve jobs satisfying the query records, including their states
- * @param query vector of Query record vectors that are ORed and ANDed to form the
- * query
- * @param ids vector of returned job id's
- * @param states vector of returned job states
+ /** Retrieve jobs satisfying the query.
+ *
+ * Finds all jobs satisfying query given in
+ * conjunctive-disjunctive form.
+ * \param[in] query Conjunction of disjunctive queries.
+ * \param[out] jobList Job id's of found jobs.
+ * \throws LoggingException Query failed.
*/
-
void queryJobs(const std::vector<std::vector<QueryRecord> >& query,
- std::vector<glite::wmsutils::jobid::JobId>& ids) const;
+ std::vector<glite::wmsutils::jobid::JobId>& jobList) const;
+ /** Convenience form of queryJobs.
+ *
+ * Same as above, but result is passed as a retutrn value.
+ */
const std::vector<glite::wmsutils::jobid::JobId>
queryJobs(const std::vector<std::vector<QueryRecord> >& query) const;
- /** Retrieve jobs satisfying the query records, including status
- * information
- * @param query vector of Query records that are anded to form the
- * query
- * @param ids vector of returned job id's
- * @param states vector of returned job states
+ /** Retrieve status of jobs satisfying the given simple query.
+ *
+ * Returns states (represented by JobStatus) of all jobs
+ * satisfying the query in conjunctive form.
+ * \param[in] query Condition on jobs.
+ * \param[in] flags The same as Job::status() flags.
+ * \param[out] states States of jobs satysfying the condition.
+ * \throws LoggingException Query failed.
*/
void queryJobStates(const std::vector<QueryRecord>& query,
int flags,
std::vector<JobStatus> & states) const;
+
+ /** Convenience form of queryJobStates.
+ *
+ * Same as above, but the result is passed as a return value.
+ */
const std::vector<JobStatus> queryJobStates(const std::vector<QueryRecord>& query,
int flags) const;
+ /** Convenience form of queryJobStates.
+ *
+ * Same as above, but results are returned as list instead of
+ * vector.
+ */
const std::list<JobStatus> queryJobStatesList(const std::vector<QueryRecord>& query,
int flags) const;
- /** Retrieve jobs satisfying the query records, including status
- * information
- * @param query vector of Query records that are anded to form the
- * query
- * @param ids vector of returned job id's
- * @param states vector of returned job states
+ /** Retrieve status of jobs satisfying the given
+ * conjunctive-disjunctive query.
+ *
+ * Returns states (represented by JobStatus) of all jobs
+ * satisfying the query in conjunctive form.
+ * \param[in] query Condition on jobs.
+ * \param[in] flags The same as Job::status() flags.
+ * \param[out] states States of jobs satysfying the condition.
+ * \throws LoggingException Query failed.
*/
void queryJobStates(const std::vector<std::vector<QueryRecord> >& query,
int flags,
std::vector<JobStatus> & states) const;
+
+ /** Convenience form of queryJobStates.
+ *
+ * Same as above, but the result is passed as a return value.
+ */
const std::vector<JobStatus>
queryJobStates(const std::vector<std::vector<QueryRecord> >& query,
int flags) const;
- /** States of all user's jobs.
- * Convenience wrapper around queryJobs.
+ /** Return states of all user's jobs.
+ *
+ * Convenience wrapper around queryJobStates, returns status of all
+ * jobs whose owner is the current user (as named in the X509
+ * certificate subject).
+ * \param[out] stateList States of jobs owned by this user.
+ * \throws LoggingException Query failed.
*/
void userJobStates(std::vector<JobStatus>& stateList) const;
const std::vector<JobStatus> userJobStates() const;
- /** JobId's of all user's jobs.
- * Convenience wrapper around queryJobs.
+ /** Find all user's jobs.
+ *
+ * Convenience wrapper around queryJobs, returns id's of all
+ * jobs whose owner is the current user (as named in the X509
+ * certificate subject).
+ * \param[out] jobs Id's of jobs owned by this user.
+ * \throws LoggingException Query failed.
*/
- void userJobs(std::vector<glite::wmsutils::jobid::JobId> &) const;
- const std::vector<glite::wmsutils::jobid::JobId> userJobs() const;
+ void userJobs(std::vector<glite::wmsutils::jobid::JobId> &jobs) const;
- /** Manipulate LB parameters, the same as for edg_wll_Context in C */
- void setParam(edg_wll_ContextParam, int);
- void setParam(edg_wll_ContextParam, const std::string);
- void setParam(edg_wll_ContextParam, const struct timeval &);
+ /** Convenience form of userJobs.
+ *
+ * Same as above, but results are passed as a return value.
+ */
+ const std::vector<glite::wmsutils::jobid::JobId> userJobs() const;
- int getParamInt(edg_wll_ContextParam) const;
- std::string getParamString(edg_wll_ContextParam) const;
- struct timeval getParamTime(edg_wll_ContextParam) const;
+ /** Set communication parameters of integer type.
+ *
+ * Sets the named parameter to the given integer value.
+ * \param[in] name Symbolic name of the parameter.
+ * \param[in] value Value.
+ * \throws LoggingException Setting parameter failed.
+ * \see edg_wll_SetParam()
+ */
+ void setParam(edg_wll_ContextParam name, int value);
+
+ /** Set communication parameters of string type.
+ *
+ * Sets the named parameter to the given string value.
+ * \param[in] name Symbolic name of the parameter.
+ * \param[in] value Value.
+ * \throws LoggingException Setting parameter failed.
+ * \see edg_wll_SetParam()
+ */
+ void setParam(edg_wll_ContextParam name, const std::string &value);
+
+ /** Set communication parameters of timeval type.
+ *
+ * Sets the named parameter to the given timeval value.
+ * \param[in] name Symbolic name of the parameter.
+ * \param[in] value Value.
+ * \throws LoggingException Setting parameter failed.
+ * \see edg_wll_SetParam()
+ */
+ void setParam(edg_wll_ContextParam name, const struct timeval &value);
+
+ /** Get communication parameters of integer type.
+ *
+ * Gets the named parameter of integer type.
+ * \param[in] name Symbolic name of the parameter.
+ * \throws LoggingException Getting parameter failed.
+ * \see edg_wll_GetParam()
+ */
+ int getParamInt(edg_wll_ContextParam name) const;
+
+ /** Get communication parameters of string type.
+ *
+ * Gets the named parameter of string type.
+ * \param[in] name Symbolic name of the parameter.
+ * \throws LoggingException Getting parameter failed.
+ * \see edg_wll_GetParam()
+ */
+ std::string getParamString(edg_wll_ContextParam name) const;
+
+ /** Get communication parameters of timeval type.
+ *
+ * Gets the named parameter of timeval type.
+ * \param[in] name Symbolic name of the parameter.
+ * \throws LoggingException Getting parameter failed.
+ * \see edg_wll_GetParam()
+ */
+ struct timeval getParamTime(edg_wll_ContextParam name) const;
protected:
edg_wll_Context context;
};
-EWL_END_NAMESPACE;
+EWL_END_NAMESPACE
#endif
#define __EDG_WORKLOAD_LOGGING_CLIENT_CONSUMER_H__
/*!
- * \file client/consumer.h (lbapi.h originaly)
+ * \file consumer.h
* \brief L&B consumer API
- *
- * General rules:
- * - functions return 0 on success, nonzero on error, errror details can
- * be found via edg_wll_ErrorCode()
- * - OUT are ** types, functions malloc()-ate objects and fill in the pointer
- * pointed to by the OUT argument
- * - returned lists of pointers are NULL-terminated malloc()-ed arrays
- * - edg_wll_Query + wrapper terminate arrays with EDG_WLL_EVENT_UNDEF event
- * - OUT is NULL if the list is empty
*/
#ident "$Header$"
extern "C" {
#endif
-/*!
+/**
+ * \defgroup querying Server querying
+ * \brief The core part of the LB querying API.
+ *
+ * The functions in this part of the API are responsible for
+ * transforming the user query to the LB protocol, contacting the server,
+ * receiving back the response and transforming back the results to the
+ * API data structures.
+ *
+ * General rules:
+ * - functions return 0 on success, nonzero on error, errror details can
+ * be found via edg_wll_ErrorCode()
+ * - OUT are ** types, functions malloc()-ate objects and fill in the pointer
+ * pointed to by the OUT argument
+ * - returned lists of pointers are NULL-terminated malloc()-ed arrays
+ * - edg_wll_Query + wrapper terminate arrays with EDG_WLL_EVENT_UNDEF event
+ * - OUT is NULL if the list is empty
+ *@{
+ */
+
+/**
* Predefined types for query attributes
*/
typedef enum _edg_wll_QueryAttr{
} edg_wll_QueryAttr;
-/*!
+/**
* Predefined types for query operands
*/
typedef enum _edg_wll_QueryOp{
} edg_wll_QueryOp;
-/*!
+/**
* Single query condition for edg_wll_Query().
* Those records are composed to form an SQL \a where clause
* when processed at the L&B server
} value, value2;
} edg_wll_QueryRec;
-/************************************************
- * API FUNCTION DECLARATIONS *
+/**
+ * default query timeout (in seconds)
*/
-
-
-#ifdef CLIENT_SBIN_PROG
-extern int edg_wll_http_send_recv(
- edg_wll_Context,
- char *, const char * const *, char *,
- char **,char ***,char **
-);
-
-extern int http_check_status(
- edg_wll_Context,
- char *,
- char **
-);
-
-extern int set_server_name_and_port(
- edg_wll_Context,
- const edg_wll_QueryRec **
-);
-
-#endif
+#define EDG_WLL_QUERY_TIMEOUT_DEFAULT 120
/**
- * \name Server querying
- *
- *@{
+ * maximal query timeout (in seconds)
*/
+#define EDG_WLL_QUERY_TIMEOUT_MAX 1800
/**
* General query on events.
- * Return events satysfying all conditions
+ * Return events satisfying all conditions
* query records represent conditions in the form
* \a attr \a op \a value eg. time > 87654321.
* \see edg_wll_QueryRec
*
- * \param context IN: context to work with
- * \param job_conditions IN: query conditions (ANDed) on current job status, null (i.e. ATTR_UNDEF) terminated list. NULL means empty list, i.e. always TRUE
- * \param event_conditions: conditions on events, null terminated list, NULL means empty list, i.e. always TRUE
- * \param events OUT: list of matching events
+ * \param[in] context context to work with
+ * \param[in] job_conditions query conditions (ANDed) on current job status, null (i.e. ATTR_UNDEF) terminated list. NULL means empty list, i.e. always TRUE
+ * \param[in] event_conditions conditions on events, null terminated list, NULL means empty list, i.e. always TRUE
+ * \param[out] events list of matching events
*/
int edg_wll_QueryEvents(
edg_wll_Context context,
edg_wll_Event ** events
);
+/**
+ * Extended event query interface.
+ * Similar to \ref edg_wll_QueryEvents but the conditions are nested lists.
+ * Elements of the inner lists have to refer to the same attribute and they
+ * are logically ORed.
+ * The inner lists themselves are logically ANDed then.
+ */
+
int edg_wll_QueryEventsExt(
edg_wll_Context context,
const edg_wll_QueryRec ** job_conditions,
/**
* Query LBProxy and use plain communication
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
*/
int edg_wll_QueryEventsProxy(
edg_wll_Context context,
edg_wll_Event ** events
);
+/**
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+ */
+
int edg_wll_QueryEventsExtProxy(
edg_wll_Context context,
const edg_wll_QueryRec ** job_conditions,
* Return jobs (and possibly their states) for which an event satisfying the conditions
* exists.
* \see edg_wll_QueryEvents
- * \param context IN: context to work with
- * \param conditions IN: query records (ANDed), null (i.e. EDG_WLL_ATTR_UNDEF) terminated list
- * \param flags IN: additional status fields to retrieve (\see edg_wll_JobStatus)
- * \param jobs OUT: list of job ids. May be NULL.
- * \param states OUT: list of corresponding states (returned only if not NULL)
+ * \param[in] context context to work with
+ * \param[in] conditions query records (ANDed), null (i.e. EDG_WLL_ATTR_UNDEF) terminated list
+ * \param[in] flags additional status fields to retrieve (\see edg_wll_JobStatus)
+ * \param[out] jobs list of job ids. May be NULL.
+ * \param[out] states list of corresponding states (returned only if not NULL)
*/
int edg_wll_QueryJobs(
edg_wll_Context context,
edg_wll_JobStat ** states
);
+/**
+ * Extended job query interface.
+ * Similar to \ref edg_wll_QueryJobs but the conditions are nested lists.
+ * Elements of the inner lists have to refer to the same attribute and they
+ * are logically ORed.
+ * The inner lists themselves are logically ANDed then.
+ */
+
+
int edg_wll_QueryJobsExt(
edg_wll_Context context,
const edg_wll_QueryRec ** conditions,
/**
* Query LBProxy and use plain communication
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
*/
int edg_wll_QueryJobsProxy(
edg_wll_Context context,
edg_wll_JobStat ** states
);
+/**
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+ */
+
int edg_wll_QueryJobsExtProxy(
edg_wll_Context context,
const edg_wll_QueryRec ** conditions,
/* starting from bit 10 private flags begins - do not add 1024 and more! */
/** Return status of a single job.
- * \param context IN: context to operate on
- * \param jobid IN: query this job
- * \param flags IN: specifies optional status fields to retrieve,
+ * \param[in] context context to operate on
+ * \param[in] jobid query this job
+ * \param[in] flags specifies optional status fields to retrieve,
* \see EDG_WLL_STAT_CLASSADS, EDG_WLL_STAT_CHILDREN, EDG_WLL_STAT_CHILDSTAT
+ * \param[out] status status
*/
int edg_wll_JobStatus(
/**
* Query LBProxy and use plain communication
+ * \param[in] context context to operate on
+ * \param[in] jobid query this job
+ * \param[in] flags specifies optional status fields to retrieve,
+ * \see EDG_WLL_STAT_CLASSADS, EDG_WLL_STAT_CHILDREN, EDG_WLL_STAT_CHILDSTAT
+ * \param[out] status the status of the job
+
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
*/
int edg_wll_JobStatusProxy(
edg_wll_Context context,
- const edg_wlc_JobId jobid,
+ const edg_wlc_JobId jobid,
int flags,
edg_wll_JobStat *status
);
/**
* Return all events related to a single job.
* Convenience wrapper around edg_wll_Query()
- * \param context IN: context to work with
- * \param jobId IN: job to query
- * \param events OUT: list of events
+ * \param[in] context context to work with
+ * \param[in] jobId job to query
+ * \param[out] events list of events
*/
int edg_wll_JobLog(
/**
* Query LBProxy and use plain communication
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+
*/
int edg_wll_JobLogProxy(
edg_wll_Context context,
/**
* All current user's jobs.
- * \param context IN: context to work with
- * \param jobs OUT: list of the user's jobs
- * \param states OUT: list of the jobs' states
+ * \param[in] context context to work with
+ * \param[out] jobs list of the user's jobs
+ * \param[out] states list of the jobs' states
*/
int edg_wll_UserJobs(
edg_wll_Context context,
/**
* Query LBProxy and use plain communication
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+
*/
int edg_wll_UserJobsProxy(
edg_wll_Context context,
/**
* Server supported indexed attributes
* \see DataGrid-01-TEN-0125
- * \param context IN: context to work with
- * \param attrs OUT: configured indices (each index is an UNDEF-terminated
+ * \param[in] context context to work with
+ * \param[out] attrs configured indices (each index is an UNDEF-terminated
* array of QueryRec's from which only attr (and attr_id
* eventually) are meaningful
*/
/**
* Retrieve limit on query result size (no. of events or jobs).
- * FIXME: not implemented.
+ * \warning not implemented.
* \see DataGrid-01-TEN-0125
- * \param context IN: context to work with
- * \param limit OUT: server imposed limit
+ * \param[in] context context to work with
+ * \param[out] limit server imposed limit
*/
int edg_wll_GetServerLimit(
edg_wll_Context context,
);
/**
- * UI port for the job
- * \param context IN: context to work with
- * \param jobId IN: job to query
- * \param name IN: name of the UI-port
- * \param host OUT: hostname of port
- * \param port OUT: port number
+ * UI port for intactive jobs. Used internally by WMS.
+ * \param[in] context context to work with
+ * \param[in] jobId job to query
+ * \param[in] name name of the UI-port
+ * \param[out] host hostname of port
+ * \param[out] port port number
*/
int edg_wll_QueryListener(
edg_wll_Context context,
/**
* Query LBProxy and use plain communication
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+
*/
-int edg_wll_QueryListener(
+int edg_wll_QueryListenerProxy(
edg_wll_Context context,
edg_wlc_JobId jobId,
const char * name,
/**
* Ask LB Proxy server for sequence number
- * \param context IN: context to work with
- * \param jobId IN: job to query
- * \param code OUT: sequence code
+ * \param[in] context context to work with
+ * \param[in] jobId job to query
+ * \param[out] code sequence code
+ * \warning edg_wll_*Proxy() functions are not implemented in release 1.
+
*/
char ** code
);
-/*@}*/
-
/*
* edg_wll_QueryRec manipulation
*/
/** Free edg_wll_QueryRec internals, not the structure itself */
void edg_wll_QueryRecFree(edg_wll_QueryRec *);
+/*
+ *@} end of group
+ */
+#ifdef CLIENT_SBIN_PROG
+extern int edg_wll_http_send_recv(
+ edg_wll_Context,
+ char *, const char * const *, char *,
+ char **,char ***,char **
+);
-/**
- * default and maximal query timeout (in seconds)
- */
-#define EDG_WLL_QUERY_TIMEOUT_DEFAULT 120
-#define EDG_WLL_QUERY_TIMEOUT_MAX 1800
+extern int http_check_status(
+ edg_wll_Context,
+ char *,
+ char **
+);
+
+extern int set_server_name_and_port(
+ edg_wll_Context,
+ const edg_wll_QueryRec **
+);
+
+#endif
#ifdef __cplusplus
}
#define _EDG_WORKLOAD_LOGGING_CLIENT_CONTEXT_H
/**
- * \file edg/workload/logging/client/context.h
* \brief L&B API common context (publicly visible) and related definitions
*/
extern "C" {
#endif
+/**
+ * \defgroup context Context
+ *
+ *@{
+ */
+
/** Opaque context type */
typedef struct _edg_wll_Context *edg_wll_Context;
/** Allocate an initialize a new context object.
- * \param context OUT returned context
+ * \param[out] context returned context
* \return 0 on success, ENOMEM if malloc() fails
*/
int edg_wll_InitContext(edg_wll_Context *context);
/** Destroy and free context object.
* Also performs necessary cleanup (closing connections etc.)
- * \param context IN context to free
+ * \param[in] context context to free
*/
void edg_wll_FreeContext(edg_wll_Context context);
/** Set a context parameter.
- * \param context INOUT context to work with
- * \param param IN parameter to set
- * \param ... IN value to set (if NULL or 0, default is used)
+ * \param[in,out] context context to work with
+ * \param[in] param parameter to set
+ * \param[in] ... value to set (if NULL or 0, default is used)
* \retval 0 success
* \retval EINVAL param is not a valid parameter, or invalid value
*/
...
);
-struct timeval; /* gcc, shut up! */
+struct timeval; /* XXX: gcc, shut up! */
+
+/** Set a context parameter of type int.
+ * \param[in,out] ctx context to work with
+ * \param[in] param parameter to set
+ * \param[in] val value to set
+ * \retval 0 success
+ * \retval EINVAL param is not a valid parameter, or invalid value
+ */
+int edg_wll_SetParamInt(edg_wll_Context ctx,edg_wll_ContextParam param,int val);
+
+/** Set a context parameter of type string.
+ * \param[in,out] ctx context to work with
+ * \param[in] param parameter to set
+ * \param[in] val value to set (if NULL, default is used)
+ * \retval 0 success
+ * \retval EINVAL param is not a valid parameter, or invalid value
+ */
+int edg_wll_SetParamString(edg_wll_Context ctx,edg_wll_ContextParam param,const char *val);
-int edg_wll_SetParamInt(edg_wll_Context,edg_wll_ContextParam,int);
-int edg_wll_SetParamString(edg_wll_Context,edg_wll_ContextParam,const char *);
-int edg_wll_SetParamTime(edg_wll_Context,edg_wll_ContextParam,const struct timeval *);
+/** Set a context parameter of type timeval.
+ * \param[in,out] ctx context to work with
+ * \param[in] param parameter to set
+ * \param[in] val value to set (if NULL, default is used)
+ * \retval 0 success
+ * \retval EINVAL param is not a valid parameter, or invalid value
+ */
+int edg_wll_SetParamTime(edg_wll_Context ctx,edg_wll_ContextParam param,const struct timeval *val);
/** Get current parameter value.
- * \param context INOUT context to work with
- * \param param IN parameter to retrieve
- * \param ... OUT pointer to output variable
+ * \param[in,out] context context to work with
+ * \param[in] param parameter to retrieve
+ * \param[out] ... pointer to output variable
* \retval 0 success
* \retval EINVAL param is not a valid parameter
*/
/**
* Retrieve error details on recent API call
- * \param context IN: context to work with
- * \param errText OUT: standard error text
+ * \param[in] context context to work with
+ * \param[out] errText standard error text
* (may be NULL - no text returned)
- * \param errDesc OUT: additional error description
+ * \param[out] errDesc additional error description
* (may be NULL - no text returned)
* \return Error code of the recent error
*/
int edg_wll_Error(
edg_wll_Context context,
char **errText,
- char **eddDesc
+ char **errDesc
);
/** Convert source code to printable string
edg_wlc_JobId *jobid_out
);
+/*
+ *@} end of group
+ */
+
#ifdef __cplusplus
}
#endif
#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_EVENTS_H__
#define __EDG_WORKLOAD_LOGGING_CLIENT_EVENTS_H__
-/**
- * \file edg/workload/logging/client/events.h
- * \brief contains definition of event type codes for use both by lbapi.h and dglog.h
- */
-
#ident "$Header$"
/*
@@@AUTO
extern "C" {
#endif
+/**
+ * \defgroup events Events
+ * \brief All L&B event types.
+ *
+ *@{
+ */
/**
* Predefined type for ULM string
} edg_wll_EventCode;
/**
- * \fn edg_wll_EventCode edg_wll_StringToEvent(char *name)
- * \param name a string event name (e.g. "JobTransfer")
+ * \fn edg_wll_EventCode edg_wll_StringToEvent(const char *name)
+ * \param[in] name a string event name (e.g. "JobTransfer")
* \return corresponding numeric code (edg_wll_EventCode)
* \brief convert a string event name to the corresponding numeric code
*/
-extern edg_wll_EventCode edg_wll_StringToEvent(char *);
+extern edg_wll_EventCode edg_wll_StringToEvent(const char *name);
/**
* \fn char *edg_wll_EventToString(edg_wll_EventCode event)
- * \param event an event numeric code (edg_wll_EventCode)
+ * \param[in] event an event numeric code (edg_wll_EventCode)
* \return corresponding string (e.g. "JobTransfer")
* \brief convert an event numeric code to the corresponding string
*/
-extern char *edg_wll_EventToString(edg_wll_EventCode);
+extern char *edg_wll_EventToString(edg_wll_EventCode event);
/**
} edg_wll_KeyNameCode;
/**
- * \fn edg_wll_KeyNameCode edg_wll_StringToKeyName(char *name)
- * \param name a string ULM key name (e.g. "DG.JOB.TRANSFER.DEST")
+ * \fn edg_wll_KeyNameCode edg_wll_StringToKeyName(const char *name)
+ * \param[in] name a string ULM key name (e.g. "DG.JOB.TRANSFER.DEST")
* \return corresponding numeric code (edg_wll_KeyNameCode)
* \brief convert a string ULM key name to the corresponding numeric code
*/
-extern edg_wll_KeyNameCode edg_wll_StringToKeyName(char *);
+extern edg_wll_KeyNameCode edg_wll_StringToKeyName(const char *name);
/**
* \fn char *edg_wll_KeyNameToString(edg_wll_KeyNameCode key)
- * \param key a ULM key name numeric code (edg_wll_KeyNameCode)
+ * \param[in] key a ULM key name numeric code (edg_wll_KeyNameCode)
* \return corresponding string (e.g. "DG.JOB.TRANSFER.DEST")
* \brief convert a ULM key name numeric code to the corresponding string
*/
-extern char *edg_wll_KeyNameToString(edg_wll_KeyNameCode);
+extern char *edg_wll_KeyNameToString(edg_wll_KeyNameCode key);
/**
# enum
gen qq{
/**
- * \\enum $enum
+ * \\$enum
* $fn codes
*/
$enum \{
# function StringTo:
gen qq{
/**
- * \\fn $enum edg_wll_StringTo${c}(char *name);
- * \\param name a string representing $fn code (e.g. \"${$f->{codes}}[1]->{name}\")
+ * \\fn $enum edg_wll_StringTo${c}(const char *name);
+ * \\param[in] name a string representing $fn code (e.g. \"${$f->{codes}}[1]->{name}\")
* \\return corresponding numeric code ($enum)
* \\brief converts a string $fn code to corresponding numeric code
*/
-extern $enum edg_wll_StringTo${c}(char *name);
+extern $enum edg_wll_StringTo${c}(const char *name);
};
# function ToString:
gen qq{
/**
* \\fn char *edg_wll\_${c}ToString($enum code);
- * \\param code a $fn numeric code ($enum)
+ * \\param[in] code a $fn numeric code ($enum)
* \\return corresponding string (e.g. \"${$f->{codes}}[1]->{name}\")
* \\brief converts a $fn numeric code to corresponding string
*/
# enum
gen qq{
/**
- * \\enum $enum
+ * \\$enum
* $fn codes of the $t event
*/
$enum \{
# function StringTo:
gen qq{
/**
- * \\fn $enum edg_wll_StringTo${c}(char *name);
- * \\param name a string representing $t $fn code (e.g. \"${$f->{codes}}[1]->{name}\")
+ * \\fn $enum edg_wll_StringTo${c}(const char *name);
+ * \\param[in] name a string representing $t $fn code (e.g. \"${$f->{codes}}[1]->{name}\")
* \\return corresponding numeric code ($enum)
* \\brief converts a string $t $fn code to corresponding numeric code
*/
-extern $enum edg_wll_StringTo${c}(char *name);
+extern $enum edg_wll_StringTo${c}(const char *name);
};
# function ToString:
gen qq{
/**
* \\fn char *edg_wll\_${c}ToString($enum code);
- * \\param code a $t $fn numeric code ($enum)
+ * \\param[in] code a $t $fn numeric code ($enum)
* \\return corresponding string (e.g. \"${$f->{codes}}[1]->{name}\")
* \\brief converts a $t $fn numeric code to corresponding string
*/
gen "\n";
@@@}
+/**
+ * \typedef edg_wll_AnyEvent
+ * common structure definition contained in all types of the events
+ */
typedef struct _edg_wll_AnyEvent {
_EDG_WLL_EVENT_COMMON
} edg_wll_AnyEvent;
/**
* Free the contents of event structure
- * \param IN event structure to be freed
+ * \param[in] event structure to be freed
* \warning As event structures are likely to be allocated in arrays,
* the structure itself is not freed.
* Its the responsibility of the caller to call free(event)
edg_wll_Event * event
);
+/*
+ *@} end of group
+ */
#ifdef __cplusplus
}
*/
/*!
- * \file client/jobstat.h
+ * \file jobstat.h
* \brief edg_wll_JobStat definition and related stuff
*/
#endif
/**
+ * \defgroup jobstatus Job Status
+ * \brief Job status structure definition and related definitions.
+ *@{
+ */
+
+/**
* Miscelaneous job status numeric codes
*/
* \name edg_wll_JobStat manipulation
*/
-/*@{*/
-
/**
* Initialize empty status structure.
* Fills in the stucture with NULL's or values with no meaning
/*@}*/
+/*
+ *@} end of group
+ */
+
#ifdef __cplusplus
}
#endif
#endif
/**
+ * \defgroup notifications Notifications handling
+ * \brief Notifications handling.
+ *@{
+ */
+
+/**
* default and maximal notif timeout (in seconds)
*/
#define EDG_WLL_NOTIF_TIMEOUT_DEFAULT 120
/** Register for receiving notifications.
* Connects to the server specified by EDG_WLL_NOTIF_SERVER context parameter
* (temporary workaround, should be resolved by registry in future).
- * \param conditions: the same conditions as for \see edg_wll_QueryJobsExt.
+ * \param[in,out] context context to work with
+ * \param[in] conditions the same conditions as for \ref edg_wll_QueryJobsExt.
* currently one or more JOBID's are required.
* Only a single occurence of a specific attribute is allowed
* among ANDed conditions (due to the ability to modify them
* further).
- * \param fd = -1 create or reuse the default listening socket (one per context)
+ * \param[in] fd = -1 create or reuse the default listening socket (one per context)
* >= 0 non-default listening socket
- * \param address_override if not NULL, use this address instead of extracting it
+ * \param[in] address_override if not NULL, use this address instead of extracting it
* from the connection (useful when multiple interfaces are present,
* circumventing NAT problems etc.)
- * \param valid until when the registration is valid (NULL means no interest in
+ * \param[in] valid until when the registration is valid (NULL means no interest in
+ * \param[out] id_out returened NotifId
* the value
* \retval 0 OK
* \retval EINVAL restrictions on conditions are not met
/** Change the receiving local address.
* Report the new address to the server.
*
- * \param fd
- * \param address_override
- * \param valid all same as for \see edg_wll_NotifNew
+ * \param[in,out] context context to work with
+ * \param[in] id notification ID you are binding to
+ * \param[in] fd same as for \ref edg_wll_NotifNew
+ * \param[in] address_override same as for \ref edg_wll_NotifNew
+ * \param[in] valid same as for \ref edg_wll_NotifNew
*/
int edg_wll_NotifBind(
);
typedef enum _edg_wll_NotifChangeOp {
+ /** No operation, equal to not defined */
EDG_WLL_NOTIF_NOOP = 0,
+ /** Replace notification registration with new one */
EDG_WLL_NOTIF_REPLACE,
+ /** Add new condition when to be notifed */
EDG_WLL_NOTIF_ADD,
+ /** Remove condition on notification */
EDG_WLL_NOTIF_REMOVE
/* if adding new attribute, add conversion string to common/xml_conversions.c too !! */
} edg_wll_NotifChangeOp;
* of uniqueness the original conditions must have contained only a single
* OR-ed row of conditions on the attributes infolved in the change.
*
- * \param op action to be taken on existing conditions,
- * \see edg_wll_NotifChangeOp
+ * \param[in,out] context context to work with
+ * \param[in] id notification ID you are working with
+ * \param[in] conditions same as for \ref edg_wll_NotifNew
+ * \param[in] op action to be taken on existing conditions,
+ * \ref edg_wll_NotifChangeOp
*/
int edg_wll_NotifChange(
edg_wll_Context context,
);
/** Refresh the registration, i.e. extend its validity period.
- * \param valid until when the registration is valid (NULL means no interest in
+ * \param[in,out] context context to work with
+ * \param[in] id notification ID you are working with
+ * \param[in] valid until when the registration is valid (NULL means no interest in
* the value
*/
/** Drop the registration.
* Server is instructed not to send notifications anymore, pending ones
* are discarded, listening socket is closed, and allocated memory freed.
+ * \param[in,out] context context to work with
+ * \param[in] id notification ID you are working with
*/
int edg_wll_NotifDrop(
/** Receive notification.
* The first incoming notification is returned.
- * \param fd receive on this socket (-1 means the default for the context)
- * \param timeout wait atmost this time long. (0,0) means polling, NULL waiting
+ * \param[in,out] context context to work with
+ * \param[in] fd receive on this socket (-1 means the default for the context)
+ * \param[in] timeout wait atmost this time long. (0,0) means polling, NULL waiting
* indefinitely
- *
+ * \param[out] state_out returned JobStatus
+ * \param[out] id_out returned NotifId
* \retval 0 notification received, state_out contains the current job state
* \retval EAGAIN no notification available, timeout occured
*/
/** Default socket descriptor where to select(2) for notifications.
- * Even if nothing is available for reading freom the socket,
- * there may be some data cached so calling \see edg_wll_NotifReceive
+ * Even if nothing is available for reading from the socket,
+ * there may be some data cached so calling \ref edg_wll_NotifReceive
* may return notifications immediately.
*
+ * \param[in,out] context context to work with
* \retval >=0 socket descriptor
* \retval -1 error, details set in context
*/
);
/** Close the default local listening socket.
- * Useful to force following \see edg_wll_NotifBind to open
+ * Useful to force following \ref edg_wll_NotifBind to open
* a new one.
+ * \param[in,out] context context to work with
*/
int edg_wll_NotifCloseFd(
edg_wll_Context context
);
+/*
+ *@} end of group
+ */
+
#ifdef __cplusplus
}
#endif
extern "C" {
#endif
+/**
+ * \defgroup notifid Notification Id (NotifId)
+ * \brief NotifId description and handling.
+ *@{
+ */
+
/** Notification handle.
* Refers to a particular registration for receiving notifications.
*/
typedef void *edg_wll_NotifId;
-/** Parse and unparse the Id. */
-int edg_wll_NotifIdParse(const char *,edg_wll_NotifId *);
-char* edg_wll_NotifIdUnparse(const edg_wll_NotifId);
+/**
+ * Create a Job ID.
+ * \param[in] server notification server hostname
+ * \param[in] port port of the notification server
+ * \param[out] notifid newly created NotifId
+ * \retval 0 for success
+ * \retval EINVAL invalid notification server
+ * \retval ENOMEM if memory allocation fails
+ */
+int edg_wll_NotifIdCreate(const char *server, int port ,edg_wll_NotifId *notifid);
+
+/**
+ * Free the NotifId structure
+ * \param[in] notifid for dealocation
+ */
+void edg_wll_NotifIdFree(edg_wll_NotifId notifid);
+
+/** Parse the NotifId string and creates NotifId structure
+ * \param[in] notifidstr string representation of NotifId
+ * \param[out] notifid parsed NotifId
+ * \retval 0 for success
+ * \retval EINVAL notifidstr can't be parsed
+ * \retval ENOMEM if memory allocation fails
+ */
+int edg_wll_NotifIdParse(const char *notifidstr, edg_wll_NotifId *notifid);
+
+/** Unparse the NotifId (produce the string form of NotifId).
+ * \param[in] notifid NotifId to be converted to string
+ * \return allocated string which represents the NotifId
+ */
+char* edg_wll_NotifIdUnparse(const edg_wll_NotifId notifid);
+
+/**
+ * Extract notification server address (address:port)
+ * \param[in] notifid NotifId from which the address should be extracted
+ * \param[in,out] srvName pointer where to return server name
+ * \param[in,out] srvPort pointer where to return server port
+ */
+void edg_wll_NotifIdGetServerParts(const edg_wll_NotifId notifid, char **srvName, unsigned int *srvPort);
-int edg_wll_NotifIdCreate(const char *,int,edg_wll_NotifId *);
-void edg_wll_NotifIdFree(edg_wll_NotifId);
+/**
+ * Extract unique string
+ * \param[in] notifid NotifId
+ * \retval pointer to allocated unique string representing jobid
+ * \retval NULL if jobid is 0 or memory allocation fails
+ */
+char *edg_wll_NotifIdGetUnique(const edg_wll_NotifId notifid);
-void edg_wll_NotifIdGetServerParts(const edg_wll_NotifId, char **, unsigned int *);
-char *edg_wll_NotifIdGetUnique(const edg_wll_NotifId);
-int edg_wll_NotifIdSetUnique(edg_wll_NotifId *, const char *);
+/**
+ * Recreate a NotifId by a new unique string
+ * \param[in] unique string which represent created notifid (if NULL then new
+ * one is created)
+ * \param[in,out] notifid newly created NotifId
+ * \retval 0 success
+ * \retval EINVAL invalid NotifId
+ * \retval ENOMEM if memory allocation fails
+ */
+int edg_wll_NotifIdSetUnique(edg_wll_NotifId *notifid, const char *unique);
+
+/*
+ *@} end of group
+ */
#ifdef __cplusplus
}
#define __EDG_WORKLOAD_LOGGING_CLIENT_PRODUCER_H__
/**
- * \file edg/workload/logging/client/producer.h
+ * \file producer.h
* \brief client API for storing data into L&B service
*/
my $a = "(edg_wll_Context context";
my $b = "(context,EDG_WLL_EVENT_$tu,EDG_WLL_FORMAT_$tu";
my $doc = qq{
- * \\param context\tcontext to work with,
+ * \\param[in,out] context\tcontext to work with,
};
selectType $event $t;
for ($event->getFieldsOrdered) {
my $fc = $f->getComment;
$a = $a . ", $ft $fn";
$b = $b . ", $fn";
- $doc = $doc . " * \\param $fn\t$fc\n";
+ $doc = $doc . " * \\param[in] $fn\t$fc\n";
}
$a = $a . ")";
$b = $b . ")";
*/
};
gen "\nextern int edg_wll_Log${t}$a;\n";
- gen "\nextern int edg_wll_Log${t}Proxy$a;\n";
+# gen "\nextern int edg_wll_Log${t}Proxy$a;\n";
# gen qq{
#int edg_wll_Log$t$a
#\{
my $e = $doc;
$c =~ s/, $ftreg $fn//g;
$d =~ s/$fn/"$code"/g;
- $e =~ s/ \* \\param $fn\t$fc\n//g;
+# FIXME: this documentation line in $e doesn't delete!!
+ $e =~ s/ \* \\param\[in\] $fn\t$fc\n//g;
gen qq{
/**
* \\fn int edg_wll_Log$t$code$c;
*/
};
gen "\nextern int edg_wll_Log$t${code}$c;\n";
- gen "\nextern int edg_wll_Log$t${code}Proxy$c;\n";
+# gen "\nextern int edg_wll_Log$t${code}Proxy$c;\n";
# gen qq{
#int edg_wll_Log$t$code$c
#\{
/**
* Formats a logging message and sends it asynchronously to local-logger
* \brief generic asynchronous logging function
- * \param context INOUT context to work with,
- * \param event IN type of the event,
- * \param fmt IN printf()-like format string,
- * \param ... IN event specific values/data according to fmt,
+ * \param[in,out] context context to work with,
+ * \param[in] event type of the event,
+ * \param[in] fmt printf()-like format string,
+ * \param[in] ... event specific values/data according to fmt,
* \retval 0 successful completition,
* \retval EINVAL bad jobId, unknown event code, or the format string together with the remaining arguments does not form a valid event,
* \retval ENOSPC L&B infrastructure failed to accept the event due to lack of disk space etc.,
/**
* Formats a logging message and sends it synchronously to local-logger
* \brief generic synchronous logging function
- * \param context INOUT context to work with,
- * \param event IN type of the event,
- * \param fmt IN printf()-like format string,
- * \param ... IN event specific values/data according to fmt,
+ * \param[in,out] context context to work with,
+ * \param[in] event type of the event,
+ * \param[in] fmt printf()-like format string,
+ * \param[in] ... event specific values/data according to fmt,
* \retval 0 successful completition,
* \retval EINVAL bad jobId, unknown event code, or the format string together with the remaining arguments does not form a valid event,
* \retval ENOSPC L&B infrastructure failed to accept the event due to lack of disk space etc.,
char *fmt, ...);
/**
- * Formats a logging message and sends it synchronously to L&B Proxy
- * \brief generic synchronous logging function
- * \param context INOUT context to work with,
- * \param event IN type of the event,
- * \param fmt IN printf()-like format string,
- * \param ... IN event specific values/data according to fmt,
- * \retval 0 successful completition,
- * \retval EINVAL bad jobId, unknown event code, or the format string together with the remaining arguments does not form a valid event,
- * \retval ENOSPC L&B infrastructure failed to accept the event due to lack of disk space etc.,
- * \retval ENOMEM failed to allocate memory,
- * \retval ECONNREFUSED cannot connect to the specified L&B Proxy
- * \retval EAGAIN non blocking return from the call, the event may or may not get logged,
- * \retval EDG_WLL_ERROR_NOJOBID logging call attempted without assigning jobId to the context.
- */
-extern int edg_wll_LogEventProxy(
- edg_wll_Context context,
- edg_wll_EventCode event,
- char *fmt, ...);
-
-/**
* Instructs interlogger to to deliver all pending events related to current job
* \brief flush events from interlogger
* \note sort of status query more than a command
- * \param context INOUT context to work with,
- * \param timeout INOUT wait at most this much time for completition, remaining time on return,
- * \retval 0 successful completition,
+ * \param[in,out] context context to work with,
+ * \param[in,out] timeout wait at most this much time for completition, remaining time on return,
+ * \retval 0 successful completition,
* \retval EDG_WLL_ERROR_INTERLOG_TIMEOUT the inter-logger did not respond within the timeout,
* \retval EDG_WLL_ERROR_INTERLOG_CONLOST inter-logger lost connection to one or more servers,
* \retval EDG_WLL_ERROR_INTERLOG_AGAIN not all pending events were delivered within the timeout.
/**
* Set a current job for given context.
* \note Should be called before any logging call.
- * \param context INOUT context to work with
- * \param job IN further logging calls are related to this job
- * \param code IN sequence code as obtained from previous component
- * \param flags IN flags on code handling (\see API documentation)
+ * \param[in,out] context context to work with
+ * \param[in] job further logging calls are related to this job
+ * \param[in] code sequence code as obtained from previous component
+ * \param[in] flags flags on code handling (\see API documentation)
*/
extern int edg_wll_SetLoggingJob(
edg_wll_Context context,
);
/**
- * Set a current job for given context.
- * \note Should be called before any logging call.
- * \param context INOUT context to work with
- * \param job IN further logging calls are related to this job
- * \param code IN sequence code as obtained from previous component
- * \param user IN user credentials
- * \param flags IN flags on code handling (\see API documentation)
- */
-extern int edg_wll_SetLoggingJobProxy(
- edg_wll_Context context,
- const edg_wlc_JobId job,
- const char * code,
- const char * user,
- int flags
-);
-
-
-/**
* Register job with L&B service.
* Done via logging REGJOB event, may generate subjob id's and create
* the parent-children associations.
* Partitionable jobs should set num_subjobs=0 initially,
* and re-register when number of subjobs becomes known.
*
- * \param type IN EDG_WLL_JOB_SIMPLE, EDG_WLL_JOB_DAG, or EDG_WLL_JOB_PARTITIONABLE
- * \param jdl IN user-specified JDL
- * \param ns IN network server contact
- * \param num_subjobs IN number of subjobs to create
- * \param seed IN seed used for subjob id's generator.
+ * \param[in,out] context context to work with
+ * \param[in] job jobId
+ * \param[in] type EDG_WLL_JOB_SIMPLE, EDG_WLL_JOB_DAG, or EDG_WLL_JOB_PARTITIONABLE
+ * \param[in] jdl user-specified JDL
+ * \param[in] ns network server contact
+ * \param[in] num_subjobs number of subjobs to create
+ * \param[in] seed seed used for subjob id's generator.
* Use non-NULL value to be able to regenerate the set of jobid's
- * \param subjobs OUT returned subjob id's
+ * \param[out] subjobs returned subjob id's
*/
/* backward compatibility */
);
/**
- * Register job with L&B Proxy service.
- * Done via logging REGJOB event, may generate subjob id's and create
- * the parent-children associations.
- * Set the job as current for the context and initialize sequence code.
- *
- * Partitionable jobs should set num_subjobs=0 initially,
- * and re-register when number of subjobs becomes known.
- *
- * \param type IN EDG_WLL_JOB_SIMPLE, EDG_WLL_JOB_DAG, or EDG_WLL_JOB_PARTITIONABLE
- * \param user IN user credentials
- * \param jdl IN user-specified JDL
- * \param ns IN network server contact
- * \param num_subjobs IN number of subjobs to create
- * \param seed IN seed used for subjob id's generator.
- * Use non-NULL value to be able to regenerate the set of jobid's
- * \param subjobs OUT returned subjob id's
- */
-
-extern int edg_wll_RegisterJobProxy(
- edg_wll_Context context,
- const edg_wlc_JobId job,
- enum edg_wll_RegJobJobtype type,
- const char * user,
- const char * jdl,
- const char * ns,
- int num_subjobs,
- const char * seed,
- edg_wlc_JobId ** subjobs
-);
-
-
-/**
* Register subjobs in a batch.
* Mainly used to provide JDL's of individual subjobs in a more efficient
* way than logging them one by one.
- * \param jdls array of JDL's
- * \param subjobs array of jobid's in the same order
+ * \param[in,out] context context to work with
+ * \param[in] parent parent's jobId
+ * \param[in] jdls array of JDL's
+ * \param[in] ns network server contact
+ * \param[out] subjobs array of jobid's in the same order
*/
extern int edg_wll_RegisterSubjobs(
/**
* Change ACL for given job.
- * \param specification of user's credential
- * \param user_id_type type of user_id,
+ * \param[in,out] context context to work with
+ * \param[in] job jobId
+ * \param[in] user_id specification of user's credential
+ * \param[in] user_id_type type of user_id,
* for EDG_WLL_USER_SUBJECT the user_id parameter is expected to be user's subject name
* for EDG_WLL_USER_VOMS_GROUP the user_id is expected to be of the form VO:group specifying required group membersip as managed by VOMS
- * \param permission ACL permission to change
- * \param permission_type type of given permission (allow or deny operation)
- * \param operation operation to perform with ACL (add or remove record)
+ * \param[in] permission ACL permission to change
+ * \param[in] permission_type type of given permission (allow or deny operation)
+ * \param[in] operation operation to perform with ACL (add or remove record)
*/
extern int edg_wll_ChangeACL(
#endif
/** Count the number of jobs which entered the specified state.
- * \param group IN: group of jobs of interest, eg. DESTINATION = something
+ * \param[in] group group of jobs of interest, eg. DESTINATION = something
* (XXX: this is the only query supported right now)
- * \param major IN: major code of the state of interest
- * \param minor IN: minor state code, eg. DONE_FAILED
- * \param from,to INOUT: on input - requested interval of interest
+ * \param[in] major major code of the state of interest
+ * \param[in] minor minor state code, eg. DONE_FAILED
+ * \param[in,out] from,to on input - requested interval of interest
* on output - when the data were available
- * \param rate OUT: average rate per second in which the jobs enter this state
- * \param res_from, res_to: time resolution of the data (seconds)
+ * \param[out] rate average rate per second in which the jobs enter this state
+ * \param[out] res_from,res_to time resolution of the data (seconds)
*/
int edg_wll_StateRate(
--- /dev/null
+#Wed Apr 13 06:21:19 CEST 2005
+module.build=233
Revision history:
$Log$
+ Revision 1.2.2.5 2005/02/25 13:39:29 mmulac
+ remove duplicate notifid in configure.properties.xml
+
+ Revision 1.2.2.4 2005/02/25 13:37:11 mmulac
+ add notifid to doxygen
+ see -> ref
+
+ Revision 1.2.2.3 2005/02/25 12:03:11 jpospi
+ Added PDF options to doxygen conf.
+
+ Revision 1.2.2.2 2005/02/25 09:37:52 mmulac
+ generate doxygen doc for notification.h
+
+ Revision 1.2.2.1 2005/02/18 14:00:16 jpospi
+ - Removed all L&B Proxy related things
+ - Documentation update
+
+ Revision 1.2 2004/12/08 13:04:29 jpospi
+ first attemtp to generate documentation using doxygen
+
Revision 1.1 2004/07/06 17:47:31 flammer
Update of classpath definitions, targets & configure file.
version=${module.version}
</echo>
<echo file="${module.build.dir}/C.dox">
-PROJECT_NAME = "Glite LB Client: C - Interface"
-PROJECT_NUMBER = ${module.version}
-OUTPUT_DIRECTORY = ${component.dir}/doc/C
-OPTIMIZE_OUTPUT_FOR_C = YES
-INPUT = ./events.h \
- ./jobstat.h \
- ./producer.h \
- ../interface/context.h \
- ../interface/consumer.h
-#HAVE_DOT = YES
-#CALL_GRAPH = YES
+PROJECT_NAME = "Glite LB Client: C - Interface"
+PROJECT_NUMBER = ${module.version}
+OUTPUT_DIRECTORY = ${component.dir}/doc/C
+OPTIMIZE_OUTPUT_FOR_C = YES
+INPUT = ./events.h \
+ ./jobstat.h \
+ ./producer.h \
+ ../interface/context.h \
+ ../interface/notifid.h \
+ ../interface/notification.h \
+ ../interface/consumer.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
</echo>
<echo file="${module.build.dir}/CPP.dox">
PROJECT_NAME = "Glite LB Client: CPP - Interface"
../interface/LoggingExceptions.h \
../interface/ServerConnection.h \
../interface/Notification.h
+SHOW_DIRECTORIES = NO
+FULL_PATH_NAMES = NO
+EXTRACT_ALL = YES
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
#HAVE_DOT = YES
#CALL_GRAPH = YES
</echo>
-#Fri Dec 10 13:18:21 CET 2004
-module.version=0.3.1
-module.build=113
-module.age=2
+
+module.version = 1.0.3
+module.age = 1
+
THRPLUSLIB:=libglite_lb_clientpp_${thrflavour}.la
TOOLS:=dump load purge
-EXAMPLES:=log_usertag_proxy job_log job_reg feed_shark notify query_ext query_seq_code stats
+EXAMPLES:=job_log job_reg feed_shark notify query_ext query_seq_code stats abort_job change_acl job_status
FAKE_EXAMPLES:=job_log_fake
version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :`
install:
mkdir -p ${PREFIX}/bin
+ mkdir -p ${PREFIX}/sbin
mkdir -p ${PREFIX}/lib
mkdir -p ${PREFIX}/share/doc/${package}-${version}
${INSTALL} -m 644 ${LIB} ${THRLIB} ${PLUSLIB} ${THRPLUSLIB} ${PREFIX}/lib
${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
+ ${INSTALL} -m 644 ${top_srcdir}/doc/README-fake ${top_srcdir}/doc/README-notify ${PREFIX}/share/doc/${package}-${version}
mkdir -p ${PREFIX}/examples
- for p in ${TOOLS} logevent; do \
+ for p in ${TOOLS}; do \
+ ${INSTALL} -m 755 "$$p" "${PREFIX}/sbin/glite-lb-$$p"; \
+ done
+ for p in logevent; do \
${INSTALL} -m 755 "$$p" "${PREFIX}/bin/glite-lb-$$p"; \
done
- for p in ${TOOLS} logevent ${EXAMPLES} ${sh_PROGS}; do \
+ for p in ${EXAMPLES} ${sh_PROGS}; do \
${INSTALL} -m 755 "$$p" "${PREFIX}/examples/glite-lb-$$p"; \
done
+ ${INSTALL} -m 755 ${top_srcdir}/examples/purge_test "${PREFIX}/examples/glite-lb-purge_test"
clean:
Revision history:
$Log$
+ Revision 1.5 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.4 2004/07/28 12:18:12 dimeglio
Changed default target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
--- /dev/null
+By default, information about a job stored in the LB server is only available
+to the user who submitted the job, i.e. the job owner. When requesting any
+information about a job from the LB server, the users must authenticate
+properly using their PKI certificates so the LB server can verify that they are
+allowed to access this information (i.e. they submitted the job in question).
+
+Besides this default functionality, the LB server also allows the job owner to
+share job information with another users. Each job can be assigned an access
+control list (ACL) that specifies another users who are also allowed to access
+the job information. The management of ACL's is entirely under control of the
+job owner so she can modify the ACL arbitrarily, specifying the set of users
+who have access to the job information. The users in the ACL's can be specified
+using either the subject names from their X.509 certificates or names of VOMS
+groups.
+
+Current ACL for a job is returned as part of the job status information
+returned by the job_status command. The commands output ACL's in the original
+XML format as specified by GACL/GridSite.
+
+Example of an ACL:
+<?xml version="1.0"?><gacl version="0.0.1">
+ <entry>
+ <voms-cred><vo>VOCE</vo><group>/VOCE</group></voms-cred>
+ <allow><read/></allow>
+ </entry>
+ <entry>
+ <person><dn>/O=CESNET/O=Masaryk University/CN=Daniel Kouril</dn></person>
+ <deny><read/></deny>
+ </entry>
+</gacl>
+
+this ACL allows all people in the VOMS /VOCE in the VO VOCE, but deny access to
+user Daniel Kouril (even if he was a member of the /VOCE group).
+
+The job owner herself is not specified in the ACL as she is always allowed to
+access the information regardles the content of the job ACL.
+
+An ACL for a job can be changed using the change_acl command-line program
+provided in the example subdirectory. In order to use change_acl, the LB
+daemons locallogger and interlogger must be running. The usage of the command
+is as follows:
+
+change_acl [-r] [-g] [-d] jobid user_id
+
+ jobid specifies the job to change
+ user_id specifies the user to use, it can be either an X.500 name
+ (subject name) or a VOMS group (if the -g option is specified).
+
+ -r Remove user/group from the ACL.
+ -g If this option is given, the user_id is handled as a VOMS group. It
+ must of the form VO:group, where VO is name of the VO (as printed out
+ by voms-proxy-info in the VO: field) and group is name of the group.
+ -d The user specified by the user_id parameter will be denied to access
+ information about job.
+
+Examples (resulting in the ACL above):
+ change_acl -g https://scientific.civ.zcu.cz:9000/PC8Y6jBitHt_fKMTEKFnVw VOCE:/VOCE
+ change_acl -d https://scientific.civ.zcu.cz:9000/PC8Y6jBitHt_fKMTEKFnVw '/O=CESNET/O=Masaryk University/CN=Daniel Kouril'
+
+LB server configuration
+In order to support the VOMS groups in the ACL's, glite_lb_bkserverd must be
+able to verify client's VOMS proxy certificate using a trusted VOMS service
+certificate stored on a local disk. Default directory with trusted VOMS
+certificates is /etc/grid-security/vomsdir, another location can be
+specified using by either the -V option to glite_lb_bkserverd or setting the
+VOMS_CERT_DIR environment variable.
edg_wll_Log* (functions for logging all event types)
edg_wll_LogEvent
edg_wll_LogEventSync
- edg_wll_LogEventProxy
edg_wll_LogFlush
edg_wll_LogFlushAll
edg_wll_SetLoggingJob
- edg_wll_SetLoggingJobProxy
edg_wll_RegisterJobSync
edg_wll_RegisterJob
edg_wll_RegisterSubjob
typedef int (edg_wll_Logging_cb_f)(edg_wll_Context context);
int edg_wll_RegisterTestLogging(edg_wll_Logging_cb_f *cb);
- int edg_wll_RegisterTestLoggingProxy(edg_wll_Logging_cb_f *cb);
It possible to unregister registered callbacks using following functions:
void edg_wll_UnregisterTestQueryEvents();
void edg_wll_UnregisterTestQueryListener();
void edg_wll_UnregisterTestLogging();
- void edg_wll_UnregisterTestLoggingProxy();
Library name is libglite_lb_client_fake_gcc32dbg[pthr].so. It is built
--- /dev/null
+LB notifications
+----------------
+
+LB infrastructure enables its users to be notified when something interesting happens on a bookkeeping server.
+
+User registers to infrastructure via client API (notification.h) or he/she can use example program glite-lb-notify (see bellow). He/she must specify a condition under which the notification is sent. The condition(s) is(are) stored in edg_wll_QueryRec data structure. Currently one or more JOBID's are required in it and only a single occurence of a specific attribute is allowed among ANDed conditions.
+
+The request for notification is then delivered to a bookkeeping server. Whenever a new event arrives to the bookkeeping server, the notification condition is tested. Always when it is true, the notification is sent to the user. Notifications are incomming until the user cancels notification registration on the server.
+
+For a notification deliveriy, a special deamon, notification interlogger is used. It stores registrations in files until they are delivered.
+
+
+
+Notification example
+--------------------
+
+In next steps, you will be instucted how to register for a notification and how to triger this registration on the bookkeeping server in order to receive registration. Our example program 'glite-lb-notify' is used for this purpose. It uses mentioned client API calls to manipulate with registrations.
+
+
+1) Set up LB environment
+
+ a) Download, compile and install LB module from SCM CVS
+ b) Install it from RPMs
+
+ See instructions at section 'Installation & Configuration'
+ from EGEE JRA1 web site. It was located at (Jan 2005) :
+
+ http://egee-jra1-wm.mi.infn.it/egee-jra1-wm/lb_install.shtml
+
+
+2) Get globus proxy certificate
+ ./grid-proxy-init -key PATH_TO_YOUR_KEY -cert PATH_TO_YOUR_CERT
+
+
+3) Start LB deamons
+
+ Substitute KEY with location server private key, CERT with location
+ of server certificate, and CERTS_DIR directory containing CA
+ certificates.
+
+ ./glite-lb-logd -k KEY -c CERT -C CERTS_DIR -d -v
+
+ ./glite-lb-interlogd -k KEY -c CERT -C CERTS_DIR -b -d -v
+
+ ./glite-lb-bkserverd -d -k KEY -c CERT -C CERTS_DIR
+
+ ./glite-lb-notif-interlogd -k KEY -c CERT -C CERTS_DIR -d -v
+
+
+4) Register a job
+ export EDG_WL_LOG_DESTINATION=HOSTNAME:9002
+ ./glite-lb-job_reg -m HOSTNAME:9000 -s UserInterface
+
+ -> returns JOBID - used in the next steps
+
+
+5) Register notification
+ export EDG_WL_NOTIF_SERVER=HOSTNAME:9000
+ ./glite-lb-notify test JOBID
+
+
+6) Change status of your job
+ export EDG_WL_LOG_DESTINATION=HOSTNAME:9002
+ ./glite-lb-running.sh -j JOBID
+
+
+7) Watch incomming notifications
+
+
+Warning: Try to destroy all your registrations when you finish, otherwise the system will still try to deliver you your notifications to nonexistent destinations (ports which nobody listens at).
+
+TIP: If you are stucked, try to clean up notif-interlogger's cache files. They are by default stored at /tmp/notif_events*, or wherever you set by -f option.
--- /dev/null
+#ident "$Header$"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "glite/lb/events_parse.h"
+#include "glite/lb/consumer.h"
+#include "glite/wmsutils/jobid/cjobid.h"
+
+static void free_events(edg_wll_Event *);
+
+static void help(const char* n)
+{
+ fprintf(stderr,"usage: %s <jobid> <source>\n", n);
+ exit(1);
+}
+
+int main(int argc,char **argv)
+{
+ edg_wll_Context ctx;
+ char *errt,*errd,*e,a;
+ edg_wll_Event *events;
+ int i;
+ edg_wll_QueryRec jq[2],eq[2];
+ edg_wlc_JobId job;
+ edg_wll_Source src;
+
+ if (argc != 3) help(argv[0]);
+
+ puts(
+"*\n"
+"* USE WITH CARE, AT YOUR OWN RISK, UNDER ABNORMAL CONDITIONS ONLY,\n"
+"* AND BE ALWAYS SURE WHAT YOU ARE DOING.\n"
+"* \n"
+"* THIS PROGRAM IS A PERFECT EXAMPLE HOW L&B SEQENCE CODES SHOULD NOT BE USED\n"
+"* IN NORMAL OPERATION.\n"
+"\n"
+"Do you want to proceed?"
+ );
+
+ scanf("%c",&a);
+ if (a != 'y' && a != 'Y') return 1;
+
+ edg_wll_InitContext(&ctx);
+
+ if (edg_wlc_JobIdParse(argv[1],&job)) {
+ fprintf(stderr,"%s: can't parse job ID\n",argv[1]);
+ return 1;
+ }
+
+ if (( src = edg_wll_StringToSource(argv[2])) == EDG_WLL_SOURCE_NONE) {
+ fprintf(stderr,"%s: unknown event source\n",argv[2]);
+ return 1;
+ }
+
+ jq[0].attr = EDG_WLL_QUERY_ATTR_JOBID;
+ jq[0].op = EDG_WLL_QUERY_OP_EQUAL;
+ jq[0].value.j = job;
+ jq[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+
+ eq[0].attr = EDG_WLL_QUERY_ATTR_SOURCE;
+ eq[0].op = EDG_WLL_QUERY_OP_EQUAL;
+ eq[0].value.i = src;
+ eq[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+
+ if ( edg_wll_QueryEvents(ctx,jq,eq,&events) )
+ {
+ if ( edg_wll_Error(ctx, &errt, &errd) != E2BIG )
+ goto err;
+
+ fprintf(stderr,"%s: %s (%s)\n",argv[0],errt,errd);
+ }
+
+ for ( i = 0; events[i].type != EDG_WLL_EVENT_UNDEF; i++ );
+
+ e = edg_wll_UnparseEvent(ctx,events+i-1);
+
+ fputs(e,stdout);
+ fputs("\n",stdout);
+
+ if (edg_wll_SetParam(ctx,EDG_WLL_PARAM_SOURCE,src) ||
+ edg_wll_SetLoggingJob(ctx,job,events[i-1].any.seqcode,EDG_WLL_SEQ_NORMAL) ||
+ edg_wll_IncSequenceCode(ctx) || /* necessary to simulate this
+ * call in last event logging
+ * _after_ current seq. was used */
+ edg_wll_LogAbort(ctx,"manual abort")) goto err;
+
+
+ free(e);
+ free_events(events);
+
+ edg_wll_FreeContext(ctx);
+
+ return 0;
+
+err:
+ switch (edg_wll_Error(ctx,&errt,&errd)) {
+ case 0: break;
+ case ENOENT:
+ puts("No events found");
+ break;
+ default:
+ fprintf(stderr,"%s: %s (%s)\n",argv[0],errt,errd);
+ return 1;
+ }
+
+ edg_wll_FreeContext(ctx);
+
+ return 0;
+}
+
+static void free_events(edg_wll_Event *events)
+{
+ int i;
+
+ if (events) {
+ for (i=0; events[i].type != EDG_WLL_EVENT_UNDEF; i++) edg_wll_FreeEvent(&(events[i]));
+ edg_wll_FreeEvent(&(events[i])); /* free last line */
+ free(events);
+ events = NULL;
+ }
+}
--- /dev/null
+#ident "$Header$"
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "glite/wmsutils/jobid/cjobid.h"
+#include "glite/lb/producer.h"
+#include "glite/lb/authz.h"
+
+void
+usage(const char *me)
+{
+ fprintf(stderr,"usage: %s [-r] [-d] [-g] jobid user_id\n"
+ "\t-r \tRemove\n"
+ "\t-d \tOperation is considered as `allow' by default, if -d is given 'deny' will be used\n"
+ "\t-g \tuser_id is treated as DN by default, if -g is given user_id is expectedto be of form VO:group\n",
+
+ me);
+}
+
+int
+main(int argc, char *argv[])
+{
+ edg_wll_Context ctx;
+ int operation = EDG_WLL_ACL_ADD;
+ int permission = EDG_WLL_PERM_READ;
+ int permission_type = EDG_WLL_PERM_ALLOW;
+ int user_id_type = EDG_WLL_USER_SUBJECT;
+ edg_wlc_JobId jobid;
+ int opt;
+ int ret;
+
+ if (argc < 3) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ while ((opt=getopt(argc, argv, "rdg")) != -1)
+ switch(opt) {
+ case 'r': operation = EDG_WLL_ACL_REMOVE; break;
+ case 'd': permission_type = EDG_WLL_PERM_DENY; break;
+ case 'g': user_id_type = EDG_WLL_USER_VOMS_GROUP; break;
+ default:
+ usage(argv[0]);
+ return 1;
+ break;
+ }
+
+ edg_wll_InitContext(&ctx);
+
+ if (edg_wlc_JobIdParse(argv[optind], &jobid)) {
+ fprintf(stderr,"can't parse job ID\n");
+ goto err;
+ }
+
+ edg_wll_SetParam(ctx, EDG_WLL_PARAM_SOURCE, EDG_WLL_SOURCE_USER_INTERFACE);
+
+ ret = edg_wll_ChangeACL(ctx,
+ jobid,
+ argv[optind+1], user_id_type,
+ permission, permission_type,
+ operation);
+
+ if (ret) {
+ char *et, *ed;
+ edg_wll_Error(ctx, &et, &ed);
+ fprintf(stderr, "%s: edg_wll_LogChangeACL() failed: %s (%s)\n",
+ argv[0], et, ed);
+ goto err;
+ }
+
+ edg_wll_FreeContext(ctx);
+ return 0;
+
+err:
+ edg_wll_FreeContext(ctx);
+ return 1;
+}
{
edg_wll_Context ctx;
char *errt,*errd;
- edg_wll_Event *events;
+ edg_wll_Event *events = NULL;
edg_wlc_JobId job;
int i,opt,delay = 1,count = 0;
if ( edg_wll_JobLog(ctx,job,&events) )
{
- if ( edg_wll_Error(ctx, &errt, &errd) != E2BIG )
- goto err;
-
fprintf(stderr,"%s: %s (%s)\n",argv[0],errt,errd);
}
- for ( i = 0; events[i].type != EDG_WLL_EVENT_UNDEF; i++ )
+ for ( i = 0; events && events[i].type != EDG_WLL_EVENT_UNDEF; i++ )
{
char *e = edg_wll_UnparseEvent(ctx,events+i);
fputs(e,stdout);
--- /dev/null
+/* sample how to use fake testing library instead glite_lb_client */
+
+#include <iostream>
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "glite/lb/consumer_fake.h"
+
+class JobLogFakeExample: public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(JobLogFakeExample);
+ CPPUNIT_TEST(testWithFake);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ static int query_events_cb(edg_wll_Context context, edg_wll_Event **events) {
+ return edg_wll_SetError(context, ENOENT, "Some error");
+ }
+
+public:
+
+ void testWithFake(void) {
+ edg_wll_Context ctx;
+ edg_wlc_JobId job;
+ edg_wll_Event *events;
+
+ edg_wll_InitContext(&ctx);
+ CPPUNIT_ASSERT(edg_wlc_JobIdParse("https://localhost:9000/someid", &job) == 0);
+
+ CPPUNIT_ASSERT(edg_wll_JobLog(ctx, job, &events) == 0);
+ freeEvents(events);
+
+ edg_wll_RegisterTestQueryEvents(&query_events_cb);
+ CPPUNIT_ASSERT(edg_wll_JobLog(ctx, job, &events) != 0);
+ // no events disposed here (they are deallocated on error)
+
+ edg_wll_UnregisterTestQueryEvents();
+ edg_wlc_JobIdFree(job);
+ edg_wll_FreeContext(ctx);
+ }
+
+private:
+
+ /* free returned events
+ */
+ void freeEvents(edg_wll_Event *events) {
+ int i;
+
+ i = 0;
+ while (events[i].type != EDG_WLL_EVENT_UNDEF) {
+ edg_wll_FreeEvent(&events[i]);
+ i++;
+ }
+ free(events);
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(JobLogFakeExample);
+
+int main(void) {
+ CppUnit::Test *suite;
+ CppUnit::TextUi::TestRunner runner;
+
+ suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+ runner.addTest(suite);
+
+ return runner.run() ? 0 : 1;
+}
--- /dev/null
+#ident "$Header$"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include <expat.h>
+
+#include "glite/lb/consumer.h"
+#include "glite/lb/xml_conversions.h"
+
+static void dgerr(edg_wll_Context,char *);
+static void printstat(edg_wll_JobStat,int);
+
+#define MAX_SERVERS 20
+
+static char *myname;
+
+
+int main(int argc,char *argv[])
+{
+ edg_wll_Context ctx, sctx[MAX_SERVERS];
+ int i, result=0, nsrv=0;
+ char *servers[MAX_SERVERS];
+ char *errstr = NULL;
+
+
+ myname = argv[0];
+ printf("\n");
+
+ if (argc < 2 || strcmp(argv[1],"--help") == 0) {
+ fprintf(stderr,"Usage: %s job_id [job_id [...]]\n",argv[0]);
+ fprintf(stderr," %s -all\n",argv[0]);
+ return 1;
+ }
+ else if (argc >= 2 && strcmp(argv[1],"-all") == 0) {
+ edg_wll_JobStat *statesOut;
+ edg_wlc_JobId *jobsOut;
+ edg_wll_QueryRec jc[2];
+
+ jobsOut = NULL;
+ statesOut = NULL;
+/* init context */
+ if (edg_wll_InitContext(&ctx)) {
+ fprintf(stderr,"%s: cannot initialize edg_wll_Context\n",myname);
+ exit(1);
+ }
+/* retrieve job ID's */
+ memset(jc,0,sizeof jc);
+
+ jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER;
+ jc[0].op = EDG_WLL_QUERY_OP_EQUAL;
+ jc[0].value.c = NULL; /* is NULL, peerName filled in on server side */
+ jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+
+ //if (edg_wll_QueryJobs(ctx,jc,EDG_WLL_STAT_CLASSADS | EDG_WLL_STAT_CHILDREN | EDG_WLL_STAT_CHILDSTAT,
+ result = edg_wll_QueryJobs(ctx,jc,0,&jobsOut, &statesOut);
+ if (result == E2BIG) {
+ int r;
+ edg_wll_Error(ctx, NULL, &errstr);
+ if (edg_wll_GetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, &r)) {
+ dgerr(ctx,"edg_wll_GetParam(EDG_WLL_PARAM_QUERY_RESULTS)");
+ free(errstr);
+ result=1; goto cleanup;
+ }
+ if (r != EDG_WLL_QUERYRES_LIMITED) goto late_error;
+ } else if (result) {
+ dgerr(ctx,"edg_wll_QueryJobs");
+ result=1; goto cleanup;
+ }
+
+/* retrieve and print status of each job */
+ for (i=0; statesOut[i].state; i++)
+ printstat(statesOut[i],0);
+
+late_error: if (result) {
+ edg_wll_SetError(ctx, result, errstr);
+ free(errstr);
+ dgerr(ctx,"edg_wll_QueryJobs");
+ result=1;
+ }
+
+cleanup:
+ if (jobsOut)
+ {
+ for (i=0; jobsOut[i]; i++) edg_wlc_JobIdFree(jobsOut[i]);
+ free(jobsOut);
+ }
+ if (statesOut)
+ {
+ for (i=0; statesOut[i].state; i++) edg_wll_FreeStatus(&statesOut[i]);
+ free(statesOut);
+ }
+ edg_wll_FreeContext(ctx);
+ }
+ else {
+ for (i=1; i<argc; i++) {
+ int j;
+ char *bserver;
+ edg_wlc_JobId job;
+ edg_wll_JobStat status;
+
+ memset(&status,0,sizeof status);
+
+/* parse job ID */
+ if (edg_wlc_JobIdParse(argv[i],&job)) {
+ fprintf(stderr,"%s: %s: cannot parse jobId\n",
+ myname,argv[i]);
+ continue;
+ }
+/* determine bookkeeping server address */
+ bserver = edg_wlc_JobIdGetServer(job);
+ if (!bserver) {
+ fprintf(stderr,"%s: %s: cannot extract bookkeeping server address\n",
+ myname,argv[i]);
+ edg_wlc_JobIdFree(job);
+ continue;
+ }
+/* use context database */
+ for (j=0; j<nsrv && strcmp(bserver,servers[j]); j++);
+ if (j==nsrv) {
+ edg_wll_InitContext(&sctx[j]);
+ nsrv++;
+ servers[j] = bserver;
+ }
+
+ if (edg_wll_JobStatus(sctx[j], job, EDG_WLL_STAT_CLASSADS | EDG_WLL_STAT_CHILDREN | EDG_WLL_STAT_CHILDSTAT, &status)) {
+ dgerr(sctx[j],"edg_wll_JobStatus");
+ result=1; goto cleanup2;
+ }
+
+/* print job status */
+ printstat(status,0);
+
+cleanup2:
+ if (job) edg_wlc_JobIdFree(job);
+ if (status.state) edg_wll_FreeStatus(&status);
+ }
+ for (i=0; i<nsrv; i++) edg_wll_FreeContext(sctx[i]);
+ }
+
+ return result;
+}
+
+static void
+dgerr(edg_wll_Context ctx,char *where)
+{
+ char *etxt,*edsc;
+
+ edg_wll_Error(ctx,&etxt,&edsc);
+ fprintf(stderr,"%s: %s: %s",myname,where,etxt);
+ if (edsc) fprintf(stderr," (%s)",edsc);
+ putc('\n',stderr);
+ free(etxt); free(edsc);
+}
+
+static void printstat(edg_wll_JobStat stat, int level)
+{
+ char *s, *j, ind[10];
+ int i;
+
+
+ for (i=0; i < level; i++)
+ ind[i]='\t';
+ ind[i]='\0';
+
+ s = edg_wll_StatToString(stat.state);
+/* print whole flat structure */
+ printf("%sstate : %s\n", ind, s);
+ printf("%sjobId : %s\n", ind, j = edg_wlc_JobIdUnparse(stat.jobId));
+ printf("%sowner : %s\n", ind, stat.owner);
+ printf("%sjobtype : %s\n", ind, (stat.jobtype ? "DAG" : "SIMPLE") );
+ printf("%sparent_job : %s\n", ind,
+ j = edg_wlc_JobIdUnparse(stat.parent_job));
+ if (stat.jobtype) {;
+ printf("%sseed : %s\n", ind, stat.seed);
+ printf("%schildren_num : %d\n", ind, stat.children_num);
+ printf("%schildren :\n", ind);
+ if (stat.children)
+ for (i=0; stat.children[i]; i++)
+ printf("%s\tchildren : %s\n", ind, stat.children[i]);
+ printf("%schildren_states :\n", ind);
+ if (stat.children_states)
+ for (i=0; stat.children_states[i].state; i++)
+ printstat(stat.children_states[i], level+1);
+ printf("%schildren_hist :\n",ind);
+ if (stat.children_hist)
+ for (i=1; i<=stat.children_hist[0]; i++)
+ printf("%s%14s %d\n", ind, edg_wll_StatToString(i-1),stat.children_hist[i]);
+ }
+ printf("%scondorId : %s\n", ind, stat.condorId);
+ printf("%sglobusId : %s\n", ind, stat.globusId);
+ printf("%slocalId : %s\n", ind, stat.localId);
+ printf("%sjdl : %s\n", ind, stat.jdl);
+ printf("%smatched_jdl : %s\n", ind, stat.matched_jdl);
+ printf("%sdestination : %s\n", ind, stat.destination);
+ printf("%snetwork server : %s\n", ind, stat.network_server);
+ printf("%scondor_jdl : %s\n", ind, stat.condor_jdl);
+ printf("%srsl : %s\n", ind, stat.rsl);
+ printf("%sreason : %s\n", ind, stat.reason);
+ printf("%slocation : %s\n", ind, stat.location);
+ printf("%sce_node : %s\n", ind, stat.ce_node);
+ printf("%ssubjob_failed : %d\n", ind, stat.subjob_failed);
+ printf("%sdone_code : %s\n", ind, edg_wll_done_codeToString(stat.done_code));
+ printf("%sexit_code : %d\n", ind, stat.exit_code);
+ printf("%sresubmitted : %d\n", ind, stat.resubmitted);
+ printf("%scancelling : %d\n", ind, stat.cancelling);
+ printf("%scancelReason : %s\n", ind, stat.cancelReason);
+ printf("%scpuTime : %d\n", ind, stat.cpuTime);
+ printf("%suser_tags :\n",ind);
+ if (stat.user_tags)
+ for (i=0; stat.user_tags[i].tag; i++) printf("%s%14s = \"%s\"\n", ind,
+ stat.user_tags[i].tag,stat.user_tags[i].value);
+ printf("%sstateEnterTime : %ld.%06ld\n", ind, stat.stateEnterTime.tv_sec,stat.stateEnterTime.tv_usec);
+ printf("%sstateEnterTimes : \n",ind);
+ if (stat.stateEnterTimes)
+ for (i=1; i<=stat.stateEnterTimes[0]; i++)
+ printf("%s%14s %s", ind, edg_wll_StatToString(i-1), (stat.stateEnterTimes[i] == 0) ?
+ " - not available -\n" : ctime((time_t *) &stat.stateEnterTimes[i]));
+ printf("%slastUpdateTime : %ld.%06ld\n", ind, stat.lastUpdateTime.tv_sec,stat.lastUpdateTime.tv_usec);
+ printf("%sexpectUpdate : %d\n", ind, stat.expectUpdate);
+ printf("%sexpectFrom : %s\n", ind, stat.expectFrom);
+ printf("%sacl : %s\n", ind, stat.acl);
+ printf("\n");
+
+ free(j);
+ free(s);
+}
+
+++ /dev/null
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <globus_common.h>
-
-#include "glite/wmsutils/jobid/cjobid.h"
-#include "glite/lb/notifid.h"
-#include "glite/lb/producer.h"
-#include "glite/lb/events.h"
-
-
-static struct option opts[] = {
- {"help", 0, NULL, 'h'},
- {"sock", 1, NULL, 's'},
- {"jobid", 1, NULL, 'j'},
- {"seq", 1, NULL, 'c'},
- {"name", 1, NULL, 'n'},
- {"value", 1, NULL, 'v'}
-};
-
-static void usage(char *me)
-{
- fprintf(stderr, "usage: %s [option]\n"
- "\t-h, --help Shows this screen.\n"
- "\t-s, --server LB Proxy socket.\n"
- "\t-j, --jobid ID of requested job.\n"
- "\t-c, --seq Sequence code.\n"
- "\t-n, --name Name of the tag.\n"
- "\t-v, --value Value of the tag.\n"
- , me);
-}
-
-
-int main(int argc, char *argv[])
-{
- edg_wll_Context ctx;
- edg_wlc_JobId jobid = NULL;
- char *server, *code, *jobid_s, *name, *value;
- int opt, err = 0;
-
-
- server = code = jobid_s = name = value = NULL;
- while ( (opt = getopt_long(argc, argv, "hs:j:c:n:v:", opts, NULL)) != EOF)
- switch (opt) {
- case 'h': usage(name); return 0;
- case 's': server = strdup(optarg); break;
- case 'j': jobid_s = strdup(optarg); break;
- case 'c': code = strdup(optarg); break;
- case 'n': name = strdup(optarg); break;
- case 'v': value = strdup(optarg); break;
- case '?': usage(name); return 1;
- }
-
- if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; }
- if ( !code ) { fprintf(stderr, "Sequence code not given\n"); return 1; }
- if ( !server ) { fprintf(stderr, "LB proxy socket not given\n"); return 1; }
- if ( !name ) { fprintf(stderr, "Tag name not given\n"); return 1; }
- if ( !value ) { fprintf(stderr, "Tag value not given\n"); return 1; }
-
- if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; }
-
- if (globus_module_activate(GLOBUS_COMMON_MODULE) != GLOBUS_SUCCESS) {
- fprintf(stderr, "Cannot initialize Globus common module\n");
- exit(1);
- }
-
- edg_wll_InitContext(&ctx);
-
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_SOURCE, EDG_WLL_SOURCE_USER_INTERFACE);
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_LBPROXY_STORE_SOCK, server);
-
- if (edg_wll_SetLoggingJob(ctx, jobid, code, EDG_WLL_SEQ_NORMAL)) {
- char *et,*ed;
- edg_wll_Error(ctx,&et,&ed);
- fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,code,et,ed);
- exit(1);
- }
-
- err = edg_wll_LogEventProxy(ctx,
- EDG_WLL_EVENT_USERTAG, EDG_WLL_FORMAT_USERTAG,
- name, value);
-
- if (err) {
- char *et,*ed;
-
- edg_wll_Error(ctx,&et,&ed);
- fprintf(stderr,"%s: edg_wll_LogEvent*(): %s (%s)\n",
- argv[0],et,ed);
- free(et); free(ed);
- }
-
- code = edg_wll_GetSequenceCode(ctx);
- puts(code);
- free(code);
-
- edg_wll_FreeContext(ctx);
-
- return err;
-}
static edg_wll_Logging_cb_f *Logging_cb = NULL;
-static edg_wll_Logging_cb_f *LoggingProxy_cb = NULL;
/* register the logging callback */
}
-/* register the proxy logging callback */
-int edg_wll_RegisterTestLoggingProxy(edg_wll_Logging_cb_f *cb) {
- if (LoggingProxy_cb) return 0;
-
- LoggingProxy_cb = cb;
- return 1;
-}
-
-
/* unregister the logging callback */
void edg_wll_UnregisterTestLogging() {
Logging_cb = NULL;
}
-/* unregister the proxy logging callback */
-void edg_wll_UnregisterTestLoggingProxy() {
- LoggingProxy_cb = NULL;
-}
-
-
/* "fake" implementation of function sending formated UML string */
int edg_wll_DoLogEvent(edg_wll_Context context, edg_wll_LogLine logLine) {
if (Logging_cb)
return edg_wll_Error(context, NULL, NULL);
}
-
-/* "fake" implementation of function sending formated ULM string */
-int edg_wll_DoLogEventProxy(edg_wll_Context context, edg_wll_LogLine logline) {
- if (Logging_cb)
- return Logging_cb(context);
- else
- return edg_wll_Error(context, NULL, NULL);
-}
--- /dev/null
+#!/usr/bin/perl
+
+
+
+BEGIN{
+$inst = $ENV{GLITE_PREFIX};
+$inst = "/opt/glite" unless $inst;
+$sbin = "$inst/sbin";
+$bin = "$inst/bin";
+$test = "$inst/examples";
+$purge = "$sbin/glite-lb-purge";
+$status = "$test/glite-lb-job_status";
+$log = "$test/glite-lb-job_log";
+$prefix = "/tmp/purge_test_$$";
+$delay = 60;
+
+$ENV{PATH} .= ":$bin";
+}
+
+$option = shift;
+$server = shift;
+
+die qq{
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ This script will DESTROY ALL DATA in the specified bookkeeping server.
+
+Don't run it unless you are absolutely sure what you are doing.
+If you really mean it, the magic usage is:
+
+ $0 --i-want-to-purge server:port
+
+Good luck!
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+} unless $option eq '--i-want-to-purge';
+
+die "usage: $0 --i-want-to-purge server:port\n" unless $server;
+
+sub logit {
+ my $ids = shift;
+ my $prefix = shift;
+ my $failed = 0;
+
+ for (qw/aborted cleared cancelled waiting/) {
+ my $key = $_ eq waiting ? 'other' : $_;
+ $id = `$test/glite-lb-$_.sh -m $server`;
+ chomp $id;
+ die "$test/glite-lb-$_.sh" if $?;
+ $id =~ s/EDG_JOBID=//;
+ $ids->{$key} = $id;
+#print "$status $id | head -1\n";
+ $stat = `$status $id | head -2 | tail -1`;
+ chomp $stat;
+ $stat =~ s/state :\s*//;
+#print "$id: ".uc($stat)." ".uc($_)."\n";
+ $failed = 1 if uc($stat) ne uc($_);
+
+ system "$log $id | grep -v '^[ ]*\$' | grep -v '^Found' >${prefix}_$_";
+ }
+
+ !$failed;
+}
+
+print "** Hey, purging the whole database\n";
+system "$purge --server $server --return-list --aborted=0 --cleared=0 --cancelled=0 --other=0";
+die "$purge: $!\n" if $!;
+
+print "** Logging test jobs\n";
+
+die "!! failed\n" if !logit \%old,"${prefix}_old";
+print "** So far good, sleeping $delay seconds\n";
+sleep $delay;
+print "** OK, another set of jobs\n";
+die "!! failed\n" if !logit \%new,"${prefix}_new";
+
+print "** Dry run\n";
+$failed = 0;
+
+$half = $delay/2;
+for (qw/aborted cleared cancelled other/) {
+ open LIST,"$purge --server $server --dry-run --return-list --$_=${half}s| grep '^https://'|" or die "!! run $purge\n";
+
+ $id = <LIST>; chomp $id;
+ if ($old{$_} ne $id) {
+ $failed = 1;
+ print "!! $old{$_} (old $_) is not there\n";
+ }
+ else {
+ print "$_ $id OK\n";
+ }
+ $id = <LIST>;
+ if ($id) {
+ $failed = 1;
+ chomp $id;
+ print "!! $id should not be there\n";
+ }
+ close LIST;
+
+ open LIST,"$purge --server $server --dry-run --return-list --$_=0s | grep '^https://'|" or die "!! run $purge\n";
+
+ $cnt = 0;
+ while ($id = <LIST>) {
+ chomp $id;
+ if ($old{$_} ne $id && $new{$_} ne $id) {
+ $failed = 1;
+ print "!! $id should not be there\n";
+ }
+ else {
+ print "$_ $id OK\n";
+ }
+ $cnt++;
+ }
+
+ close LIST;
+ if ($cnt != 2) {
+ $failed = 1;
+ print "!! bad number of $_ jobs ($cnt)\n";
+ }
+}
+
+die "!! aborting\n" if $failed;
+
+print "** Server defaults\n";
+
+open LIST,"$purge --server $server --dry-run --return-list | grep '^https://'|" or die "!! run $purge\n";
+
+$failed = 0;
+while ($id = <LIST>) {
+ $failed = 1;
+ print "$id\n";
+}
+
+die "!! Oops, should not do anything, too short defaults?\n" if $failed;
+
+print "Nothing purged as expected\n";
+
+print "** Purge the first set of jobs\n";
+
+open DUMP,"$purge --server $server --server-dump --aborted=${half}s --cleared=${half}s --cancelled=${half}s --other=${half}s | grep '^Server dump:'|"
+ or die "!! run $purge\n";
+
+$dump = <DUMP>; chomp $dump; $dump =~ s/Server dump: //;
+close DUMP;
+
+die "!! no dump file reported\n" unless $dump;
+@list = glob "${prefix}_old*";
+system "cat @list | sort >${prefix}_old_all";
+system "cat $dump | sed -e s/^.*DATE/DATE/ | sort >${prefix}_old_dump";
+sleep 60;
+system "diff ${prefix}_old_all ${prefix}_old_dump >/dev/null";
+
+die "!! aggregate log and dump differ\n" if $? & 0xff00;
+
+print "diff OK\n";
+
+print "** Purge the rest\n";
+open DUMP,"$purge --server $server --server-dump --aborted=0 --cleared=0 --cancelled=0 --other=0 | grep '^Server dump:'|"
+ or die "!! run $purge\n";
+
+$dump = <DUMP>; chomp $dump; $dump =~ s/Server dump: //;
+close DUMP;
+
+die "!! no dump file reported\n" unless $dump;
+@list = glob "${prefix}_new*";
+system "cat @list | sort >${prefix}_new_all";
+system "cat $dump | sed -e s/^.*DATE/DATE/ | sort >${prefix}_new_dump";
+system "diff ${prefix}_new_all ${prefix}_new_dump >/dev/null";
+
+die "!! aggregate log and dump differ\n" if $? & 0xff00;
+
+print "diff OK\n";
+
+
+print "** Anything left?\n";
+open LIST,"$purge --server $server --return-list --dry-run --aborted=0 --cleared=0 --cancelled=0 --other=0 | grep '^https://'|" or die "!! $purge\n";
+
+$id = <LIST>;
+close LIST;
+die "!! Yes, but should not\n" if $id;
+print "No, OK\n";
+
+print "\n** All tests passed **\n";
+exit 0;
+
+END{ unlink glob "${prefix}*" if $prefix; }
--- /dev/null
+#Thu Jul 07 08:25:28 CEST 2005
+module.build=304
-#Fri Dec 10 13:24:00 CET 2004
-module.version=0.5.0
-module.build=112
-module.age=2
+
+module.version = 1.0.5
+module.age = 1
+
std::pair<std::string, int>
ServerConnection::getQueryServer() const
{
- /* FIXME: not implemented in C API */
- STACK_ADD;
- throw Exception(EXCEPTION_MANDATORY, 0, "method not implemented");
+ char *hostname;
+ int port;
+
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_QUERY_SERVER,
+ &hostname),
+ context,
+ "getting query server address");
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_QUERY_SERVER_PORT,
+ &port),
+ context,
+ "getting query server port");
+ return std::pair<std::string,int>(std::string(strdup(hostname)), port);
}
int
ServerConnection::getQueryTimeout() const
{
- /* FIXME: not implemented in C API */
- STACK_ADD;
- throw Exception(EXCEPTION_MANDATORY, 0, "method not implemented");
+ int timeout;
+
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_QUERY_TIMEOUT,
+ &timeout),
+ context,
+ "getting query timeout");
+ return timeout;
}
std::string
ServerConnection::getX509Proxy() const
{
- /* FIXME: not implemented in C API */
- STACK_ADD;
- throw Exception(EXCEPTION_MANDATORY, 0, "method not implemented");
+ char *proxy;
+
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_X509_PROXY,
+ &proxy),
+ context,
+ "getting X509 proxy");
+ return std::string(strdup(proxy));
}
std::pair<std::string, std::string>
ServerConnection::getX509Cert() const
{
- /* FIXME: not implemented in C API */
- STACK_ADD;
- throw Exception(EXCEPTION_MANDATORY, 0, "method not implemented");
+ char *cert, *key;
+
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_X509_CERT,
+ &cert),
+ context,
+ "getting X509 cert");
+ check_result(edg_wll_GetParam(context,
+ EDG_WLL_PARAM_X509_KEY,
+ &key),
+ context,
+ "getting X509 key");
+
+ return std::pair<std::string, std::string>(std::string(strdup(cert)),
+ std::string(strdup(key)));
}
// static
convertQueryVectorExt(const std::vector<std::vector<QueryRecord> > &in)
{
unsigned i;
- edg_wll_QueryRec **out = new (edg_wll_QueryRec*)[in.size() + 1];
+ edg_wll_QueryRec **out = new edg_wll_QueryRec*[in.size() + 1];
if(out == NULL) {
STACK_ADD;
"edg_wll_SetParamInt()");
}
-void ServerConnection::setParam(edg_wll_ContextParam par, const std::string val)
+void ServerConnection::setParam(edg_wll_ContextParam par, const std::string &val)
{
check_result(edg_wll_SetParamString(context,par,val.c_str()),
context,
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <assert.h>
#include "glite/lb/consumer.h"
#include "glite/lb/context-int.h"
/* close connection ad free its structures */
OM_uint32 min_stat;
+ assert(ctx->connOpened);
+ assert(conn_index < ctx->connOpened);
+
edg_wll_gss_close(&ctx->connPool[conn_index].gss, &ctx->p_tmp_timeout);
if (ctx->connPool[conn_index].gsiCred)
gss_release_cred(&min_stat, &ctx->connPool[conn_index].gsiCred);
int edg_wll_close(edg_wll_Context ctx)
{
edg_wll_ResetError(ctx);
+ if (ctx->connToUse == -1) return 0;
CloseConnection(ctx, ctx->connToUse);
+ ctx->connToUse = -1;
return edg_wll_Error(ctx,NULL,NULL);
}
/* some error occured; close created connection
* and free all fields in connPool[index] */
CloseConnection(ctx, index);
+ ctx->connToUse = -1;
ok:
return edg_wll_Error(ctx,NULL,NULL);
}
char ***resp_head,
char **resp_body)
{
+ int ec;
+ char *ed = NULL;
+
if (edg_wll_open(ctx)) return edg_wll_Error(ctx,NULL,NULL);
switch (edg_wll_http_send(ctx,request,req_head,req_body)) {
edg_wll_close(ctx);
if (edg_wll_open(ctx)
|| edg_wll_http_send(ctx,request,req_head,req_body))
- return edg_wll_Error(ctx,NULL,NULL);
+ goto err;
/* fallthrough */
case 0: break;
- default: return edg_wll_Error(ctx,NULL,NULL);
+ default: goto err;
}
- if (edg_wll_http_recv(ctx,response,resp_head,resp_body) == ENOTCONN) {
- edg_wll_close(ctx);
- (void) (edg_wll_open(ctx)
- || edg_wll_http_send(ctx,request,req_head,req_body)
- || edg_wll_http_recv(ctx,response,resp_head,resp_body));
+ switch (edg_wll_http_recv(ctx,response,resp_head,resp_body)) {
+ case ENOTCONN:
+ edg_wll_close(ctx);
+ if (edg_wll_open(ctx)
+ || edg_wll_http_send(ctx,request,req_head,req_body)
+ || edg_wll_http_recv(ctx,response,resp_head,resp_body))
+ goto err;
+ /* fallthrough */
+ case 0: break;
+ default: goto err;
}
+ assert(ctx->connToUse >= 0);
gettimeofday(&ctx->connPool[ctx->connToUse].lastUsed, NULL);
-
- return edg_wll_Error(ctx,NULL,NULL);
+ return 0;
+
+err:
+ ec = edg_wll_Error(ctx,NULL,&ed);
+ edg_wll_close(ctx);
+ edg_wll_SetError(ctx,ec,ed);
+ free(ed);
+ return ec;
}
edg_wll_Args parray[] = {
{ EDG_WLL_ARGS_EVENT, "e", "event", "select event type (see -e help)", &event },
{ EDG_WLL_ARGS_BOOL, "p", "priority", "send as priority event", &pri },
- { EDG_WLL_ARGS_STRING, "x", "lbproxy", "send directly to L&B Proxy (not locallogger) with given credentials", &lbproxy },
{ EDG_WLL_ARGS_STRING, "m", "machine", 0, &server },
{ EDG_WLL_ARGS_SOURCE, "s", "source", "event source (see -s help)", &src },
{ EDG_WLL_ARGS_STRING, "i", "source-instance", "event source instance", &src_instance },
/* log the event - priority/normal/proxy */
logev = (pri) ? edg_wll_LogEventSync : edg_wll_LogEvent;
- logev = (lbproxy) ? edg_wll_LogEventProxy : logev;
/* if no job given - generate some */
if (jobid_s == 0) {
edg_wll_SetParam(ctx, EDG_WLL_PARAM_LEVEL,
(deb) ? EDG_WLL_LEVEL_DEBUG : EDG_WLL_LEVEL_SYSTEM);
- if (lbproxy) {
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_LBPROXY_STORE_SOCK, "/tmp/lb_proxy_store.sock");
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_LBPROXY_SERVE_SOCK, "/tmp/lb_proxy_serve.sock");
- if (edg_wll_SetLoggingJobProxy(ctx,jobid,code,lbproxy,EDG_WLL_SEQ_NORMAL)) {
- char *et,*ed;
- edg_wll_Error(ctx,&et,&ed);
- fprintf(stderr,"SetLoggingJobProxy(%s,%s,%s): %s (%s)\n",jobid_s,code,lbproxy,et,ed);
- exit(1);
- }
- } else {
- if (edg_wll_SetLoggingJob(ctx,jobid,code,EDG_WLL_SEQ_NORMAL)) {
- char *et,*ed;
- edg_wll_Error(ctx,&et,&ed);
- fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,code,et,ed);
- exit(1);
- }
+ if (edg_wll_SetLoggingJob(ctx,jobid,code,EDG_WLL_SEQ_NORMAL)) {
+ char *et,*ed;
+ edg_wll_Error(ctx,&et,&ed);
+ fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,code,et,ed);
+ exit(1);
}
#ifdef ENABLE_REASON_LENGTH
#ifdef FAKE_VERSION
int edg_wll_DoLogEvent(edg_wll_Context context, edg_wll_LogLine logline);
-int edg_wll_DoLogEventProxy(edg_wll_Context context, edg_wll_LogLine logline);
#else
/**
*----------------------------------------------------------------------
return edg_wll_Error(context, NULL, NULL);
}
-/**
- *----------------------------------------------------------------------
- * Connects to L&B Proxy and sends already formatted ULM string
- * \brief helper logging function
- * \param context INOUT context to work with,
- * \param logline IN formated ULM string
- *----------------------------------------------------------------------
- */
-static int edg_wll_DoLogEventProxy(
- edg_wll_Context context,
- edg_wll_LogLine logline)
-{
- int answer;
- struct sockaddr_un saddr;
- int flags;
- edg_wll_PlainConnection conn;
-
- edg_wll_ResetError(context);
- answer = 0;
-
- /* open a connection to the L&B Proxy: */
-
-#ifdef EDG_WLL_LOG_STUB
- fprintf(stderr,"Logging to L&B Proxy at socket %s\n",
- context->p_lbproxy_store_sock? context->p_lbproxy_store_sock: socket_path);
-#endif
- memset(&conn, 0, sizeof(conn));
- conn.sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (conn.sock < 0) {
- edg_wll_SetError(context,answer = errno,"socket() error");
- goto edg_wll_DoLogEventProxy_end;
- }
- memset(&saddr, 0, sizeof(saddr));
- saddr.sun_family = AF_UNIX;
- strcpy(saddr.sun_path, context->p_lbproxy_store_sock?
- context->p_lbproxy_store_sock: socket_path);
- if ((flags = fcntl(conn.sock, F_GETFL, 0)) < 0 || fcntl(conn.sock, F_SETFL, flags | O_NONBLOCK) < 0) {
- edg_wll_SetError(context,answer = errno,"fcntl()");
- close(conn.sock);
- goto edg_wll_DoLogEventProxy_end;
- }
- if (connect(conn.sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
- if(errno != EISCONN) {
- edg_wll_SetError(context,answer = errno,"connect()");
- close(conn.sock);
- goto edg_wll_DoLogEventProxy_end;
- }
- }
-
-
- /* and send the message to the L&B Proxy: */
-
- answer = edg_wll_log_proto_client_proxy(context,&conn,logline);
-
- edg_wll_plain_close(&conn);
-
-edg_wll_DoLogEventProxy_end:
-
- switch(answer) {
- case 0:
- case EINVAL:
- case ENOSPC:
- case ENOMEM:
- case EDG_WLL_ERROR_GSS:
- case EDG_WLL_ERROR_DNS:
- case ENOTCONN:
- case ECONNREFUSED:
- case ETIMEDOUT:
- case EAGAIN:
- break;
- case EDG_WLL_ERROR_PARSE_EVENT_UNDEF:
- case EDG_WLL_ERROR_PARSE_MSG_INCOMPLETE:
- case EDG_WLL_ERROR_PARSE_KEY_DUPLICITY:
- case EDG_WLL_ERROR_PARSE_KEY_MISUSE:
-// case EDG_WLL_ERROR_PARSE_OK_WITH_EXTRA_FIELDS:
- edg_wll_UpdateError(context,EINVAL,"edg_wll_DoLogEventProxy(): Error code mapped to EINVAL");
- break;
-
- default:
- edg_wll_UpdateError(context,EAGAIN,"edg_wll_DoLogEventProxy(): Error code mapped to EAGAIN");
- break;
- }
-
- return edg_wll_Error(context, NULL, NULL);
-}
#endif /* FAKE_VERSION */
/**
*----------------------------------------------------------------------
- * Formats a logging message and sends it to L&B Proxy
- * \brief master proxy logging event function
- * \param context INOUT context to work with,
- * \param event IN type of the event,
- * \param fmt IN printf()-like format string,
- * \param ... IN event specific values/data according to fmt.
- *----------------------------------------------------------------------
- */
-static int edg_wll_LogEventMasterProxy(
- edg_wll_Context context,
- edg_wll_EventCode event,
- char *fmt, ...)
-{
- va_list fmt_args;
- int ret,answer;
- char *fix,*var,*dguser;
- char *source,*eventName,*lvl, *fullid,*seq,*name_esc;
- struct timeval start_time;
- char date[ULM_DATE_STRING_LENGTH+1];
- edg_wll_LogLine out;
- size_t size;
- int i;
-
- i = errno = size = 0;
- seq = fix = var = dguser = out = source = eventName = lvl = fullid = NULL;
-
- edg_wll_ResetError(context);
-
- /* default return value is "Try Again" */
- answer = ret = EAGAIN;
-
- /* format the message: */
- va_start(fmt_args,fmt);
-
- gettimeofday(&start_time,0);
- if (edg_wll_ULMTimevalToDate(start_time.tv_sec,start_time.tv_usec,date) != 0) {
- edg_wll_SetError(context,ret = EINVAL,"edg_wll_LogEventMasterProxy(): edg_wll_ULMTimevalToDate() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- source = edg_wll_SourceToString(context->p_source);
- lvl = edg_wll_LevelToString(context->p_level);
- eventName = edg_wll_EventToString(event);
- if (!eventName) {
- edg_wll_SetError(context,ret = EINVAL,"edg_wll_LogEventMasterProxy(): event name not specified");
- goto edg_wll_logeventmasterproxy_end;
- }
- if (!(fullid = edg_wlc_JobIdUnparse(context->p_jobid))) {
- edg_wll_SetError(context,ret = EINVAL,"edg_wll_LogEventMasterProxy(): edg_wlc_JobIdUnparse() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- seq = edg_wll_GetSequenceCode(context);
- if (edg_wll_IncSequenceCode(context)) {
- ret = EINVAL;
- goto edg_wll_logeventmasterproxy_end;
- }
- if (trio_asprintf(&fix,EDG_WLL_FORMAT_COMMON,
- date,context->p_host,lvl,1,
- source,context->p_instance ? context->p_instance : "",
- eventName,fullid,seq) == -1) {
- edg_wll_SetError(context,ret = ENOMEM,"edg_wll_LogEventMasterProxy(): trio_asprintf() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- if (trio_vasprintf(&var,fmt,fmt_args) == -1) {
- edg_wll_SetError(context,ret = ENOMEM,"edg_wll_LogEventMasterProxy(): trio_vasprintf() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- /* format the DG.USER string */
-/* XXX: put user credentials here probably from context */
- name_esc = edg_wll_LogEscape(context->p_user_lbproxy);
- if (asprintf(&dguser,"DG.USER=\"%s\" ",name_esc) == -1) {
- edg_wll_SetError(context,ret = ENOMEM,"edg_wll_LogEventMasterProxy(): asprintf() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- if (asprintf(&out,"%s%s%s\n",dguser,fix,var) == -1) {
- edg_wll_SetError(context,ret = ENOMEM,"edg_wll_LogEventMasterProxy(): asprintf() error");
- goto edg_wll_logeventmasterproxy_end;
- }
- size = strlen(out);
-
- if (size > EDG_WLL_LOG_SYNC_MAXMSGSIZE) {
- edg_wll_SetError(context,ret = ENOSPC,"edg_wll_LogEventMasterProxy(): Message size too large for synchronous transfer");
- goto edg_wll_logeventmasterproxy_end;
- }
-
-#ifdef EDG_WLL_LOG_STUB
-// fprintf(stderr,"edg_wll_LogEvent (%d chars): %s",size,out);
-#endif
-
- context->p_tmp_timeout = context->p_sync_timeout;
-
- /* and send the message to the L&B Proxy: */
- ret = edg_wll_DoLogEventProxy(context, out);
-
-edg_wll_logeventmasterproxy_end:
- va_end(fmt_args);
- if (seq) free(seq);
- if (fix) free(fix);
- if (var) free(var);
- if (dguser) free(dguser);
- if (out) free(out);
- if (source) free(source);
- if (lvl) free(lvl);
- if (eventName) free(eventName);
- if (fullid) free(fullid);
- if (name_esc) free(name_esc);
-
- if (ret) edg_wll_UpdateError(context,0,"Logging library ERROR: ");
-
- return edg_wll_Error(context,NULL,NULL);
-}
-
-/**
- *----------------------------------------------------------------------
* Formats a logging message and sends it asynchronously to local-logger
* \brief generic asynchronous logging function
*----------------------------------------------------------------------
}
/**
- *----------------------------------------------------------------------
- * Formats a logging message and sends it synchronously to L&B Proxy
- * \brief generic synchronous logging function
- *----------------------------------------------------------------------
- */
-int edg_wll_LogEventProxy(
- edg_wll_Context context,
- edg_wll_EventCode event,
- char *fmt, ...)
-{
- int ret=0;
- char *list=NULL;
- va_list fmt_args;
-
- edg_wll_ResetError(context);
-
- va_start(fmt_args,fmt);
- if (trio_vasprintf(&list,fmt,fmt_args) == -1) {
- edg_wll_SetError(context,ret = ENOMEM,"edg_wll_LogEventProxy(): trio_vasprintf() error");
- goto edg_wll_logevent_end;
- }
-
- ret=edg_wll_LogEventMasterProxy(context,event,"%s",list);
-
-edg_wll_logevent_end:
- va_end(fmt_args);
- if (list) free(list);
-
- if (ret) edg_wll_UpdateError(context,0,"edg_wll_LogEventProxy(): ");
-
- return edg_wll_Error(context,NULL,NULL);
-}
-
-
-/**
*-----------------------------------------------------------------------
* Instructs interlogger to to deliver all pending events related to current job
* \brief flush events from interlogger
/**
*-----------------------------------------------------------------------
- * Set a current job for given context.
- * \note Should be called before any logging call.
- *-----------------------------------------------------------------------
- */
-int edg_wll_SetLoggingJobProxy(
- edg_wll_Context context,
- const edg_wlc_JobId job,
- const char *code,
- const char *user,
- int flags)
-{
- int err;
- char *code_loc = NULL;
-
- edg_wll_ResetError(context);
-
- if (!job) return edg_wll_SetError(context,EINVAL,"jobid is null");
-
- edg_wlc_JobIdFree(context->p_jobid);
- if ((err = edg_wlc_JobIdDup(job,&context->p_jobid))) {
- edg_wll_SetError(context,err,"edg_wll_SetLoggingJob(): edg_wlc_JobIdDup() error");
- goto edg_wll_setloggingjobproxy_end;
- }
-
- /* add user credentials to context */
- edg_wll_SetParamString(context, EDG_WLL_PARAM_LBPROXY_USER, user);
-
- /* query LBProxyServer for sequence code if not user-suplied */
-/* FIXME: doesn't work yet
- if (!code) {
- edg_wll_QuerySequenceCodeProxy(context, job, &code_loc);
- goto edg_wll_setloggingjobproxy_end;
- } else {
- code_loc = strdup(code);
- }
-
- if (!edg_wll_SetSequenceCode(context,code_loc,flags)) */ {
- edg_wll_IncSequenceCode(context);
- }
-
-edg_wll_setloggingjobproxy_end:
- if (code_loc) free(code_loc);
- return edg_wll_Error(context,NULL,NULL);
-}
-
-/**
- *-----------------------------------------------------------------------
* Register job with L&B service.
*-----------------------------------------------------------------------
*/
return edg_wll_Error(context,NULL,NULL);
}
-/**
- *-----------------------------------------------------------------------
- * Register job with L&B Proxy service.
- *-----------------------------------------------------------------------
- */
-static int edg_wll_RegisterJobMasterProxy(
- edg_wll_Context context,
- const edg_wlc_JobId job,
- enum edg_wll_RegJobJobtype type,
- const char * user,
- const char * jdl,
- const char * ns,
- edg_wlc_JobId parent,
- int num_subjobs,
- const char * seed,
- edg_wlc_JobId ** subjobs)
-{
- char *type_s = NULL,*intseed = NULL, *seq = NULL;
- char *parent_s = NULL;
- int err = 0;
-
- edg_wll_ResetError(context);
-
- intseed = seed ? strdup(seed) :
- str2md5base64(seq = edg_wll_GetSequenceCode(context));
-
- free(seq);
-
- type_s = edg_wll_RegJobJobtypeToString(type);
- if (!type_s) return edg_wll_SetError(context,EINVAL,"edg_wll_RegisterJobMaster(): no jobtype specified");
-
- if ((type == EDG_WLL_REGJOB_DAG || type == EDG_WLL_REGJOB_PARTITIONED)
- && num_subjobs > 0)
- err = edg_wll_GenerateSubjobIds(context,job,
- num_subjobs,intseed,subjobs);
-
- parent_s = parent ? edg_wlc_JobIdUnparse(parent) : strdup("");
-
- if (err == 0 &&
- edg_wll_SetLoggingJobProxy(context,job,NULL,user,EDG_WLL_SEQ_NORMAL) == 0)
- edg_wll_LogEventMasterProxy(context,
- EDG_WLL_EVENT_REGJOB,EDG_WLL_FORMAT_REGJOB,
- (char *)jdl,ns,parent_s,type_s,num_subjobs,intseed);
-
- free(type_s); free(intseed); free(parent_s);
- return edg_wll_Error(context,NULL,NULL);
-}
-
int edg_wll_RegisterJobSync(
edg_wll_Context context,
const edg_wlc_JobId job,
return edg_wll_Error(ctx, NULL, NULL);
}
-int edg_wll_RegisterJobProxy(
- edg_wll_Context context,
- const edg_wlc_JobId job,
- enum edg_wll_RegJobJobtype type,
- const char * user,
- const char * jdl,
- const char * ns,
- int num_subjobs,
- const char * seed,
- edg_wlc_JobId ** subjobs)
-{
- return edg_wll_RegisterJobMasterProxy(context,job,type,user,jdl,ns, NULL, num_subjobs,seed,subjobs);
-}
-
int edg_wll_ChangeACL(
edg_wll_Context ctx,
const edg_wlc_JobId jobid,
my $tu = uc $t;
my $a = "(edg_wll_Context context";
my $b = "(context,EDG_WLL_EVENT_$tu,EDG_WLL_FORMAT_$tu";
- my $decl = "";
+ my $decl = "\tint ret;\n";
my $free = "";
my $doc = qq{
* \\param context\tcontext to work with,
int edg_wll_Log$t$a
\{
$decl
- return edg_wll_LogEvent$b;
-\}\n
-};
- gen qq{
-int edg_wll_Log${t}Proxy$a
-\{
-$decl
- return edg_wll_LogEventProxy$b;
+ ret = edg_wll_LogEvent$b;
+$free
+ return ret;
\}\n
};
+# gen qq{
+#int edg_wll_Log${t}Proxy$a
+#\{
+#$decl
+# return edg_wll_LogEventProxy$b;
+#\}\n
+#};
for ($event->getFieldsOrdered) {
my $f = selectField $event $_;
my $fn = $f->getName;
int edg_wll_Log$t$code$c
\{
$decl
- return edg_wll_LogEvent$d;
-\}\n
-};
- gen qq{
-int edg_wll_Log$t${code}Proxy$c
-\{
-$decl
- return edg_wll_LogEventProxy$d;
+ ret = edg_wll_LogEvent$d;
+$free
+ return ret;
\}\n
};
+# gen qq{
+#int edg_wll_Log$t${code}Proxy$c
+#\{
+#$decl
+# return edg_wll_LogEventProxy$d;
+#\}\n
+#};
}
}
}
# major version more frequently. This variable specifies how many steps ahead
# we are.
-VERSION_AHEAD=1
+VERSION_AHEAD=0
GLOBUS_LIBS:=-L${globus_prefix}/lib \
-lglobus_common_${nothrflavour} \
Revision history:
$Log$
+ Revision 1.6 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.5 2004/07/28 12:27:00 dimeglio
Changed default target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
typedef struct _edg_wll_GssConnection {
gss_ctx_id_t context;
int sock;
- char buffer[BUFSIZ];
+ char *buffer;
size_t bufsize;
} edg_wll_GssConnection;
--- /dev/null
+#Thu Jul 07 08:23:05 CEST 2005
+module.build=303
-#Fri Dec 10 13:22:02 CET 2004
-module.version=1.0.0
-module.build=111
-module.age=2
+
+module.version = 1.1.6
+module.age = 1
+
out->connPoolNotif = (edg_wll_ConnPool *) calloc(1, sizeof(edg_wll_ConnPool));
out->connProxy = (edg_wll_ConnPool *) calloc(1, sizeof(edg_wll_ConnProxy));
out->connProxy->conn.sock = -1;
+ out->connToUse = -1;
*ctx = out;
return 0;
};
/**
- * \fn edg_wll_EventCode edg_wll_StringToEvent(char *name)
+ * \fn edg_wll_EventCode edg_wll_StringToEvent(const char *name)
* \param name a string event name (e.g. "JobTransfer")
* \return corresponding numeric code (edg_wll_EventCode)
* \brief convert a string event name to the corresponding numeric code
* Calls: strcasecmp
* Algorithm: array lookup
*/
-edg_wll_EventCode edg_wll_StringToEvent(char *name)
+edg_wll_EventCode edg_wll_StringToEvent(const char *name)
{
unsigned int i;
};
/*
- * \fn edg_wll_KeyNameCode edg_wll_StringToKeyName(char *name)
+ * \fn edg_wll_KeyNameCode edg_wll_StringToKeyName(const char *name)
* \param name a string ULM key name (e.g. "DG.JOB.TRANSFER.DEST")
* \return corresponding numeric code (edg_wll_KeyNameCode)
* \brief convert a string ULM key name to the corresponding numeric code
* Calls: strcasecmp
* Algorithm: array lookup
*/
-edg_wll_KeyNameCode edg_wll_StringToKeyName(char *name)
+edg_wll_KeyNameCode edg_wll_StringToKeyName(const char *name)
{
unsigned int i;
# function StringTo:
gen qq{
/**
- * \\fn $enum edg_wll_StringTo${c}(char *name)
+ * \\fn $enum edg_wll_StringTo${c}(const char *name)
* Calls: strcasecmp
* Algorithm: array lookup
*/
-$enum edg_wll_StringTo${c}(char *name)
+$enum edg_wll_StringTo${c}(const char *name)
\{
unsigned int i;
# function StringTo:
gen qq{
/**
- * \\fn $enum edg_wll_StringTo${c}(char *name)
+ * \\fn $enum edg_wll_StringTo${c}(const char *name)
* Calls: strcasecmp
* Algorithm: array lookup
*/
-$enum edg_wll_StringTo${c}(char *name)
+$enum edg_wll_StringTo${c}(const char *name)
\{
unsigned int i;
if ($ft eq 'string') {
gen $indent."\tif (event->$tl.$fn) free(event->$tl.$fn);\n"
}
+ if ($ft eq 'jobid') {
+ gen $indent."\tif (event->$tl.$fn) edg_wlc_JobIdFree(event->$tl.$fn);\n"
+ }
+ if ($ft eq 'notifid') {
+ gen $indent."\tif (event->$tl.$fn) edg_wll_NotifIdFree(event->$tl.$fn);\n"
+ }
}
gen $indent.$indent."break;\n"
}
#include <stdlib.h>
#include <stdarg.h>
#include <syslog.h>
+#include <pthread.h>
int log_level;
vasprintf(&err_text, fmt, fmt_args);
va_end(fmt_args);
- if(level <= log_level)
+ if(level <= log_level) {
+ fprintf(stderr, "[%6d] ", pthread_self());
fprintf(stderr, err_text);
-
+ }
+
if(level <= LOG_ERR) {
openlog("edg-wl-interlogd", LOG_PID | LOG_CONS, LOG_DAEMON);
syslog(level, "%s", err_text);
input_token.value = (void*)buf;
input_token.length = bufsize;
- maj_stat = gss_wrap (&min_stat, connection->context, 0, GSS_C_QOP_DEFAULT,
+ maj_stat = gss_wrap (&min_stat, connection->context, 1, GSS_C_QOP_DEFAULT,
&input_token, NULL, &output_token);
if (GSS_ERROR(maj_stat)) {
if (gss_code) {
len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
memcpy(buf, connection->buffer, len);
- connection->bufsize -= len;
- if (connection->bufsize > 0) {
- for (i = 0; i < sizeof(connection->buffer) - len; i++)
+ if (connection->bufsize - len == 0) {
+ free(connection->buffer);
+ connection->buffer = NULL;
+ } else {
+ for (i = 0; i < connection->bufsize - len; i++)
connection->buffer[i] = connection->buffer[i+len];
}
+ connection->bufsize -= len;
return len;
}
maj_stat = gss_unwrap(&min_stat, connection->context, &input_token,
&output_token, NULL, NULL);
+ gss_release_buffer(&min_stat, &input_token);
if (GSS_ERROR(maj_stat)) {
/* XXX cleanup */
return EDG_WLL_GSS_ERROR_GSS;
} while (maj_stat == 0 && output_token.length == 0 && output_token.value == NULL);
if (output_token.length > bufsize) {
- if (output_token.length - bufsize > sizeof(connection->buffer))
- return EINVAL;
connection->bufsize = output_token.length - bufsize;
+ connection->buffer = malloc(connection->bufsize);
+ if (connection->buffer == NULL) {
+ connection->bufsize = 0;
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
memcpy(connection->buffer, output_token.value + bufsize, connection->bufsize);
output_token.length = bufsize;
}
+
memcpy(buf, output_token.value, output_token.length);
+ ret = output_token.length;
- return output_token.length;
+end:
+ gss_release_buffer(&min_stat, &output_token);
+
+ return ret;
}
int
if (connection->bufsize > 0) {
size_t len;
-
len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
memcpy(buf, connection->buffer, len);
- connection->bufsize -= len;
- if (connection->bufsize > 0) {
- for (i = 0; i < sizeof(connection->buffer) - len; i++)
+ if (connection->bufsize - len == 0) {
+ free(connection->buffer);
+ connection->buffer = NULL;
+ } else {
+ for (i = 0; i < connection->bufsize - len; i++)
connection->buffer[i] = connection->buffer[i+len];
}
+ connection->bufsize -= len;
*total = len;
}
if (con->sock >= 0)
close(con->sock);
}
+ if (con->buffer)
+ free(con->buffer);
memset(con, 0, sizeof(*con));
con->context = GSS_C_NO_CONTEXT;
con->sock = -1;
NULL,
NULL,
NULL,
- "EDG_WL_LOG_DESTINATION",
- "EDG_WL_LOG_DESTINATION",
- "EDG_WL_LOG_TIMEOUT",
- "EDG_WL_LOG_SYNC_TIMEOUT",
- "EDG_WL_QUERY_SERVER",
- "EDG_WL_QUERY_SERVER",
- "EDG_WL_QUERY_SERVER_OVERRIDE",
- "EDG_WL_QUERY_TIMEOUT",
- "EDG_WL_QUERY_JOBS_LIMIT",
- "EDG_WL_QUERY_EVENTS_LIMIT",
- "EDG_WL_QUERY_RESULTS",
- "EDG_WL_QUERY_CONNECTIONS",
- "EDG_WL_NOTIF_SERVER",
- "EDG_WL_NOTIF_SERVER",
- "EDG_WL_NOTIF_TIMEOUT",
+ "%sLOG_DESTINATION",
+ "%sLOG_DESTINATION",
+ "%sLOG_TIMEOUT",
+ "%sLOG_SYNC_TIMEOUT",
+ "%sQUERY_SERVER",
+ "%sQUERY_SERVER",
+ "%sQUERY_SERVER_OVERRIDE",
+ "%sQUERY_TIMEOUT",
+ "%sQUERY_JOBS_LIMIT",
+ "%sQUERY_EVENTS_LIMIT",
+ "%sQUERY_RESULTS",
+ "%sQUERY_CONNECTIONS",
+ "%sNOTIF_SERVER",
+ "%sNOTIF_SERVER",
+ "%sNOTIF_TIMEOUT",
/* don't care about X509_USER_*, GSI looks at them anyway */
NULL,
NULL,
NULL,
- "EDG_WL_LBPROXY_STORE_SOCK",
- "EDG_WL_LBPROXY_SERVE_SOCK",
- "EDG_WL_LBPROXY_USER",
+ "%sLBPROXY_STORE_SOCK",
+ "%sLBPROXY_SERVE_SOCK",
+ "%sLBPROXY_USER",
};
/* XXX: does not parse URL, just hostname[:port] */
-static int extract_port(edg_wll_ContextParam param,int dflt)
+static char *mygetenv(int param)
{
- char *p = NULL,*s = NULL;
+ char *s = NULL;
+
if (myenv[param]) {
- s = getenv(myenv[param]);
- if (s) p = strchr(s,':');
+ char varname[100];
+
+ sprintf(varname,myenv[param],"GLITE_WMS_");
+ s = getenv(varname);
+
+ if (!s) {
+ sprintf(varname,myenv[param],"EDG_WL_");
+ s = getenv(varname);
+ }
}
+ return s;
+}
+
+static int extract_port(edg_wll_ContextParam param,int dflt)
+{
+ char *p = NULL,*s = mygetenv(param);
+
+ if (s) p = strchr(s,':');
return p ? atoi(p+1) : dflt;
}
static int extract_num(edg_wll_ContextParam param,int dflt)
{
- if (myenv[param]) {
- char *s = getenv(myenv[param]);
- if (s) return(atoi(s));
- }
- return dflt;
+ char *s = mygetenv(param);
+ return s ? atoi(s) : dflt;
}
static char *extract_host(edg_wll_ContextParam param,const char *dflt)
{
char *p,*s = NULL;
- if (myenv[param]) s = getenv(myenv[param]);
+ s = mygetenv(param);
if (!s && !dflt) return NULL;
s = strdup(s?s:dflt),
p = strchr(s,':');
char *s = NULL;
double d;
- if (myenv[param]) s = getenv(myenv[param]);
+ s = mygetenv(param);
d = s ? atof(s) : dflt;
t->tv_sec = (long) d;
t->tv_usec = (long) ((d-t->tv_sec)*1e6);
int i;
char *s,*e;
- if (!myenv[param]) return NULL;
- if (!(s = getenv(myenv[param]))) return NULL;
+ if (!(s = mygetenv(param))) return NULL;
for (i=0; i<index && (s=strchr(s,by));i++) s++;
return i==index ? ( (e = strchr(s,by)) ? strndup(s,e-s) : strdup(s))
: NULL;
ctx->p_cert_filename = val ? strdup(val) : NULL;
break;
case EDG_WLL_PARAM_QUERY_SERVER_OVERRIDE:
- if (!val) val = getenv(myenv[param]);
+ if (!val) val = mygetenv(param);
if (!val) val = "no";
ctx->p_query_server_override = !strcasecmp(val,"yes");
break;
break;
case EDG_WLL_PARAM_QUERY_CONNECTIONS:
{
- char *s = getenv(myenv[param]);
+ char *s = mygetenv(param);
if (!val && s) val = atoi(s);
ctx->poolSize = val ? val : EDG_WLL_LOG_CONNECTIONS_DEFAULT;
Revision history:
$Log$
+ Revision 1.4 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.3 2004/07/29 23:21:51 dimeglio
Changed default target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
--- /dev/null
+#Thu Jul 07 08:30:47 CEST 2005
+module.build=306
-#Fri Dec 10 13:27:13 CET 2004
-module.version=0.5.0
-module.build=112
-module.age=3
+
+#already contains fix for #9135 (--ljocha, Jun 29) after glite 1.2 (lb.logger 1.0.2)
+
+module.version = 1.0.3
+module.age = 1
+
assert(eq != NULL);
event_queue_lock_ro(eq);
- ret = eq->head == NULL;
+ ret = (eq->head == NULL);
event_queue_unlock(eq);
return(ret);
if(eq->mark_this && (el->prev == eq->mark_this))
eq->mark_prev = el;
#endif
+
event_queue_unlock(eq);
/* end of critical section */
assert(eq != NULL);
assert(msg != NULL);
- event_queue_lock_ro(eq);
+ event_queue_lock(eq);
el = eq->head;
#if defined(INTERLOGD_EMS)
/* this message is marked for removal, it is first on the queue */
}
if(el == eq->tail) {
/* we are removing the last message */
- eq->tail = NULL;
+ eq->tail = prev;
}
if(el == eq->tail_ems) {
/* we are removing last priority message */
- eq->tail_ems = NULL;
+ eq->tail_ems = prev;
}
eq->mark_this = NULL;
eq_s->tail = NULL;
while(p) {
if(strcmp(p->msg->job_id_s, notif_id) == 0) {
- il_log(LOG_DEBUG, " moving event with notif id %s from %s:%d to %s:%d\n",
- notif_id, eq_s->dest_name,eq_s->dest_port, eq_d ? eq_d->dest_name : "trash",eq_d ? eq_d->dest_port : -1);
+ il_log(LOG_DEBUG, " moving event at offset %d from %s:%d to %s:%d\n",
+ p->msg->offset, eq_s->dest_name,eq_s->dest_port, eq_d ? eq_d->dest_name : "trash",eq_d ? eq_d->dest_port : -1);
+ il_log(LOG_DEBUG, " current: %x, next: %x\n", p, p->prev);
/* remove the message from the source list */
*source_prev = p->prev;
if(eq_d) {
return(-1);
}
- /* get the position in file to be sought */
- if(es->offset)
- last = es->offset;
- else {
+ while(1) { /* try, try, try */
+
+ /* get the position in file to be sought */
+ if(es->offset)
+ last = es->offset;
+ else {
#if !defined(IL_NOTIFICATIONS)
- if(eq_b == eq_l)
- last = es->last_committed_ls;
- else
+ if(eq_b == eq_l)
+ last = es->last_committed_ls;
+ else
#endif
- /* last = min(ls, bs) */
- last = (es->last_committed_bs < es->last_committed_ls) ? es->last_committed_bs : es->last_committed_ls;
- }
-
- il_log(LOG_DEBUG, " setting starting file position to %ld\n", last);
- il_log(LOG_DEBUG, " bytes sent to logging server: %d\n", es->last_committed_ls);
- il_log(LOG_DEBUG, " bytes sent to bookkeeping server: %d\n", es->last_committed_bs);
+ /* last = min(ls, bs) */
+ /* I took the liberty to optimize this,
+ since LS is not used. */
+ /* last = (es->last_committed_bs <
+ es->last_committed_ls) ? es->last_committed_bs :
+ es->last_committed_ls; */
+ last = es->last_committed_bs;
+ }
- /* skip all committed or already enqueued events */
- if(fseek(ef, last, SEEK_SET) < 0) {
- set_error(IL_SYS, errno, "event_store_recover: error setting position for read");
- event_store_unlock(es);
- fclose(ef);
- return(-1);
+ il_log(LOG_DEBUG, " setting starting file position to %ld\n", last);
+ il_log(LOG_DEBUG, " bytes sent to logging server: %d\n", es->last_committed_ls);
+ il_log(LOG_DEBUG, " bytes sent to bookkeeping server: %d\n", es->last_committed_bs);
+
+ if(last > 0) {
+ int c;
+
+ /* skip all committed or already enqueued events */
+ /* be careful - check, if the offset really points to the
+ beginning of event string */
+ if(fseek(ef, last-1, SEEK_SET) < 0) {
+ set_error(IL_SYS, errno, "event_store_recover: error setting position for read");
+ event_store_unlock(es);
+ fclose(ef);
+ return(-1);
+ }
+ /* the last enqueued event MUST end with EVENT_SEPARATOR,
+ even if the offset points at EOF */
+ if((c=fgetc(ef)) != EVENT_SEPARATOR) {
+ /* Houston, we have got a problem */
+ il_log(LOG_WARNING,
+ " file position %ld does not point at the beginning of event string, backing off!\n",
+ last);
+ /* now, where were we? */
+ if(es->offset) {
+ /* next try will be with
+ last_commited_bs */
+ es->offset = 0;
+ } else {
+ /* this is really weird... back off completely */
+ es->last_committed_ls = es->last_committed_bs = 0;
+ }
+ } else {
+ /* OK, break out of the loop */
+ break;
+ }
+ } else {
+ /* this breaks out of the loop, we are starting at
+ * the beginning of file
+ */
+ if(fseek(ef, 0, SEEK_SET) < 0) {
+ set_error(IL_SYS, errno, "event_store_recover: error setting position for read");
+ event_store_unlock(es);
+ fclose(ef);
+ return(-1);
+ }
+ break;
+ }
}
/* enqueue all remaining events */
msg = server_msg_create(event_s, last);
free(event_s);
if(msg == NULL) {
- break;
+ il_log(LOG_ALERT, " event file corrupted! Please move it to quarantine (ie. somewhere else) and restart interlogger.\n");
+ break;
}
msg->es = es;
* 2) es->offset is set only by recover() and next().
* 3) Additional recover can not do much harm.
* 4) And next() is only called by the same thread as sync().
- * => no one is messing with us right now */
+ * 5) use_lock is in place, so no cleanup possible
+ * => no one is messing with us right now */
event_store_lock_ro(es);
if(ret < 0)
ret = -1;
else
- /* somehow we suppose that now es->offset >= offset */
- /* in fact it must be es->offset > offset, anything else would be weird */
- ret = (es->offset > offset) ? 0 : 1;
+ if(es->offset <= offset) {
+ /* Apparently there is something wrong - we are receiving an event
+ * which is beyond the end of file. Someone must have removed the file
+ * when we were not looking. The question is - what should we do with the event?
+ * We have to send it, as this is the only one occasion when we see it.
+ * However, we must not allow the es->offset to be set using this event,
+ * as it would point after the end of file. Sort this out in event_store_next().
+ */
+ ret = 1;
+ } else if(es->offset > offset) {
+ /* we have seen at least this event */
+ ret = 0;
+ }
}
event_store_unlock(es);
return(ret);
int
-event_store_next(struct event_store *es, int len)
+event_store_next(struct event_store *es, long offset, int len)
{
assert(es != NULL);
event_store_lock(es);
- es->offset += len;
+ /* Whoa, be careful now. The es->offset points right after the last enqueued event,
+ * but it may not be the offset of the event WE have just enqueued, because:!
+ * 1) someone could have removed the event file behind our back
+ * 2) the file could have been recover()ed and more events read
+ * In either case the offset should not be moved.
+ */
+ if(es->offset == offset) {
+ es->offset += len;
+ }
event_store_unlock(es);
return(0);
(messsage was just to change the delivery address) */
if(msg->len == 0)
return(0);
-
#endif
/* avoid losing signal to thread */
event_queue_cond_lock(eq);
/* insert new event */
- if(event_queue_insert(eq, msg) < 0)
+ if(event_queue_insert(eq, msg) < 0) {
+ event_queue_cond_unlock(eq);
return(-1);
+ }
/* signal thread that we have a new message */
event_queue_signal(eq);
#endif
/* if there was no error, set the next expected event offset */
- event_store_next(es, msg->ev_len);
+ event_store_next(es, offset, msg->ev_len);
+
/* allow cleanup thread to check on this event_store */
event_store_release(es);
int event_store_recover_all(void);
struct event_store *event_store_find(char *);
int event_store_sync(struct event_store *, long);
-int event_store_next(struct event_store *, int);
+int event_store_next(struct event_store *, long, int);
int event_store_commit(struct event_store *, int, int);
int event_store_recover(struct event_store *);
int event_store_release(struct event_store *);
gettimeofday(&before,NULL);
}
len = write(sock,buf,bufsize);
- while (len <= 0) {
+ if (len <= 0 && errno == EAGAIN) {
FD_ZERO(&fds);
FD_SET(sock,&fds);
- if ((ret=select(sock+1,&fds,NULL,NULL,timeout?&to:NULL)) < 0) {
+ if ((ret=select(sock+1,NULL, &fds ,NULL,timeout?&to:NULL)) < 0) {
edg_wll_ll_log(LOG_ERR,"edg_wll_socket_write(): error selecting socket\n");
SYSTEM_ERROR("select");
- break;
- }
- len = write(sock,buf,bufsize);
+ } else
+ len = write(sock,buf,bufsize);
}
if (timeout) {
gettimeofday(&after,NULL);
queue_thread(void *q)
{
struct event_queue *eq = (struct event_queue *)q;
- int ret, exit, flushing;
+ int ret, exit;
if(init_errors(0) < 0) {
il_log(LOG_ERR, "Error initializing thread specific data, exiting!");
pthread_exit(NULL);
}
+ il_log(LOG_DEBUG, " started new thread for delivery to %s:%d\n", eq->dest_name, eq->dest_port);
+
pthread_cleanup_push(queue_thread_cleanup, q);
event_queue_cond_lock(eq);
ret = 0;
while (event_queue_empty(eq)
#if defined(INTERLOGD_HANDLE_CMD) && defined(INTERLOGD_FLUSH)
- && ((flushing=eq->flushing) != 1)
+ && (eq->flushing != 1)
#endif
) {
ret = event_queue_wait(eq, 0);
event_queue_cond_lock(eq);
/* Check if we are flushing and if we are, report status to master */
- if(flushing == 1) {
+ if(eq->flushing == 1) {
il_log(LOG_DEBUG, " flushing mode detected, reporting status\n");
/* 0 - events waiting, 1 - events sent, < 0 - some error */
eq->flush_result = ret;
{
assert(eq != NULL);
+ event_queue_lock(eq);
+
/* if there is a thread already, just return */
- if(eq->thread_id > 0)
+ if(eq->thread_id > 0) {
+ event_queue_unlock(eq);
return(0);
+ }
/* create the thread itself */
if(pthread_create(&eq->thread_id, NULL, queue_thread, eq) < 0) {
eq->thread_id = 0;
set_error(IL_SYS, errno, "event_queue_create_thread: error creating new thread");
+ event_queue_unlock(eq);
return(-1);
}
/* the thread is never going to be joined */
pthread_detach(eq->thread_id);
+
+ event_queue_unlock(eq);
return(1);
}
${LINK} -o $@ ${LOBJS}
stage: compile
- $(MAKE) install PREFIX=${stagedir}
+ $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes
check:
-echo "No unit tests so far."
install:
mkdir -p ${PREFIX}/include/${globalprefix}/${lbprefix}
mkdir -p ${PREFIX}/lib
- ${INSTALL} -m 644 ${STATICLIB} ${PREFIX}/lib
${INSTALL} -m 644 ${LTLIB} ${PREFIX}/lib
- cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbprefix}
+ if [ x${DOSTAGE} = xyes ]; then \
+ ${INSTALL} -m 644 ${STATICLIB} ${PREFIX}/lib ; \
+ cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbprefix} ; \
+ fi
clean:
Revision history:
$Log$
+ Revision 1.2 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.1 2004/09/22 15:41:24 jskrabal
- sorry! Forgot to add
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
--- /dev/null
+#Wed Apr 13 06:30:39 CEST 2005
+module.build=187
-#Fri Dec 10 13:25:32 CET 2004
-module.version=0.1.0
-module.build=70
-module.age=1
+
+module.version = 1.0.1
+module.age = 1
+
-include Makefile.inc
-include ../Makefile.inc
+default all: compile
+
GLITE_LB_SERVER_WITH_WS=yes
ifeq ($(GLITE_LB_SERVER_WITH_WS),yes)
SUFFIXES = .T
DEBUG:=-g -O0 -Wall
-# not yet
-# -I${voms}/include \
-# -I${gacl}/include \
-# -I/usr/include/libxml2 \
-
-# -DNO_VOMS -DNO_GACL to be removed when voms/gridsite are available
-CFLAGS:= -DNO_VOMS -DNO_GACL \
- ${WS_CFLAGS} ${DEBUG} \
+
+GRIDSITE_CFLAGS = `xml2-config --cflags`
+GRIDSITE_LIBS = -lgridsite_globus `xml2-config --libs`
+
+CFLAGS:= ${WS_CFLAGS} ${DEBUG} \
-DVERSION=\"${version}\" \
-I${stagedir}/include -I${top_srcdir}/src -I. \
-I${expat_prefix}/include \
${COVERAGE_FLAGS} \
-I${mysql_prefix}/include -I${mysql_prefix}/include/mysql \
-I${globus_prefix}/include/${nothrflavour} \
- -I${gridsite_prefix}/include -I${globus_prefix}/include/${nothrflavour}/openssl \
+ $(GRIDSITE_CFLAGS) \
-D_GNU_SOURCE
-
TEST_LIBS:=-L${cppunit}/lib -lcppunit
TEST_INC:=-I${cppunit}/include
-lglobus_gssapi_gsi_${nothrflavour} \
ifneq (${mysql_prefix},/usr)
- myslqlib := -L${mysql_prefix}/lib
+ 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
ifneq (${expat_prefix},/usr)
endif
EXT_LIBS:= -L${ares_prefix}/lib -lares \
- ${myslqlib} -lmysqlclient -lz\
+ ${mysqlib} -lmysqlclient -lz\
${expatlib} -lexpat \
+ ${GRIDSITE_LIBS} \
+ -lvomsc \
${GLOBUS_LIBS}
GSOAP_LIBS:= -L${gsoap_prefix}/lib -lgsoap
glite_lb_bkindex: ${INDEX_OBJS}
${LINK} -o $@ ${INDEX_OBJS} ${COMMON_LIB} ${EXT_LIBS}
-default all: compile
-
compile: glite_lb_bkserverd glite_lb_bkindex glite_lb_proxy
check: compile test.xml test.query
Revision history:
$Log$
+ Revision 1.4 2004/10/18 19:16:09 zsalvet
+ RPM descriptions
+
Revision 1.3 2004/08/05 15:24:32 dimeglio
Changed default target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
--- /dev/null
+#Wed Jun 08 07:24:43 CEST 2005
+module.build=278
Revision history:
$Log$
+ Revision 1.4 2004/10/15 11:03:03 jskrabal
+ - merge fixes
+
Revision 1.3 2004/10/06 08:14:36 dkouril
Support for VOMS and GACL (gridsite) from SCM CVS
- legacy names of GACL routines changed to new ones, which also prevents from
expat_prefix=${with.expat.prefix}
ares_prefix=${with.ares.prefix}
mysql_prefix=${with.mysql.prefix}
+mysql_version=${ext.mysql.version}
cppunit=${with.cppunit.prefix}
gridsite_prefix=${with.gridsite.prefix}
gsoap_prefix=${with.gsoap.prefix}
-#Fri Dec 10 13:29:01 CET 2004
-module.version=0.7.0
-module.build=113
-module.age=4
+
+module.version = 1.0.4
+module.age = 1
+
#include "server_state.h"
#include "purge.h"
+static char *time_to_string(time_t t, char **ptr);
static int handle_specials(edg_wll_Context,time_t *);
#define sizofa(a) (sizeof(a)/sizeof((a)[0]))
int edg_wll_DumpEvents(edg_wll_Context ctx,const edg_wll_DumpRequest *req,edg_wll_DumpResult *result)
{
- char *from_s, *to_s, *stmt, *time_s;
+ char *from_s, *to_s, *stmt, *time_s, *ptr;
char *tmpfname;
time_t start,end;
edg_wll_Stmt q = NULL;
"where u.userid=e.userid "
"and j.jobid = e.jobid "
"and j.dg_jobid like 'https://%|Ss:%d%%' "
- "and arrived > '%|Ss' and arrived <= '%|Ss' "
+ "and arrived > %s and arrived <= %s "
"order by arrived",
ctx->srvName,ctx->srvPort,
from_s,to_s);
}
time(&end);
-/* XXX: get rid of apostrophes returned by edg_wll_TimeToDB() */
- time_s = strdup(edg_wll_TimeToDB(start));
- time_s[strlen(time_s)-1] = 0;
- edg_wll_SetServerState(ctx,EDG_WLL_STATE_DUMP_START,time_s+1);
- free(time_s);
+ time_s = time_to_string(start, &ptr);
+ edg_wll_SetServerState(ctx,EDG_WLL_STATE_DUMP_START,time_s);
+ free(ptr);
- time_s = strdup(edg_wll_TimeToDB(end));
- time_s[strlen(time_s)-1] = 0;
- edg_wll_SetServerState(ctx,EDG_WLL_STATE_DUMP_END,time_s+1);
- free(time_s);
+ time_s = time_to_string(end, &ptr);
+ edg_wll_SetServerState(ctx,EDG_WLL_STATE_DUMP_END,time_s);
+ free(ptr);
result->from = from;
result->to = to;
}
+static char *time_to_string(time_t t, char **ptr) {
+ char *s;
+
+ s = edg_wll_TimeToDB(t);
+ s[strlen(s) - 1] = '\0';
+ *ptr = s;
+
+ return s + 1;
+}
edg_wll_SetError(ctx, errno, NULL);
goto cleanup;
}
- time_s[strlen(time_s)-1] = 0;
/* Format the address
*/
*/
trio_asprintf(&q,
"insert into notif_registrations(notifid,destination,valid,userid,conditions) "
- "values ('%|Ss','%|Ss','%|Ss','%|Ss', '<and>%|Ss</and>')",
- nid_s, addr_s? addr_s: address_override, time_s+1, owner, xml_conds);
+ "values ('%|Ss','%|Ss',%s,'%|Ss', '<and>%|Ss</and>')",
+ nid_s, addr_s? addr_s: address_override, time_s, owner, xml_conds);
if ( edg_wll_ExecStmt(ctx, q, NULL) < 0 )
goto cleanup;
edg_wll_SetError(ctx, errno, "Formating validity time");
goto cleanup;
}
- time_s[strlen(time_s)-1] = 0;
/* Format the address
*/
}
- update_notif(ctx, nid, NULL, addr_s? addr_s: address_override, (const char *)(time_s+1));
+ update_notif(ctx, nid, NULL, addr_s? addr_s: address_override, (const char *)(time_s));
cleanup:
if ( time_s ) free(time_s);
edg_wll_SetError(ctx, errno, "Formating validity time");
goto cleanup;
}
- time_s[strlen(time_s)-1] = 0;
- update_notif(ctx, nid, NULL, NULL, time_s+1);
+ update_notif(ctx, nid, NULL, NULL, time_s);
cleanup:
if ( time_s ) free(time_s);
}
if ( valid )
{
- trio_asprintf(&aux, "%s %svalid='%|Ss'", stmt, dest? ",": "", valid);
+ trio_asprintf(&aux, "%s %svalid=%s", stmt, dest? ",": "", valid);
free(stmt);
stmt = aux;
}
case 1: break;
case -1: if (edg_wll_Error(ctx,NULL,NULL) == EEXIST) {
free(stmt);
- trio_asprintf(&stmt,"update server_state set value = '%|Ss' "
+ trio_asprintf(&stmt,"update server_state set value = %s "
"where prefix = 'https://%|Ss:%d' "
"and name = '%|Ss'",
val,ctx->srvName,ctx->srvPort,name);
char buff[100];
sprintf(buff, "couldn't create temporary server file");
- return edg_wll_SetError(ctx, errno, buff);
+ edg_wll_SetError(ctx, errno, buff);
+ return -1;
}
}
else
* with readers */
trio_asprintf(&stmt,
"insert into events(jobid,event,code,prog,host,time_stamp,usec,arrived,level,userid) "
- "values ('%|Ss',%d,%d,'%|Ss','%|Ss',%s,%d,'%|Ss',%d,'%|Ss')",
+ "values ('%|Ss',%d,%d,'%|Ss','%|Ss',%s,%d,%s,%d,'%|Ss')",
jobid,next,EDG_WLL_EVENT_UNDEF,ssrc,e->any.host,
edg_wll_TimeToDB(e->any.timestamp.tv_sec),e->any.timestamp.tv_usec,
now_s, e->any.level,userid);
-include Makefile.inc
-VPATH=${top_srcdir}/interface
+SUFFIXES = .T
+
+VPATH=${top_srcdir}/src
+AT3=perl -I${top_srcdir}/project ${top_srcdir}/project/at3
+XSLTPROC=xsltproc
+
STAGETO=interface
WSDL=LB.wsdl
-mkdir -p ${PREFIX}/share/doc/${package}-${version}
install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
cd ${top_srcdir}/interface && install -m 644 ${WSDL} ${PREFIX}/${STAGETO}
+# install -m 644 ${WSDL} ${PREFIX}/${STAGETO}
clean:
rm -f *.h
+
+%.xml: %.xml.T
+ rm -f $@
+ ${AT3} $< >$@ || rm -f $@
+ chmod -w $@ >/dev/null
+
+${WSDL}: LB.xml puke-wsdl.xsl
+ ${XSLTPROC} ../src/puke-wsdl.xsl LB.xml >$@
+
+
+LB-ug.xml: LB.xml puke-ug.xsl
+ ${XSLTPROC} ../src/puke-ug.xsl LB.xml >$@
Revision history:
$Log$
- Revision 1.5 2004/07/20 16:08:30 flammer
- Changed incorrect my_... instead of .._template entries for subsystem and component.
-
- Revision 1.4 2004/07/16 16:32:53 flammer
- Added comment where to add language target.
-
- Revision 1.3 2004/07/16 14:56:55 flammer
- Corrected input path of build.properties.
-
- Revision 1.2 2004/07/06 20:43:19 flammer
- Update of configure & targets.
-
- Revision 1.1.1.1 2004/06/18 12:40:17 flammer
- Added general component template.
+ Revision 1.1.1.1.2.1 2005/02/12 01:39:43 glbuild
+ Changed start time
+ Revision 1.1.1.1 2004/11/25 15:20:10 akrenek
+ initial import
-->
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ==============================================
Local private targets
<target name="localinit"
description="Module specific initialization tasks">
+ <copy toDir="${module.project.dir}">
+ <fileset dir="${subsystem.project.dir}">
+ <include name="at3" />
+ <include name="*.T" />
+ <include name="*.pm" />
+ </fileset>
+ </copy>
<antcall target="lbmakefiles" />
</target>
--- /dev/null
+#Sun Apr 03 06:45:36 CEST 2005
+module.build=123
-#Fri Dec 10 13:20:01 CET 2004
-module.version=0.1.0
-module.build=13
-module.age=0
+
+module.version = 1.0.1
+module.age = 1
+
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+
+@@@LANG: wsdl
+<!--
+@@@AUTO
+-->
+
+<service name="LoggingAndBookkeeping"
+ ns="http://glite.org/wsdl/services/lb"
+ prefix="lb">
+
+LB web service interface currently reflects the functionality of legacy
+LB query API.
+
+
+ <types ns="http://glite.org/wsdl/types/lb" prefix="lbt">
+ <flags name="jobFlags">
+ Flags determining which fields of job status should be retrieved.
+ <val name="CLASSADS">Include also long job descriptions (JDL).</val>
+ <val name="CHILDREN">Return list of subjobs of a DAG.</val>
+ <val name="CHILDSTAT">Return state of the subjobs, i.e. apply other flags recursively </val>
+ </flags>
+
+ <enum name="statName">
+ Classification of job states.
+@@@{
+ for my $stat ($status->getTypesOrdered) {
+ my $u = uc $stat;
+ my $c = getTypeComment $status $stat;
+ gen qq{
+! <val name="$u">$c</val>
+};
+ }
+@@@}
+ </enum>
+
+@@@{
+ for my $n ($status->getAllFieldsOrdered) {
+ my $f = selectField $status $n;
+ if ($f->{codes}) {
+ my $n = getName $f;
+ $n = $1.ucfirst $2 while $n =~ /([[:alpha:]]*)_([[:alpha:]]*)/;
+ gen qq{
+! <enum name="$n">
+! Auxiliary type; values of the jobStatus.$n field.
+};
+ for (@{$f->{codes}}) {
+ my $uc = uc $_->{name};
+ gen qq{
+! <val name="$uc">$_->{comment}</val>
+};
+ }
+ gen qq{
+! </enum>
+};
+ }
+ }
+@@@}
+
+<!-- FIXME: list which are arrays in fact are not portable and
+ will not work most likely in this way -->
+
+ <struct name="jobStatus">
+ Status of a job, possibly including subjobs.
+ <elem name="state" type="statName">Status name.</elem>
+@@@{
+ for my $n (getAllFieldsOrdered $status) {
+ selectField $status $n;
+ my $f = getField $status;
+ my $name = getName $f;
+ $name = $1.ucfirst $2 while $name =~ /([[:alpha:]]*)_([[:alpha:]]*)/;
+ my $type = $f->{type};
+ my $list = 'no';
+
+ if ($main::baseTypes{$type}) {
+ $type = eval $main::types{wsdl}->{$main::baseTypes{$type}};
+ $list = 'yes'
+ }
+ elsif ($f->{codes}) {
+ $type = $name;
+ }
+ else {
+ $type = getType $f;
+ }
+
+ my $comment = getComment $f;
+# XXX: currently nothing is "optional" as we don't know from status.T
+ gen qq{
+! <elem name="$name" type="$type" list="$list" optional="no">$comment</elem>
+};
+ }
+@@@}
+ </struct>
+
+ <struct name="tagValue">
+ Value of a single user tag.
+ <elem name="tag" type="xsd:string">Tag name</elem>
+ <elem name="value" type="xsd:string" optional="yes">Tag value</elem>
+ </struct>
+
+ <struct name="timeval">
+ UNIX time representation.
+ <elem name="tvSec" type="xsd:long">Seconds since Jan 1 1970</elem>
+ <elem name="tvUsec" type="xsd:long">Microseconds</elem>
+ </struct>
+
+
+ <struct name="genericFault" fault="yes">
+ Generic SOAP fault, used to deliver any LB errors.
+ May be returned by any of the operations.
+ <elem name="source" type="xsd:string">Source component (module) of the error.</elem>
+ <elem name="code" type="xsd:int">Numeric error code.</elem>
+ <elem name="text" type="xsd:string">Error text corresponding to the code.</elem>
+ <elem name="description" type="xsd:string" optional="yes">Additional description of the error (e.g. filename)</elem>
+ <elem name="reason" type="genericFault" optional="yes">Reason of the error, coming from lower levels.</elem>
+ </struct>
+
+ <simple name="string"/>
+ <simple name="int"/>
+
+ <struct name="queryConditions">
+ An element of outer list of query conditions in job queries.
+ It expresses possibly several conditions (records) on a single job attribute.
+ These conditions are logically OR-ed.
+ <elem name="attr" type="queryAttr"> The job attribute to which the query conditions apply. </elem>
+ <elem name="tagName" type="string" optional="yes"> Name of the queried user tag if attr is USERTAG.</elem>
+ <elem name="statName" type="statName" optional="yes"> Name of the job state to which "attr = TIME" condition refers.</elem>
+ <elem name="record" type="queryRecord" list="yes"> The conditions. </elem>
+ </struct>
+
+ <enum name="queryAttr">
+ Specification of a job attribute in query.
+ <val name="JOBID">A concrete JobId</val>
+ <val name="OWNER">Owner of the job (X509 certificate subject).</val>
+ <val name="STATUS">Status of the job (see statName type).</val>
+ <val name="LOCATION">Where the job is currently handled (hostname).</val>
+ <val name="DESTINATION">Where the job is or was scheduled to be executed.</val>
+ <val name="DONECODE">How the job terminated (see doneCode type)</val>
+ <val name="USERTAG">Value of particular user tag. The tag name has to be specified in queryConditions.tagName.</val>
+ <val name="TIME">When the job entered a particular state. The state has to be specified in queryCondition.statName.</val>
+ <val name="RESUBMITTED">The job was resubmitted.</val>
+ <val name="PARENT">JobId of the job parend (DAG).</val>
+ <val name="EXITCODE">UNIX exit code of the job.</val>
+ </enum>
+
+ <struct name="queryRecord">
+ A single query condition.
+ <elem name="op" type="queryOp"> Relational operator of the condition.</elem>
+ <elem name="value1" type="queryRecValue"> Value to compare the attribute with.</elem>
+ <elem name="value2" type="queryRecValue" optional="yes"> Another value to compare the attribute with (op = WITHIN only).</elem>
+ </struct>
+
+ <enum name="queryOp">
+ Relational operator of query conditions.
+ <val name="EQUAL"> Attribute is equal to the specified value </val>
+ <val name="LESS"> Attribute is less than the specified value or equal </val>
+ <val name="GREATER"> Attribute is greater than the specified value or equal </val>
+ <val name="WITHIN"> Attribute is withing a range (queryRecord.value2 must be specified) </val>
+ <val name="UNEQUAL"> Attribute is not equal to the specified value.</val>
+ </enum>
+
+ <struct name="queryRecValue">
+ A value to compare an attribute with in queries.
+ Exactly one of the elements must be specified.
+ <elem name="i" type="int">Integer.</elem>
+ <elem name="c" type="string">String.</elem>
+ <elem name="t" type="timeval">Timestamp.</elem>
+ </struct>
+
+ </types>
+
+
+
+ <op name="JobStatus">
+ Query state of a single job.
+ <input name="jobid" type="string"> Id of the queried job. </input>
+ <input name="flags" type="jobFlags"> Which data fields to retrieve. </input>
+ <output name="stat" type="jobStatus"> Current state of the job. </output>
+ <fault name="genericFault" type="genericFault"> Any error. </fault>
+ </op>
+
+ <op name="QueryJobs">
+ Retrieve a list of jobs, including their states, based on
+ query conditions.
+ The conditions take the form of a list of lists.
+ Elements of the inner lists refer to a single job attribute, the conditions are or-ed.
+ Elements of the outer list may refer to different job attributes, they are and-ed.
+
+ <input name="conditions" type="queryConditions" list="yes">The query conditions.</input>
+ <input name="flags" type="jobFlags"> Which data fields to retrieve.</input>
+ <output name="jobs" type="string" list="yes"> JobId's of jobs matching the query.</output>
+ <output name="states" type="jobStatus" list="yes"> States of jobs matching the query.</output>
+ <fault name="genericFault" type="genericFault"> Any error. </fault>
+ </op>
+
+ <op name="GetVersion">
+ Return version of the service.
+ <output name="version" type="string">Returned version.</output>
+ <fault name="genericFault" type="genericFault"> Any error. </fault>
+ </op>
+
+ <op name="UserJobs">
+ Simplified query, return all jobs of the authenticated user.
+ <output name="jobs" type="string" list="yes"> JobId's of jobs matching the query.</output>
+ <output name="states" type="jobStatus" list="yes"> States of jobs matching the query.</output>
+ <fault name="genericFault" type="genericFault"> Any error. </fault>
+ </op>
+
+</service>
--- /dev/null
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="">
+
+<xsl:output indent="yes"/>
+
+
+<xsl:template match="/service">
+
+ <chapter>
+ <title><xsl:value-of select="@name"/></title>
+ <sect1>
+ <title>Operations</title>
+ <xsl:apply-templates select="op">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </sect1>
+
+ <sect1>
+ <title>Types</title>
+ <xsl:apply-templates select="types"/>
+ </sect1>
+
+ </chapter>
+
+</xsl:template>
+
+<xsl:template match="input|output|fault">
+ <varlistentry>
+ <term>
+ <type>
+ <xsl:choose>
+ <xsl:when test="@type!='string' and @type!='int'">
+ <link linkend="type:{@type}">
+ <xsl:value-of select="@type "/>
+ </link>
+ </xsl:when>
+ <xsl:otherwise>xsd:<xsl:value-of select="@type "/></xsl:otherwise>
+ </xsl:choose>
+ </type>
+ <parameter><xsl:value-of select="@name"/></parameter>
+ </term>
+ <listitem>
+ <simpara><xsl:value-of select="text()"/></simpara>
+ </listitem>
+ </varlistentry>
+</xsl:template>
+
+<xsl:template match="op" >
+ <sect2 id="op:{@name}">
+ <title><xsl:value-of select="@name"/></title>
+ <para><xsl:value-of select="text()"/></para>
+ <para>
+ Inputs:
+ <xsl:choose>
+ <xsl:when test="count(./input)>0">
+ <variablelist>
+ <xsl:apply-templates select="./input"/>
+ </variablelist>
+ </xsl:when>
+ <xsl:otherwise>N/A</xsl:otherwise>
+ </xsl:choose>
+ </para>
+ <para>
+ Outputs:
+ <variablelist>
+ <xsl:apply-templates select="./output"/>
+ </variablelist>
+ </para>
+ </sect2>
+</xsl:template>
+
+<xsl:template match="types">
+ <xsl:for-each select="flags|enum|struct">
+ <xsl:sort select="@name"/>
+ <sect2 id="type:{@name}">
+ <title> <xsl:value-of select="@name"/> </title>
+ <para> <xsl:value-of select="text()"/> </para>
+ <xsl:choose>
+ <xsl:when test="name(.)='struct'">
+ <para> <emphasis>Structure</emphasis> (sequence complex type in WSDL)</para>
+ <para> Fields: ( <type>type </type> <structfield>name</structfield> description )</para>
+ </xsl:when>
+ <xsl:when test="name(.)='enum'">
+ <para> <emphasis>Enumeration</emphasis> (restriction of xsd:string in WSDL),
+ exactly one of the values must be specified.
+ </para>
+ <para> Values: </para>
+ </xsl:when>
+ <xsl:when test="name(.)='flags'">
+ <para> <emphasis>Flags</emphasis> (sequence of restricted xsd:string in WSDL),
+ any number of values can be specified together.
+ </para>
+ <para> Values: </para>
+ </xsl:when>
+ </xsl:choose>
+ <variablelist>
+ <xsl:for-each select="elem|val">
+ <varlistentry>
+ <term>
+ <xsl:choose>
+ <xsl:when test="name(.)='elem'">
+ <type>
+ <xsl:choose>
+ <xsl:when test="@type!='string' and @type!='int' and @type!='xsd:string' and @type!='xsd:int' and @type!='xsd:boolean' and @type!='xsd:long'">
+ <link linkend="type:{@type}">
+ <xsl:value-of select="@type "/>
+ </link>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="@type "/></xsl:otherwise>
+ </xsl:choose>
+ </type>
+ <!-- <type><xsl:value-of select="@type"/></type> -->
+ <xsl:value-of select="' '"/>
+ <structfield><xsl:value-of select="@name"/></structfield>
+ </xsl:when>
+ <xsl:otherwise>
+ <constant><xsl:value-of select="@name"/></constant>
+ </xsl:otherwise>
+ </xsl:choose>
+ </term>
+ <listitem>
+ <simpara>
+ <xsl:if test="@optional = 'yes'"> (optional) </xsl:if>
+ <xsl:if test="@list = 'yes'"> (multiple occurence) </xsl:if>
+ <xsl:value-of select=" text()"/>
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </xsl:for-each>
+ </variablelist>
+ </sect2>
+ </xsl:for-each>
+</xsl:template>
+
+
+</xsl:stylesheet>
Revision history:
$Log$
+ Revision 1.28 2004/11/29 15:16:26 zsalvet
+ Add ws-interface to checkout/build machinery.
+
Revision 1.27 2004/11/29 13:55:02 akrenek
added dependence on ws-interface
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ===============================================
Public common targets
--- /dev/null
+#Thu Jul 07 08:35:10 CEST 2005
+module.build=305
+
###################################################################
# 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.server-bones.version = HEAD
-org.glite.lb.logger.version = HEAD
+
+
+ org.glite.version = glite_R_1_2_0
+ org.glite.lb.version = glite-lb_R_1_0_5
+
+ org.glite.lb.client-interface.version = glite-lb-client-interface_R_1_0_3
+
+ org.glite.lb.ws-interface.version = glite-lb-ws-interface_R_1_0_1
+
+ org.glite.lb.common.version = glite-lb-common_R_1_1_6
+
+ org.glite.lb.client.version = glite-lb-client_R_1_0_5
+
+ org.glite.lb.server-bones.version = glite-lb-server-bones_R_1_0_1
+
+ org.glite.lb.logger.version = glite-lb-logger_R_1_0_3
+
+ org.glite.lb.server.version = glite-lb-server_R_1_0_3
+
+
@type _common_
- timeval timestamp timestamp of event generation
+ timeval timestamp Time the event was generated.
_alias_ date ULM
- timeval arrived timestamp of event store
+ 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
+ string host Hostname of the machine where the event was generated.
_alias_ host ULM
- int level logging level (system, debug, ...)
+ int level Logging level (in the range from DEBUG to EMERGENCY).
_alias_ lvl ULM
_code_ EMERGENCY emergency
_code_ ALERT alert
_code_ SYSTEM system
_code_ IMPORTANT important
_code_ DEBUG debug
- int priority message priority (yet 0 for asynchronous and 1 for synchronous transfers)
+ int priority Message priority (yet 0 for asynchronous and 1 for synchronous transfers).
_null_ -1
- jobid jobId DataGrid job id of the source job
- string seqcode sequence code assigned to the event
- string user identity (cert. subj.) of the generator
- logsrc source source (WMS component) which generated this event
-# string prog name of program ("EDG WMS" of name of the application)
- string src_instance instance of WMS component (e.g. service communication endpoint)
+ 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 destination hostname
- string dest_instance destination instance
+@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 language
- int result result of the attempt
- _code_ START the sending component has started or is about to start the transfer
- _code_ OK job was sent successfully
- _code_ REFUSED job was refused by the other component
- _code_ FAIL transfer failed for other reason than explicit refusal (eg. network timeout)
- string reason detailed description of transfer, especially reason of failure
+ 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 destination internal jobid
+ string dest_jobid Job id as assigned by the receiving software component.
_optional_
-@type Accepted Accepting job (successful couterpart to Transfer)
- logsrc from where was the job received from
- string from_host sending component hostname
- string from_instance sending component instance
+@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 jobId (Condor, Globus ...) assigned by the receiving component
+ string local_jobid New job id as assigned by the receiving component.
-@type Refused Refusing job (unsuccessful couterpart to Transfer)
- logsrc from where was the job received from
- string from_host sending component hostname
- string from_instance sending component instance
+@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 reason of refusal
-
-@type EnQueued The job has been enqueued in an inter-component queue
- string queue destination queue
- string job job description in receiver language
- int result result of the attempt
- _code_ START the sending component has started or is about to start the transfer
- _code_ OK job was sent successfully
- _code_ REFUSED job was refused by the other component
- _code_ FAIL transfer failed for other reason than explicit refusal (eg. network timeout)
- string reason detailed description of transfer, especially reason of failure
-
-@type DeQueued The job has been dequeued from an inter-component queue
- string queue queue name
- string local_jobid new jobId assigned by the receiving component
-
-@type HelperCall Helper component is called
- string helper_name name of the called component
- string helper_params parameters of the call
- int src_role whether the logging component is called or calling one
- _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 component
- string retval returned data
- int src_role whether the logging component is called or calling one
- _code_ CALLING the logging component is caller
- _code_ CALLED the logging component is callee
-
-@type Running Executable started
- string node worker node where the executable is run
-
-@type Resubmission Result of resubmission decision
- int result result code
- _code_ WILLRESUB will be resubmitted
- _code_ WONTRESUB will not be resubmitted
- string reason reason for the decision
- string tag value of the attribute on which the decision is based
-
-@type Done Execution terminated (normally or abnormally)
- int status_code way of termination
- _code_ OK terminated by itself
- _code_ FAILED disappeared from LRMS
- _code_ CANCELLED cancelled by user request
- string reason reason for the change
- int exit_code process exit code
+ 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 Executable 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).
+ _code_ WILLRESUB The job will be resubmitted.
+ _code_ WONTRESUB The job will not be resubmitted.
+ 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 cancel
- _code_ REQ request acknowledged
- _code_ REFUSE request declined by this component
- _code_ DONE request completed by whole WMS
- _code_ ABORT request refused by whole WMS
- string reason detailed description
+@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 of abort
+@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 why the job was cleared
- _code_ USER user retrieved output sandbox
- _code_ TIMEOUT timed out, resource purge forced
- _code_ NOOUTPUT no output was generated
+ 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 Purge Job is purged from bookkepping server.
-@type Match Matching CE found
- string dest_id Id of the destination CE/queue
+@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 match found yet
- string reason why matching CE cannot be found
+@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
- string ns NetworkServer handling the job
- jobid parent jobid of parent job
+@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 job type
- _code_ SIMPLE simple job
- _code_ DAG dag (containing static set of subjobs)
- _code_ PARTITIONABLE partitionable (may become partitioned)
- _code_ PARTITIONED partitioned (dynamically created dag)
+ 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).
- int nsubjobs number of subjobs
+ int nsubjobs Number of subjobs this job plans to spawn.
_optional_
- string seed seed for subjob id generation
+ string seed Seed for subjob id generation.
_optional_
-@type Chkpt Application-specific checkpoint record
- string tag checkpoint tag
- string classad checkpoint value
+@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 port instance name
- string svc_host hostname
- port svc_port port number
+@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 current job transformation (output of helper)
+@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 tag name
- string value tag value
+@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)
+@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)
+ int permission ACL permission to change (currently only READ).
_null_ -1
- int permission_type type of permission requested ('allow', 'deny')
+ int permission_type Type of permission requested ('allow', 'deny').
_null_ -1
- int operation operation requested to perform with ACL (add, remove)
+ int operation Operation requested to perform with ACL (add, remove).
_null_ -1
-@type Notification Management of notification service
- notifid notifId notification id
- string owner owner
- string dest_host destination host
- port dest_port destination port
- string jobstat job status
+@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).
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"',
}
);
+%baseTypes = (
+ intlist=>'int',
+ strlist=>'string',
+ stslist=>'jobstat',
+ taglist=>'usertag'
+);
+
%toString = (
C=>{
int=>'qq{asprintf(&$dst,"%d",$src);}',
-#Fri Dec 10 13:30:32 CET 2004
-module.version=0.3.0
-module.build=113
-module.age=2
+
+module.version = 1.0.5
+module.age = 1
+
--- /dev/null
+LICENSE file for EGEE Middleware\r
+================================\r
+\r
+Copyright (c) 2004 on behalf of the EU EGEE Project: \r
+The European Organization for Nuclear Research (CERN), \r
+Istituto Nazionale di Fisica Nucleare (INFN), Italy\r
+Datamat Spa, Italy\r
+Centre National de la Recherche Scientifique (CNRS), France\r
+CS Systeme d'Information (CSSI), France\r
+Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden\r
+Universiteit van Amsterdam (UvA), Netherlands\r
+University of Helsinki (UH.HIP), Finlan\r
+University of Bergen (UiB), Norway\r
+Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are\r
+met: \r
+\r
+1. Redistributions of source code must retain the above copyright\r
+notice, this list of conditions and the following disclaimer.\r
+\r
+2. Redistributions in binary form must reproduce the above copyright\r
+notice, this list of conditions and the following disclaimer in the\r
+documentation and/or other materials provided with the distribution.\r
+\r
+3. The end-user documentation included with the redistribution, if\r
+any, must include the following acknowledgment: "This product includes\r
+software developed by The EU EGEE Project (http://cern.ch/eu-egee/)."\r
+Alternatively, this acknowledgment may appear in the software itself, if\r
+and wherever such third-party acknowledgments normally appear.\r
+\r
+4. The names EGEE and the EU EGEE Project must not be\r
+used to endorse or promote products derived from this software without\r
+prior written permission. For written permission, please contact\r
+<email address>.\r
+\r
+5. You are under no obligation whatsoever to provide anyone with any\r
+bug fixes, patches, or upgrades to the features, functionality or\r
+performance of the Software ("Enhancements") that you may develop over\r
+time; however, if you choose to provide your Enhancements to The EU\r
+EGEE Project, or if you choose to otherwise publish or distribute your\r
+Enhancements, in source code form without contemporaneously requiring\r
+end users of The EU EGEE Proejct to enter into a separate written license\r
+agreement for such Enhancements, then you hereby grant The EU EGEE Project\r
+a non-exclusive, royalty-free perpetual license to install, use, copy,\r
+modify, prepare derivative works, incorporate into the EGEE Middleware\r
+or any other computer software, distribute, and sublicense your\r
+Enhancements or derivative works thereof, in binary and source code\r
+form (if any), whether developed by The EU EGEE Project or third parties.\r
+\r
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED\r
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE\r
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\r
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+This software consists of voluntary contributions made by many\r
+individuals on behalf of the EU EGEE Prject. For more information on The\r
+EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on\r
+EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/\r
+\r
+\r
--- /dev/null
+# defaults
+top_srcdir=.
+builddir=build
+top_builddir=${top_srcdir}/${builddir}
+stagedir=.
+distdir=.
+globalprefix=glite
+package=gsoap-plugin
+version=1.0.0
+PREFIX=/opt/glite
+
+glite_location=/opt/glite
+globus_prefix=/opt/globus
+nothrflavour=gcc32
+thrflavour=gcc32pthr
+gsoap_prefix=/opt/gsoap
+gsplugin_version_checking=yes
+
+CC=gcc
+
+-include Makefile.inc
+-include ../Makefile.inc
+
+GSPLUGIN_DEBUG?=no
+
+version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :`
+
+VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/examples
+
+TEST_LIBS:=-L${cppunit}/lib -lcppunit
+TEST_INC:=-I${cppunit}/include
+
+ifeq ($(gsplugin_version_checking),yes)
+ DEBUG:=-g -O0 -Wall -DGSPLUGIN_DEBUG
+else
+ DEBUG:=-g -O0 -Wall
+endif
+
+ifeq ($(GSPLUGIN_VERSION_CHECKING),yes)
+ DEBUG:=${DEBUG} -DCHECK_GSOAP_VERSION
+endif
+
+CFLAGS:= ${DEBUG} \
+ -DVERSION=\"${version}\" \
+ -I${top_srcdir}/src -I${top_srcdir}/interface -I. \
+ -I${stagedir}/include \
+ -I${gsoap_prefix}/include \
+ -I${ares_prefix}/include \
+ -I${globus_prefix}/include/${nothrflavour} \
+ -I${globus_prefix}/include/${nothrflavour}/openssl \
+ ${COVERAGE_FLAGS} -D_GNU_SOURCE -DDATAGRID_EXTENSION
+
+LDFLAGS:=${COVERAGE_FLAGS}
+
+COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
+LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS}
+LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS}
+INSTALL:=libtool --mode=install install
+LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}/lib ${LDFLAGS}
+
+GLOBUS_INC:= -I${globus_prefix}/include/${nothrflavour}
+GLOBUS_LIBS:= -L${globus_prefix}/lib \
+ -lglobus_common_${nothrflavour} \
+ -lglobus_gssapi_gsi_${nothrflavour} \
+
+GSOAP_LIBS:= -L${gsoap_prefix}/lib -lgsoap
+
+EX_LIBS:= ${GLOBUS_LIBS} -L${ares_prefix}/lib -lares
+
+PATCHED_GSOAP_SRC:=stdsoap2_2.6.2.c
+
+HDRS:=glite_gss.h glite_gsplugin.h
+
+GSS_OBJS:=glite_gss.o
+GSS_LOBJS:=${GSS_OBJS:.o=.lo}
+GSS_THROBJS:=${GSS_OBJS:.o=.thr.o}
+GSS_THRLOBJS:=${GSS_OBJS:.o=.thr.lo}
+
+GSS_STATICLIB:=libglite_security_gss_${nothrflavour}.a
+GSS_THRSTATICLIB:=libglite_security_gss_${thrflavour}.a
+GSS_LTLIB:=libglite_security_gss_${nothrflavour}.la
+GSS_THRLTLIB:=libglite_security_gss_${thrflavour}.la
+
+OBJS:=${GSS_OBJS} glite_gsplugin.o
+LOBJS:=${GSS_OBJS:.o=.lo}
+THROBJS:=${GSS_OBJS:.o=.thr.o}
+THRLOBJS:=${GSS_OBJS:.o=.thr.lo}
+
+STATICLIB:=libglite_security_gsoap_plugin_${nothrflavour}.a
+THRSTATICLIB:=libglite_security_gsoap_plugin_${thrflavour}.a
+LTLIB:=libglite_security_gsoap_plugin_${nothrflavour}.la
+THRLTLIB:=libglite_security_gsoap_plugin_${thrflavour}.la
+
+${GSS_STATICLIB}: ${GSS_OBJS}
+ ar crv $@ ${GSS_OBJS}
+ ranlib $@
+
+${GSS_THRSTATICLIB}: ${GSS_THROBJS}
+ ar crv $@ ${GSS_THROBJS}
+ ranlib $@
+
+${GSS_LTLIB}: ${GSS_OBJS}
+ ${LINK} ${version_info} -o $@ ${GSS_LOBJS}
+
+${GSS_THRLTLIB}: ${GSS_THROBJS}
+ ${LINK} ${version_info} -o $@ ${GSS_THRLOBJS}
+
+${STATICLIB}: ${OBJS}
+ ar crv $@ ${OBJS}
+ ranlib $@
+
+${THRSTATICLIB}: ${THROBJS}
+ ar crv $@ ${THROBJS}
+ ranlib $@
+
+${LTLIB}: ${OBJS}
+ ${LINK} ${version_info} -o $@ ${LOBJS}
+
+${THRLTLIB}: ${THROBJS}
+ ${LINK} ${version_info} -o $@ ${THRLOBJS}
+
+default: all
+
+all compile: ${GSS_STATICLIB} ${GSS_LTLIB} ${GSS_THRSTATICLIB} ${GSS_THRLTLIB} ${STATICLIB} ${LTLIB} ${THRSTATICLIB} ${THRLTLIB} examples
+
+check: compile check.gss
+
+check.gss: test_gss
+ # ./test_gss
+ echo test_gss not run automatically util we have got some credentials
+
+test_gss: test_gss.o
+ ${LINKXX} -o $@ test_gss.o ${GSS_LTLIB} ${TEST_LIBS} ${GLOBUS_LIBS} ${EX_LIBS}
+
+test_coverage:
+ -mkdir coverage
+ cd coverage && $(MAKE) -f ../Makefile top_srcdir=../../ COVERAGE_FLAGS="-fprofile-arcs -ftest-coverage" check
+ cd coverage && for i in ${OBJS}; do gcov -o .libs/ $$i ; done
+
+
+examples: soap_gen wscalc_clt_ex wscalc_srv_ex wscalc_srv_ex2
+
+GSOAP_FPREFIX:= GSOAP_
+
+ifeq ($(GSPLUGIN_DEBUG),yes)
+ WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o \
+ stdsoap2.o
+ WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \
+ stdsoap2.o
+ WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \
+ stdsoap2.o
+else
+ WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o
+ WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o
+ WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o
+endif
+
+
+wscalc_clt_ex: ${WSCALC_CLT_OBJS} ${STATICLIB}
+ ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_CLT_OBJS}
+
+wscalc_srv_ex: ${WSCALC_SRV_OBJS} ${STATICLIB}
+ ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV_OBJS}
+
+wscalc_srv_ex2: ${WSCALC_SRV2_OBJS} ${STATICLIB}
+ ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV2_OBJS}
+
+${GSOAP_FPREFIX}H.h ${GSOAP_FPREFIX}C.c ${GSOAP_FPREFIX}Server.c ${GSOAP_FPREFIX}Client.c ${GSOAP_FPREFIX}ServerLib.c ${GSOAP_FPREFIX}ClientLib.c soap_gen: calc.h.S
+ ${gsoap_prefix}/bin/soapcpp2 -c -p ${GSOAP_FPREFIX} ${top_srcdir}/examples/calc.h.S
+
+wscalc_clt_ex.o: wscalc_clt_ex.c
+ ${CC} -c ${CFLAGS} ${GLOBUS_INC} -o $@ $<
+
+stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c
+ ${CC} -c ${CFLAGS} -o $@ $<
+
+doc:
+
+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}/share/doc/${package}-${version}
+ -mkdir -p ${PREFIX}/include/glite/security/${package}
+ ${INSTALL} -m 644 ${GSS_LTLIB} ${GSS_THRLTLIB} ${PREFIX}/lib
+ ${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 ${top_srcdir}/src/${PATCHED_GSOAP_SRC} ${PREFIX}/lib; \
+ fi
+
+clean:
+
+%.o: %.c
+ ${COMPILE} ${GLOBUS_INC} -o $@ -c $<
+
+%.thr.o: %.c
+ ${COMPILE} ${GLOBUS_THR_INC} -o $@ -c $<
+
+test_gss.o: %.o: %.cpp
+ ${CXX} -c ${CFLAGS} ${GLOBUSINC} ${TEST_INC} $<
+
+soap_version.h:
+ ${gsoap_prefix}/bin/soapcpp2 /dev/null
+ perl -ne '$$. == 2 && /.*([0-9])\.([0-9])\.(\S+)\s.*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_MIN_VERSION \"$$3\"\n",$$1,$$2,$$3' soapH.h >$@
+ -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp
+
+glite_gsplugin.o: soap_version.h
+
University of Bergen (UiB), Norway
Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
- Build file for the GLite jp ws-interface component
-
- Authors: Joachim Flammer <Joachim.Flammer@Cern.ch>
- Version info: $Id$
+ Build file for the GLite gSOAP plugin and gss libraries
+
Release: $Name$
Revision history:
- $Log$
- Revision 1.5 2004/07/20 16:08:30 flammer
- Changed incorrect my_... instead of .._template entries for subsystem and component.
-
- Revision 1.4 2004/07/16 16:32:53 flammer
- Added comment where to add language target.
-
- Revision 1.3 2004/07/16 14:56:55 flammer
- Corrected input path of build.properties.
-
- Revision 1.2 2004/07/06 20:43:19 flammer
- Update of configure & targets.
-
- Revision 1.1.1.1 2004/06/18 12:40:17 flammer
- Added general component template.
-
-->
-<project name="ws-interface" default="dist">
-
- <!-- ==============================================
- Builds the GLite jp ws-interface component
- ============================================== -->
+<project name="gsoap-plugin" default="dist">
<!-- =========================================
- Import properties (order is important)
+ Builds the GLite gSOAP plugin and gss libraries
========================================= -->
- <!-- Import baseline properties & user properties -->
+ <!-- =========================================
+ Import properties (order is important)
+ ========================================= -->
+
+ <!-- import baseline & user properties -->
<import file="../org.glite/project/baseline.properties.xml" />
<!-- import component build properties,
<import file="${global.properties.file}" />
<!-- =========================================
- Load dependency property files (order is important)
+ Load dependency property files (order is important)
========================================= -->
<property file="${user.dependencies.file}"/>
<property file="${component.dependencies.file}" />
<property file="${subsystem.dependencies.file}" />
<property file="${global.dependencies.file}"/>
-
- <!-- =========================================
- Load configuration definitions (order is important)
- ========================================= -->
- <import file="${global.configure.options.file}"/>
- <import file="${component.configure.options.file}"/>
<!-- =========================================
- Import task definitions (order is important)
+ Load configure options (order is important)
+ ========================================= -->
+ <import file="${global.configure.options.file}"/>
+ <import file="${component.configure.options.file}"/>
+
+ <!-- =========================================
+ Import task definitions (order is important)
========================================= -->
<import file="${subsystem.taskdefs.file}" />
<import file="${global.taskdefs.file}" />
-
+
<!-- =========================================
Load common targets
========================================= -->
- <!-- Put your language target (java/c++-ant/c++-autotool/perl) here -->
<import file="${global.targets-simple_make.file}" />
-
+
<!-- =========================================
Load version file
========================================= -->
<property file="${module.version.file}"/>
-
+ <property file="${module.build.file}"/>
+
<!-- ==============================================
Local private targets
============================================== -->
<target name="localinit"
description="Module specific initialization tasks">
- <antcall target="lbmakefiles" />
+ <antcall target="secmakefiles" />
</target>
-
+
<target name="localcompile"
description="Module specific compile tasks">
</target>
-
+
<target name="localclean"
description="Module specific cleaning tasks">
</target>
+ <!-- =========================================
+ RPM settings
+ ========================================= -->
+
+ <property name="build.package.summary" value="gSOAP plugin and gss libraries" />
+ <property name="build.package.description" value=" The gSOAP gss plugin" />
+
</project>
--- /dev/null
+//gsoap egeesec schema namespace: urn:calc
+//
+//gsoap egeesec service name: calc
+//gsoap egeesec service port: http://localhost:9999/
+//gsoap egeesec service namespace: urn:calc:wscalc
+
+//gsoap egeesec service method-style: add rpc
+//gsoap egeesec service method-action: add ""
+int wscalc__add(double a, double b, double *result);
+
+//gsoap egeesec service method-style: sub rpc
+//gsoap egeesec service method-action: sub ""
+int wscalc__sub(double a, double b, double *result);
--- /dev/null
+#include <glite_gsplugin.h>
+
+#include "GSOAP_H.h"
+#include "wscalc.nsmap"
+
+static const char *server = "http://localhost:9999/";
+
+int
+main(int argc, char **argv)
+{
+ struct soap soap;
+ double a, b, result;
+ int ret;
+
+
+ if (argc < 4) {
+ fprintf(stderr, "Usage: [add|sub] num num\n");
+ exit(1);
+ }
+
+ soap_init(&soap);
+ soap_register_plugin(&soap, glite_gsplugin);
+
+ a = strtod(argv[2], NULL);
+ b = strtod(argv[3], NULL);
+ switch ( *argv[1] ) {
+ case 'a':
+ ret = soap_call_wscalc__add(&soap, server, "", a, b, &result);
+ break;
+ case 's':
+ ret = soap_call_wscalc__sub(&soap, server, "", a, b, &result);
+ break;
+ default:
+ fprintf(stderr, "Unknown command\n");
+ exit(2);
+ }
+
+ if ( ret ) {
+ fprintf(stderr, "NECO JE V ****\n\n");
+ fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap));
+ soap_print_fault(&soap, stderr);
+ }
+ else printf("result = %g\n", result);
+
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <getopt.h>
+#include <stdsoap2.h>
+#include <glite_gsplugin.h>
+
+#include "GSOAP_H.h"
+#include "wscalc.nsmap"
+
+
+static struct option long_options[] = {
+ { "cert", required_argument, NULL, 'c' },
+ { "key", required_argument, NULL, 'k' },
+ { NULL, 0, NULL, 0 }
+};
+
+void
+usage(const char *me)
+{
+ fprintf(stderr,
+ "usage: %s [option]\n"
+ "\t-c, --cred\t certificate file\n"
+ "\t-k, --key\t private key file\n", me);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct soap soap;
+ glite_gsplugin_Context ctx = NULL;
+ char *name;
+ char *cert, *key;
+ int opt;
+
+
+ cert = key = NULL;
+ name = strrchr(argv[0],'/');
+ if ( name ) name++; else name = argv[0];
+
+ while ((opt = getopt_long(argc, argv, "c:k:", long_options, NULL)) != EOF) {
+ switch (opt) {
+ case 'c': cert = optarg; break;
+ case 'k': key = optarg; break;
+ case '?':
+ default : usage(name); exit(1);
+ }
+ }
+
+ if ( cert || key ) {
+ if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); }
+ ctx->cert_filename = strdup(cert? : key);
+ ctx->key_filename = strdup(key? : cert);
+ }
+
+ soap_init(&soap);
+
+ if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx? : NULL) ) {
+ fprintf(stderr, "Can't register plugin\n");
+ exit(1);
+ }
+
+ if ( soap_bind(&soap, NULL, 9999, 100) < 0 ) {
+ soap_print_fault(&soap, stderr);
+ exit(1);
+ }
+
+ while ( 1 ) {
+ printf("accepting connection\n");
+ if ( soap_accept(&soap) < 0 ) {
+ fprintf(stderr, "soap_accept() failed!!!\n");
+ soap_print_fault(&soap, stderr);
+ fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap));
+ break;
+ }
+
+ printf("serving connection\n");
+ if ( soap_serve(&soap) ) {
+ soap_print_fault(&soap, stderr);
+ fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap));
+ }
+
+ soap_destroy(&soap); /* clean up class instances */
+ soap_end(&soap); /* clean up everything and close socket */
+ }
+ soap_done(&soap); /* close master socket */
+
+ if ( ctx ) glite_gsplugin_free_context(ctx);
+
+ return 0;
+}
+
+int wscalc__add(struct soap *soap, double a, double b, double *result)
+{
+ *result = a + b;
+ return SOAP_OK;
+}
+
+int wscalc__sub(struct soap *soap, double a, double b, double *result)
+{
+ *result = a - b;
+ return SOAP_OK;
+}
--- /dev/null
+#include <stdio.h>
+#include <getopt.h>
+#include <stdsoap2.h>
+#include <glite_gsplugin.h>
+
+#include "GSOAP_H.h"
+#include "wscalc.nsmap"
+
+
+static struct option long_options[] = {
+ { "cert", required_argument, NULL, 'c' },
+ { "key", required_argument, NULL, 'k' },
+ { "port", required_argument, NULL, 'p' },
+ { NULL, 0, NULL, 0 }
+};
+
+void
+usage(const char *me)
+{
+ fprintf(stderr,
+ "usage: %s [option]\n"
+ "\t-p, --port\t listening port\n"
+ "\t-c, --cred\t certificate file\n"
+ "\t-k, --key\t private key file\n", me);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct soap soap;
+ edg_wll_GssStatus gss_code;
+ glite_gsplugin_Context ctx;
+ struct sockaddr_in a;
+ int alen;
+ char *name, *msg;
+ char *subject = NULL;
+ int opt,
+ port = 9999;
+ int sock;
+
+
+ name = strrchr(argv[0],'/');
+ if ( name ) name++; else name = argv[0];
+
+ if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); }
+
+ while ((opt = getopt_long(argc, argv, "c:k:p:", long_options, NULL)) != EOF) {
+ switch (opt) {
+ case 'p': port = atoi(optarg); break;
+ case 'c': ctx->cert_filename = strdup(optarg); break;
+ case 'k': ctx->key_filename = strdup(optarg); break;
+ case '?':
+ default : usage(name); exit(1);
+ }
+ }
+
+ if ( edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename, &ctx->cred, &subject, &gss_code) ) {
+ edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg);
+ fprintf(stderr, "%s\n", msg);
+ free(msg);
+ exit(1);
+ }
+ if (subject) {
+ printf("server running with certificate: %s\n", subject);
+ free(subject);
+ }
+
+ soap_init(&soap);
+
+ if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx) ) {
+ fprintf(stderr, "Can't register plugin\n");
+ exit(1);
+ }
+
+ alen = sizeof(a);
+ if ( (sock = socket(PF_INET,SOCK_STREAM,0)) < 0 ) { perror("socket()"); exit(1); }
+ a.sin_family = AF_INET;
+ a.sin_port = htons(port);
+ a.sin_addr.s_addr = INADDR_ANY;
+ if ( bind(sock, (struct sockaddr *)&a, sizeof(a)) ) { perror("bind()"); exit(1); }
+ if ( listen(sock, 100) ) { perror("listen()"); exit(1); }
+ if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) exit(1);
+
+ bzero((char *) &a, alen);
+
+ while ( 1 ) {
+ int conn;
+
+ printf("accepting connection\n");
+ if ( (conn = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) {
+ close(sock);
+ perror("accept");
+ exit(1);
+ }
+ if ( edg_wll_gss_accept(ctx->cred,conn,ctx->timeout,ctx->connection,&gss_code) ){
+ edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg);
+ fprintf(stderr, "%s\n", msg);
+ free(msg);
+ exit(1);
+ }
+
+ printf("serving connection\n");
+ if ( soap_serve(&soap) ) {
+ soap_print_fault(&soap, stderr);
+ fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap));
+ }
+
+ soap_destroy(&soap); /* clean up class instances */
+ soap_end(&soap); /* clean up everything and close socket */
+ }
+
+ soap_done(&soap); /* close master socket */
+
+ glite_gsplugin_free_context(ctx);
+
+ return 0;
+}
+
+int wscalc__add(struct soap *soap, double a, double b, double *result)
+{
+ *result = a + b;
+ return SOAP_OK;
+}
+
+int wscalc__sub(struct soap *soap, double a, double b, double *result)
+{
+ *result = a - b;
+ return SOAP_OK;
+}
--- /dev/null
+#ifndef __GLITE_GSOAP_PLUGIN_H__
+#define __GLITE_GSOAP_PLUGIN_H__
+
+#include <stdsoap2.h>
+
+#include "glite_gss.h"
+
+#define PLUGIN_ID "GLITE_GSOAP_PLUGIN"
+
+struct _glite_gsplugin_ctx {
+ struct timeval _timeout, *timeout;
+
+ char *error_msg;
+
+ char *key_filename;
+ char *cert_filename;
+
+ edg_wll_GssConnection *connection;
+ gss_cred_id_t cred;
+
+ void *user_data;
+};
+
+typedef struct _glite_gsplugin_ctx *glite_gsplugin_Context;
+
+extern int glite_gsplugin_init_context(glite_gsplugin_Context *);
+extern int glite_gsplugin_free_context(glite_gsplugin_Context);
+extern glite_gsplugin_Context glite_gsplugin_get_context(struct soap *);
+extern void *glite_gsplugin_get_udata(struct soap *);
+extern void glite_gsplugin_set_udata(struct soap *, void *);
+
+extern void glite_gsplugin_set_timeout(glite_gsplugin_Context, struct timeval const *);
+
+extern int glite_gsplugin(struct soap *, struct soap_plugin *, void *);
+extern char *glite_gsplugin_errdesc(struct soap *);
+
+#endif
--- /dev/null
+#ifndef __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__
+#define __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__
+
+#ident "$Header$"
+
+#include <gssapi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ EDG_WLL_GSS_OK = 0, /* no GSS errors */
+ EDG_WLL_GSS_ERROR_GSS = -1, /* GSS specific error, call edg_wll_get_gss_error() for details */
+ EDG_WLL_GSS_ERROR_TIMEOUT = -2, /* Timeout */
+ EDG_WLL_GSS_ERROR_EOF = -3, /* EOF occured */
+ EDG_WLL_GSS_ERROR_ERRNO = -4, /* System error. See errno */
+ EDG_WLL_GSS_ERROR_HERRNO = -5 /* Resolver error. See h_errno */
+};
+
+typedef struct _edg_wll_GssConnection {
+ gss_ctx_id_t context;
+ int sock;
+ char *buffer;
+ size_t bufsize;
+} edg_wll_GssConnection;
+
+typedef struct _edg_wll_GssStatus {
+ OM_uint32 major_status;
+ OM_uint32 minor_status;
+} edg_wll_GssStatus;
+
+/* XXX Support anonymous connections. Are we able/required to support
+ * anonymous servers as well. */
+
+int
+edg_wll_gss_acquire_cred_gsi(char *cert_file,
+ char *key_file,
+ gss_cred_id_t *cred,
+ char **name,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_connect(gss_cred_id_t cred,
+ char const *hostname,
+ int port,
+ struct timeval *timeout,
+ edg_wll_GssConnection *connection,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_accept(gss_cred_id_t cred,
+ int sock,
+ struct timeval *timeout,
+ edg_wll_GssConnection *connection,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_read(edg_wll_GssConnection *connection,
+ void *buf,
+ size_t bufsize,
+ struct timeval *timeout,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_write(edg_wll_GssConnection *connection,
+ const void *buf,
+ size_t bufsize,
+ struct timeval *timeout,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_read_full(edg_wll_GssConnection *connection,
+ void *buf,
+ size_t bufsize,
+ struct timeval *timeout,
+ size_t *total,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_write_full(edg_wll_GssConnection *connection,
+ const void *buf,
+ size_t bufsize,
+ struct timeval *timeout,
+ size_t *total,
+ edg_wll_GssStatus* gss_code);
+
+int
+edg_wll_gss_watch_creds(const char * proxy_file,
+ time_t * proxy_mtime);
+
+int
+edg_wll_gss_get_error(edg_wll_GssStatus* gss_code,
+ const char *prefix,
+ char **errmsg);
+
+int
+edg_wll_gss_close(edg_wll_GssConnection *connection,
+ struct timeval *timeout);
+
+int
+edg_wll_gss_reject(int sock);
+
+int
+edg_wll_gss_oid_equal(const gss_OID a,
+ const gss_OID b);
+
+/*
+int
+edg_wll_gss_get_name(gss_cred_id_t cred, char **name);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ */
--- /dev/null
+#Thu Jun 02 03:37:13 CEST 2005
+module.build=21
<?xml version="1.0" encoding="UTF-8" ?>
<!--
- 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
+ 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
- Configuration options for the gLite JP Primary module
+ Configuration options for the GLite gSOAP plugin and gss libraries
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
-
Revision history:
- $Log$
- Revision 1.2 2004/10/15 12:19:28 akrenek
- build with gsoap 2.7 too
- Revision 1.1.1.1 2004/10/15 09:49:24 akrenek
+
-->
<!-- ======================================================
Define extra properties here ...
====================================================== -->
- <project name="LB Common configuration options">
- <target name="lbmakefiles">
+ <project name="gSOAP plugin configuration options">
+ <target name="secmakefiles">
<exec executable="ln" failonerror="true">
<arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
</exec>
PREFIX=${install.dir}
version=${module.version}
glite_location=${with.glite.location}
-globus_prefix=${with.globus.prefix}
-expat_prefix=${with.expat.prefix}
ares_prefix=${with.ares.prefix}
-gsoap_prefix=${with.gsoap.prefix}
+globus_prefix=${with.globus.prefix}
thrflavour=${with.globus.thr.flavor}
nothrflavour=${with.globus.nothr.flavor}
cppunit=${with.cppunit.prefix}
-jpproject=${subsystem.project.dir}
-project=${component.project.dir}
+gsoap_prefix=${with.gsoap.prefix}
+gsplugin_version_checking=${gsplugin.version.checking}
</echo>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
- 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
+ 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 build properties file for the gLite JP Common component
-
- Authors: Ales Krenek <ljocha@ics.muni.cz>
- Version info: $Id$
- Release: $Name$
+ Common build properties file for the GLite gSOAP plugin and gss libraries
Revision history:
- $Log$
- Revision 1.1.1.1 2004/10/15 09:49:02 akrenek
+
-->
-<project name="JP Common component common properties">
+<project name="GLite gSOAP plugin component common properties">
<!-- Include build properties to allow overwriting
of properties for subsystem -->
- <property file="project/build.properties" />
+ <property file="build.properties" />
<!-- ======================================================
Define corresponding subsystem properties
====================================================== -->
<!-- Subsystem name -->
- <property name="subsystem.name" value="${jp.subsystem.name}"/>
+ <property name="subsystem.name" value="${security.subsystem.name}"/>
<!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${jp.subsystem.prefix}"/>
+ <property name="subsystem.prefix" value="${security.subsystem.prefix}"/>
<!-- ======================================================
Define component properties
====================================================== -->
<!-- Component name prefix -->
- <property name="component.prefix" value="common" />
+ <property name="component.prefix" value="gsoap-plugin" />
<!-- ======================================================
Define general component properties
build
build.properties
properties.xml
-configure.properties.xml
+configure-options.xml
.cvsignore
.project
.cdtproject
--- /dev/null
+module.version=1.1.1
+module.age=0
--- /dev/null
+#include <stdio.h>
+#include <assert.h>
+#include <signal.h>
+#include <stdsoap2.h>
+
+#include "soap_version.h"
+#include "glite_gsplugin.h"
+
+#ifdef GSPLUGIN_DEBUG
+# define pdprintf(s) printf s
+#else
+# define pdprintf(s)
+#endif
+
+typedef struct _int_plugin_data_t {
+ glite_gsplugin_Context ctx; /**< data used for connection etc. */
+ int def; /**< is the context created by plugin? */
+} int_plugin_data_t;
+
+static const char plugin_id[] = PLUGIN_ID;
+
+static void glite_gsplugin_delete(struct soap *, struct soap_plugin *);
+static int glite_gsplugin_copy(struct soap *, struct soap_plugin *, struct soap_plugin *);
+
+static size_t glite_gsplugin_recv(struct soap *, char *, size_t);
+static int glite_gsplugin_send(struct soap *, const char *, size_t);
+static int glite_gsplugin_connect(struct soap *, const char *, const char *, int);
+static int glite_gsplugin_close(struct soap *);
+static int glite_gsplugin_accept(struct soap *, int, struct sockaddr *, int *);
+
+
+int
+glite_gsplugin_init_context(glite_gsplugin_Context *ctx)
+{
+ glite_gsplugin_Context out = (glite_gsplugin_Context) malloc(sizeof(*out));
+ if (!out) return ENOMEM;
+
+ memset(out, 0, sizeof(*out));
+ out->cred = GSS_C_NO_CREDENTIAL;
+
+ /* XXX: some troubles with glite_gss and blocking calls!
+ out->timeout.tv_sec = 10000;
+ */
+
+ out->timeout = NULL;
+ *ctx = out;
+
+ return 0;
+}
+
+int
+glite_gsplugin_free_context(glite_gsplugin_Context ctx)
+{
+ OM_uint32 ms;
+
+ if ( ctx->cred != GSS_C_NO_CREDENTIAL ) gss_release_cred(&ms, &ctx->cred);
+ if ( ctx->connection ) {
+ if ( ctx->connection->context != GSS_C_NO_CONTEXT )
+ edg_wll_gss_close(ctx->connection, NULL);
+ free(ctx->connection);
+ }
+ free(ctx->error_msg);
+ free(ctx->key_filename);
+ free(ctx->cert_filename);
+ free(ctx);
+
+ return 0;
+}
+
+glite_gsplugin_Context
+glite_gsplugin_get_context(struct soap *soap)
+{
+ return ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+}
+
+void *
+glite_gsplugin_get_udata(struct soap *soap)
+{
+ int_plugin_data_t *pdata;
+
+ pdata = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id);
+ assert(pdata);
+ return pdata->ctx->user_data;
+}
+
+void
+glite_gsplugin_set_udata(struct soap *soap, void *d)
+{
+ int_plugin_data_t *pdata;
+
+ pdata = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id);
+ assert(pdata);
+ pdata->ctx->user_data = d;
+}
+
+void glite_gsplugin_set_timeout(glite_gsplugin_Context ctx, struct timeval const *to)
+{
+ if (to) {
+ ctx->_timeout = *to;
+ ctx->timeout = &ctx->_timeout;
+ }
+ else ctx->timeout = NULL;
+}
+
+
+int
+glite_gsplugin(struct soap *soap, struct soap_plugin *p, void *arg)
+{
+ int_plugin_data_t *pdata = malloc(sizeof(int_plugin_data_t));
+
+ pdprintf(("GSLITE_GSPLUGIN: initializing gSOAP plugin\n"));
+ if ( !pdata ) return ENOMEM;
+ if ( arg ) {
+ pdprintf(("GSLITE_GSPLUGIN: Context is given\n"));
+ pdata->ctx = arg;
+ pdata->def = 0;
+ }
+ else {
+ edg_wll_GssStatus gss_code;
+ char *subject = NULL;
+
+ pdprintf(("GSLITE_GSPLUGIN: Creating default context\n"));
+ if ( glite_gsplugin_init_context((glite_gsplugin_Context*)&(pdata->ctx)) ) {
+ free(pdata);
+ return ENOMEM;
+ }
+ if ( edg_wll_gss_acquire_cred_gsi(NULL, NULL, &pdata->ctx->cred, &subject, &gss_code) ) {
+ /* XXX: Let user know, that cred. load failed. Somehow...
+ */
+ glite_gsplugin_free_context(pdata->ctx);
+ return EINVAL;
+ }
+ pdprintf(("GSLITE_GSPLUGIN: server running with certificate: %s\n", subject));
+ free(subject);
+ }
+
+ p->id = plugin_id;
+ p->data = pdata;
+ p->fdelete = glite_gsplugin_delete;
+ p->fcopy = glite_gsplugin_copy;
+
+ soap->fconnect = glite_gsplugin_connect;
+ soap->fclose = glite_gsplugin_close;
+#if GSOAP_VERSION >= 20700
+ soap->fclosesocket = glite_gsplugin_close;
+#endif
+ soap->faccept = glite_gsplugin_accept;
+ soap->fsend = glite_gsplugin_send;
+ soap->frecv = glite_gsplugin_recv;
+
+
+ return SOAP_OK;
+}
+
+
+char *glite_gsplugin_errdesc(struct soap *soap)
+{
+ glite_gsplugin_Context ctx;
+
+ ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+ if ( ctx ) return ctx->error_msg;
+
+ return NULL;
+}
+
+
+
+static int
+glite_gsplugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src)
+{
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_copy()\n"));
+ /* Should be the copy code here?
+ */
+ return ENOSYS;
+}
+
+static void
+glite_gsplugin_delete(struct soap *soap, struct soap_plugin *p)
+{
+ int_plugin_data_t *d = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id);
+
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_delete()\n"));
+ if ( d->def ) {
+ OM_uint32 ms;
+
+ glite_gsplugin_close(soap);
+ if (d->ctx->cred != GSS_C_NO_CREDENTIAL) gss_release_cred(&ms, &d->ctx->cred);
+ free(d->ctx->error_msg);
+ }
+ free(d);
+}
+
+
+static int
+glite_gsplugin_connect(
+ struct soap *soap,
+ const char *endpoint,
+ const char *host,
+ int port)
+{
+ glite_gsplugin_Context ctx;
+ edg_wll_GssStatus gss_stat;
+ int ret;
+
+
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect()\n"));
+#if defined(CHECK_GSOAP_VERSION) && GSOAP_VERSION <= 20700
+ if ( GSOAP_VERSION < 20700
+ || (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");
+ return ENOSYS;
+ }
+#else
+# warning "gSOAP version checking is switched off!"
+#endif
+
+ ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+
+ if ( ctx->cred == GSS_C_NO_CREDENTIAL ) {
+ pdprintf(("GSLITE_GSPLUGIN: loading credentials\n"));
+ ret = edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename,
+ &ctx->cred, NULL, &gss_stat);
+ if ( ret ) {
+ edg_wll_gss_get_error(&gss_stat, "failed to load GSI credentials",
+ &ctx->error_msg);
+ goto err;
+ }
+ }
+
+ if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) return errno;
+ ret = edg_wll_gss_connect(ctx->cred,
+ host, port,
+ ctx->timeout,
+ ctx->connection, &gss_stat);
+ if ( ret ) {
+ free(ctx->connection);
+ ctx->connection = NULL;
+ edg_wll_gss_get_error(&gss_stat, "edg_wll_gss_connect()", &ctx->error_msg);
+ goto err;
+ }
+
+
+err:
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect() error!\n"));
+ switch ( ret ) {
+ 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;
+ }
+
+ return ret;
+}
+
+/** It is called in soap_closesocket()
+ *
+ * return like errno value
+ */
+static int
+glite_gsplugin_close(struct soap *soap)
+{
+ glite_gsplugin_Context ctx;
+ int ret = SOAP_OK;
+
+
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_close()\n"));
+ ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+ if ( ctx->connection ) {
+ if ( ctx->connection->context != GSS_C_NO_CONTEXT) {
+ pdprintf(("GSLITE_GSPLUGIN: closing gss connection\n"));
+ ret = edg_wll_gss_close(ctx->connection, ctx->timeout);
+ }
+ ctx->connection->context = GSS_C_NO_CONTEXT;
+ }
+
+ return ret;
+}
+
+
+static int
+glite_gsplugin_accept(struct soap *soap, int s, struct sockaddr *a, int *n)
+{
+ glite_gsplugin_Context ctx;
+ edg_wll_GssStatus gss_code;
+ int conn;
+
+
+ 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;
+ if ( !ctx->connection
+ && !(ctx->connection = malloc(sizeof(*ctx->connection))) ) return -1;
+ 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);
+ return -1;
+ }
+
+ return conn;
+}
+
+static size_t
+glite_gsplugin_recv(struct soap *soap, char *buf, size_t bufsz)
+{
+ glite_gsplugin_Context ctx;
+ edg_wll_GssStatus gss_code;
+ int len;
+
+
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_recv()\n"));
+ ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+ if ( ctx->error_msg ) { free(ctx->error_msg); ctx->error_msg = NULL; }
+
+ if ( ctx->connection->context == GSS_C_NO_CONTEXT ) {
+ soap->errnum = ENOTCONN;
+ /* XXX: glite_gsplugin_send() returns SOAP_EOF on errors
+ */
+ return 0;
+ }
+
+ len = edg_wll_gss_read(ctx->connection, buf, bufsz,
+ ctx->timeout,
+ &gss_code);
+
+ switch ( len ) {
+ case EDG_WLL_GSS_OK:
+ break;
+
+ case EDG_WLL_GSS_ERROR_GSS:
+ edg_wll_gss_get_error(&gss_code, "receving WS request",
+ &ctx->error_msg);
+ soap->errnum = ENOTCONN;
+ return 0;
+
+ case EDG_WLL_GSS_ERROR_ERRNO:
+ ctx->error_msg = strdup("edg_wll_gss_read()");
+ soap->errnum = errno;
+ return 0;
+
+ case EDG_WLL_GSS_ERROR_TIMEOUT:
+ soap->errnum = ETIMEDOUT;
+ return 0;
+
+ case EDG_WLL_GSS_ERROR_EOF:
+ soap->errnum = ENOTCONN;
+ return 0;
+
+ /* default: fallthrough */
+ }
+
+ return len;
+}
+
+static int
+glite_gsplugin_send(struct soap *soap, const char *buf, size_t bufsz)
+{
+ glite_gsplugin_Context ctx;
+ edg_wll_GssStatus gss_code;
+ struct sigaction sa, osa;
+ size_t total = 0;
+ int ret;
+
+
+ pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_send()\n"));
+ ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx;
+ /* XXX: check whether ctx is initialized
+ * i.e. ctx->connection != NULL
+ */
+ if ( ctx->error_msg ) { free(ctx->error_msg); ctx->error_msg = NULL; }
+ if ( ctx->connection->context == GSS_C_NO_CONTEXT ) {
+ soap->errnum = ENOTCONN;
+ return SOAP_EOF;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ assert(sa.sa_handler == NULL);
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, &osa);
+
+ ret = edg_wll_gss_write_full(ctx->connection,
+ (void*)buf, bufsz, ctx->timeout, &total, &gss_code);
+
+ sigaction(SIGPIPE, &osa, NULL);
+
+ switch ( ret ) {
+ case EDG_WLL_GSS_OK:
+ break;
+
+ case EDG_WLL_GSS_ERROR_TIMEOUT:
+ ctx->error_msg = strdup("glite_gsplugin_send()");
+ soap->errnum = ETIMEDOUT;
+ return SOAP_EOF;
+
+ case EDG_WLL_GSS_ERROR_ERRNO:
+ if ( errno == EPIPE ) {
+ ctx->error_msg = strdup("glite_gsplugin_send()");
+ soap->errnum = ENOTCONN;
+ }
+ else {
+ ctx->error_msg = strdup("glite_gsplugin_send()");
+ soap->errnum = errno;
+ }
+ return SOAP_EOF;
+
+ case EDG_WLL_GSS_ERROR_GSS:
+ case EDG_WLL_GSS_ERROR_EOF:
+ default:
+ ctx->error_msg = strdup("glite_gsplugin_send()");
+ soap->errnum = ENOTCONN;
+ return SOAP_EOF;
+ }
+
+ return SOAP_OK;
+}
+
--- /dev/null
+#ident "$Header$"
+
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <ares.h>
+#include <errno.h>
+
+#include "glite_gss.h"
+
+#define tv_sub(a,b) {\
+ (a).tv_usec -= (b).tv_usec;\
+ (a).tv_sec -= (b).tv_sec;\
+ if ((a).tv_usec < 0) {\
+ (a).tv_sec--;\
+ (a).tv_usec += 1000000;\
+ }\
+}
+
+struct asyn_result {
+ struct hostent *ent;
+ int err;
+};
+
+static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after)
+{
+ (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec);
+ (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec);
+ while ( (*timeout).tv_usec < 0) {
+ (*timeout).tv_sec--;
+ (*timeout).tv_usec += 1000000;
+ }
+ if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1);
+ else return(0);
+}
+
+/* ares callback handler for ares_gethostbyname() */
+static void callback_handler(void *arg, int status, struct hostent *h) {
+ struct asyn_result *arp = (struct asyn_result *) arg;
+
+ switch (status) {
+ case ARES_SUCCESS:
+ if (h && h->h_addr_list[0]) {
+ arp->ent->h_addr_list =
+ (char **) malloc(2 * sizeof(char *));
+ if (arp->ent->h_addr_list == NULL) {
+ arp->err = NETDB_INTERNAL;
+ break;
+ }
+ arp->ent->h_addr_list[0] =
+ malloc(sizeof(struct in_addr));
+ if (arp->ent->h_addr_list[0] == NULL) {
+ free(arp->ent->h_addr_list);
+ arp->err = NETDB_INTERNAL;
+ break;
+ }
+ memcpy(arp->ent->h_addr_list[0], h->h_addr_list[0],
+ sizeof(struct in_addr));
+ arp->ent->h_addr_list[1] = NULL;
+ arp->err = NETDB_SUCCESS;
+ } else {
+ arp->err = NO_DATA;
+ }
+ break;
+ case ARES_EBADNAME:
+ case ARES_ENOTFOUND:
+ arp->err = HOST_NOT_FOUND;
+ break;
+ case ARES_ENOTIMP:
+ arp->err = NO_RECOVERY;
+ break;
+ case ARES_ENOMEM:
+ case ARES_EDESTRUCTION:
+ default:
+ arp->err = NETDB_INTERNAL;
+ break;
+ }
+}
+
+static void free_hostent(struct hostent *h){
+ int i;
+
+ if (h) {
+ if (h->h_name) free(h->h_name);
+ if (h->h_aliases) {
+ for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]);
+ free(h->h_aliases);
+ }
+ if (h->h_addr_list) {
+ for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]);
+ free(h->h_addr_list);
+ }
+ free(h);
+ }
+}
+
+static int asyn_gethostbyname(char **addrOut, char const *name, struct timeval *timeout) {
+ struct asyn_result ar;
+ ares_channel channel;
+ int nfds;
+ fd_set readers, writers;
+ struct timeval tv, *tvp;
+ struct timeval start_time,check_time;
+
+/* start timer */
+ gettimeofday(&start_time,0);
+
+/* ares init */
+ if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL);
+ ar.ent = (struct hostent *) calloc (sizeof(*ar.ent),1);
+
+/* query DNS server asynchronously */
+ ares_gethostbyname(channel, name, AF_INET, callback_handler,
+ (void *) &ar);
+
+/* wait for result */
+ while (1) {
+ FD_ZERO(&readers);
+ FD_ZERO(&writers);
+ nfds = ares_fds(channel, &readers, &writers);
+ if (nfds == 0)
+ break;
+
+ gettimeofday(&check_time,0);
+ if (decrement_timeout(timeout, start_time, check_time)) {
+ ares_destroy(channel);
+ free_hostent(ar.ent);
+ return(TRY_AGAIN);
+ }
+ start_time = check_time;
+
+ tvp = ares_timeout(channel, timeout, &tv);
+
+ switch ( select(nfds, &readers, &writers, NULL, tvp) ) {
+ case -1: if (errno != EINTR) {
+ ares_destroy(channel);
+ free_hostent(ar.ent);
+ return NETDB_INTERNAL;
+ } else
+ continue;
+ case 0:
+ FD_ZERO(&readers);
+ FD_ZERO(&writers);
+ /* fallthrough */
+ default: ares_process(channel, &readers, &writers);
+ }
+ }
+
+ ares_destroy(channel);
+
+ if (ar.err == NETDB_SUCCESS) {
+ *addrOut = malloc(sizeof(struct in_addr));
+ memcpy(*addrOut,ar.ent->h_addr_list[0], sizeof(struct in_addr));
+ free_hostent(ar.ent);
+ }
+ return(ar.err);
+}
+
+static int
+do_connect(int *s, char const *hostname, int port, struct timeval *timeout)
+{
+ int sock;
+ struct timeval before,after,to;
+ struct sockaddr_in a;
+ int sock_err;
+ socklen_t err_len;
+ char *addr;
+ int h_errno;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) return EDG_WLL_GSS_ERROR_ERRNO;
+
+ if (timeout) {
+ int flags = fcntl(sock, F_GETFL, 0);
+ if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0)
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ gettimeofday(&before,NULL);
+ }
+
+ if (timeout) {
+ switch (h_errno = asyn_gethostbyname(&addr, hostname, timeout)) {
+ case NETDB_SUCCESS:
+ memset(&a,0,sizeof a);
+ a.sin_family = AF_INET;
+ memcpy(&a.sin_addr.s_addr,addr,sizeof a.sin_addr.s_addr);
+ a.sin_port = htons(port);
+ free(addr);
+ break;
+ case TRY_AGAIN:
+ close(sock);
+ return EDG_WLL_GSS_ERROR_TIMEOUT;
+ case NETDB_INTERNAL:
+ /* fall through */
+ default:
+ close(sock);
+ /* h_errno may be thread safe with Linux pthread libs,
+ * but such an assumption is not portable
+ */
+ errno = h_errno;
+ return EDG_WLL_GSS_ERROR_HERRNO;
+ }
+ } else {
+ struct hostent *hp;
+
+ hp = gethostbyname(hostname);
+ if (hp == NULL) {
+ close(sock);
+ errno = h_errno;
+ return EDG_WLL_GSS_ERROR_HERRNO;
+ }
+
+ memset(&a,0,sizeof a);
+ a.sin_family = AF_INET;
+ memcpy(&a.sin_addr.s_addr, hp->h_addr_list[0], sizeof(a.sin_addr.s_addr));
+ a.sin_port = htons(port);
+ }
+
+ if (connect(sock,(struct sockaddr *) &a,sizeof a) < 0) {
+ if (timeout && errno == EINPROGRESS) {
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ memcpy(&to,timeout,sizeof to);
+ gettimeofday(&before,NULL);
+ switch (select(sock+1,NULL,&fds,NULL,&to)) {
+ case -1: close(sock);
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ case 0: close(sock);
+ return EDG_WLL_GSS_ERROR_TIMEOUT;
+ }
+ gettimeofday(&after,NULL);
+ tv_sub(after,before);
+ tv_sub(*timeout,after);
+
+ err_len = sizeof sock_err;
+ if (getsockopt(sock,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) {
+ close(sock);
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ }
+ if (sock_err) {
+ close(sock);
+ errno = sock_err;
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ }
+ }
+ else {
+ close(sock);
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ }
+ }
+
+ *s = sock;
+ return 0;
+}
+
+static int
+send_token(int sock, void *token, size_t token_length, struct timeval *to)
+{
+ size_t num_written = 0;
+ ssize_t count;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
+
+
+ ret = 0;
+ while(num_written < token_length) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) {
+ case 0: ret = EDG_WLL_GSS_ERROR_TIMEOUT;
+ goto end;
+ break;
+ case -1: ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ break;
+ }
+
+ count = write(sock, ((char *)token) + num_written,
+ token_length - num_written);
+ if(count < 0) {
+ if(errno == EINTR)
+ continue;
+ else {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ }
+ num_written += count;
+ }
+
+end:
+ if (to) {
+ gettimeofday(&after,NULL);
+ tv_sub(after,before);
+ tv_sub(*to,after);
+ if (to->tv_sec < 0) {
+ to->tv_sec = 0;
+ to->tv_usec = 0;
+ }
+ }
+
+ return ret;
+}
+
+static int
+recv_token(int sock, void **token, size_t *token_length, struct timeval *to)
+{
+ ssize_t count;
+ char buf[4098];
+ char *t = NULL;
+ char *tmp;
+ size_t tl = 0;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
+
+ ret = 0;
+ do {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) {
+ case 0:
+ ret = EDG_WLL_GSS_ERROR_TIMEOUT;
+ goto end;
+ break;
+ case -1:
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ break;
+ }
+
+ count = read(sock, buf, sizeof(buf));
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ }
+ if (count == 0 && tl == 0 && errno == 0)
+ return EDG_WLL_GSS_ERROR_EOF;
+ tmp=realloc(t, tl + count);
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ return EDG_WLL_GSS_ERROR_ERRNO;
+ }
+ t = tmp;
+ memcpy(t + tl, buf, count);
+ tl += count;
+ } while (count == sizeof(buf));
+
+end:
+ if (to) {
+ gettimeofday(&after,NULL);
+ tv_sub(after,before);
+ tv_sub(*to,after);
+ if (to->tv_sec < 0) {
+ to->tv_sec = 0;
+ to->tv_usec = 0;
+ }
+ }
+
+ if (ret == 0) {
+ *token = t;
+ *token_length = tl;
+ } else
+ free(t);
+
+ return ret;
+}
+
+static int
+create_proxy(char *cert_file, char *key_file, char **proxy_file)
+{
+ char buf[4096];
+ int in, out;
+ char *name = NULL;
+ int ret, len;
+
+ *proxy_file = NULL;
+
+ asprintf(&name, "%s/%d.lb.XXXXXX", P_tmpdir, getpid());
+
+ out = mkstemp(name);
+ if (out < 0)
+ return EDG_WLL_GSS_ERROR_ERRNO;
+
+ in = open(cert_file, O_RDONLY);
+ if (in < 0) {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ while ((ret = read(in, buf, sizeof(buf))) > 0) {
+ len = write(out, buf, ret);
+ if (len != ret) {
+ ret = -1;
+ break;
+ }
+ }
+ close(in);
+ if (ret < 0) {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+
+ in = open(key_file, O_RDONLY);
+ if (in < 0) {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ while ((ret = read(in, buf, sizeof(buf))) > 0) {
+ len = write(out, buf, ret);
+ if (len != ret) {
+ ret = -1;
+ break;
+ }
+ }
+ close(in);
+ if (ret < 0) {
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+
+ ret = 0;
+ *proxy_file = name;
+
+end:
+ close(out);
+ if (ret) {
+ unlink(name);
+ free(name);
+ }
+
+ return ret;
+}
+
+static int
+destroy_proxy(char *proxy_file)
+{
+ /* XXX we should erase the contents safely (i.e. overwrite with 0's) */
+ unlink(proxy_file);
+ return 0;
+}
+
+int
+edg_wll_gss_acquire_cred_gsi(char *cert_file, char *key_file, gss_cred_id_t *cred,
+ char **name, edg_wll_GssStatus* gss_code)
+{
+ OM_uint32 major_status = 0, minor_status, minor_status2;
+ gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
+ gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+ gss_name_t gss_name = GSS_C_NO_NAME;
+ OM_uint32 lifetime;
+ char *proxy_file = NULL;
+ int ret;
+
+ if ((cert_file == NULL && key_file != NULL) ||
+ (cert_file != NULL && key_file == NULL))
+ return EINVAL;
+
+ if (cert_file == NULL) {
+ major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0,
+ GSS_C_NO_OID_SET, GSS_C_BOTH,
+ &gss_cred, NULL, NULL);
+ if (GSS_ERROR(major_status)) {
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+ } else {
+ proxy_file = cert_file;
+ if (strcmp(cert_file, key_file) != 0 &&
+ (ret = create_proxy(cert_file, key_file, &proxy_file))) {
+ proxy_file = NULL;
+ goto end;
+ }
+
+ asprintf((char**)&buffer.value, "X509_USER_PROXY=%s", proxy_file);
+ if (buffer.value == NULL) {
+ errno = ENOMEM;
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ buffer.length = strlen(proxy_file);
+
+ major_status = gss_import_cred(&minor_status, &gss_cred, GSS_C_NO_OID, 1,
+ &buffer, 0, NULL);
+ free(buffer.value);
+ if (GSS_ERROR(major_status)) {
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+ }
+
+ /* gss_import_cred() doesn't check validity of credential loaded, so let's
+ * verify it now */
+ major_status = gss_inquire_cred(&minor_status, gss_cred, &gss_name,
+ &lifetime, NULL, NULL);
+ if (GSS_ERROR(major_status)) {
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ /* Must cast to time_t since OM_uint32 is unsinged and hence we couldn't
+ * detect negative values. */
+ if ((time_t) lifetime <= 0) {
+ major_status = GSS_S_CREDENTIALS_EXPIRED;
+ minor_status = 0; /* XXX */
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ if (name) {
+ major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL);
+ if (GSS_ERROR(major_status)) {
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+ *name = buffer.value;
+ memset(&buffer, 0, sizeof(buffer));
+ }
+
+ *cred = gss_cred;
+ gss_cred = GSS_C_NO_CREDENTIAL;
+ ret = 0;
+
+end:
+ if (cert_file && key_file && proxy_file && strcmp(cert_file, key_file) != 0) {
+ destroy_proxy(proxy_file);
+ free(proxy_file);
+ }
+
+ if (gss_name != GSS_C_NO_NAME)
+ gss_release_name(&minor_status2, &gss_name);
+
+ if (gss_cred != GSS_C_NO_CREDENTIAL)
+ gss_release_cred(&minor_status2, &gss_cred);
+
+ if (GSS_ERROR(major_status)) {
+ if (gss_code) {
+ gss_code->major_status = major_status;
+ gss_code->minor_status = minor_status;
+ }
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ }
+
+ return ret;
+}
+
+int
+edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port,
+ struct timeval *timeout, edg_wll_GssConnection *connection,
+ edg_wll_GssStatus* gss_code)
+{
+ int sock, ret;
+ OM_uint32 maj_stat, min_stat, min_stat2, req_flags;
+ int context_established = 0;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ gss_name_t server = GSS_C_NO_NAME;
+ gss_ctx_id_t context = GSS_C_NO_CONTEXT;
+ char *servername = NULL;
+
+ maj_stat = min_stat = min_stat2 = req_flags = 0;
+
+ /* GSI specific */
+ req_flags = GSS_C_GLOBUS_SSL_COMPATIBLE;
+
+ ret = do_connect(&sock, hostname, port, timeout);
+ if (ret)
+ return ret;
+
+ /* XXX find appropriate fqdn */
+ asprintf (&servername, "host@%s", hostname);
+ if (servername == NULL) {
+ errno = ENOMEM;
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ input_token.value = servername;
+ input_token.length = strlen(servername) + 1;
+
+ maj_stat = gss_import_name(&min_stat, &input_token,
+ GSS_C_NT_HOSTBASED_SERVICE, &server);
+ if (GSS_ERROR(maj_stat)) {
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ free(servername);
+ memset(&input_token, 0, sizeof(input_token));
+
+ /* XXX if cred == GSS_C_NO_CREDENTIAL set the ANONYMOUS flag */
+
+ /* XXX prepsat na do {} while (maj_stat == CONT) a osetrit chyby*/
+ while (!context_established) {
+ /* XXX verify ret_flags match what was requested */
+ maj_stat = gss_init_sec_context(&min_stat, cred, &context,
+ GSS_C_NO_NAME, GSS_C_NO_OID,
+ req_flags | GSS_C_MUTUAL_FLAG,
+ 0, GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token, NULL, &output_token,
+ NULL, NULL);
+ if (input_token.length > 0) {
+ free(input_token.value);
+ input_token.length = 0;
+ }
+
+ if (output_token.length != 0) {
+ ret = send_token(sock, output_token.value, output_token.length, timeout);
+ gss_release_buffer(&min_stat2, &output_token);
+ if (ret)
+ goto end;
+ }
+
+ if (GSS_ERROR(maj_stat)) {
+ if (context != GSS_C_NO_CONTEXT) {
+ /* XXX send closing token to the friend */
+ gss_delete_sec_context(&min_stat2, &context, GSS_C_NO_BUFFER);
+ context = GSS_C_NO_CONTEXT;
+ }
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ if(maj_stat & GSS_S_CONTINUE_NEEDED) {
+ ret = recv_token(sock, &input_token.value, &input_token.length, timeout);
+ if (ret)
+ goto end;
+ } else
+ context_established = 1;
+ }
+
+ /* XXX check ret_flags matches to what was requested */
+
+ memset(connection, 0, sizeof(*connection));
+ connection->sock = sock;
+ connection->context = context;
+ servername = NULL;
+ ret = 0;
+
+end:
+ if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) {
+ gss_code->major_status = maj_stat;
+ gss_code->minor_status = min_stat;
+ }
+ if (server != GSS_C_NO_NAME)
+ gss_release_name(&min_stat2, &server);
+ if (servername == NULL)
+ free(servername);
+ if (ret)
+ close(sock);
+
+ return ret;
+}
+
+int
+edg_wll_gss_accept(gss_cred_id_t cred, int sock, struct timeval *timeout,
+ edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code)
+{
+ OM_uint32 maj_stat, min_stat, min_stat2;
+ OM_uint32 ret_flags = 0;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ gss_name_t client_name = GSS_C_NO_NAME;
+ gss_ctx_id_t context = GSS_C_NO_CONTEXT;
+ int ret;
+
+ maj_stat = min_stat = min_stat2 = 0;
+
+ /* GSI specific */
+ ret_flags = GSS_C_GLOBUS_SSL_COMPATIBLE;
+
+ do {
+ ret = recv_token(sock, &input_token.value, &input_token.length, timeout);
+ if (ret)
+ goto end;
+
+ maj_stat = gss_accept_sec_context(&min_stat, &context,
+ cred, &input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client_name, NULL, &output_token,
+ &ret_flags, NULL, NULL);
+ if (input_token.length > 0) {
+ free(input_token.value);
+ input_token.length = 0;
+ }
+
+ if (output_token.length) {
+ ret = send_token(sock, output_token.value, output_token.length, timeout);
+ gss_release_buffer(&min_stat2, &output_token);
+ if (ret)
+ goto end;
+ }
+ } while(maj_stat & GSS_S_CONTINUE_NEEDED);
+
+ if (GSS_ERROR(maj_stat)) {
+ if (context != GSS_C_NO_CONTEXT) {
+ /* XXX send closing token to the friend */
+ gss_delete_sec_context(&min_stat2, &context, GSS_C_NO_BUFFER);
+ context = GSS_C_NO_CONTEXT;
+ }
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ maj_stat = gss_display_name(&min_stat, client_name, &output_token, NULL);
+ if (GSS_ERROR(maj_stat)) {
+ /* XXX close context ??? */
+ ret = EDG_WLL_GSS_ERROR_GSS;
+ goto end;
+ }
+
+ memset(connection, 0, sizeof(*connection));
+ connection->sock = sock;
+ connection->context = context;
+ memset(&output_token, 0, sizeof(output_token.value));
+ ret = 0;
+
+end:
+ if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) {
+ gss_code->major_status = maj_stat;
+ gss_code->minor_status = min_stat;
+ }
+ if (client_name != GSS_C_NO_NAME)
+ gss_release_name(&min_stat2, &client_name);
+
+ return ret;
+}
+
+int
+edg_wll_gss_write(edg_wll_GssConnection *connection, const void *buf, size_t bufsize,
+ struct timeval *timeout, edg_wll_GssStatus* gss_code)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc input_token;
+ gss_buffer_desc output_token;
+ int ret;
+
+ input_token.value = (void*)buf;
+ input_token.length = bufsize;
+
+ maj_stat = gss_wrap (&min_stat, connection->context, 1, GSS_C_QOP_DEFAULT,
+ &input_token, NULL, &output_token);
+ if (GSS_ERROR(maj_stat)) {
+ if (gss_code) {
+ gss_code->minor_status = min_stat;
+ gss_code->major_status = maj_stat;
+ }
+
+ return EDG_WLL_GSS_ERROR_GSS;
+ }
+
+ ret = send_token(connection->sock, output_token.value, output_token.length,
+ timeout);
+ gss_release_buffer(&min_stat, &output_token);
+
+ return ret;
+}
+
+
+int
+edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize,
+ struct timeval *timeout, edg_wll_GssStatus* gss_code)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc input_token;
+ gss_buffer_desc output_token;
+ int ret, i;
+
+ if (connection->bufsize > 0) {
+ size_t len;
+
+ len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
+ memcpy(buf, connection->buffer, len);
+ if (connection->bufsize - len == 0) {
+ free(connection->buffer);
+ connection->buffer = NULL;
+ } else {
+ for (i = 0; i < connection->bufsize - len; i++)
+ connection->buffer[i] = connection->buffer[i+len];
+ }
+ connection->bufsize -= len;
+
+ return len;
+ }
+
+ do {
+ ret = recv_token(connection->sock, &input_token.value, &input_token.length,
+ timeout);
+ if (ret)
+ /* XXX cleanup */
+ return ret;
+
+ maj_stat = gss_unwrap(&min_stat, connection->context, &input_token,
+ &output_token, NULL, NULL);
+ gss_release_buffer(&min_stat, &input_token);
+ if (GSS_ERROR(maj_stat)) {
+ /* XXX cleanup */
+ return EDG_WLL_GSS_ERROR_GSS;
+ }
+ } while (maj_stat == 0 && output_token.length == 0 && output_token.value == NULL);
+
+ if (output_token.length > bufsize) {
+ connection->bufsize = output_token.length - bufsize;
+ connection->buffer = malloc(connection->bufsize);
+ if (connection->buffer == NULL) {
+ connection->bufsize = 0;
+ ret = EDG_WLL_GSS_ERROR_ERRNO;
+ goto end;
+ }
+ memcpy(connection->buffer, output_token.value + bufsize, connection->bufsize);
+ output_token.length = bufsize;
+ }
+
+ memcpy(buf, output_token.value, output_token.length);
+ ret = output_token.length;
+
+end:
+ gss_release_buffer(&min_stat, &output_token);
+
+ return ret;
+}
+
+int
+edg_wll_gss_read_full(edg_wll_GssConnection *connection, void *buf,
+ size_t bufsize, struct timeval *timeout, size_t *total,
+ edg_wll_GssStatus* gss_code)
+{
+ int len,i;
+ *total = 0;
+
+ if (connection->bufsize > 0) {
+ size_t len;
+
+ len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize;
+ memcpy(buf, connection->buffer, len);
+ if (connection->bufsize - len == 0) {
+ free(connection->buffer);
+ connection->buffer = NULL;
+ } else {
+ for (i = 0; i < connection->bufsize - len; i++)
+ connection->buffer[i] = connection->buffer[i+len];
+ }
+ connection->bufsize -= len;
+ *total = len;
+ }
+
+ while (*total < bufsize) {
+ len = edg_wll_gss_read(connection, buf+*total, bufsize-*total,
+ timeout, gss_code);
+ if (len < 0) return len;
+ *total += len;
+ }
+
+ return 0;
+}
+
+int
+edg_wll_gss_write_full(edg_wll_GssConnection *connection, const void *buf,
+ size_t bufsize, struct timeval *timeout, size_t *total,
+ edg_wll_GssStatus* gss_code)
+{
+ return edg_wll_gss_write(connection, buf, bufsize, timeout, gss_code);
+}
+
+/* XXX: I'm afraid the contents of stuct stat is somewhat OS dependent */
+int
+edg_wll_gss_watch_creds(const char *proxy_file, time_t *proxy_mtime)
+{
+ struct stat pstat;
+ int reload = 0;
+
+ if (!proxy_file) return 0;
+ if (stat(proxy_file,&pstat)) return -1;
+
+ if (!*proxy_mtime) *proxy_mtime = pstat.st_mtime;
+
+ if (*proxy_mtime != pstat.st_mtime) {
+ *proxy_mtime = pstat.st_mtime;
+ reload = 1;
+ }
+
+ return reload;
+}
+
+int
+edg_wll_gss_close(edg_wll_GssConnection *con, struct timeval *timeout)
+{
+ OM_uint32 min_stat;
+
+ /* XXX if timeout is NULL use value of 120 secs */
+
+ if (con->context != GSS_C_NO_CONTEXT) {
+ gss_delete_sec_context(&min_stat, &con->context, GSS_C_NO_BUFFER);
+ /* XXX send the buffer (if any) to the peer. GSSAPI specs doesn't
+ * recommend sending it, though */
+
+ /* XXX can socket be open even if context == GSS_C_NO_CONTEXT) ? */
+ /* XXX ensure that edg_wll_GssConnection is created with sock set to -1 */
+ if (con->sock >= 0)
+ close(con->sock);
+ }
+ if (con->buffer)
+ free(con->buffer);
+ memset(con, 0, sizeof(*con));
+ con->context = GSS_C_NO_CONTEXT;
+ con->sock = -1;
+ return 0;
+}
+
+int
+edg_wll_gss_get_error(edg_wll_GssStatus *gss_err, const char *prefix, char **msg)
+{
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc maj_status_string = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc min_status_string = GSS_C_EMPTY_BUFFER;
+ char *str = NULL;
+ char *line, *tmp;
+
+ str = strdup(prefix);
+ do {
+ maj_stat = gss_display_status(&min_stat, gss_err->major_status,
+ GSS_C_GSS_CODE, GSS_C_NO_OID,
+ &msg_ctx, &maj_status_string);
+ if (GSS_ERROR(maj_stat))
+ break;
+
+ maj_stat = gss_display_status(&min_stat, gss_err->minor_status,
+ GSS_C_MECH_CODE, GSS_C_NULL_OID,
+ &msg_ctx, &min_status_string);
+ if (GSS_ERROR(maj_stat)) {
+ gss_release_buffer(&min_stat, &maj_status_string);
+ break;
+ }
+
+ asprintf(&line, ": %s (%s)", (char *)maj_status_string.value,
+ (char *)min_status_string.value);
+ gss_release_buffer(&min_stat, &maj_status_string);
+ gss_release_buffer(&min_stat, &min_status_string);
+
+ tmp = realloc(str, strlen(str) + strlen(line) + 1);
+ if (tmp == NULL) {
+ /* abort() ? */
+ free(line);
+ free(str);
+ str = "WARNING: Not enough memory to produce error message";
+ break;
+ }
+ str = tmp;
+ strcat(str, line);
+ free(line);
+ } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+ *msg = str;
+ return 0;
+}
+
+int
+edg_wll_gss_oid_equal(const gss_OID a, const gss_OID b)
+{
+ if (a == b)
+ return 1;
+ else {
+ if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
+ return 0;
+ else
+ return (memcmp(a->elements, b->elements, a->length) == 0);
+ }
+}
+
+int
+edg_wll_gss_reject(int sock)
+{
+ /* XXX is it possible to cut & paste edg_wll_ssl_reject() ? */
+ return 0;
+}
--- /dev/null
+/*
+
+stdsoap2.c[pp] 2.6.2
+
+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.
+
+--------------------------------------------------------------------------------
+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 A. 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
+--------------------------------------------------------------------------------
+
+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
+
+*/
+
+#include "stdsoap2.h"
+
+#ifdef __cplusplus
+SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.6.2 2004-06-12 12:00:00 GMT")
+extern "C" {
+#else
+SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.6.2 2004-06-12 12:00:00 GMT")
+#endif
+
+/* 8bit character representing unknown/nonrepresentable character data (not supported by current locale) */
+#ifndef SOAP_UNKNOWN_CHAR
+#define SOAP_UNKNOWN_CHAR (127)
+#endif
+
+/* EOF=-1 */
+#define LT (wchar)(-2) /* XML character '<' */
+#define TT (wchar)(-3) /* XML character '</' */
+#define GT (wchar)(-4) /* XML character '>' */
+#define QT (wchar)(-5) /* XML character '"' */
+#define AP (wchar)(-6) /* XML character ''' */
+
+#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 wchar soap_char(struct soap*);
+static wchar soap_getchunkchar(struct soap*);
+static void soap_update_ptrs(struct soap*, char*, char*, long);
+static int soap_has_copies(struct soap*, char*, 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*);
+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, wchar);
+static void soap_set_local_namespaces(struct soap*);
+static size_t soap_begin_dime(struct soap*);
+static int soap_isnumeric(struct soap*, const char*);
+static void *fplugin(struct soap*, const char*);
+
+#ifndef WITH_LEAN
+static time_t soap_timegm(struct tm*);
+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
+/* Use look-aside buffers */
+static int soap_append_lab(struct soap*, const char*, size_t);
+#endif
+
+#ifndef WITH_LEANER
+static int soap_putdimefield(struct soap*, const char*, size_t);
+static char *soap_getdimefield(struct soap*, size_t);
+#endif
+
+#ifdef WITH_GZIP
+static int soap_getgzipheader(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 *);
+/* This callback is included for future references. It should not be deleted
+static DH *ssl_tmp_dh(SSL*, int, int);
+*/
+#endif
+
+static const char *soap_strerror(struct soap*);
+static const char *tcp_error(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_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*);
+static int tcp_connect(struct soap*, const char*, const char*, int);
+static int tcp_accept(struct soap*, int, struct sockaddr*, int*);
+static int tcp_disconnect(struct soap*);
+static int fsend(struct soap*, const char*, size_t);
+static size_t frecv(struct soap*, char*, size_t);
+
+/* WR[ */
+#ifdef VXWORKS
+static int vx_nonblocking = TRUE; /* ioctl argument */
+#endif
+/* ]WR */
+
+#ifndef PALM_2
+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_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
+
+#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
+
+#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
+
+#ifdef WIN32
+static int tcp_done = 0;
+#endif
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#ifndef PALM_1
+static int
+fsend(struct soap *soap, const char *s, size_t n)
+{ register int nwritten;
+#if defined(__cplusplus) && !defined(UNDER_CE)
+ 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)
+{
+#ifndef WITH_LEAN
+ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
+ { char *t;
+ if (!(t = (char*)soap_push_block(soap, n)))
+ return soap->error = SOAP_EOM;
+ memcpy(t, s, n);
+ return SOAP_OK;
+ }
+ 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;
+ }
+#endif
+ DBGMSG(SENT, s, n);
+ 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;
+ if (soap->fprepare)
+ return soap->fprepare(soap, s, n);
+ 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 MAC_CARBON
+#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(UNDER_CE)
+ 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
+ struct timeval timeout;
+ fd_set fd;
+ if (soap->recv_timeout)
+ { 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)
+ return 0;
+ if (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->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);
+ 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 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 PALM_1
+static 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\n", (unsigned int)soap->buflen));
+ DBGMSG(RECV, soap->buf, soap->buflen);
+ if (soap->buflen)
+ return soap->buf[soap->bufidx++];
+ return EOF;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static int
+soap_isxdigit(int c)
+{ switch (c)
+ { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ return 1;
+ }
+ return 0;
+}
+#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
+ 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 wchar c;
+ char tmp[8], *t;
+ t = tmp;
+ if (!soap->chunkbuflen)
+ { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes\n", (unsigned int)ret));
+ 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
+ { soap->bufidx = 0;
+ soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes\n", (unsigned int)ret));
+ DBGMSG(RECV, soap->buf, ret);
+ }
+#ifdef WITH_ZLIB
+ if (soap->mode & SOAP_ENC_ZLIB)
+ { 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
+wchar
+SOAP_FMAC2
+soap_getchar(struct soap *soap)
+{ register 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))
+ 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 (!strcmp(str, map->string))
+ 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 wchar
+soap_char(struct soap *soap)
+{ char tmp[8];
+ register int i;
+ register 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 (wchar)soap_int_code(html_entity_codes, tmp, 127);
+#else
+ return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */
+#endif
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+wchar
+SOAP_FMAC2
+soap_get(struct soap *soap)
+{ register 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 TT;
+ soap_revget1(soap);
+ return LT;
+ case '>':
+ return GT;
+ case '"':
+ return QT;
+ case '\'':
+ return AP;
+ case '&':
+ return soap_char(soap) | 0x80000000;
+ }
+ break;
+ }
+ return c;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+wchar
+SOAP_FMAC2
+soap_advance(struct soap *soap)
+{ register wchar c;
+ while ((int)((c = soap_get(soap)) != EOF) && c != LT && c != TT)
+ ;
+ return c;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+wchar
+SOAP_FMAC2
+soap_skip(struct soap *soap)
+{ register 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
+wchar
+SOAP_FMAC2
+soap_getutf8(struct soap *soap)
+{ register wchar c, c1, c2, c3, c4;
+ c = soap_get(soap);
+ if (c < 0x80)
+ return c;
+ c1 = soap_get(soap);
+ if (c1 < 0x80)
+ { soap_unget(soap, c1);
+ return c;
+ }
+ c1 &= 0x3F;
+ if (c < 0xE0)
+ return ((wchar)(c & 0x1F) << 6) | c1;
+ c2 = (wchar)soap_get1(soap) & 0x3F;
+ if (c < 0xF0)
+ return ((wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
+ c3 = (wchar)soap_get1(soap) & 0x3F;
+ if (c < 0xF8)
+ return ((wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
+ c4 = (wchar)soap_get1(soap) & 0x3F;
+ if (c < 0xFC)
+ return ((wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
+ return ((wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (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 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 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);
+ 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];
+#ifdef WITH_DOM
+ if ((soap->mode & SOAP_XML_DOM) && soap->dom)
+ { soap->dom->data = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1);
+ return soap_s2base64(soap, s, soap->dom->data, n);
+ }
+#endif
+ if (!s)
+ return SOAP_OK;
+ for (; n > 2; n -= 3, s += 3)
+ { m = ((unsigned long)((unsigned char*)s)[0] << 16) | ((unsigned long)((unsigned char*)s)[1] << 8) | (unsigned long)((unsigned char*)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 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 != LT && c != 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 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);
+ if (c >= 0)
+ { while ((int)((c = soap_get(soap)) != EOF) && c != LT && c != 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));
+ 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 PALM_1
+static void
+soap_update_ptrs(struct soap *soap, char *start, char *end, long offset)
+{ int i;
+ register struct soap_ilist *ip;
+ 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)
+ 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 update id='%s' %p\n", ip->id, p));
+ *q = (char*)p + offset;
+ }
+ }
+ }
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static int
+soap_has_copies(struct soap *soap, register char *start, register char *end)
+{ int i;
+ register struct soap_ilist *ip;
+ register char *p;
+ for (i = 0; i < SOAP_IDHASH; i++)
+ for (ip = soap->iht[i]; ip; ip = ip->next)
+ for (p = (char*)ip->copy; p; p = *(char**)p)
+ if (p >= start && p < end)
+ return SOAP_ERR;
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_resolve(struct soap *soap)
+{ register int i;
+ register struct soap_ilist *ip;
+ short flag1 = 0, flag2;
+ for (i = 0; i < SOAP_IDHASH; i++)
+ for (ip = soap->iht[i]; ip; ip = ip->next)
+ { if (ip->ptr)
+ soap_resolve_ptr(ip);
+ else if (*ip->id == '#')
+ flag1 = 1;
+ }
+ do
+ { flag2 = 0;
+ 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->copy && ip->ptr && ip->size)
+ if (!soap_has_copies(soap, (char*)ip->ptr, (char*)ip->ptr + ip->size))
+ { 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);
+ flag2 = 1;
+ }
+ } while (flag2);
+ for (i = 0; i < SOAP_IDHASH; i++)
+ for (ip = soap->iht[i]; ip; ip = ip->next)
+ { register struct soap_flist *fp;
+ for (fp = ip->flist; fp; fp = fp->next)
+ if (fp->finsert)
+ { unsigned int k = fp->level;
+ void *p = ip->ptr;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded container data type=%d location=%p level=%u,%u\n", fp->type, fp->ptr, ip->level, fp->level));
+ while (ip->level < k)
+ { void **q = (void**)soap_malloc(soap, sizeof(void*));
+ if (!q)
+ return SOAP_EOM;
+ *q = p;
+ p = (void*)q;
+ k--;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
+ }
+ fp->finsert(soap, fp->type, fp->ptr, p);
+ }
+ }
+ if (flag1)
+ return soap->error = SOAP_MISSING_ID;
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_resolve_ptr(struct soap_ilist *ip)
+{ register void *p, **q, *r;
+ q = (void**)ip->link;
+ ip->link = NULL;
+ r = ip->ptr;
+ while (q)
+ { p = *q;
+ *q = r;
+ q = (void**)p;
+ }
+}
+#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)
+{ 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);
+ soap_update_ptrs(soap, q, q + n, (long)s - (long)q); /* pointers s and q may or may not be related */
+ 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_1
+SOAP_FMAC1
+char*
+SOAP_FMAC2
+soap_store_block(struct soap *soap, char *p)
+{ p = soap_save_block(soap, p);
+ if (!soap->blist)
+ { struct soap_ilist *ip;
+ int i;
+ for (i = 0; i < SOAP_IDHASH; i++)
+ for (ip = soap->iht[i]; ip; ip = ip->next)
+ if (ip->ptr)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolve link chain to point to %p\n", ip->ptr));
+ soap_resolve_ptr(ip);
+ }
+ }
+ 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;
+ if (!strcmp(ns, soap_env1))
+ soap->version = 1; /* make sure we use SOAP 1.1 */
+ else if (!strcmp(ns, soap_env2))
+ soap->version = 2; /* make sure we use SOAP 1.2 */
+ else
+ { for (; p->id; p++, i++)
+ { if (p->ns)
+ if (!strcmp(ns, p->ns))
+ break;
+ if (p->in)
+ if (!soap_tag_cmp(ns, p->in))
+ { if (p->out)
+ SOAP_FREE(p->out);
+ if ((p->out = (char*)SOAP_MALLOC(strlen(ns) + 1)))
+ strcpy(p->out, ns);
+ break;
+ }
+ }
+ }
+ if (i == 0 && (!p->ns || strcmp(ns, p->ns)))
+ { if (p[0].out)
+ SOAP_FREE(p[0].out);
+ if ((p[0].out = (char*)SOAP_MALLOC(strlen(ns) + 1)))
+ strcpy(p[0].out, ns);
+ if (p[1].out)
+ SOAP_FREE(p[1].out);
+ if (soap->version == 1)
+ { if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc1))))
+ strcpy(p[1].out, soap_enc1);
+ }
+ else if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc2))))
+ strcpy(p[1].out, soap_enc2);
+ }
+ 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
+int
+SOAP_FMAC2
+soap_push_default_namespace(struct soap *soap, const char *id, int n)
+{ register struct soap_nlist *np = soap->nlist;
+ while (np && np->index >= -1)
+ np = np->next;
+ if (np && (!strncmp(np->id, id, n) && !np->id[n]))
+ return SOAP_OK;
+ np = (struct soap_nlist*)SOAP_MALLOC(sizeof(struct soap_nlist) + n);
+ if (!np)
+ return soap->error = SOAP_EOM;
+ np->next = soap->nlist;
+ soap->nlist = np;
+ strncpy(np->id, id, n);
+ np->id[n] = '\0';
+ np->level = soap->level;
+ np->index = -2;
+ np->ns = NULL;
+ 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 && (np->index == -2 || (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
+const char*
+SOAP_FMAC2
+soap_default_namespace(struct soap *soap)
+{ register struct soap_nlist *np = soap->nlist;
+ while (np && np->index >= -1)
+ np = np->next;
+ if (np)
+ return np->id;
+ return NULL;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_tag_cmp(register const char *s, register const char *t)
+{ for (; *s && *s != '"'; s++, t++)
+ if (tolower(*s) != tolower(*t))
+ if (*t != '-')
+ { if (*t != '*')
+ return 1;
+ if (*++t)
+ { register int c = tolower(*t);
+ for (; *s && *s != '"'; s++)
+ { if (tolower(*s) == c)
+ if (!soap_tag_cmp(s + 1, t + 1))
+ return 0;
+ }
+ break;
+ }
+ else
+ return 0;
+ }
+ 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 (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->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER && soap->encodingStyle))
+ return SOAP_TAG_MISMATCH;
+ if (SOAP_STRCMP(s + 1, tag2))
+ return SOAP_TAG_MISMATCH;
+ if (!soap->encodingStyle)
+ { t = soap_default_namespace(soap);
+ if (!t || soap_match_namespace(soap, tag1, t, s - tag1, strlen(t)))
+ 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_1
+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_1
+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_1
+static void
+ssl_init()
+{ static int done = 0;
+ if (!done)
+ { done = 1;
+ SSL_library_init();
+#ifndef WITH_LEAN
+ SSL_load_error_strings();
+#endif
+ }
+}
+#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_1
+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);
+ }
+ else if (!RAND_load_file("/dev/urandom", 1024))
+ { int r;
+#ifdef HAVE_RAND_R
+ unsigned int s = (unsigned int)time(NULL);
+#endif
+ RAND_seed(soap->buf, sizeof(soap->buf));
+ while (!RAND_status())
+ {
+#ifdef HAVE_RAND_R
+ r = rand_r(&s);
+#else
+ r = rand();
+#endif
+ RAND_seed(&r, sizeof(int));
+ }
+ }
+ 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);
+#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 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;
+ 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;
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#endif /* WITH_OPENSSL */
+
+/******************************************************************************/
+#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
+#ifdef PALM
+ errno = 0;
+ h_errno = 0;
+ AppNetRefnum = 0;
+ NetUInit();
+ AppNetTimeout = 10000;
+ NetLibOpen(AppNetRefnum, &h_errno);
+#endif
+ return 0;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_done(struct soap *soap)
+{
+#ifndef WITH_LEAN
+ 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;
+ 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;
+#ifndef MAC_CARBON
+ soap->faccept = tcp_accept;
+ soap->fopen = tcp_connect;
+ soap->fclose = tcp_disconnect;
+ soap->fsend = fsend;
+ soap->frecv = frecv;
+#endif
+ soap->fprepare = NULL;
+ soap->fignore = 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))
+ { closesocket((SOAP_SOCKET)soap->master);
+ soap->master = SOAP_INVALID_SOCKET;
+ }
+#ifdef WITH_OPENSSL
+ if (soap->ctx)
+ { SSL_CTX_free(soap->ctx);
+ soap->ctx = NULL;
+ }
+#endif
+ }
+#ifndef WITH_LEAN
+ 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 PALM_1
+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
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#ifndef PALM_1
+static const char*
+http_error(struct soap *soap, int status)
+{ register const char *msg = NULL;
+#ifndef WITH_LEAN
+ msg = soap_str_code(h_http_error_codes, status);
+ if (!msg)
+#endif
+ { sprintf(soap->msgbuf, "HTTP error %d", status);
+ msg = soap->msgbuf;
+ }
+ return msg;
+}
+#endif
+
+/******************************************************************************/
+/* WR[ */
+#ifndef WITH_IPV6
+/* ]WR */
+#ifndef MAC_CARBON
+#ifndef PALM_1
+static int
+soap_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 0;
+ }
+#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(&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 -1;
+ }
+/* WR[ */
+#ifdef VXWORKS
+ inaddr->s_addr = hostint;
+#else
+/* ]WR */
+ memcpy(inaddr, host->h_addr, host->h_length);
+/* WR[ */
+#endif
+/* ]WR */
+ return 0;
+}
+#endif
+#endif
+/* WR[ */
+#endif /* WITH_IPV6 */
+/* ]WR */
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#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))
+ closesocket((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 -1;
+ }
+ soap->errmode = 0;
+/* WR[ */
+#ifdef WITH_IPV6
+ memset(&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 -1;
+ }
+ 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 -1;
+ }
+#ifndef WITH_LEAN
+ if (soap->connect_flags & SO_LINGER)
+ { struct linger linger;
+ memset(&linger, 0, sizeof(struct 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+#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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+#endif
+#endif
+/* WR[ */
+#ifndef WITH_IPV6
+/* ]WR */
+ memset(&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_gethost(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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ sockaddr.sin_port = htons((short)soap->proxy_port);
+ }
+ else
+ { if (soap_gethost(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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ 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);
+ closesocket((SOAP_SOCKET)fd);
+ return -1;
+ }
+ }
+ 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 &= ~0xFF; /* 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 -1;
+#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 -1;
+ soap->omode = k;
+ k = soap->imode;
+ soap->imode &= ~0xFF; /* mask IO and ENC */
+ if (soap_begin_recv(soap))
+ return -1;
+ 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 -1;
+ }
+ soap->ssl = SSL_new(soap->ctx);
+ if (!soap->ssl)
+ { soap->error = SOAP_SSL_ERROR;
+ return -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+ }
+ 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 cannot be verified in tcp_connect()", SOAP_SSL_ERROR);
+ return -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+ }
+ }
+#endif
+ return fd;
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#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))
+ { closesocket((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 -1;
+ }
+/* WR[ */
+#ifdef WITH_IPV6
+ memset(&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 -1;
+ }
+ 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 -1;
+ }
+#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 -1;
+ }
+/* WR[ */
+#endif /* WITH_IPV6 */
+/* ]WR */
+#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 -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+#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 -1;
+ }
+#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 -1;
+ }
+#else /* WITH_IPV6 */
+/* ]WR */
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ soap->errmode = 2;
+ if (host)
+ { if (soap_gethost(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 -1;
+ }
+ }
+ 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 -1;
+ }
+/* WR[ */
+#endif /* WITH_IPV6 */
+/* ]WR */
+#ifdef WITH_OPENSSL
+ if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
+ return -1;
+#endif
+ return soap->master;
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#ifndef PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_poll(struct soap *soap)
+{
+#ifndef WITH_LEAN
+ struct timeval timeout;
+ fd_set sfd,rfd;
+ int r;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ FD_ZERO(&rfd);
+ FD_ZERO(&sfd);
+ if (soap->socket >= 0)
+ { FD_SET(soap->socket, &rfd);
+ FD_SET(soap->socket, &sfd);
+ r = select(soap->socket + 1, &rfd, &sfd, NULL, &timeout);
+ }
+ else if (soap->master >= 0)
+ { FD_SET(soap->master, &rfd);
+ r = select(soap->master + 1, &rfd, &sfd, NULL, &timeout);
+ }
+ else
+ { FD_SET(soap->sendfd, &sfd);
+ FD_SET(soap->recvfd, &rfd);
+ r = select((soap->sendfd > soap->recvfd ? soap->sendfd : soap->recvfd) + 1, &rfd, &sfd, NULL, &timeout);
+ }
+ if (r > 0)
+ {
+#ifdef WITH_OPENSSL
+ if (soap->ssl)
+ { if ((soap->socket >= 0) && FD_ISSET(soap->socket, &rfd))
+ { char buf = '\0';
+ if (SSL_peek(soap->ssl, &buf, 1) <= 0)
+ return SOAP_EOF;
+ }
+ }
+#endif
+ 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 MAC_CARBON
+#ifndef PALM_1
+static int
+tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n)
+{
+#if defined(SOCKLEN_T)
+ return (int)accept((SOAP_SOCKET)s, a, (SOCKLEN_T*)n);
+#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN)
+ return (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)
+ return (int)accept((SOAP_SOCKET)s, a, n);
+#else
+ return (int)accept((SOAP_SOCKET)s, a, (size_t*)n);
+#endif
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#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(struct sockaddr);
+#ifndef WITH_LEAN
+ int len = SOAP_BUFLEN;
+ int set = 1;
+#endif
+ memset(&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 -1;
+ }
+ 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 -1;
+ }
+ }
+#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
+ if ((soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&sockaddr, &n)) >= 0)
+ {
+/* 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);
+ 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);
+/* 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(&linger, 0, sizeof(struct 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 -1;
+ }
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+ 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 -1;
+ }
+#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 -1;
+ }
+#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 */
+#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)
+ { soap->errnum = soap_socket_errno;
+ soap_set_receiver_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
+ return -1;
+ }
+ }
+ }
+ else
+ { soap_set_receiver_error(soap, tcp_error(soap), "TCP no master socket in soap_accept()", SOAP_TCP_ERROR);
+ return -1;
+ }
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef MAC_CARBON
+#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))
+ { shutdown((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));
+ shutdown((SOAP_SOCKET)soap->socket, 2);
+ closesocket((SOAP_SOCKET)soap->socket);
+ soap->socket = SOAP_INVALID_SOCKET;
+ }
+ return SOAP_OK;
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_closesock(struct soap *soap)
+{ register int status = soap->error;
+#ifndef MAC_CARBON
+ if (status == SOAP_EOF || !soap->keep_alive)
+ { if ((soap->error = soap->fclose(soap)))
+ return soap->error;
+ soap->socket = SOAP_INVALID_SOCKET;
+ }
+#endif
+#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 PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_hash(register const char *s)
+{ register int h = 0;
+ while (*s)
+ h += *s++ & 0x1F;
+ return h % SOAP_IDHASH;
+}
+#endif
+
+/******************************************************************************/
+#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 < SOAP_PTRHASH; i++)
+ soap->pht[i] = NULL;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+struct soap*
+SOAP_FMAC2
+soap_new()
+{ struct soap *soap = (struct soap*)SOAP_MALLOC(sizeof(struct soap));
+ if (soap)
+ soap_init(soap);
+ return soap;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+struct soap*
+SOAP_FMAC2
+soap_new1(int mode)
+{ return soap_new2(mode, mode);
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+struct soap*
+SOAP_FMAC2
+soap_new2(int imode, int omode)
+{ struct soap *soap = (struct soap*)SOAP_MALLOC(sizeof(struct soap));
+ if (soap)
+ soap_init2(soap, imode, omode);
+ return soap;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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 < SOAP_PTRHASH; i++)
+ { for (pp = soap->pht[i]; pp; pp = next)
+ { next = pp->next;
+ SOAP_FREE(pp);
+ }
+ soap->pht[i] = NULL;
+ }
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_embed_element(struct soap *soap, const void *p, const char *tag, int type)
+{ register int i;
+ struct soap_plist *pp;
+ if (soap->version != 1)
+ soap->encoding = 1;
+ if ((i = soap_pointer_lookup(soap, p, type, &pp)))
+ { if (soap_is_embedded(soap, pp) || soap_is_single(soap, pp))
+ return 0;
+ soap_set_embedded(soap, pp);
+ }
+ return i;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_embed_array(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 ((i = soap_array_pointer_lookup(soap, p, a, n, type, &pp)))
+ { if (soap_is_embedded(soap, pp) || soap_is_single(soap, pp))
+ return 0;
+ soap_set_embedded(soap, pp);
+ }
+ return i;
+}
+#endif
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#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)
+{ 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 && pp->array->__size == 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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_pointer_enter(struct soap *soap, const void *p, int type, struct soap_plist **ppp)
+{ register struct soap_plist *pp;
+ if (!p)
+ { *ppp = NULL;
+ return 0;
+ }
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enter location=%p type=%d id=%lu\n", p, type, soap->idnum+1));
+ *ppp = pp = (struct soap_plist*)SOAP_MALLOC(sizeof(struct soap_plist));
+ if (pp)
+ { register int h = soap_hash_ptr(p);
+ pp->next = soap->pht[h];
+ pp->type = type;
+ if ((soap->mode & SOAP_XML_TREE) || soap->part == SOAP_IN_HEADER)
+ { pp->mark1 = 0;
+ pp->mark2 = 0;
+ }
+ else
+ { pp->mark1 = 1;
+ pp->mark2 = 1;
+ }
+ pp->ptr = p;
+ pp->array = NULL;
+ soap->pht[h] = pp;
+ return pp->id = ++soap->idnum;
+ }
+ return 0;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_array_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int type, struct soap_plist **ppp)
+{ struct soap_plist *pp;
+ *ppp = NULL;
+ if (!p || !a->__ptr)
+ return 0;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array enter location=%p size=%d type=%d id=%lu\n", a->__ptr, a->__size, type, soap->idnum+1));
+ *ppp = pp = (struct soap_plist*)SOAP_MALLOC(sizeof(struct soap_plist));
+ if (pp)
+ { register int h = soap_hash_ptr(a->__ptr);
+ pp->next = soap->pht[h];
+ pp->type = type;
+ if ((soap->mode & SOAP_XML_TREE) || soap->part == SOAP_IN_HEADER)
+ { pp->mark1 = 0;
+ pp->mark2 = 0;
+ }
+ else
+ { pp->mark1 = 1;
+ pp->mark2 = 1;
+ }
+ pp->ptr = p;
+ pp->array = a;
+ soap->pht[h] = pp;
+ return pp->id = ++soap->idnum;
+ }
+ return 0;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_begin_count(struct soap *soap)
+{ soap_clr_attr(soap);
+ soap_set_local_namespaces(soap);
+ if (soap->mode & SOAP_ENC_DIME)
+ soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME;
+ else
+ { soap->mode = soap->omode;
+ if (((soap->mode & (SOAP_IO_STORE | SOAP_IO_CHUNK)) || (soap->mode & SOAP_ENC_XML)) && !soap->fprepare)
+ soap->mode &= ~SOAP_IO_LENGTH;
+ else
+ soap->mode |= SOAP_IO_LENGTH;
+ }
+ 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;
+ }
+ 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->dime_count = 0; /* count # of attachments */
+ soap->dime_size = 0; /* accumulate total size of attachments */
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=%hd count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_begin_send(struct soap *soap)
+{ soap_clr_attr(soap);
+ soap_set_local_namespaces(soap);
+ soap->mode = (soap->omode & ~SOAP_IO_LENGTH) | (soap->mode & SOAP_ENC_DIME);
+ 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;
+ }
+ if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket))
+ { if (soap->count || (soap->mode & SOAP_ENC_XML))
+ soap->mode |= SOAP_IO_BUFFER;
+ else
+ soap->mode |= SOAP_IO_STORE;
+ }
+ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
+ soap_new_block(soap);
+ if (!(soap->mode & SOAP_IO_KEEPALIVE))
+ soap->keep_alive = 0;
+#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
+ 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=%hd count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_embedded(struct soap *soap, const void *p, int t)
+{ struct soap_plist *pp;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d\n", p, t));
+ if (soap_pointer_lookup(soap, p, t, &pp))
+ { pp->mark1 = 1;
+ pp->mark2 = 1;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d set to %d\n", p, t, (int)pp->mark1));
+ }
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_reference(struct soap *soap, const void *p, int t)
+{ register int i;
+ struct soap_plist *pp;
+ if (!p)
+ return 1;
+ i = soap_pointer_lookup(soap, p, t, &pp);
+ if (i)
+ { if (pp->mark1 == 0)
+ { pp->mark1 = 2;
+ pp->mark2 = 2;
+ }
+ }
+ else
+ { soap_pointer_enter(soap, p, t, &pp);
+ pp->mark1 = 0;
+ pp->mark2 = 0;
+ }
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type = %d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2));
+ return pp->mark1;
+}
+#endif
+
+/******************************************************************************/
+#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_array_pointer_enter(soap, p, a, t, &pp))
+ return 1;
+ pp->mark1 = 0;
+ pp->mark2 = 0;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p size=%d type = %d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2));
+ return pp->mark1;
+}
+#endif
+
+/******************************************************************************/
+#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->version == 1 && soap->encodingStyle && !(soap->mode & (SOAP_XML_TREE | SOAP_XML_GRAPH)) && soap->part != SOAP_IN_HEADER)
+ { if (id < 0)
+ { id = soap_pointer_lookup(soap, p, t, &pp);
+ if (id > 0 && pp)
+ { if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 2;
+ else
+ pp->mark2 = 2;
+ }
+ return -1;
+ }
+ return id;
+ }
+ if (id < 0)
+ id = soap_pointer_lookup(soap, p, t, &pp);
+ else
+ soap_pointer_lookup(soap, p, t, &pp);
+ if (id > 0 && pp)
+ { if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 1;
+ else
+ pp->mark2 = 1;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2));
+ }
+ return id;
+}
+#endif
+
+/******************************************************************************/
+#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_TREE | 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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_is_single(struct soap *soap, struct soap_plist *pp)
+{ if ((soap->mode & SOAP_XML_TREE) || 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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_is_multi(struct soap *soap, struct soap_plist *pp)
+{ if (soap->mode & SOAP_IO_LENGTH)
+ return pp->mark1 == 2;
+ return pp->mark2 == 2;
+}
+#endif
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#ifndef WITH_LEANER
+#ifndef PALM_2
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_set_attached(struct soap *soap, struct soap_plist *pp, const char *id, const char *type, const char *options, size_t size)
+{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attached id='%s' type='%s'\n", id?id:"", type?type:""));
+ if (soap->mode & SOAP_IO_LENGTH)
+ { if (pp->mark1 != 3)
+ { pp->mark1 = 3;
+ soap->dime_count++; /* one more attachment found */
+ soap->dime_size += 12; /* increase total size (DIME fields) */
+ if (id)
+ soap->dime_size += (strlen(id)+3)&(~3);
+ if (type)
+ soap->dime_size += (strlen(type)+3)&(~3);
+ if (options)
+ soap->dime_size += 4 + (((((unsigned char)options[2] << 8 | (unsigned char)options[3]))+3)&(~3));
+ soap->dime_size += (size+3)&(~3);
+ }
+ }
+ else if (pp->mark2 != 3)
+ pp->mark2 = 3;
+}
+#endif
+#endif
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#ifndef PALM_2
+static void
+soap_free_iht(struct soap *soap)
+{ register int i;
+ register struct soap_ilist *ip, *p;
+ register struct soap_flist *fp, *q;
+ 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 = q)
+ { q = fp->next;
+ SOAP_FREE(fp);
+ }
+ p = ip->next;
+ SOAP_FREE(ip);
+ }
+ soap->iht[i] = NULL;
+ }
+}
+#endif
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+struct soap_ilist *
+SOAP_FMAC2
+soap_enter(struct soap *soap, const char *id)
+{ register int 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
+
+/******************************************************************************/
+#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*));
+ if (q == (char*)soap->fault)
+ soap->fault = NULL; /* this was deallocated */
+ else if (q == (char*)soap->header)
+ soap->header = NULL; /* this was deallocated */
+ SOAP_FREE(q);
+ }
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Dealloc all data done\n"));
+ }
+}
+#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 PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_lookup_type(struct soap *soap, const char *id)
+{ register struct soap_ilist *ip;
+ if (*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
+
+/******************************************************************************/
+#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 (*id == '\0')
+ return p;
+ soap->alloced = 0;
+ if (!p)
+ p = (void**)soap_malloc(soap, sizeof(void*));
+ 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' %p (%u bytes)\n", id, 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 (!soap->blist && ip->ptr)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type='%d' (%u bytes)\n", id, t, (unsigned int)n));
+ if (ip->type != t)
+ { soap->error = SOAP_HREF;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Object mismatch: id's type='%d' href's 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***)q;
+ 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' (%u bytes)\n", id, (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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+void*
+SOAP_FMAC2
+soap_id_forward(struct soap *soap, const char *href, void *p, int t, size_t n)
+{ struct soap_ilist *ip;
+ if (!p || !*href)
+ return p;
+ ip = soap_lookup(soap, soap->href); /* lookup pointer to hash table entry for string id */
+ if (!ip)
+ { if (n >= sizeof(void*))
+ { ip = soap_enter(soap, href); /* new hash table entry for string id */
+ ip->type = t;
+ ip->size = n;
+ ip->link = NULL;
+ ip->copy = p;
+ ip->flist = NULL;
+ *(void**)p = NULL;
+ ip->ptr = NULL;
+ ip->level = 0;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first copying address %p for type %d href='%s'\n", p, t, href));
+ return p;
+ }
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding problem: copying location %p too small (%u) for href='%s'\n", p, (unsigned int)n, href));
+ soap->error = SOAP_HREF;
+ return NULL;
+ }
+ else if (ip->ptr)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying value from location %p to location %p to resolve href='%s'\n", ip->ptr, p, href));
+ memcpy(p, ip->ptr, n);
+ }
+ else if (n >= sizeof(void*))
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type %d href='%s' (prev in chain = %p)\n", p, t, href, ip->copy));
+ *(void**)p = ip->copy;
+ ip->copy = p;
+ return p;
+ }
+ else
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding problem: copying location %p too small (%u) for href='%s'\n", p, (unsigned int)n, href));
+ soap->error = SOAP_HREF; /* href to object too small to hold pointer */
+ return NULL;
+ }
+ return ip->ptr;
+}
+#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, int k)
+{ struct soap_ilist *ip;
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%d level=%d\n", id, t, p, (int)n, k));
+ soap->alloced = 0;
+ if (*id == '\0')
+ { if (!p)
+ return soap_malloc(soap, n);
+ else
+ return p;
+ }
+ ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s'\n", id));
+ if (!ip)
+ { ip = soap_enter(soap, id); /* new hash table entry for string id */
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%u\n", id, t, (unsigned int)n));
+ ip->type = t;
+ ip->size = n;
+ ip->link = NULL;
+ ip->copy = NULL;
+ ip->flist = NULL;
+ if (!p)
+ p = soap_malloc(soap, n);
+ ip->ptr = p;
+ ip->level = k;
+ }
+ else if (ip->ptr) /* storage address was forwarded */
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id));
+ if (p)
+ { soap->error = SOAP_MULTI_ID;
+ return NULL;
+ }
+ }
+ else
+ { if (!p)
+ p = soap_malloc(soap, n);
+ ip->ptr = p;
+ if (!soap->blist)
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolve link chain to point to %p\n", ip->ptr));
+ soap_resolve_ptr(ip);
+ }
+ }
+ return ip->ptr;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_end_send(struct soap *soap)
+{ 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", soap->z_crc));
+#endif
+ }
+#endif
+#ifndef WITH_LEAN
+ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
+ { char *p;
+ 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++;
+ }
+ 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);
+ }
+ 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)
+ shutdown((SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
+#else
+ if (soap_valid_socket(soap->socket) && !soap->keep_alive)
+ shutdown((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;
+ 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)
+ { 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 != ((unsigned char)soap->z_buf[0] | (unsigned long)((unsigned char)soap->z_buf[1] << 8) | (unsigned long)((unsigned char)soap->z_buf[2] << 16) | (unsigned long)((unsigned char)soap->z_buf[3] << 24)))
+ { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", soap->z_crc));
+ return soap->error = SOAP_ZLIB_ERROR;
+ }
+ if (soap->d_stream.total_out != ((unsigned char)soap->z_buf[4] | (unsigned long)((unsigned char)soap->z_buf[5] << 8) | (unsigned long)((unsigned char)soap->z_buf[6] << 16) | (unsigned long)((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)
+ if ((soap->error = soap->fdisconnect(soap)))
+ return soap->error;
+ return soap_resolve(soap);
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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;
+ }
+ if (soap->labbuf)
+ SOAP_FREE(soap->labbuf);
+ soap->labbuf = NULL;
+ soap->lablen = 0;
+ soap->labidx = 0;
+ soap_free_pht(soap);
+ soap_free_iht(soap);
+ 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
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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;
+ }
+#ifdef SOAP_DEBUG
+ soap_set_recv_logfile(soap, "RECV.log");
+ soap_set_sent_logfile(soap, "SENT.log");
+ soap_set_test_logfile(soap, "TEST.log");
+#endif
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+static void
+soap_close_logfile(struct soap *soap, int i)
+{ if (soap->fdebug[i])
+ { fclose(soap->fdebug[i]);
+ soap->fdebug[i] = NULL;
+ }
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_set_recv_logfile(struct soap *soap, const char *logfile)
+{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile);
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_set_sent_logfile(struct soap *soap, const char *logfile)
+{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile);
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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);
+ soap_init_iht(copy);
+ soap_init_pht(copy);
+ 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
+ soap_init_logs(copy);
+#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 = 1; /* default SOAP 1.1 */
+ 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;
+ 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;
+ soap->fconnect = NULL;
+ soap->fdisconnect = NULL;
+#ifndef MAC_CARBON
+ soap->faccept = tcp_accept;
+ soap->fopen = tcp_connect;
+ soap->fclose = tcp_disconnect;
+ soap->fsend = fsend;
+ soap->frecv = frecv;
+#endif
+ soap->fprepare = NULL;
+ soap->fignore = NULL;
+ soap->fplugin = fplugin;
+ soap->fdimereadopen = NULL;
+ soap->fdimewriteopen = NULL;
+ soap->fdimereadclose = NULL;
+ soap->fdimewriteclose = NULL;
+ soap->fdimeread = NULL;
+ soap->fdimewrite = NULL;
+ 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->encodingStyle = SOAP_STR_EOS;
+ 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;
+#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;
+ soap->dom = NULL;
+#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;
+#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;
+ soap_init_logs(soap);
+#endif
+/* WR[ */
+#ifdef WMW_RPM_IO
+ soap->rpmreqid = NULL;
+#endif /* WMW_RPM_IO */
+/* ]WR */
+ soap_init_iht(soap);
+ soap_init_pht(soap);
+ soap_begin(soap);
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_init1(struct soap *soap, int mode)
+{ soap_init2(soap, mode, mode);
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+SOAP_FMAC1
+void
+SOAP_FMAC2
+soap_init2(struct soap *soap, int imode, int 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';
+ soap->dime_chunksize = 0;
+ soap->dime_buflen = 0;
+ soap->dot_net_bug = 0;
+ 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);
+#ifndef WITH_LEAN
+ soap_close_logfiles(soap);
+#endif
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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_2
+static void
+soap_set_local_namespaces(struct soap *soap)
+{ if (soap->namespaces && !soap->local_namespaces)
+ { register struct Namespace *ns;
+ register size_t n = 1;
+ for (ns = soap->namespaces; ns->id; ns++)
+ n++;
+ if (n > 3)
+ { n *= sizeof(struct Namespace);
+ ns = (struct Namespace*)SOAP_MALLOC(n);
+ if (ns)
+ { memcpy(ns, soap->namespaces, n);
+ ns[0].id = "SOAP-ENV";
+ ns[1].id = "SOAP-ENC";
+ ns[2].id = "xsi";
+ if (ns[0].ns)
+ { if (!strcmp(ns[0].ns, soap_env1))
+ soap->version = 1;
+ else
+ soap->version = 2;
+ }
+ soap->local_namespaces = ns;
+ }
+ }
+ }
+}
+#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;
+ register const char *s;
+ 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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))
+ return soap->error;
+ if (soap_send_raw(soap, "<", 1))
+ return soap->error;
+ s = tag;
+ if (ns && soap->part != SOAP_IN_ENVELOPE && (soap->part == SOAP_IN_HEADER || !soap->encodingStyle))
+ { register const char *t = strchr(s, ':');
+ if (t)
+ { s = t + 1;
+ for (ns++; ns->id; ns++)
+ { if ((ns->out || ns->ns) && !strncmp(ns->id, tag, t - tag) && !ns->id[t - tag])
+ { if (soap_send(soap, s) || soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns))
+ return soap->error;
+ s = NULL;
+ break;
+ }
+ }
+ }
+ }
+ if (s)
+ if (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)
+ { if (!*soap->encodingStyle && soap->local_namespaces)
+ { 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_2
+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_2
+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_raw(soap, " ", 1)
+ || 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_2
+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
+/**/
+ if (soap->part != SOAP_IN_ENVELOPE && (soap->part == SOAP_IN_HEADER || !soap->encodingStyle) && soap->local_namespaces)
+ { const char *s = strchr(tag, ':');
+ if (s && strncmp(tag, "SOAP-ENV", s - tag))
+ tag = s + 1;
+ }
+ soap->level--;
+ if (soap_send_raw(soap, "</", 2)
+ || soap_send(soap, tag)
+ || soap_send_raw(soap, ">", 1))
+ return soap->error;
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_element_ref(struct soap *soap, const char *tag, int id, int href)
+{ int n = 0;
+ if (soap_element(soap, tag, id, NULL))
+ return soap->error;
+ if (soap->version == 2)
+ n = 1;
+ sprintf(soap->tmpbuf, "#_%d", href);
+ if (soap_attribute(soap, "href" + n, soap->tmpbuf + n)
+ || soap_element_start_end_out(soap, tag))
+ return soap->error;
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_element_href(struct soap *soap, const char *tag, int id, const char *href)
+{ if (soap_element(soap, tag, id, NULL)
+ || soap_attribute(soap, "href", href)
+ || soap_element_start_end_out(soap, tag))
+ return soap->error;
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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_2
+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_raw(soap, " ", 1)
+ || 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)
+{ if (tag && *tag == '-')
+ return SOAP_OK;
+ if (!soap_peek_element(soap))
+ { if (soap->other)
+ return soap->error = SOAP_TAG_MISMATCH;
+ if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
+ { if (tag && !soap->encodingStyle)
+ { const char *s = strchr(tag, ':');
+ if (s)
+ soap_push_default_namespace(soap, tag, s - tag);
+ }
+ soap->peeked = 0;
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" ));
+ if (soap->body)
+ soap->level++;
+ }
+ }
+ return soap->error;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_element_end_in(struct soap *soap, const char *tag)
+{ register wchar c;
+ register char *s;
+ register const char *t;
+ if (tag && *tag == '-')
+ return SOAP_OK;
+ soap->level--;
+ soap_pop_namespace(soap);
+ if (soap->peeked)
+ { if (*soap->tag == '\0')
+ { soap->peeked = 0;
+ soap->error = SOAP_OK;
+ }
+ else
+ return soap->error = SOAP_SYNTAX_ERROR;
+ }
+ else
+ { while (((c = soap_get(soap)) != TT))
+ { if ((int)c == EOF)
+ return soap->error = SOAP_EOF;
+ if (c == LT)
+ return soap->error = SOAP_SYNTAX_ERROR;
+ }
+ }
+ 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 != 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 does not match\n"));
+ return soap->error = SOAP_SYNTAX_ERROR;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+struct soap_attribute *
+SOAP_FMAC2
+soap_attr(struct soap *soap, const char *name)
+{ register struct soap_attribute *tp;
+ for (tp = soap->attributes; tp; tp = tp->next)
+ if (!soap_match_tag(soap, tp->name, name))
+ return tp;
+ return NULL;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+const char *
+SOAP_FMAC2
+soap_attr_value(struct soap *soap, const char *name)
+{ register struct soap_attribute *tp = soap_attr(soap, name);
+ if (tp && tp->visible == 2)
+ return tp->value;
+ 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, wchar d)
+{ size_t i;
+ wchar c;
+ for (i = 0; i < n; i++)
+ { c = soap_getutf8(soap);
+ switch (c)
+ {
+ case TT:
+ *s++ = '<';
+ soap_unget(soap, '/');
+ break;
+ case LT:
+ *s++ = '<';
+ break;
+ case GT:
+ if (d == ' ')
+ { soap_unget(soap, c);
+ *s = '\0';
+ return SOAP_OK;
+ }
+ *s++ = '>';
+ break;
+ case QT:
+ if (c == d)
+ { *s = '\0';
+ return SOAP_OK;
+ }
+ *s++ = '"';
+ break;
+ case 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)
+{ struct soap_attribute *tp;
+ const char *t;
+ register char *s;
+ register wchar c;
+ register int i;
+ if (soap->peeked)
+ { if (*soap->tag == '\0')
+ return soap->error = SOAP_NO_TAG;
+ return SOAP_OK;
+ }
+ soap->peeked = 1;
+ for (;;)
+ { while (((c = soap_get(soap)) != LT) && c != TT)
+ { if ((int)c == EOF)
+ return soap->error = SOAP_EOF;
+ }
+ if (c == TT)
+ { *soap->tag = '\0';
+ return soap->error = SOAP_NO_TAG; /* ending tag found */
+ }
+ 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 != GT && c != '?')
+ { s = soap->tmpbuf;
+ i = sizeof(soap->tmpbuf) - 2;
+ while (c != '=' && c != 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 != QT && c != 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_C_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);
+ soap_pop_namespace(soap);
+ while ((int)c != EOF && c != 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;
+ tp = soap_attr(soap, soap->tmpbuf);
+ 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 != QT && c != 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);
+ 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"))
+ { if (soap->part != SOAP_IN_HEADER || !soap->dot_net_bug)
+ { *soap->id = '#';
+ strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
+ }
+ }
+ else if (soap->version == 1 && !strcmp(tp->name, "href"))
+ strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
+ else if (soap->version == 2 && !strcmp(tp->name, "ref"))
+ { *soap->href = '#';
+ strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
+ }
+ else if (!soap_match_tag(soap, tp->name, "xsi:type"))
+ strncpy(soap->type, tp->value, sizeof(soap->type) - 1);
+ 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);
+ }
+ 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_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)
+{ 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 wchar c;
+ register wchar mask = 0x80000000;
+#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:
+#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
+ 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)
+{ register char *s;
+ char *t = NULL;
+ register size_t i;
+ register int n = 0;
+ register int m = 0;
+ register wchar c;
+#ifdef HAVE_WCTOMB
+ char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8];
+#else
+ char buf[8];
+#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_C_LATIN))
+ { soap_unget(soap, c);
+ c = soap_getutf8(soap);
+ if (soap->mode & SOAP_C_UTFSTRING)
+ { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < 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_get1(soap);
+ if (c == '>')
+ n--;
+ soap_unget(soap, c);
+ }
+ *s++ = '/';
+ break;
+ case '<':
+ c = soap_get1(soap);
+ if (c == '/')
+ { if (n == 0)
+ { c = TT;
+ goto end;
+ }
+ n--;
+ }
+ else if (c == '!')
+ { c = soap_get1(soap);
+ if (c == '[')
+ { do c = soap_get1(soap);
+ while ((int)c != EOF && c != '[');
+ if ((int)c == EOF)
+ goto end;
+ t = (char*)"![CDATA[";
+ state = 1;
+ }
+ else if (c == '-')
+ { if ((c = soap_get1(soap)) == '-')
+ state = 2;
+ t = (char*)"!-";
+ soap_unget(soap, c);
+ }
+ else
+ { t = (char*)"!";
+ 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:
+#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
+ *s++ = (char)(c & 0xFF);
+ }
+ }
+ }
+ }
+#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 < 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 if (soap->mode & SOAP_C_LATIN)
+ c = soap_get(soap);
+ else
+ c = soap_getutf8(soap);
+ switch (c)
+ {
+ case TT:
+ if (n == 0)
+ goto end;
+ n--;
+ *s++ = '<';
+ soap_unget(soap, '/');
+ break;
+ case LT:
+ n++;
+ *s++ = '<';
+ break;
+ case GT:
+ *s++ = '>';
+ break;
+ case QT:
+ *s++ = '"';
+ break;
+ case AP:
+ *s++ = '\'';
+ break;
+ case '/':
+ if (n > 0)
+ { c = soap_get(soap);
+ if (c == GT)
+ n--;
+ soap_unget(soap, c);
+ }
+ *s++ = '/';
+ break;
+ case '<':
+ if (flag)
+ *s++ = '<';
+ else
+ { *s++ = '&';
+ t = (char*)"lt;";
+ }
+ break;
+ case '>':
+ if (flag)
+ *s++ = '>';
+ else
+ { *s++ = '&';
+ t = (char*)"gt;";
+ }
+ break;
+ case '"':
+ if (flag)
+ *s++ = '"';
+ else
+ { *s++ = '&';
+ t = (char*)"quot;";
+ }
+ break;
+ default:
+ if ((int)c == EOF)
+ goto end;
+#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
+ *s++ = (char)(c & 0xFF);
+ }
+ }
+ }
+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);
+#endif
+ if (flag == 2)
+ if (soap_s2QName(soap, t, &t))
+ return NULL;
+ return t;
+}
+#endif
+
+/******************************************************************************/
+#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 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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+wchar_t *
+SOAP_FMAC2
+soap_wstring_in(struct soap *soap, int flag)
+{ wchar_t *s;
+ register int i, n = 0;
+ register wchar c;
+ const char *t = NULL;
+ 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;
+ }
+ if (soap->mode & SOAP_C_LATIN)
+ c = soap_get(soap);
+ else
+ c = soap_getutf8(soap);
+ switch (c)
+ {
+ case TT:
+ if (n == 0)
+ goto end;
+ n--;
+ *s++ = '<';
+ soap_unget(soap, '/');
+ break;
+ case LT:
+ n++;
+ *s++ = '<';
+ break;
+ case GT:
+ *s++ = '>';
+ break;
+ case QT:
+ *s++ = '"';
+ break;
+ case AP:
+ *s++ = '\'';
+ break;
+ case '/':
+ if (n > 0)
+ { c = soap_getutf8(soap);
+ if (c == GT)
+ n--;
+ soap_unget(soap, c);
+ }
+ *s++ = '/';
+ break;
+ case '<':
+ if (flag)
+ *s++ = (wchar)'<';
+ else
+ { *s++ = (wchar)'&';
+ t = "lt;";
+ }
+ break;
+ case '>':
+ if (flag)
+ *s++ = (wchar)'>';
+ else
+ { *s++ = (wchar)'&';
+ t = "gt;";
+ }
+ break;
+ case '"':
+ if (flag)
+ *s++ = (wchar)'"';
+ else
+ { *s++ = (wchar)'&';
+ t = "quot;";
+ }
+ break;
+ default:
+ if ((int)c == EOF)
+ goto end;
+ *s++ = (wchar_t)c & 0x7FFFFFFF;
+ }
+ }
+ }
+end:
+ soap_unget(soap, c);
+ *s = '\0';
+ soap_size_block(soap, sizeof(wchar_t) * (i + 1));
+ return (wchar_t*)soap_save_block(soap, NULL);
+}
+#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)
+{ long m = (long)*p;
+ return soap_outlong(soap, tag, id, &m, type, n);
+}
+#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)
+ return soap->error = SOAP_TYPE;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0);
+ if (p && soap->body && !*soap->href)
+ soap_s2int(soap, soap_value(soap), p);
+ else
+ p = (int*)soap_id_forward(soap, soap->href, p, t, sizeof(int));
+ 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)
+ return soap->error = SOAP_TYPE;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0);
+ if (p && soap->body && !*soap->href)
+ soap_s2long(soap, soap_value(soap), p);
+ else
+ p = (long*)soap_id_forward(soap, soap->href, p, t, sizeof(long));
+ 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)
+ return soap->error = SOAP_TYPE;
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0);
+ if (soap->body && !*soap->href)
+ soap_s2LONG64(soap, soap_value(soap), p);
+ else
+ p = (LONG64*)soap_id_forward(soap, soap->href, p, t, sizeof(LONG64));
+ 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)
+{ long m = (long)*p;
+ return soap_outlong(soap, tag, id, &m, type, n);
+}
+#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)
+ return soap->error = SOAP_TYPE;
+ *p = (char)n;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0);
+ if (soap->body && !*soap->href)
+ soap_s2byte(soap, soap_value(soap), p);
+ else
+ p = (char*)soap_id_forward(soap, soap->href, p, t, sizeof(char));
+ 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)
+{ long m = (long)*p;
+ return soap_outlong(soap, tag, id, &m, type, n);
+}
+#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)
+ return soap->error = SOAP_TYPE;
+ *p = (char)n;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0);
+ if (soap->body && !*soap->href)
+ soap_s2short(soap, soap_value(soap), p);
+ else
+ p = (short*)soap_id_forward(soap, soap->href, p, t, sizeof(short));
+ 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 (isnan(n))
+ s = "NaN";
+ else if (n >= FLT_PINFTY)
+ s = "INF";
+ else if (n <= FLT_NINFTY)
+ 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
+ {
+#ifdef HAVE_STRTOD
+ char *r;
+ *p = (float)strtod(s, &r);
+ if (*r)
+#endif
+ if (sscanf(s, soap->float_format, p) != 1)
+ return soap->error = SOAP_TYPE;
+ }
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ if (*soap->type != '\0' && soap_isnumeric(soap, type))
+ return NULL;
+ p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0);
+ if (soap->body && !*soap->href)
+ soap_s2float(soap, soap_value(soap), p);
+ else
+ p = (float*)soap_id_forward(soap, soap->href, p, t, sizeof(float));
+ 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 (isnan(n))
+ s = "NaN";
+ else if (n >= DBL_PINFTY)
+ s = "INF";
+ else if (n <= DBL_NINFTY)
+ 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
+ if (sscanf(s, soap->double_format, p) != 1)
+ return soap->error = SOAP_TYPE;
+ }
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ if (*soap->type != '\0' && soap_isnumeric(soap, type))
+ return NULL;
+ p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0);
+ if (soap->body && !*soap->href)
+ soap_s2double(soap, soap_value(soap), p);
+ else
+ p = (double*)soap_id_forward(soap, soap->href, p, t, sizeof(double));
+ 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)
+{ unsigned long m = (unsigned long)*p;
+ return soap_outunsignedLong(soap, tag, id, &m, type, n);
+}
+#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)
+ return soap->error = SOAP_TYPE;
+ *p = (unsigned char)n;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0);
+ if (soap->body && !*soap->href)
+ soap_s2unsignedByte(soap, soap_value(soap), p);
+ else
+ p = (unsigned char*)soap_id_forward(soap, soap->href, p, t, sizeof(unsigned char));
+ if (soap->body && soap_element_end_in(soap, tag))
+ return NULL;
+ return p;
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+SOAP_FMAC1
+const char*
+SOAP_FMAC2
+soap_unsignedShort2s(struct soap *soap, unsigned short n)
+{ return soap_unsignedLong2s(soap, (unsigned long)n);
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n)
+{ unsigned long m = (unsigned long)*p;
+ return soap_outunsignedLong(soap, tag, id, &m, type, n);
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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)
+ return soap->error = SOAP_TYPE;
+ *p = (unsigned short)n;
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0);
+ if (soap->body && !*soap->href)
+ soap_s2unsignedShort(soap, soap_value(soap), p);
+ else
+ p = (unsigned short*)soap_id_forward(soap, soap->href, p, t, sizeof(unsigned short));
+ 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)
+{ unsigned long m = (unsigned long)*p;
+ return soap_outunsignedLong(soap, tag, id, &m, type, n);
+}
+#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)
+ return soap->error = SOAP_TYPE;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0);
+ if (soap->body && !*soap->href)
+ soap_s2unsignedInt(soap, soap_value(soap), p);
+ else
+ p = (unsigned int*)soap_id_forward(soap, soap->href, p, t, sizeof(unsigned int));
+ 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)
+ return soap->error = SOAP_TYPE;
+ }
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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;
+ }
+ p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0);
+ if (soap->body && !*soap->href)
+ soap_s2unsignedLong(soap, soap_value(soap), p);
+ else
+ p = (unsigned long*)soap_id_forward(soap, soap->href, p, t, sizeof(unsigned long));
+ 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)
+ return soap->error = SOAP_TYPE;
+ return SOAP_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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);
+ if (soap->body && !*soap->href)
+ soap_s2ULONG64(soap, soap_value(soap), p);
+ else
+ p = (ULONG64*)soap_id_forward(soap, soap->href, p, t, sizeof(ULONG64));
+ 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)))
+ return soap->error = SOAP_EOM;
+ return SOAP_OK;
+}
+#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 = strchr(s, ':');
+ if (p)
+ { int n = p - s;
+ while (np && (np->index == -2 || 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)
+ { 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_OK;
+}
+#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)
+{ if (!*p)
+ { if (soap_element_null(soap, tag, id, type))
+ return soap->error;
+ }
+ else
+ { struct soap_plist *pp;
+ int i = soap_pointer_lookup(soap, *p, n, &pp);
+ if (id > 0)
+ { if (i)
+ { if (soap_element_begin_out(soap, tag, id, type) || soap_string_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ soap_set_embedded(soap, pp);
+ }
+ else
+ { i = soap_pointer_enter(soap, *p, n, &pp);
+ if (soap_element_begin_out(soap, tag, id, type) || soap_string_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 0;
+ else
+ pp->mark2 = 0;
+ }
+ }
+ else if (i)
+ { if (soap_is_embedded(soap, pp))
+ { if (soap_element_ref(soap, tag, 0, i))
+ return soap->error;
+ }
+ else if (soap_is_single(soap, pp))
+ { if (soap_element_begin_out(soap, tag, 0, type) || soap_string_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ }
+ else
+ { if (soap_element_begin_out(soap, tag, i, type) || soap_string_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ soap_set_embedded(soap, pp);
+ }
+ }
+ else
+ { soap_pointer_enter(soap, *p, n, &pp);
+ if (soap_element_begin_out(soap, tag, id, type) || soap_string_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 0;
+ else
+ pp->mark2 = 0;
+ }
+ }
+ 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)
+{ if (soap_element_begin_in(soap, tag))
+ return NULL;
+ if (soap->null)
+ { p = (char**)soap_id_enter(soap, soap->id, p, t, sizeof(char**), 0);
+ if (p)
+ *p = NULL;
+ }
+ else if (soap->body && !*soap->href)
+ { if (soap_match_tag(soap, soap->type, "PointerTostring") == 0)
+ { p = (char**)soap_id_enter(soap, soap->id, p, t, sizeof(char**), 0);
+ p = (char**)soap_instring(soap, "string", p, type, t, flag);
+ }
+ else
+ { if (!p)
+ if ((p = (char**)soap_id_enter(soap, SOAP_STR_EOS, p, t, sizeof(char**), 0)) == NULL)
+ return NULL;
+ *p = (char*)soap_id_enter(soap, soap->id, soap_string_in(soap, flag), t, 0, 0);
+ }
+ }
+ else
+ 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 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)
+{ if (!*p)
+ { if (soap_element_null(soap, tag, id, type))
+ return soap->error;
+ }
+ else
+ { struct soap_plist *pp;
+ int i = soap_pointer_lookup(soap, *p, n, &pp);
+ if (id > 0)
+ { if (i)
+ { if (soap_element_begin_out(soap, tag, id, type) || soap_wstring_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ soap_set_embedded(soap, pp);
+ }
+ else
+ { i = soap_pointer_enter(soap, *p, n, &pp);
+ if (soap_element_begin_out(soap, tag, id, type) || soap_wstring_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 0;
+ else
+ pp->mark2 = 0;
+ }
+ }
+ else if (i)
+ { if (soap_is_embedded(soap, pp))
+ { if (soap_element_ref(soap, tag, 0, i))
+ return soap->error;
+ }
+ else if (soap_is_single(soap, pp))
+ { if (soap_element_begin_out(soap, tag, 0, type) || soap_wstring_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ }
+ else
+ { if (soap_element_begin_out(soap, tag, i, type) || soap_wstring_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ soap_set_embedded(soap, pp);
+ }
+ }
+ else
+ { if (soap_element_begin_out(soap, tag, id, type) || soap_wstring_out(soap, *p, 0) || soap_element_end_out(soap, tag))
+ return soap->error;
+ if (soap->mode & SOAP_IO_LENGTH)
+ pp->mark1 = 0;
+ else
+ pp->mark2 = 0;
+ }
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#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)
+{ if (soap_element_begin_in(soap, tag))
+ return NULL;
+ if (soap->null)
+ { p = (wchar_t**)soap_id_enter(soap, soap->id, p, t, sizeof(wchar_t**), 0);
+ if (p)
+ *p = NULL;
+ }
+ else if (soap->body && !*soap->href)
+ { if (soap_match_tag(soap, soap->type, "PointerTostring") == 0)
+ p = (wchar_t**)soap_inwstring(soap, "string", (wchar_t**)soap_id_enter(soap, soap->id, p, t, sizeof(wchar_t**), 0), type, t);
+ else
+ { if (!p)
+ if (!(p = (wchar_t**)soap_id_enter(soap, SOAP_STR_EOS, p, t, sizeof(wchar_t**), 0)))
+ return NULL;
+ *p = (wchar_t*)soap_id_enter(soap, soap->id, soap_wstring_in(soap, 1), t, 0, 0);
+ }
+ }
+ else
+ 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
+
+/******************************************************************************/
+#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;
+ gettimeofday(&tv, &t); /* doesn't work properly on Solaris */
+ T->tm_min -= t.tz_minuteswest;
+ T->tm_isdst = (t.tz_dsttime != 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;
+ t.timezone = 0;
+ t.dstflag = -1;
+ ftime(&t);
+ T->tm_min -= t.timezone;
+ T->tm_isdst = t.dstflag; /* doesn't work properly on Solaris */
+ 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 t;
+#if defined(HAVE_LOCALTIME_R)
+ if (localtime_r(&n, pT))
+ { struct timeval tv;
+ gettimeofday(&tv, &t);
+ strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
+ sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.tz_minuteswest/60-(t.tz_dsttime!=0), abs(t.tz_minuteswest)%60);
+ }
+#else
+ if ((pT = localtime(&n)))
+ { struct timeval tv;
+ gettimeofday(&tv, &t);
+ strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
+ sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.tz_minuteswest/60-(t.tz_dsttime!=0), abs(t.tz_minuteswest)%60);
+ }
+#endif
+#elif defined(HAVE_FTIME)
+ struct timeb 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(&T, 0, sizeof(struct tm));
+ 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_OK;
+}
+#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))
+ return NULL;
+ if (soap->null)
+ { if (soap->mode & SOAP_XML_NIL)
+ { soap->error = SOAP_NULL;
+ return NULL;
+ }
+ return p;
+ }
+ 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);
+ if (soap->body && !*soap->href)
+ soap_s2dateTime(soap, soap_value(soap), p);
+ else
+ p = (time_t*)soap_id_forward(soap, soap->href, p, t, sizeof(time_t));
+ 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, "</%s>", 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))
+ return NULL;
+ if (!p)
+ if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
+ return NULL;
+ if (soap->null)
+ *p = NULL;
+ else if (soap->body)
+ *p = soap_string_in(soap, 0);
+ else
+ *p = NULL;
+ if (soap->body && soap_element_end_in(soap, tag))
+ return NULL;
+ return p;
+}
+#endif
+
+/******************************************************************************/
+#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, "</%s>", t);
+ return soap_send(soap, soap->tmpbuf);
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#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))
+ return NULL;
+ if (!p)
+ if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
+ return NULL;
+ if (soap->null)
+ *p = NULL;
+ else if (soap->body)
+ *p = soap_wstring_in(soap, 0);
+ else
+ *p = NULL;
+ if (soap->body && soap_element_end_in(soap, tag))
+ return NULL;
+ return p;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+char *
+SOAP_FMAC2
+soap_value(struct soap *soap)
+{ size_t i;
+ wchar c = 0;
+ char *s;
+ s = soap->tmpbuf;
+ for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++)
+ { c = soap_get(soap);
+ if (c == TT || (int)c == EOF || soap_blank(c))
+ break;
+ *s++ = (char)c;
+ }
+ if ((int)c == EOF || c == TT)
+ soap_unget(soap, c);
+ *s = '\0';
+ return soap->tmpbuf; /* return non-null pointer */
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_getline(struct soap *soap, char *s, int len)
+{ int i = len;
+ wchar c = 0;
+ for (;;)
+ { while (--i > 0)
+ { c = soap_getchar(soap);
+ if (c == '\r' || c == '\n' || (int)c == EOF)
+ break;
+ *s++ = (char)c;
+ }
+ *s = '\0';
+ while (c != '\n' && (int)c != EOF)
+ c = soap_getchar(soap);
+ if ((int)c == EOF)
+ return SOAP_EOF;
+ if (i+1 == len) /* empty line: end of HTTP header */
+ break;
+ c = soap_unget(soap, soap_getchar(soap));
+ if (c != ' ' && c != '\t') /* HTTP line continuation? */
+ break;
+ }
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static size_t
+soap_begin_dime(struct soap *soap)
+{
+#ifndef WITH_LEANER
+ if (soap->mode & SOAP_ENC_DIME)
+ { size_t count;
+ 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;
+ count = soap->dime_size + 12 + ((soap->count+3)&(~3)) + ((strlen(soap->dime_id)+3)&(~3)) + ((strlen(soap->dime_type)+3)&(~3));
+ soap->dime_size = soap->count;
+ if (soap->dime_count)
+ soap->dime_flags = SOAP_DIME_MB | SOAP_DIME_ABSURI;
+ else
+ soap->dime_flags = SOAP_DIME_MB | SOAP_DIME_ME | SOAP_DIME_ABSURI;
+ return count;
+ }
+#endif
+ return soap->count;
+}
+#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 type, 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] = type >> 8;
+ s[1] = type & 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, int i, char *id, char *type, char *options, void *ptr, size_t size)
+{ void *h;
+ if (id)
+ soap->dime_id = id;
+ else
+ { sprintf(soap->id, soap->dime_id_format, i);
+ soap->dime_id = soap->id;
+ }
+ soap->dime_type = type;
+ soap->dime_options = options;
+ soap->dime_size = size;
+ soap->dime_flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA;
+ if (soap->fdimereadopen && ((h = soap->fdimereadopen(soap, (void*)ptr, soap->dime_id, type, options)) || soap->error))
+ { size_t n;
+ if (!h)
+ { 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))
+ { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n"));
+ n = sizeof(soap->tmpbuf);
+ do
+ { size = soap->fdimeread(soap, h, soap->tmpbuf, n);
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size));
+ if (size == n)
+ soap->dime_flags |= SOAP_DIME_CF;
+ else
+ { soap->dime_flags &= ~SOAP_DIME_CF;
+ if (--soap->dime_count == 0)
+ soap->dime_flags |= SOAP_DIME_ME;
+ }
+ soap->dime_size = size;
+ if (soap_putdimehdr(soap)
+ || soap_send_raw(soap, soap->tmpbuf, size)
+ || soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime_size&3))
+ 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 >= n);
+ }
+ else
+ { if (--soap->dime_count == 0)
+ soap->dime_flags |= SOAP_DIME_ME;
+ if (soap_putdimehdr(soap))
+ return soap->error;
+ do
+ { if (size < sizeof(soap->tmpbuf))
+ n = size;
+ else
+ n = sizeof(soap->tmpbuf);
+ if (!(n = soap->fdimeread(soap, h, soap->tmpbuf, n)))
+ { 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, n))
+ break;
+ size -= n;
+ } 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, h);
+ return soap->error;
+ }
+ if (--soap->dime_count == 0)
+ soap->dime_flags |= SOAP_DIME_ME;
+ if (soap_putdimehdr(soap))
+ return soap->error;
+ return soap_putdimefield(soap, (char*)ptr, size);
+}
+#endif
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEANER
+#ifndef PALM_1
+static char *
+soap_getdimefield(struct soap *soap, size_t n)
+{ register 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 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_EOD;
+ 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=%u flags=0x%X\n", (unsigned int)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)
+{ 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))
+ { 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)
+ { char *id, *type, *options;
+ register 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)))
+ return soap->error;
+ soap->dime_ptr[soap->dime_size] = '\0'; /* make 0-terminated to enable string-based attachments */
+ soap->dime_id = id;
+ soap->dime_type = type;
+ soap->dime_options = options;
+ }
+ else
+ soap->dime_ptr = soap_getdimefield(soap, soap->dime_size);
+ return soap->error;
+}
+#endif
+#endif
+
+/******************************************************************************/
+
+#ifdef WITH_COOKIES
+/******************************************************************************/
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_encode_cookie(const char *s, char *t, int len)
+{ register int c;
+ register int n = len;
+ while ((c = *s++) && --n > 0)
+ { if (c > ' ' && c < 128 && c != ';' && 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
+const char*
+SOAP_FMAC2
+soap_decode_cookie(char *buf, int len, const char *val)
+{ const char *s;
+ char *t;
+ for (s = val; *s; s++)
+ if (*s != ' ' && *s != '=')
+ break;
+ if (*s == '"')
+ { t = buf;
+ s++;
+ while (*s && *s != '"' && --len)
+ *t++ = *s++;
+ *t = '\0';
+ do s++;
+ while (*s && *s != ';' && *s != '=');
+ }
+ else
+ { t = buf;
+ while (*s && *s != ';' && *s != '=' && --len)
+ switch (*s)
+ { case ' ':
+ s++;
+ break;
+ case '%':
+ *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4)
+ + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0');
+ s += 3;
+ break;
+ default:
+ *t++ = *s++;
+ }
+ *t = '\0';
+ }
+ return s;
+}
+
+/******************************************************************************/
+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)
+ { *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);
+ strcpy(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)
+ { sprintf(s, ";Version=%u", p->version);
+ s += strlen(s);
+ }
+ if (p->expire >= 0)
+ { sprintf(s, ";Max-Age=%ld", p->expire);
+ s += strlen(s);
+ }
+ if (p->secure)
+ strcpy(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)
+ { *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_cookie(tmp, sizeof(tmp), s);
+ if (!soap_tag_cmp(tmp, "$Version"))
+ { if ((s = soap_decode_cookie(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_cookie(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_cookie(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"))
+ { s = soap_decode_cookie(tmp, sizeof(tmp), s);
+ if (p->path)
+ SOAP_FREE(p->path);
+ 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"))
+ { s = soap_decode_cookie(tmp, sizeof(tmp), s);
+ if (p->domain)
+ SOAP_FREE(p->domain);
+ 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_cookie(tmp, sizeof(tmp), s);
+ p->version = (unsigned int)atol(tmp);
+ }
+ else if (p && !soap_tag_cmp(tmp, "Max-Age"))
+ { s = soap_decode_cookie(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_cookie(tmp, sizeof(tmp), s);
+ memset(&T, 0, sizeof(struct tm));
+ 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_cookie(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 (*s == ';')
+ s++;
+ }
+ 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_cookie(key, sizeof(key), s);
+ s = soap_decode_cookie(val, sizeof(val), s);
+ p = soap_set_cookie(soap, key, val, NULL, NULL);
+ if (p)
+ p->env = 1;
+ if (*s == ';')
+ s++;
+ } 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_2
+static int
+soap_getgzipheader(struct soap *soap)
+{ int i;
+ 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_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_begin_recv(struct soap *soap)
+{ wchar c;
+ soap_set_local_namespaces(soap);
+ soap->version = 0; /* don't assume we're parsing SOAP content by default */
+ soap_free_iht(soap);
+ 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->dime_chunksize = 0;
+ soap->dime_buflen = 0;
+#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
+ c = soap_getchar(soap);
+ if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20)
+ soap->mode |= SOAP_ENC_DIME;
+#ifdef WITH_GZIP
+ else if (c == 0x1F)
+ { if (soap_getgzipheader(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;
+ }
+#endif
+ else
+ { if (c == 0xEF && !(soap->mode & SOAP_C_LATIN))
+ { soap_unget(soap, c);
+ c = soap_getutf8(soap);
+ if (c == 0xFEFF)
+ c = soap_getchar(soap);
+ }
+ while (soap_blank(c))
+ c = soap_getchar(soap);
+ }
+ if ((int)c == EOF)
+ return soap->error = SOAP_EOF;
+ soap_unget(soap, c);
+ if (c != '<' && !(soap->mode & (SOAP_ENC_DIME | SOAP_ENC_ZLIB)))
+ { soap->mode &= ~SOAP_IO;
+ if ((soap->error = soap->fparse(soap)))
+ { if (soap->error == 307) /* HTTP redirect */
+ { soap_getline(soap, soap->endpoint, sizeof(soap->endpoint));
+ soap->keep_alive = 0; /* force close when soap_closesock() */
+ }
+ return soap->error;
+ }
+ if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
+ { soap->chunkbuflen = soap->buflen;
+ soap->buflen = soap->bufidx;
+ soap->chunksize = 0;
+ }
+#ifdef WITH_ZLIB
+ if (soap->zlib_in)
+ { /* fparse should not use soap_unget */
+#ifdef WITH_GZIP
+ c = soap_get1(soap);
+ if (c == 0x1F)
+ { if (soap_getgzipheader(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
+ }
+#ifndef WITH_LEANER
+ 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 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_EOF;
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf));
+ for (;;)
+ { if (soap_getline(soap, header, SOAP_HDRLEN))
+ return SOAP_EOF;
+ 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
+
+/******************************************************************************/
+#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';
+ }
+ else if (!soap_tag_cmp(key, "Content-Type"))
+ { if (!soap_tag_cmp(val, "*application/dime*"))
+ soap->mode |= SOAP_ENC_DIME;
+ }
+ 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_tag_cmp(val, "*gzip*"))
+ soap->zlib_out = SOAP_ZLIB_GZIP;
+ else
+#endif
+ if (strchr(val, '*') || !soap_tag_cmp(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);
+ }
+ }
+ }
+#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';
+ }
+ }
+/* [ Deal with .NET bug (invalid XML id-ref) */
+ else if (!soap_tag_cmp(key, "Server"))
+ { if (!soap_tag_cmp(val, "Microsoft-IIS*"))
+ soap->dot_net_bug = 1;
+ }
+ else if (!soap_tag_cmp(key, "User-Agent"))
+ { if (!soap_tag_cmp(val, "*.NET CLR*") || !soap_tag_cmp(val, "*MS Web Services Client Protocol*"))
+ soap->dot_net_bug = 1;
+ }
+/* ] */
+#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
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_envelope_begin_out(struct soap *soap)
+{ 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;
+ soap->part = SOAP_END_ENVELOPE;
+#ifndef WITH_LEANER
+ if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME))
+ return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->count&3);
+#endif
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_envelope_begin_in(struct soap *soap)
+{ soap->part = SOAP_IN_ENVELOPE;
+ if (soap_element_begin_in(soap, "SOAP-ENV:Envelope"))
+ return soap->error = SOAP_VERSIONMISMATCH;
+ return soap->error;
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_2
+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_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");
+}
+#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;
+ 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);
+ if (soap->fconnect)
+ {
+ if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port)))
+ return soap->error;
+ }
+ else if (*soap->host)
+ { soap->status = http_command;
+ if (!soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port)
+ { soap->keep_alive = 0; /* force close */
+ soap_closesock(soap);
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect 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);
+ }
+ else if (!soap->keep_alive || soap_poll(soap))
+ { soap->keep_alive = 0; /* force close */
+ soap_closesock(soap);
+ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "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;
+ }
+ }
+ count = soap_begin_dime(soap);
+ if (soap_begin_send(soap))
+ return soap->error;
+ 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;
+ if ((k & SOAP_IO) == SOAP_IO_CHUNK)
+ { if (soap_flush(soap))
+ return soap->error;
+ }
+ soap->mode = k;
+ }
+ if (http_command != SOAP_POST)
+ return soap_end_send(soap);
+#ifndef WITH_LEANER
+ if (soap->mode & SOAP_ENC_DIME)
+ return soap_putdimehdr(soap);
+#endif
+ return SOAP_OK;
+}
+#endif
+
+/******************************************************************************/
+#ifndef WITH_LEAN
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_s2base64(struct soap *soap, const unsigned char *s, char *t, size_t n)
+{ register size_t i;
+ register unsigned long m;
+ if (!t)
+ return SOAP_EOM;
+ t[0] = '\0';
+ if (!s)
+ return SOAP_OK;
+ for (; n > 2; n -= 3, s += 3)
+ { m = ((unsigned long)((unsigned char*)s)[0] << 16) | ((unsigned long)((unsigned char*)s)[1] << 8) | (unsigned long)((unsigned char*)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 SOAP_OK;
+}
+#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 PALM_1
+SOAP_FMAC1
+int
+SOAP_FMAC2
+soap_puthttphdr(struct soap *soap, int status, size_t count)
+{ const char *s;
+ if (status == SOAP_FILE)
+ s = soap->http_content;
+ else if (status == SOAP_HTML)
+ s = "text/html; charset=utf-8";
+ else 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";
+ soap->error = soap->fposthdr(soap, "Content-Type", s);
+ if (soap->error)
+ return soap->error;
+#ifdef WITH_ZLIB
+ if (soap->omode & SOAP_ENC_ZLIB)
+#ifdef WITH_GZIP
+ soap->error = soap->fposthdr(soap, "Content-Encoding", "gzip");
+#else
+ soap->error = soap->fposthdr(soap, "Content-Encoding", "deflate");
+#endif
+#endif
+ if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
+ soap->error = soap->fposthdr(soap, "Transfer-Encoding", "chunked");
+ else if (count > 0)
+ { sprintf(soap->tmpbuf, "%lu", (unsigned long)count);
+ soap->error = soap->fposthdr(soap, "Content-Length", soap->tmpbuf);
+ }
+ if (soap->error)
+ return soap->error;
+ return soap->error = soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close");
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static int
+http_get(struct soap *soap)
+{ return SOAP_GET_METHOD;
+}
+#endif
+
+/******************************************************************************/
+#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)
+{ const char *s;
+ if (soap->status == SOAP_GET)
+ { s = "GET";
+ count = 0;
+ }
+ else
+ s = "POST";
+#ifndef PALM
+ if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)))
+#else
+ 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))
+#endif
+ return SOAP_OK;
+ if (soap->proxy_host)
+ 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 ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
+ return soap->error;
+ if (port != 80)
+ sprintf(soap->tmpbuf, "%s:%d", host, port);
+ else
+ strcpy(soap->tmpbuf, host);
+ if ((soap->error = soap->fposthdr(soap, "Host", soap->tmpbuf))
+ || (soap->error = soap->fposthdr(soap, "User-Agent", "gSOAP/2.6"))
+ || (soap->error = soap_puthttphdr(soap, SOAP_OK, count)))
+ return soap->error;
+#ifdef WITH_ZLIB
+#ifdef WITH_GZIP
+ if ((soap->error = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate")))
+#else
+ if ((soap->error = soap->fposthdr(soap, "Accept-Encoding", "deflate")))
+#endif
+ return soap->error;
+#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 ((soap->error = soap->fposthdr(soap, "Authorization", soap->tmpbuf)))
+ return soap->error;
+ }
+ 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
+#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)
+ { sprintf(soap->tmpbuf, "\"%s\"", action);
+ if ((soap->error = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf)))
+ return soap->error;
+ }
+ return soap->error = soap->fposthdr(soap, NULL, NULL);
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static int
+http_post_header(struct soap *soap, const char *key, const char *val)
+{ if (key)
+ { if (soap_send(soap, key))
+ return soap->error;
+ if (val && (soap_send(soap, ": ") || soap_send(soap, val)))
+ return soap->error;
+ }
+ return soap_send(soap, "\r\n");
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+static int
+http_response(struct soap *soap, int status, size_t count)
+{
+/* 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 ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
+ return soap->error;
+ }
+ else if ((soap->error = soap->fposthdr(soap, "Status", "200 OK")))
+ return soap->error;
+ }
+ else if (status > 200 && status < 600)
+ { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status));
+ if ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
+ return soap->error;
+ if (status == 401)
+ if ((soap->error = soap->fposthdr(soap, "WWW-Authenticate", "Basic realm=\"gSOAP Service\"")))
+ return soap->error;
+ }
+ else
+ { const char *s = *soap_faultcode(soap);
+ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error\n"));
+ if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender"))
+ s = "400 Bad Request";
+ else
+ s = "500 Internal Server Error";
+/* 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 ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
+ return soap->error;
+ }
+ else if ((soap->error = soap->fposthdr(soap, "Status", s)))
+ return soap->error;
+ }
+ if ((soap->error = soap->fposthdr(soap, "Server", "gSOAP/2.6"))
+ || (soap->error = soap_puthttphdr(soap, status, count)))
+ return soap->error;
+#ifdef WITH_COOKIES
+ if (soap_putsetcookies(soap))
+ return soap->error;
+#endif
+ return soap->error = soap->fposthdr(soap, NULL, NULL);
+}
+#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_begin_dime(soap);
+ if (soap_begin_send(soap))
+ return soap->error;
+ 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;
+ if ((n & SOAP_IO) == SOAP_IO_CHUNK)
+ { if (soap_flush(soap))
+ return soap->error;
+ }
+ soap->mode = n;
+ }
+#ifndef WITH_LEANER
+ if (soap->mode & SOAP_ENC_DIME)
+ return soap_putdimehdr(soap);
+#endif
+ return SOAP_OK;
+}
+#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)
+ { case SOAP_CLI_FAULT:
+ *s = "Client fault";
+ break;
+ case SOAP_SVR_FAULT:
+ *s = "Server fault";
+ break;
+ case SOAP_TAG_MISMATCH:
+ sprintf(soap->msgbuf, "Tag mismatch: element '%s' does not correspond to expected element", soap->tag);
+ *s = soap->msgbuf;
+ break;
+ case SOAP_TYPE:
+ sprintf(soap->msgbuf, "Data type '%s' mismatch in element '%s'", soap->type, soap->tag);
+ *s = soap->msgbuf;
+ break;
+ case SOAP_SYNTAX_ERROR:
+ *s = "XML syntax error";
+ 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_DIME_MISMATCH:
+ *s = "DIME version mismatch";
+ break;
+ case SOAP_NAMESPACE:
+ sprintf(soap->msgbuf, "Namespace URI mismatch in element '%s'", soap->tag);
+ *s = soap->msgbuf;
+ break;
+ case SOAP_OBJ_MISMATCH:
+ *s = "Object mismatch";
+ break;
+ case SOAP_FATAL_ERROR:
+ *s = "Fatal error";
+ break;
+ case SOAP_NO_METHOD:
+ sprintf(soap->msgbuf, "Method '%s' not implemented", 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:
+ sprintf(soap->msgbuf, "Cannot create nilable object for type '%s' in element '%s'", soap->type, soap->tag);
+ *s = soap->msgbuf;
+ break;
+ case SOAP_MULTI_ID:
+ *s = "Non-unique id attribute";
+ break;
+ case SOAP_MISSING_ID:
+ *s = "Missing id: referenced data is missing or had to be ignored";
+ break;
+ case SOAP_HREF:
+ *s = "Invalid XML: object reference with href attribute is incompatible with actual object referred to";
+ break;
+ case SOAP_FAULT:
+ break;
+ case SOAP_TCP_ERROR:
+ *s = tcp_error(soap);
+ break;
+ 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_ERROR:
+ *s = "DIME 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_EOD:
+ *s = "End of DIME error";
+ break;
+ case SOAP_REQUIRED:
+ *s = "Validation failure: XML attribute required";
+ break;
+ case SOAP_OCCURS:
+ *s = "Validation failure: XML element occurs count";
+ break;
+ case SOAP_EOF:
+ sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap));
+ *s = soap->msgbuf;
+ break;
+ default:
+ if (soap->error > 200 && soap->error < 600)
+ { sprintf(soap->msgbuf, "HTTP Error: '%s'", http_error(soap, soap->error));
+ *s = soap->msgbuf;
+ }
+ else
+ *s = "Unknown error code";
+ }
+}
+#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_poll(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_closesock(soap);
+ return soap->error = status;
+}
+#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 PALM_1
+static const char*
+soap_strerror(struct soap *soap)
+{ int err = soap->errnum;
+ if (!err)
+ err = soap_errno;
+ if (err)
+ {
+#ifndef UNDER_CE
+ return strerror(err);
+#else
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&soap->werrorstr, 256, NULL);
+ wcstombs(soap->errorstr, soap->werrorstr, 256);
+ return soap->errorstr;
+#endif
+ }
+ return "Operation interrupted or timed out";
+}
+#endif
+
+/******************************************************************************/
+#ifndef PALM_1
+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_1
+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_1
+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_1
+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_1
+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_1
+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_1
+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
+
+/******************************************************************************/
+#ifndef PALM_1
+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';
+ soap->buf[soap->buflen - 1] = '\0';
+ if (soap->bufidx < soap->buflen)
+ fprintf(fd, "%s%c\n** HERE **\n%s\n", soap->buf, c, soap->buf + soap->bufidx);
+ else
+ fprintf(fd, "%s%c\n** HERE **\n", soap->buf, c);
+ }
+#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_1
+SOAP_FMAC1
+void *
+SOAP_FMAC2
+soap_lookup_plugin(struct soap *soap, const char *id)
+{ return soap->fplugin(soap, id);
+}
+#endif
+
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
--- /dev/null
+#include <iostream>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+
+#include "glite_gss.h"
+
+class GSSTest: public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(GSSTest);
+ CPPUNIT_TEST(echo);
+ CPPUNIT_TEST(errorTest);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void echo();
+ void errorTest();
+
+ void setUp();
+
+private:
+ gss_cred_id_t my_cred;
+ char * my_subject;
+ int sock, port;
+ struct timeval timeout;
+
+ void replier();
+
+};
+
+
+void GSSTest::replier() {
+ edg_wll_GssConnection conn;
+ edg_wll_GssStatus stat;
+ struct sockaddr_in a;
+ socklen_t alen = sizeof(a);
+ int s, len;
+ char buf[100];
+
+
+ if ( (s = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) exit(1);
+
+ if ( edg_wll_gss_accept(my_cred, s, &timeout, &conn, &stat) ) exit(1);
+
+ while ( (len = edg_wll_gss_read(&conn, buf, sizeof(buf), &timeout, &stat)) >= 0 ) {
+ if ( edg_wll_gss_write(&conn, buf, len, &timeout, &stat) ) exit(1);
+ }
+
+ exit(0);
+}
+
+
+void GSSTest::setUp(void) {
+ pid_t pid;
+ edg_wll_GssStatus stat;
+ struct sockaddr_in a;
+ socklen_t alen = sizeof(a);
+ char * cred_file = NULL;
+ char * key_file = NULL;
+
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ key_file = cred_file = getenv("X509_USER_PROXY");
+ CPPUNIT_ASSERT_MESSAGE("credential file", cred_file);
+
+ if (edg_wll_gss_acquire_cred_gsi(cred_file, key_file, &my_cred, &my_subject, &stat))
+ CPPUNIT_ASSERT_MESSAGE("gss_acquire_cred", 0);
+
+ sock = socket(PF_INET,SOCK_STREAM,0);
+ CPPUNIT_ASSERT_MESSAGE("socket()", sock >= 0);
+
+ a.sin_family = AF_INET;
+ a.sin_port = 0;
+ a.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(sock,(struct sockaddr *) &a,sizeof(a))) {
+ CPPUNIT_ASSERT_MESSAGE("bind()", 0);
+ }
+
+ if (listen(sock,1)) {
+ CPPUNIT_ASSERT_MESSAGE("listen()", 0);
+ }
+
+ getsockname(sock,(struct sockaddr *) &a,&alen);
+ port = ntohs(a.sin_port);
+
+ if ( !(pid = fork()) ) replier();
+ else close(sock);
+}
+
+
+
+void GSSTest::echo()
+{
+ edg_wll_GssConnection conn;
+ edg_wll_GssStatus stat;
+ size_t total;
+ int err;
+ char buf[] = "f843fejwfanczn nc4*&686%$$&^(*)*#$@WSH";
+ char buf2[100];
+
+
+ err = edg_wll_gss_connect(my_cred, "localhost", port, &timeout, &conn, &stat);
+ CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_connect()", !err);
+
+ err = edg_wll_gss_write(&conn, buf, strlen(buf)+1, &timeout, &stat);
+ CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_write()", !err);
+
+ err = edg_wll_gss_read_full(&conn, buf2, strlen(buf)+1, &timeout, &total, &stat);
+ CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_read_full()", !err);
+
+ CPPUNIT_ASSERT(strlen(buf)+1 == total && !strcmp(buf,buf2) );
+
+ edg_wll_gss_close(&conn, &timeout);
+
+}
+
+
+void GSSTest::errorTest()
+{
+ edg_wll_GssConnection conn;
+ edg_wll_GssStatus stat;
+ int err;
+ char * msg = NULL;
+
+
+ err = edg_wll_gss_connect(my_cred, "xxx.porno.net", port, &timeout, &conn, &stat);
+ if (err) edg_wll_gss_get_error(&stat, "gss_connect()", &msg);
+ CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_get_error()", msg);
+}
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( GSSTest );
+
+int main (int ac,const char *av[])
+{
+ CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+ CppUnit::TextUi::TestRunner runner;
+
+ runner.addTest(suite);
+ return runner.run() ? 0 : 1;
+}
glite_location=$PREFIX
globus_prefix=/opt/globus
-voms_prefix=/opt/glite
nothrflavour=gcc32
thrflavour=gcc32pthr
myproxy_prefix=$globus_prefix
DEBUG:=-g -O0
-# XXX: until VOMS is ready in SCM
-CFLAGS:= -DNOVOMS \
- ${DEBUG} \
- -DVOMS_INSTALL_PATH=\"${voms_prefix}\"\
+CFLAGS:= ${DEBUG} \
${MYPROXYINC} \
-I${top_srcdir}/src -I${top_srcdir}/interface \
-I${glite_location}/include
LINK:=libtool --mode=link ${CC} ${LDFLAGS}
INSTALL:=libtool --mode=install install
-DAEMONOBJ:=renewd.o renew.o common.o commands.o api.o
+DAEMONOBJ:=renewd.o renew.o common.o commands.o api.o voms.o
LIBOBJ:=api.o common.o
CLIENTOBJ:=client.o
${LINK} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib
${DAEMON}: ${DAEMONOBJ}
- ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB} -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS}
+ ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB} -lvomsc -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS}
${CLIENT}: ${CLIENTOBJ} ${LIB}
${LINK} -o $@ ${CLIENTOBJ} ${LIB} ${GLOBUS_LIBS}
${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h ${PREFIX}/include/glite/security/proxyrenewal
- ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/${DAEMON}
+ ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-proxy-renewald
clean:
Revision history:
$Log$
+ Revision 1.4 2004/11/02 15:10:43 dkouril
+ RPM description
+
Revision 1.3 2004/07/30 08:31:07 dimeglio
Changed default Ant target from compile to dist
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
+ <property file="${module.build.file}" />
<!-- ==============================================
Local private targets
PROXY_REPOSITORY="$GLITE_LOCATION_VAR/spool/glite-renewd"
+unset creds
+
start()
{
if test -z "$GLITE_USER" ;then
return 1
fi
- if [ -n "$GLITE_HOST_CERT" ]; then
- X509_USER_CERT="$GLITE_HOST_CERT"
- export X509_USER_CERT
+ [ -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
- if [ -n "$GLITE_HOST_KEY" ]; then
- X509_USER_KEY="$GLITE_HOST_KEY"
- export X509_USER_KEY
+
+ [ -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 ...
chmod 0700 $PROXY_REPOSITORY
fi
- su - $GLITE_USER -c "$GLITE_LOCATION/bin/glite-proxy-renewd \
- -r $PROXY_REPOSITORY" && echo " done"
+ 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 ..."
- PIDS=`ps -C glite-proxy-renewd -o pid --no-heading`
- if [ -z "$PIDS" ]; then
- echo " no process glite-proxy-renewd running"
- exit 1
- else
- kill $PIDS && echo " done"
- fi
+ killall glite-proxy-renewd
+ echo " done"
}
status()
{
- PIDS=`ps -C glite-proxy-renewd -o pid --no-heading`
- if ps p $PIDS >/dev/null 2>&1; then
- echo glite-proxy-renewd running \($PIDS\)
- return 0
+ 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
-
- echo glite-proxy-renewd not running
- return 1
}
case x$1 in
EDG_WLPR_PROXY_NOT_REGISTERED,
EDG_WLPR_PROXY_EXPIRED,
EDG_WLPR_ERROR_VOMS,
+ EDG_WLPR_ERROR_TIMEOUT,
+ EDG_WLPR_ERROR_ERRNO,
} edg_wlpr_ErrorCode;
/**
--- /dev/null
+#Fri Apr 08 04:14:02 CEST 2005
+module.build=224
-#Fri Dec 10 13:12:42 CET 2004
-module.version=0.1.1
-module.build=104
-module.age=1
+
+module.version = 1.0.13
+module.age = 1
+
--- /dev/null
+/*********************************************************************
+ *
+ * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it
+ *
+ * Copyright (c) 2002, 2003 INFN-CNAF on behalf of the EU DataGrid.
+ * For license conditions see LICENSE file or
+ * http://www.edg.org/license.html
+ *
+ * Parts of this code may be based upon or even include verbatim pieces,
+ * originally written by other people, in which case the original header
+ * follows.
+ *
+ *********************************************************************/
+#ifndef _ACSTACK_H
+#define _ACSTACK_H
+
+#include <openssl/asn1.h>
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#define IMPL_STACK(type) \
+ DECLARE_STACK_OF(type) \
+ STACK_OF(type) *sk_##type##_new (int (*cmp)(const type * const *, const type * const *)) \
+ { return sk_new ( (int (*)(const char * const *, const char * const *))cmp);} \
+ STACK_OF(type) *sk_##type##_new_null () { return sk_new_null(); } \
+ void sk_##type##_free (STACK_OF(type) *st) { sk_free(st); } \
+ int sk_##type##_num (const STACK_OF(type) *st) { return sk_num(st); } \
+ type *sk_##type##_value (const STACK_OF(type) *st, int i) { return (type *)sk_value(st, i); } \
+ type *sk_##type##_set (STACK_OF(type) *st, int i, type *val) { return ((type *)sk_set(st, i, (char *)val)); } \
+ void sk_##type##_zero (STACK_OF(type) *st) { sk_zero(st);} \
+ int sk_##type##_push (STACK_OF(type) *st, type *val) { return sk_push(st, (char *)val); } \
+ int sk_##type##_unshift (STACK_OF(type) *st, type *val) { return sk_unshift(st, (char *)val); } \
+ int sk_##type##_find (STACK_OF(type) *st, type *val) { return sk_find(st, (char *)val); } \
+ type *sk_##type##_delete (STACK_OF(type) *st, int i) { return (type *)sk_delete(st, i); } \
+ type *sk_##type##_delete_ptr (STACK_OF(type) *st, type *ptr) { return (type *)sk_delete_ptr(st, (char *)ptr); } \
+ int sk_##type##_insert (STACK_OF(type) *st, type *val, int i) { return sk_insert(st, (char *)val, i); } \
+ int (*sk_##type##_set_cmp_func (STACK_OF(type) *st, int (*cmp)(const type * const *, const type * const *)))(const type * const *, const type * const *) \
+ { return (int ((*)(const type * const *, const type * const *)))sk_set_cmp_func (st, (int (*)(const char * const *, const char * const *))cmp); } \
+ STACK_OF(type) *sk_##type##_dup (STACK_OF(type) *st) { return sk_dup(st); } \
+ void sk_##type##_pop_free (STACK_OF(type) *st, void (*func)(type *)) { sk_pop_free(st, (void (*)(void *))func); } \
+ type *sk_##type##_shift (STACK_OF(type) *st) { return (type *)sk_shift(st); } \
+ type *sk_##type##_pop (STACK_OF(type) *st) { return (type *)sk_pop(st); } \
+ void sk_##type##_sort (STACK_OF(type) *st) { sk_sort(st); } \
+ STACK_OF(type) *d2i_ASN1_SET_OF_##type (STACK_OF(type) **st, unsigned char **pp, long length, type *(*d2ifunc)(), void (*freefunc)(type *), int ex_tag, int ex_class) \
+ { return d2i_ASN1_SET(st, pp, length, (char *(*)())d2ifunc, (void (*)(void *))freefunc, ex_tag, ex_class); } \
+ int i2d_ASN1_SET_OF_##type (STACK_OF(type) *st, unsigned char **pp, int (*i2dfunc)(), int ex_tag, int ex_class, int is_set) \
+ { return i2d_ASN1_SET(st, pp, i2dfunc, ex_tag, ex_class, is_set); } \
+ unsigned char *ASN1_seq_pack_##type (STACK_OF(type) *st, int (*i2d)(), unsigned char **buf, int *len) { return ASN1_seq_pack(st, i2d, buf, len); } \
+ STACK_OF(type) *ASN1_seq_unpack_##type (unsigned char *buf, int len, type *(*d2i)(), void (*freefunc)(type *)) \
+ { return ASN1_seq_unpack(buf, len, (char *(*)())d2i, (void (*)(void *))freefunc); }
+
+
+#define DECL_STACK(type) \
+ DECLARE_STACK_OF(type) \
+ extern STACK_OF(type) *sk_##type##_new (int (*)(const type * const *, const type * const *)); \
+ extern STACK_OF(type) *sk_##type##_new_null (); \
+ extern void sk_##type##_free (STACK_OF(type) *); \
+ extern int sk_##type##_num (const STACK_OF(type) *); \
+ extern type *sk_##type##_value (const STACK_OF(type) *, int); \
+ extern type *sk_##type##_set (STACK_OF(type) *, int, type *); \
+ extern void sk_##type##_zero (STACK_OF(type) *); \
+ extern int sk_##type##_push (STACK_OF(type) *, type *); \
+ extern int sk_##type##_unshift (STACK_OF(type) *, type *); \
+ extern int sk_##type##_find (STACK_OF(type) *, type *); \
+ extern type *sk_##type##_delete (STACK_OF(type) *, int); \
+ extern type *sk_##type##_delete_ptr (STACK_OF(type) *, type *); \
+ extern int sk_##type##_insert (STACK_OF(type) *, type *, int); \
+ extern int (*sk_##type##_set_cmp_func (STACK_OF(type) *, int (*)(const type * const *, const type * const *)))(const type * const *, const type * const *); \
+ extern STACK_OF(type) *sk_##type##_dup (STACK_OF(type) *); \
+ extern void sk_##type##_pop_free (STACK_OF(type) *, void (*)(type *)); \
+ extern type *sk_##type##_shift (STACK_OF(type) *); \
+ extern type *sk_##type##_pop (STACK_OF(type) *); \
+ extern void sk_##type##_sort (STACK_OF(type) *); \
+ extern STACK_OF(type) *d2i_ASN1_SET_OF_##type (STACK_OF(type) **, unsigned char **, long, type *(*)(), void (*)(type *), int, int); \
+ extern int i2d_ASN1_SET_OF_##type (STACK_OF(type) *, unsigned char **, int (*)(), int, int, int); \
+ extern unsigned char *ASN1_seq_pack_##type (STACK_OF(type) *, int (*)(), unsigned char **, int *); \
+ extern STACK_OF(type) *ASN1_seq_unpack_##type (unsigned char *, int, type *(*)(), void (*)(type *)) ;
+
+#endif
decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response);
static int
-do_connect(char *socket_name, int *sock);
+do_connect(char *socket_name, struct timeval *timeout, int *sock);
static int
-send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response);
-
+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)
}
static int
-do_connect(char *socket_name, int *sock)
+do_connect(char *socket_name, struct timeval *timeout, int *sock)
{
struct sockaddr_un my_addr;
int s;
int ret;
+ struct timeval before,after,to;
+ int sock_err;
+ socklen_t err_len;
assert(sock != NULL);
memset(&my_addr, 0, sizeof(my_addr));
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) {
- close(s);
- return errno;
+ if (errno == EINPROGRESS) {
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ memcpy(&to, timeout, sizeof(to));
+ gettimeofday(&before,NULL);
+ switch (select(s+1, NULL, &fds, NULL, &to)) {
+ 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;
}
static int
-send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response)
+send_request(int sock, struct timeval *timeout, edg_wlpr_Request *request, edg_wlpr_Response *response)
{
int ret;
char *buf = NULL;
if (ret)
return ret;
- ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ ret = edg_wlpr_Write(sock, timeout, buf, strlen(buf) + 1);
free(buf);
if (ret)
return ret;
- ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ ret = edg_wlpr_Read(sock, timeout, &buf, &buf_len);
if (ret)
return ret;
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, &sock);
+ ret = do_connect(sockname, &timeout, &sock);
if (ret)
return ret;
- ret = send_request(sock, request, response);
+ ret = send_request(sock, &timeout, request, response);
close(sock);
return ret;
"Proxy not registered",
"Proxy expired",
"VOMS error",
+ "Operation timed out",
+ "System error"
};
const char *
#include "renewal_locl.h"
#include "renewd_locl.h"
-#ifndef NOVOMS
-#include <voms_apic.h>
-#endif
+#include "glite/security/voms/voms_apic.h"
#ident "$Header$"
#define SEPARATORS ",\n"
#define RENEWAL_START_FRACTION 0.75 /* XXX */
-#define RENEWAL_CLOCK_SKEW (5 * 60)
#define RENEWAL_MIN_LIFETIME (15 * 60)
extern char *repository;
static time_t
get_delta(time_t current_time, time_t start_time, time_t end_time)
{
- time_t length, lifetime;
+ time_t remaining_life;
+ time_t life_to_lose;
+ time_t limit;
time_t delta;
- int condor_tested = 0;
- lifetime = end_time - start_time;
- delta = 0;
- while (1) {
- if (end_time - current_time <= RENEWAL_MIN_LIFETIME)
- /* if the proxy is too short, renew it as soon as possible */
- return RENEWAL_CLOCK_SKEW;
-
- /* renewal starts at 3/4 of lifetime */
- length = end_time - (start_time + delta);
- delta += length * RENEWAL_START_FRACTION;
-
- if (!condor_tested && delta > lifetime - condor_limit) {
- /* Condor requires the proxies to be renewed a specified time interval
- before the proxies have expired (see the
- GRIDMANAGER_MINIMUM_PROXY_TIME variable). We must ensure that
- renewal takes place before Condor does this check */
- if (current_time > end_time - condor_limit) {
- edg_wlpr_Log(LOG_ERR, "Proxy lifetime exceeded value of the Condor limit!");
- }
- else
- delta = lifetime - condor_limit - RENEWAL_CLOCK_SKEW;
- condor_tested = 1;
- }
+ if (RENEWAL_MIN_LIFETIME > condor_limit) {
+ limit = RENEWAL_MIN_LIFETIME;
+ } else {
+ limit = condor_limit;
+ }
- if (abs(current_time - (start_time + delta)) < RENEWAL_CLOCK_SKEW)
- continue;
-
- return (start_time + delta) - current_time;
- };
+ limit += RENEWAL_CLOCK_SKEW;
- /* not reachable */
- return 0;
+ 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 ) {
+ edg_wlpr_Log(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
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(&tmp_record);
p = strchr(line, '\n');
if (p)
*p = '\0';
ret = decode_record(line, &tmp_record);
- if (ret)
- return ret; /* XXX continue */
+ if (ret) {
+ edg_wlpr_Log(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;
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 */
- char *server = record->myproxy_server;
-
- memset(record, sizeof(*record), 0);
record->suffix = tmp_record.suffix;
- if (record->myproxy_server)
- free(record->myproxy_server);
- record->myproxy_server = server;
+ record->next_renewal = record->end_time = 0;
free_record(&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 &&
- tmp_record.end_time - current_time < condor_limit) {
- /* skip expired proxy (and that ones that are going to expire soon),
+ 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 */
+ renewal process) */
+
continue;
}
proxy_record tmp_record;
char tmp_file[FILENAME_MAX];
char meta_file[FILENAME_MAX];
+ int line_num = 0;
assert (record != NULL);
goto end;
}
while (fgets(line, sizeof(line), fd) != NULL) {
+ line_num++;
free_record(&tmp_record);
p = strchr(line, '\n');
if (p)
*p = '\0';
ret = decode_record(line, &tmp_record);
- if (ret)
- goto end;
+ if (ret) {
+ edg_wlpr_Log(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;
return EDG_WLPR_ERROR_VOMS;
}
- ret = load_proxy(file, &cert, &privkey, &chain);
+ ret = load_proxy(file, &cert, &privkey, &chain, NULL);
if (ret) {
VOMS_Destroy(voms_info);
return ret;
free_record(&record);
record.suffix = suffix;
record.myproxy_server = server;
- edg_wlpr_Log(LOG_WARNING, "Removed expired proxy (suffix %d)",
- suffix);
+ edg_wlpr_Log(LOG_WARNING, "Removed expired proxy %s", cur_proxy);
} else
get_times(cur_proxy, &record);
} else {
#ident "$Header$"
/* nread() and nwrite() never return partial data */
-static size_t
-nread(int sock, char *buf, size_t buf_len)
+static int
+nread(int sock, struct timeval *to, char *buf, size_t buf_len, size_t *read_len)
{
size_t count;
size_t remain = buf_len;
char *cbuf = buf;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
while (remain > 0) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) {
+ 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
- return count;
+ else {
+ ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
} else
if (count == 0) {
- return count;
+ *read_len = 0;
+ return 0;
}
cbuf += count;
remain -= count;
}
- return buf_len;
+ *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 size_t
-nwrite(int sock, const char *buf, size_t buf_len)
+nwrite(int sock, struct timeval *to, const char *buf, size_t buf_len)
{
const char *cbuf = buf;
size_t count;
size_t remain = buf_len;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
while (remain > 0) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) {
+ 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
- return count;
+ else {
+ ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
}
cbuf += count;
remain -= count;
}
- return buf_len;
+ ret = buf_len;
+
+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, char **buf, size_t *buf_len)
+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, length, 4);
- if (ret == -1) {
+ ret = nread(sock, timeout, length, 4, &len);
+ if (ret) {
*buf_len = 0;
- return errno;
+ return ret;
}
- if (ret < 4) {
+ if (len != 4) {
*buf_len = 0;
return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX vraci i kdyz peer spadne a zavre trubku */
}
if (*buf == NULL)
return ENOMEM;
- ret = nread(sock, *buf, *buf_len);
- if (ret != *buf_len) {
+ ret = nread(sock, timeout, *buf, *buf_len, &len);
+ if (ret)
+ return ret;
+
+ if (len != *buf_len) {
free(*buf);
*buf_len = 0;
- return errno;
+ return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX */
}
return 0;
}
int
-edg_wlpr_Write(int sock, char *buf, size_t buf_len)
+edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len)
{
unsigned char length[4];
length[2] = (buf_len >> 8) & 0xFF;
length[3] = (buf_len >> 0) & 0xFF;
- if (nwrite(sock, length, 4) != 4 ||
- nwrite(sock, buf, buf_len) != buf_len)
+ if (nwrite(sock, timeout, length, 4) != 4 ||
+ nwrite(sock, timeout, buf, buf_len) != buf_len)
return errno;
return 0;
*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);
+}
--- /dev/null
+/*********************************************************************
+ *
+ * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it
+ *
+ * Copyright (c) 2002, 2003 INFN-CNAF on behalf of the EU DataGrid.
+ * For license conditions see LICENSE file or
+ * http://www.edg.org/license.html
+ *
+ * Parts of this code may be based upon or even include verbatim pieces,
+ * originally written by other people, in which case the original header
+ * follows.
+ *
+ *********************************************************************/
+#ifndef _NEW_FORMAT_H
+#define _NEW_FORMAT_H
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#include "acstack.h"
+#if 0
+static STACK_OF(CRYPT_EX_DATA_FUNS) *AC_meth = NULL;
+
+static AC_METHOD meth = {
+ (int (*)()) i2d_AC,
+ (char *(*)())d2i_AC,
+ (char *(*)())AC_new,
+ (void (*)()) AC_free};
+a
+ASN1_METHOD *AC_asn1_meth(void)
+{
+ return &meth;
+}
+#endif
+
+typedef struct ACDIGEST {
+ ASN1_ENUMERATED *type;
+ ASN1_OBJECT *oid;
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *digest;
+} AC_DIGEST;
+
+typedef struct ACIS {
+ STACK_OF(GENERAL_NAME) *issuer;
+ ASN1_INTEGER *serial;
+ ASN1_BIT_STRING *uid;
+} AC_IS;
+
+typedef struct ACFORM {
+ STACK_OF(GENERAL_NAME) *names;
+ AC_IS *is;
+ AC_DIGEST *digest;
+} AC_FORM;
+
+typedef struct ACACI {
+ STACK_OF(GENERAL_NAME) *names;
+ AC_FORM *form;
+} AC_ACI;
+
+typedef struct ACHOLDER {
+ AC_IS *baseid;
+ STACK_OF(GENERAL_NAMES) *name;
+ AC_DIGEST *digest;
+} AC_HOLDER;
+
+typedef struct ACVAL {
+ ASN1_GENERALIZEDTIME *notBefore;
+ ASN1_GENERALIZEDTIME *notAfter;
+} AC_VAL;
+
+typedef struct asn1_string_st AC_IETFATTRVAL;
+
+typedef struct ACIETFATTR {
+ STACK_OF(GENERAL_NAMES) *names;
+ STACK_OF(AC_IETFATTRVAL) *values;
+} AC_IETFATTR;
+
+typedef struct ACTARGET {
+ GENERAL_NAME *name;
+ GENERAL_NAME *group;
+ AC_IS *cert;
+} AC_TARGET;
+
+typedef struct ACTARGETS {
+ STACK_OF(AC_TARGET) *targets;
+} AC_TARGETS;
+
+typedef struct ACATTR {
+ ASN1_OBJECT *type;
+ STACK_OF(AC_IETFATTR) *ietfattr;
+} AC_ATTR;
+
+typedef struct ACINFO {
+ ASN1_INTEGER *version;
+ AC_HOLDER *holder;
+ AC_FORM *form;
+ X509_ALGOR *alg;
+ ASN1_INTEGER *serial;
+ AC_VAL *validity;
+ STACK_OF(AC_ATTR) *attrib;
+ ASN1_BIT_STRING *id;
+ STACK_OF(X509_EXTENSION) *exts;
+} AC_INFO;
+
+typedef struct ACC {
+ AC_INFO *acinfo;
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *signature;
+} AC;
+
+typedef struct ACSEQ {
+ STACK_OF(AC) *acs;
+} AC_SEQ;
+
+DECL_STACK(AC_TARGET)
+DECL_STACK(AC_TARGETS)
+DECL_STACK(AC_IETFATTR)
+DECL_STACK(AC_IETFATTRVAL)
+DECL_STACK(AC_ATTR)
+DECL_STACK(AC);
+DECL_STACK(AC_INFO);
+DECL_STACK(AC_VAL);
+DECL_STACK(AC_HOLDER);
+DECL_STACK(AC_ACI);
+DECL_STACK(AC_FORM);
+DECL_STACK(AC_IS);
+DECL_STACK(AC_DIGEST);
+
+extern int i2d_AC_ATTR(AC_ATTR *a, unsigned char **pp);
+extern AC_ATTR *d2i_AC_ATTR(AC_ATTR **a, unsigned char **p, long length);
+extern AC_ATTR *AC_ATTR_new();
+extern void AC_ATTR_free(AC_ATTR *a);
+extern int i2d_AC_IETFATTR(AC_IETFATTR *a, unsigned char **pp);
+extern AC_IETFATTR *d2i_AC_IETFATTR(AC_IETFATTR **a, unsigned char **p, long length);
+extern AC_IETFATTR *AC_IETFATTR_new();
+extern void AC_IETFATTR_free (AC_IETFATTR *a);
+extern int i2d_AC_IETFATTRVAL(AC_IETFATTRVAL *a, unsigned char **pp);
+extern AC_IETFATTRVAL *d2i_AC_IETFATTRVAL(AC_IETFATTRVAL **a, unsigned char **pp, long length);
+extern AC_IETFATTRVAL *AC_IETFATTRVAL_new();
+extern void AC_IETFATTRVAL_free(AC_IETFATTRVAL *a);
+extern int i2d_AC_DIGEST(AC_DIGEST *a, unsigned char **pp);
+extern AC_DIGEST *d2i_AC_DIGEST(AC_DIGEST **a, unsigned char **pp, long length);;
+extern AC_DIGEST *AC_DIGEST_new(void);
+extern void AC_DIGEST_free(AC_DIGEST *a);
+extern int i2d_AC_IS(AC_IS *a, unsigned char **pp);
+extern AC_IS *d2i_AC_IS(AC_IS **a, unsigned char **pp, long length);
+extern AC_IS *AC_IS_new(void);
+extern void AC_IS_free(AC_IS *a);
+extern int i2d_AC_FORM(AC_FORM *a, unsigned char **pp);
+extern AC_FORM *d2i_AC_FORM(AC_FORM **a, unsigned char **pp, long length);
+extern AC_FORM *AC_FORM_new(void);
+extern void AC_FORM_free(AC_FORM *a);
+extern int i2d_AC_ACI(AC_ACI *a, unsigned char **pp);
+extern AC_ACI *d2i_AC_ACI(AC_ACI **a, unsigned char **pp, long length);
+extern AC_ACI *AC_ACI_new(void);
+extern void AC_ACI_free(AC_ACI *a);
+
+extern int i2d_AC_HOLDER(AC_HOLDER *a, unsigned char **pp);
+extern AC_HOLDER *d2i_AC_HOLDER(AC_HOLDER **a, unsigned char **pp, long length);
+extern AC_HOLDER *AC_HOLDER_new(void);
+extern void AC_HOLDER_free(AC_HOLDER *a);
+
+/* new AC_VAL functions by Valerio */
+extern int i2d_AC_VAL(AC_VAL *a, unsigned char **pp);
+extern AC_VAL *d2i_AC_VAL(AC_VAL **a, unsigned char **pp, long length);
+extern AC_VAL *AC_VAL_new(void);
+extern void AC_VAL_free(AC_VAL *a);
+/* end*/
+
+extern int i2d_AC_INFO(AC_INFO *a, unsigned char **pp);
+extern AC_INFO *d2i_AC_INFO(AC_INFO **a, unsigned char **p, long length);
+extern AC_INFO *AC_INFO_new(void);
+extern void AC_INFO_free(AC_INFO *a);
+extern int i2d_AC(AC *a, unsigned char **pp) ;
+extern AC *d2i_AC(AC **a, unsigned char **pp, long length);
+extern AC *AC_new(void);
+extern void AC_free(AC *a);
+extern int i2d_AC_TARGETS(AC_TARGETS *a, unsigned char **pp) ;
+extern AC_TARGETS *d2i_AC_TARGETS(AC_TARGETS **a, unsigned char **pp, long length);
+extern AC_TARGETS *AC_TARGETS_new(void);
+extern void AC_TARGETS_free(AC_TARGETS *a);
+extern int i2d_AC_TARGET(AC_TARGET *a, unsigned char **pp) ;
+extern AC_TARGET *d2i_AC_TARGET(AC_TARGET **a, unsigned char **pp, long length);
+extern AC_TARGET *AC_TARGET_new(void);
+extern void AC_TARGET_free(AC_TARGET *a);
+extern int i2d_AC_SEQ(AC_SEQ *a, unsigned char **pp) ;
+extern AC_SEQ *d2i_AC_SEQ(AC_SEQ **a, unsigned char **pp, long length);
+extern AC_SEQ *AC_SEQ_new(void);
+extern void AC_SEQ_free(AC_SEQ *a);
+
+#endif
#include "renewal_locl.h"
#include "renewd_locl.h"
-#ifndef NOVOMS
-#include <voms_apic.h>
-#endif
+#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;
extern char *vomsconf;
-extern struct vomses_records vomses;
-static int received_signal = -1;
+static int received_signal = -1, die = 0;
static void
-check_renewal(char *datafile, int force_renew);
+check_renewal(char *datafile, int force_renew, int *num_renewed);
static int
renew_proxy(proxy_record *record, char *basename, char **new_proxy);
static void
register_signal(int signal);
-
-#define DGPR_RETRIEVE_DEFAULT_HOURS 10
-#define RENEWAL_CLOCK_SKEW 5 * 60
-
-static const char *
-get_ssl_err()
-{
- return "SSL failed";
-}
-
int
-load_proxy(const char *filename, X509 **cert, EVP_PKEY **privkey,
- STACK_OF(X509) **chain)
+load_proxy(const char *cur_file, X509 **cert, EVP_PKEY **priv_key,
+ STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy)
{
- X509 *my_cert = NULL;
- EVP_PKEY *my_key = NULL;
- STACK_OF(X509) *my_chain = NULL;
- FILE *fd = NULL;
+ globus_result_t result;
+ globus_gsi_cred_handle_t proxy = NULL;
int ret;
- fd = fopen(filename, "r");
- if (fd == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot read VOMS certificate (fopen() failed on %s: %s)",
- filename, strerror(errno));
- return errno;
- }
-
- my_cert = PEM_read_X509(fd, NULL, NULL, NULL);
- if (my_cert == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot read VOMS certificate (PEM_read_X509() failed: %s)",
- get_ssl_err());
- ret = EDG_WLPR_ERROR_SSL;
- goto end;
- }
-
- my_key = PEM_read_PrivateKey(fd, NULL, NULL, NULL);
- if (my_key == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot read VOMS certificate (PEM_read_PrivateKey() failed: %s)",
- get_ssl_err());
- ret = EDG_WLPR_ERROR_SSL;
+ result = globus_gsi_cred_handle_init(&proxy, NULL);
+ if (result) {
+ fprintf(stderr, "globus_gsi_cred_handle_init() failed\n");
goto end;
}
- my_chain = sk_X509_new_null();
- if (my_chain == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot read VOMS certificate (sk_X509_new_null() failed: %s)",
- get_ssl_err());
- ret = EDG_WLPR_ERROR_SSL;
+ result = globus_gsi_cred_read_proxy(proxy, cur_file);
+ if (result) {
+ fprintf(stderr, "globus_gsi_cred_read_proxy() failed\n");
goto end;
}
- while (1) {
- X509 *c;
-
- c = PEM_read_X509(fd, NULL, NULL, NULL);
- if (c == NULL) {
- if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) {
- /* End of file reached. no error */
- ERR_clear_error();
- break;
- }
- edg_wlpr_Log(LOG_ERR,
- "Cannot read VOMS certificate (PEM_read_X509() failed: %s)",
- get_ssl_err());
- ret = EDG_WLPR_ERROR_SSL;
+ if (cert) {
+ result = globus_gsi_cred_get_cert(proxy, cert);
+ if (result) {
+ fprintf(stderr, "globus_gsi_cred_get_cert() failed\n");
goto end;
}
- sk_X509_push(my_chain, c);
}
- *cert = my_cert;
- *privkey = my_key;
- *chain = my_chain;
- my_cert = NULL; my_key = NULL; my_chain = NULL;
- ret = 0;
-
-end:
- fclose(fd);
-
- if (my_cert)
- X509_free(my_cert);
- if (my_key)
- EVP_PKEY_free(my_key);
- if (my_chain)
- sk_X509_pop_free(my_chain, X509_free);
-
- return ret;
-}
-
-static int
-save_proxy(const char *filename, X509 *new_cert, EVP_PKEY *new_privkey,
- STACK_OF(X509) *chain)
-{
- FILE *fd = NULL;
- int ret, i;
- int retval = EDG_WLPR_ERROR_SSL;
-
- fd = fopen(filename, "w");
- if (fd == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot store proxy (fopen() failed on %s: %s)",
- filename, strerror(errno));
- return errno;
- }
-
- ret = PEM_write_X509(fd, new_cert);
- if (ret == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot store proxy (PEM_write_X509() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- ret = PEM_write_PrivateKey(fd, new_privkey, NULL, NULL, 0, NULL, NULL);
- if (ret == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot store proxy (PEM_write_PrivateKey() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- for (i = 0; i < sk_X509_num(chain); i++) {
- X509 *cert = sk_X509_value(chain, i);
- ret = PEM_write_X509(fd, cert);
- if (ret == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot store proxy (PEM_write_X509() failed: %s)",
- get_ssl_err());
+ 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;
}
}
-
- retval = 0;
-
-end:
- fclose(fd);
-
- return retval;
-}
-
-static int
-gen_keypair(EVP_PKEY **keypair, int requested_bits)
-{
- RSA *rsa = NULL;
- EVP_PKEY *key;
-
- *keypair = NULL;
- rsa = RSA_generate_key(requested_bits,
- RSA_F4 /* public exponent */,
- NULL, NULL);
- if (rsa == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (RSA_generate_key() failed: %s)",
- get_ssl_err());
- return EDG_WLPR_ERROR_SSL;
- }
-
- key = EVP_PKEY_new();
- if (key == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (EVP_PKEY_new() failed: %s)",
- get_ssl_err());
- RSA_free(rsa);
- return EDG_WLPR_ERROR_SSL;
- }
-
- if (EVP_PKEY_assign_RSA(key, rsa) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (EVP_PKEY_assign_RSA() failed: %s)",
- get_ssl_err());
- RSA_free(rsa);
- EVP_PKEY_free(key);
- return EDG_WLPR_ERROR_SSL;
- }
-
- *keypair = key;
-
- return 0;
-}
-
-static int
-gen_subject_name(X509 *old_cert, X509 *new_cert)
-{
- X509_NAME *name = NULL;
- X509_NAME_ENTRY *name_entry = NULL;
- int ret = EDG_WLPR_ERROR_SSL;
-
- name = X509_NAME_dup(X509_get_subject_name(old_cert));
- if (name == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_NAME_dup() failed: %s",
- get_ssl_err());
- goto end;
- }
-
- name_entry = X509_NAME_ENTRY_create_by_NID(NULL /* make new entry */,
- NID_commonName,
- V_ASN1_APP_CHOOSE,
- "proxy", -1);
- if (name_entry == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_NAME_ENTRY_create_by_NID() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- if (X509_NAME_add_entry(name, name_entry, X509_NAME_entry_count(name), 0) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_NAME_add_entry() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
-
- if (X509_set_subject_name(new_cert, name) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_set_subject_name() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- ret = 0;
-
-end:
- if (name)
- X509_NAME_free(name);
- if (name_entry != NULL)
- X509_NAME_ENTRY_free(name_entry);
-
- return ret;
-}
-
-static int
-create_proxy(X509 *old_cert, EVP_PKEY *old_privkey, X509_EXTENSION *extension,
- X509 **new_cert, EVP_PKEY **new_privkey)
-{
- /* Inspired by code from Myproxy */
- EVP_PKEY *key_pair = NULL;
- X509 *cert = NULL;
- int ret;
- int retval = EDG_WLPR_ERROR_SSL;
-
- ret = gen_keypair(&key_pair, 512);
- if (ret)
- return ret;
-
- cert = X509_new();
- if (cert == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (X509_new() failed: Not enough memory)");
- goto end;
- }
-
- ret = gen_subject_name(old_cert, cert);
- if (ret) {
- retval = ret;
- goto end;
- }
-
- if (X509_set_issuer_name(cert, X509_get_subject_name(old_cert)) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_set_issuer_name() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- if (X509_set_serialNumber(cert, X509_get_serialNumber(old_cert)) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_set_serialNumber() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- X509_gmtime_adj(X509_get_notBefore(cert), -(60 * 5));
- X509_set_notAfter(cert, X509_get_notAfter(old_cert));
-
- if (X509_set_pubkey(cert, key_pair) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_set_pubkey() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- /* set v3 */
- if (X509_set_version(cert, 2L) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_set_version() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- if (cert->cert_info->extensions != NULL)
- sk_X509_EXTENSION_pop_free(cert->cert_info->extensions,
- X509_EXTENSION_free);
- cert->cert_info->extensions = sk_X509_EXTENSION_new_null();
- sk_X509_EXTENSION_push(cert->cert_info->extensions, extension);
-
- if (X509_sign(cert, old_privkey, EVP_md5()) == 0) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (X509_sign() failed: %s)",
- get_ssl_err());
- goto end;
- }
-
- *new_privkey = key_pair;
- *new_cert = cert;
- key_pair = NULL;
- cert = NULL;
-
- retval = 0;
-
-end:
- if (key_pair)
- EVP_PKEY_free(key_pair);
- if (cert)
- X509_free(cert);
-
- return retval;
-}
-
-static int
-create_voms_extension(char *buf, size_t buf_len, X509_EXTENSION **extensions)
-{
- ASN1_OBJECT *voms_obj = NULL;
- ASN1_OCTET_STRING *voms_oct = NULL;
-
- *extensions = NULL;
-
- voms_oct = ASN1_OCTET_STRING_new();
- if (voms_oct == NULL) {
- edg_wlpr_Log(LOG_ERR,
- "Cannot generate new proxy (ASN1_OCTET_STRING_new() failed: %s)",
- get_ssl_err());
- return EDG_WLPR_ERROR_SSL;
- }
-
- voms_oct->data = buf;
- voms_oct->length = buf_len;
-
- voms_obj = OBJ_nid2obj(OBJ_txt2nid("VOMS"));
- if (voms_obj == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (OBJ_nid2obj() failed");
- goto end;
- }
-
- *extensions = X509_EXTENSION_create_by_OBJ(NULL, voms_obj, 0, voms_oct);
- if (*extensions == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (X509_EXTENSION_create_by_OBJ() failed");
- goto end;
- }
-
- return 0;
-
-end:
- if (voms_oct)
- ASN1_OCTET_STRING_free(voms_oct);
- if (voms_obj)
- ASN1_OBJECT_free(voms_obj);
- return EDG_WLPR_ERROR_SSL;
-}
-
-#ifndef NOVOMS
-static int
-export_std_data(struct data *voms_data, char **buf)
-{
- asprintf(buf, "GROUP: %s\n"
- "ROLE:%s\n" /* the space is missing intentionaly */
- "CAP: %s\n",
- (voms_data->group) ? voms_data->group : "NULL",
- (voms_data->role) ? voms_data->role : "NULL",
- (voms_data->cap) ? voms_data->cap : "NULL");
- return 0;
-}
-
-static int
-export_user_data(struct voms *voms_cert, char **buf, size_t *len)
-{
- struct data **voms_data;
- char *str = NULL;
- char *ptr;
-
- *buf = NULL;
-
- switch (voms_cert->type) {
- case TYPE_NODATA:
- *buf = strdup("NO DATA");
- break;
- case TYPE_CUSTOM:
- *buf = strdup(voms_cert->custom);
- break;
- case TYPE_STD:
- for (voms_data = voms_cert->std; voms_data && *voms_data; voms_data++) {
- export_std_data(*voms_data, &str);
- if (*buf == NULL)
- ptr = calloc(strlen(str) + 1, 1);
- else
- ptr = realloc(*buf, strlen(*buf) + strlen(str) + 1);
- if (ptr == NULL) {
- return ENOMEM;
- }
- *buf = ptr;
- strcat(*buf, str);
- free(str);
- }
-
- break;
- default:
- return -1;
- }
-
- *len = strlen(*buf);
- return 0;
-}
-
-#endif
-
-static int
-encode_voms_buf(const char *label, char *data, size_t data_len,
- char **buf, size_t *buf_len)
-{
- char *tmp;
-
- tmp = realloc(*buf, *buf_len + strlen(label) + data_len + 1);
- if (tmp == NULL)
- return ENOMEM;
-
- memcpy(tmp + *buf_len, label, strlen(label));
-
- memcpy(tmp + *buf_len + strlen(label), data, data_len);
- tmp[*buf_len + strlen(label) + data_len] = '\n';
- *buf = tmp;
- *buf_len = *buf_len + strlen(label) + data_len + 1;
- return 0;
-}
-
-static int
-encode_voms_int(const char *label, int value, char **buf, size_t *buf_len)
-{
- char tmp[16];
-
- snprintf(tmp, sizeof(tmp), "%d", value);
- return encode_voms_buf(label, tmp, strlen(tmp), buf, buf_len);
-}
-
-static int
-encode_voms_str(const char *label, char *value, char **buf, size_t *buf_len)
-{
- return encode_voms_buf(label, value, strlen(value), buf, buf_len);
-}
-
-#if 0
-static int
-VOMS_Export(struct vomsdata *voms_info, char **buf, size_t *len)
-{
- struct voms *vc;
- char *enc_voms = NULL;
- size_t enc_voms_len = 0;
- char *data_buf;
- size_t data_len;
- int ret;
-
- if (voms_info == NULL || voms_info->data == NULL || *voms_info->data == NULL)
- return EINVAL;
- vc = *voms_info->data;
-
- ret = export_user_data(vc, &data_buf, &data_len);
- if (ret)
- return ret;
-
- encode_voms_int("SIGLEN:", vc->siglen, &enc_voms, &enc_voms_len);
- encode_voms_buf("SIGNATURE:",vc->signature, vc->siglen,
- &enc_voms, &enc_voms_len);
- enc_voms_len--; /* Signature is not followed by '\n' */
- encode_voms_str("USER:", vc->user, &enc_voms, &enc_voms_len);
- encode_voms_str("UCA:", vc->userca, &enc_voms, &enc_voms_len);
- encode_voms_str("SERVER:", vc->server, &enc_voms, &enc_voms_len);
- encode_voms_str("SCA:", vc->serverca, &enc_voms, &enc_voms_len);
- encode_voms_str("VO:", vc->voname, &enc_voms, &enc_voms_len);
- encode_voms_str("URI:", vc->uri, &enc_voms, &enc_voms_len);
- encode_voms_str("TIME1:", vc->date1, &enc_voms, &enc_voms_len);
- encode_voms_str("TIME2:", vc->date2, &enc_voms, &enc_voms_len);
- encode_voms_int("DATALEN:", data_len, &enc_voms, &enc_voms_len);
- encode_voms_buf("", data_buf, data_len, &enc_voms, &enc_voms_len);
- enc_voms_len--; /* the data already contains endind '\n' */
-
- free(data_buf);
- if (enc_voms == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (Not enough memory)");
- return ENOMEM;
- }
- *buf = enc_voms;
- *len = enc_voms_len;
- return 0;
-}
-
-static int
-voms_cert_renew(char *hostname, int port, char *voms_subject,
- char *proxy,
- struct voms **cur_voms_cert, struct vomsdata *voms_info)
-{
- int ret = 0;
- char *command = "A";
- int err = 0;
- char *old_env_proxy = getenv("X509_USER_PROXY");
-
- setenv("X509_USER_PROXY", proxy, 1);
-
- /* hack (suggested by Vincenzo Ciaschini) to work around problem with
- * unitialized VOMS struct */
- ret = VOMS_Ordering("zzz:zzz", voms_info, &err);
- if (ret == 0) {
- edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Ordering() failed");
- ret = EDG_WLPR_ERROR_VOMS;
- goto end;
- }
-
- /* XXX only attributes which are in current certificate should be requested*/
- ret = VOMS_Contact(hostname, port, (*cur_voms_cert)->server, command,
- voms_info, &err);
- if (ret == 0) {
-#if 0
- if (err == 1) { /* XXX cannot connect voms server */
- ret = 0;
+ 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;
}
-#endif
- edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Contact() failed: %d)", err);
- ret = EDG_WLPR_ERROR_VOMS;
- } else
- ret = 0;
-
-end:
- (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) :
- unsetenv("X509_USER_PROXY");
-
- return ret;
-}
-
-static int
-renew_voms_cert(struct voms **cur_voms_cert, char *proxy, char **buf, size_t *buf_len)
-{
- struct vomsdata *voms_info = NULL;
- char *hostname = NULL;
- char *p;
- int port, ret;
-
- hostname = strdup((*cur_voms_cert)->uri);
- p = strchr(hostname, ':');
- if (p)
- *p = '\0';
- port = (p) ? atoi(p+1) : 15000;
-
- voms_info = VOMS_Init(vomsdir, cadir);
- if (voms_info == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Init() failed)");
- ret = EDG_WLPR_ERROR_VOMS;
- goto end;
}
- ret = voms_cert_renew(hostname, port, (*cur_voms_cert)->server, proxy, cur_voms_cert,
- voms_info);
- if (ret)
- goto end;
-
- ret = VOMS_Export(voms_info, buf, buf_len);
- if (ret) {
- edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Export() failed)");
- ret = EDG_WLPR_ERROR_VOMS;
- goto end;
+ if (cur_proxy) {
+ *cur_proxy = proxy;
+ proxy = NULL;
}
ret = 0;
-
-end:
- if (hostname)
- free(hostname);
-#if 0
- if (voms_info)
- VOMS_Destroy(voms_info);
-#endif
-
- return ret;
-}
-#endif
-
-#ifndef NOVOMS
-static vomses_record *
-find_vomses_record(char *hostname, int port)
-{
- int i;
-
- for (i = 0; i < vomses.len; i++) {
- if (strcmp(vomses.val[i]->hostname, hostname) == 0 &&
- vomses.val[i]->port == port)
- return vomses.val[i];
- }
-
- return NULL;
-}
-
-static int
-set_vo_params(struct voms **voms_cert, char **arg)
-{
- vomses_record *r;
- char *tmp;
- int port;
- char *hostname;
- char *p;
-
- hostname = strdup((*voms_cert)->uri);
- p = strchr(hostname, ':');
- if (p)
- *p = '\0';
- port = (p) ? atoi(p+1) : 15000;
-
- r = find_vomses_record(hostname, port);
- if (r == NULL)
- return EINVAL;
-
- if (*arg == NULL) {
- asprintf(arg, " -voms %s", r->nick);
- } else {
- tmp = realloc(*arg,
- strlen(*arg) + strlen(" -voms ") + strlen(r->nick) + 1);
- if (tmp == NULL)
- return ENOMEM;
- *arg = tmp;
- *arg = strcat(*arg, " -voms ");
- *arg = strcat(*arg, r->nick);
- }
- return 0;
-}
-#endif
-
-static int
-exec_voms_proxy_init(char *arg, char *old_proxy, char *new_proxy)
-{
- char command[256];
- int ret;
- char *old_env_proxy = getenv("X509_USER_PROXY");
-
- setenv("X509_USER_PROXY", old_proxy, 1);
-
- snprintf(command, sizeof(command),
- "edg-voms-proxy-init -out %s -key %s -cert %s -confile %s -q %s",
- new_proxy, old_proxy, old_proxy, vomsconf, arg);
- ret = system(command);
-
- (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) :
- unsetenv("X509_USER_PROXY");
-
- return ret;
-}
-
-#if 0
-static int
-renew_voms_certs(const char *old_proxy, const char *new_proxy)
-{
- struct vomsdata *voms_info = NULL;
- struct voms **voms_cert = NULL;
- STACK_OF(X509) *chain = NULL;
- EVP_PKEY *privkey = NULL;
- X509 *cert = NULL;
- int ret, err;
- char *buf = NULL;
- size_t buf_len = 0;
- X509_EXTENSION *extension = NULL;
- X509 *new_cert = NULL;
- EVP_PKEY *new_privkey = NULL;
-
- voms_info = VOMS_Init(vomsdir, cadir);
- if (voms_info == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot initialize VOMS context (VOMS_Init() failed)");
- return EDG_WLPR_ERROR_VOMS;
- }
-
- ret = load_proxy(old_proxy, &cert, &privkey, &chain);
- if (ret)
- goto end;
-
- ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err);
- if (ret == 0) {
- if (err == VERR_NOEXT) {
- /* no VOMS cred, no problem; continue */
- ret = 0;
- } else {
- edg_wlpr_Log(LOG_ERR, "Cannot get VOMS certificate(s) from proxy");
- ret = EDG_WLPR_ERROR_VOMS;
- }
- goto end;
- }
-
- for (voms_cert = voms_info->data; voms_cert && *voms_cert; voms_cert++) {
- char *tmp, *ptr;
- size_t tmp_len;
-
- ret = renew_voms_cert(voms_cert, old_proxy, &tmp, &tmp_len);
- if (ret)
- continue;
- 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 = create_voms_extension(buf, buf_len, &extension);
- if (ret)
- goto end;
-
- X509_free(cert);
- EVP_PKEY_free(privkey);
- sk_X509_pop_free(chain, X509_free);
-
- ret = load_proxy(new_proxy, &cert, &privkey, &chain);
- if (ret)
- goto end;
-
- ret = create_proxy(cert, privkey, extension, &new_cert, &new_privkey);
- if (ret)
- goto end;
-
- sk_X509_insert(chain, cert, 0);
-
- ret = save_proxy(new_proxy, new_cert, new_privkey, chain);
- if (ret)
- goto end;
-
- ret = 0;
-
+
end:
- VOMS_Destroy(voms_info);
-
- return ret;
-}
-#else /* 0 */
-
-#ifdef NOVOMS
-static int
-renew_voms_certs(const char *old_proxy, char *myproxy_proxy, const char *new_proxy)
-{
- return 0;
-}
-
-#else
-static int
-renew_voms_certs(const char *old_proxy, char *myproxy_proxy, const char *new_proxy)
-{
- struct vomsdata *voms_info = NULL;
- struct voms **voms_cert = NULL;
- STACK_OF(X509) *chain = NULL;
- EVP_PKEY *privkey = NULL;
- X509 *cert = NULL;
- int ret, err;
- char *arg = NULL;
-
- voms_info = VOMS_Init(vomsdir, cadir);
- if (voms_info == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot initialize VOMS context (VOMS_Init() failed)");
- return EDG_WLPR_ERROR_VOMS;
- }
-
- ret = load_proxy(old_proxy, &cert, &privkey, &chain);
- if (ret)
- goto end;
-
- ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err);
- if (ret == 0) {
- if (err == VERR_NOEXT) {
- /* no VOMS cred, no problem; continue */
- ret = 0;
- } else {
- edg_wlpr_Log(LOG_ERR, "Cannot get VOMS certificate(s) from proxy");
- ret = EDG_WLPR_ERROR_VOMS;
- }
- goto end;
- }
-
- for (voms_cert = voms_info->data; voms_cert && *voms_cert; voms_cert++) {
- ret = set_vo_params(voms_cert, &arg);
- if (ret)
- goto end;
- }
- ret = exec_voms_proxy_init(arg, myproxy_proxy, new_proxy);
+ if (proxy)
+ globus_gsi_cred_handle_destroy(proxy);
+ if (result)
+ ret = EDG_WLPR_ERROR_GENERIC;
-end:
- VOMS_Destroy(voms_info);
return ret;
}
-#endif /* NOVOMS */
-
-#endif /* 0 */
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
edg_wlpr_Log(LOG_DEBUG, "Trying to renew proxy in %s.%d",
basename, record->suffix);
- snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.%d.renew.XXXXXX",
+ snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.%d.myproxy.XXXXXX",
basename, record->suffix);
tmp_fd = mkstemp(tmp_proxy);
if (tmp_fd == -1) {
} else
socket_attrs->psport = MYPROXY_SERVER_PORT;
+ verror_clear();
ret = myproxy_get_delegation(socket_attrs, client_request,
server_response, tmp_proxy);
if (ret == 1) {
ret = EDG_WLPR_ERROR_MYPROXY;
- edg_wlpr_Log(LOG_ERR, "Cannot get renewed proxy from Myproxy server");
+ edg_wlpr_Log(LOG_ERR, "Error contacting MyProxy server for proxy %s: %s",
+ repository_file, verror_get_string());
+ verror_clear();
goto end;
}
renewed_proxy = tmp_proxy;
- if (voms_enabled) {
+ if (voms_enabled && record->voms_exts) {
char tmp_voms_proxy[FILENAME_MAX];
int tmp_voms_fd;
- snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.%d.renew.XXXXXX",
+ snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.%d.voms.XXXXXX",
basename, record->suffix);
tmp_voms_fd = mkstemp(tmp_voms_proxy);
if (tmp_voms_fd == -1) {
goto end;
}
- ret = renew_voms_certs(repository_file, tmp_proxy, tmp_voms_proxy);
- if (ret)
+ ret = renew_voms_creds(repository_file, 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)
}
static void
-check_renewal(char *datafile, int force_renew)
+check_renewal(char *datafile, int force_renew, int *num_renewed)
{
char line[1024];
proxy_record record;
assert(datafile != NULL);
+ *num_renewed = 0;
+
memset(&record, 0, sizeof(record));
memset(basename, 0, sizeof(basename));
memset(&request, 0, sizeof(request));
continue; /* XXX exit? */
if (record.jobids.len == 0) /* no jobid registered for this proxy */
continue;
- if (record.end_time - current_time < RENEWAL_CLOCK_SKEW ||
- abs(record.next_renewal - current_time) < RENEWAL_CLOCK_SKEW ||
- record.next_renewal < current_time ||
- record.end_time < current_time ||
+ 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 >= current_time)
+ if ( record.end_time + RENEWAL_CLOCK_SKEW >= current_time) {
/* only try renewal if the proxy hasn't already expired */
ret = renew_proxy(&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 : "");
edg_wlpr_CleanResponse(&response);
edg_wlpr_CleanRequest(&request);
+ *num_renewed = num;
+
return;
}
-int renewal(int force_renew)
+int renewal(int force_renew, int *num_renewed)
{
DIR *dir = NULL;
struct dirent *file;
FILE *fd;
+ int num = 0;
edg_wlpr_Log(LOG_DEBUG, "Starting renewal process");
+ *num_renewed = 0;
+
if (chdir(repository)) {
edg_wlpr_Log(LOG_ERR, "Cannot access repository directory %s (%s)",
repository, strerror(errno));
file->d_name, strerror(errno));
continue;
}
- check_renewal(file->d_name, force_renew);
+ check_renewal(file->d_name, force_renew, &num);
+ *num_renewed += num;
fclose(fd);
}
closedir(dir);
{
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);
- /* load_vomses(); */
-
- while (1) {
+ 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(force_renewal);
+ renewal(force_renewal, &num);
+ count += num;
}
+ edg_wlpr_Log(LOG_DEBUG, "Terminating after %d renewal attempts", count);
+ exit(0);
}
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/file.h>
+#include <sys/wait.h>
#include <openssl/md5.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#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 *value, const char *separator);
int
-edg_wlpr_Read(int sock, char **buf, size_t *buf_len);
+edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len);
int
-edg_wlpr_Write(int sock, char *buf, size_t buf_len);
+edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len);
void
edg_wlpr_CleanRequest(edg_wlpr_Request *request);
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 */
char *cadir = NULL;
char *vomsdir = NULL;
int voms_enabled = 0;
+char *cert = NULL;
+char *key = NULL;
+char *vomsconf = NULL;
-char *vomsconf = "/opt/edg/etc/vomses";
-#ifndef NOVOMS
-struct vomses_records vomses;
-#endif
+static volatile int die = 0, child_died = 0;
+double default_timeout = 0;
static struct option opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "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 }
};
static int
decode_request(const char *msg, const size_t msg_len, edg_wlpr_Request *request);
+int
+start_watchdog(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(edg_wlpr_Command code)
{
edg_wlpr_Response response;
edg_wlpr_Request request;
command_table *command;
+ struct timeval timeout;
memset(&request, 0, sizeof(request));
memset(&response, 0, sizeof(response));
- ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ 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) {
edg_wlpr_Log(LOG_ERR, "Error reading from client: %s",
edg_wlpr_GetErrorString(ret));
goto end;
}
- edg_wlpr_Log(LOG_INFO, "Received command code %d for proxy %s",
+ edg_wlpr_Log(LOG_INFO, "Received command code %d for proxy %s and jobid %s",
request.command,
- request.proxy_filename ? request.proxy_filename : "(unspecified)");
+ request.proxy_filename ? request.proxy_filename : "(unspecified)",
+ request.jobid ? request.jobid : "(unspecified)");
command->handler(&request, &response);
if (ret)
goto end;
- ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ ret = edg_wlpr_Write(sock, &timeout, buf, strlen(buf) + 1);
free(buf);
if (ret) {
edg_wlpr_Log(LOG_ERR, "Error sending response to client: %s",
int newsock;
struct sockaddr_un client_addr;
int client_addr_len = sizeof(client_addr);
-#if 0
- next_renewal = LONG_MAX;
- size_of_proxies = PROXIES_ALLOC_SIZE;
- proxies = malloc((size_of_proxies) * sizeof(struct guarded_proxy *));
- if (proxies == NULL) {
- return ENOMEM;
- }
- proxies[0] = NULL;
-#endif
+ int flags;
-#if 0
- sigemptyset(&sset);
- sigaddset(&sset,SIGTERM);
- sigaddset(&sset,SIGINT);
- sigaddset(&sset, SIGKILL);
- sigaddset(&sset, SIGUSR1);
- sigaddset(&sset, SIGALRM);
- sigprocmask(SIG_BLOCK,&sset,NULL);
-#endif
+ while (!die) {
- while (1) {
-#if 0
- sigprocmask(SIG_UNBLOCK,&sset,NULL);
- newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
- sigprocmask(SIG_BLOCK,&sset,NULL);
+ if (child_died) {
+ int pid, newpid, ret;
- if (newsock == -1) {
- if (errno == EINTR) /* ERESTARTSYS */
- proxy_renewal(received_signal);
- else
- log();
- continue;
+ while ((pid=waitpid(-1,NULL,WNOHANG))>0)
+ ;
+ ret = start_watchdog(&newpid);
+ if (ret)
+ return ret;
+ edg_wlpr_Log(LOG_DEBUG, "Renewal slave process re-started");
+ child_died = 0;
+ continue;
}
-#else
+
newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
if (newsock == -1) {
- edg_wlpr_Log(LOG_ERR, "accept() failed");
+ if (errno != EINTR)
+ edg_wlpr_Log(LOG_ERR, "accept() failed");
continue;
}
edg_wlpr_Log(LOG_DEBUG, "Got connection");
-#endif
-
+ flags = fcntl(newsock, F_GETFL, 0);
+ if (fcntl(newsock, F_SETFL, flags | O_NONBLOCK) < 0) {
+ edg_wlpr_Log(LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n",
+ strerror(errno));
+ close(newsock);
+ continue;
+ }
+
proto(newsock);
edg_wlpr_Log(LOG_DEBUG, "Connection closed");
close(newsock);
}
+ edg_wlpr_Log(LOG_DEBUG, "Terminating on signal %d\n",die);
+ return 0;
}
static int
return errno;
}
- ret = listen(s, 5); /* XXX enough ? */
+ ret = listen(s, 50);
if (ret == -1) {
edg_wlpr_Log(LOG_ERR, "listen(): %s", strerror(errno));
close(s);
exit(0);
}
-#ifdef NOVOMS
-static int
-load_vomses()
-{
- return ENOSYS;
-}
-
-#else
-static int
-load_vomses()
-{
- FILE *fd = NULL;
- char line[1024];
- char *nick, *hostname;
- int port;
- vomses_record *rec;
- vomses_record **tmp;
- char *p;
-
- fd = fopen(vomsconf, "r");
- if (fd == NULL) {
- edg_wlpr_Log(LOG_ERR, "Cannot open vomses configuration file (%s)",
- strerror(errno));
- return errno;
- }
- while (fgets(line, sizeof(line), fd) != NULL) {
- p = line;
- if (*p != '"') {
- edg_wlpr_Log(LOG_ERR, "Parsing error when reading vomses configuration file");
- return EINVAL;
- }
- nick = strdup(strtok(p+1, "\""));
-
- p = strtok(NULL, "\"");
- hostname = strdup(strtok(NULL, "\""));
-
- p = strtok(NULL, "\"");
- port = atoi(strdup(strtok(NULL, "\"")));
-
- if (nick == NULL || hostname == NULL) {
- edg_wlpr_Log(LOG_ERR, "Parsing error when reading vomses configuration file");
- return EINVAL;
- }
-
- rec = calloc(1, sizeof(*rec));
- if (rec == NULL) {
- edg_wlpr_Log(LOG_ERR, "Not enough memory");
- return ENOMEM;
- }
- rec->nick = nick;
- rec->hostname = hostname;
- rec->port = port;
-
- tmp = realloc(vomses.val, vomses.len + 1);
- if (tmp == NULL) {
- edg_wlpr_Log(LOG_ERR, "Not enough memory");
- return ENOMEM;
- }
- vomses.val = tmp;
- vomses.len++;
-
- vomses.val[vomses.len-1] = rec;
- }
- fclose(fd);
- return 0;
-}
-#endif
-
int main(int argc, char *argv[])
{
int sock;
char sockname[PATH_MAX];
int ret;
pid_t pid;
+ struct sigaction sa;
+ const char *s = NULL;
progname = strrchr(argv[0],'/');
if (progname) progname++;
repository = EDG_WLPR_REPOSITORY_ROOT;
debug = 0;
- while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:", opts, NULL)) != EOF)
+ while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:t:k:", opts, NULL)) != EOF)
switch (opt) {
case 'h': usage(progname); exit(0);
case 'v': fprintf(stdout, "%s:\t%s\n", progname, rcsid); exit(0);
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(progname); return 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);
openlog(progname, LOG_PID, LOG_DAEMON);
}
- if (voms_enabled) {
- char *path;
- char *new_path;
- ret = load_vomses();
- if (ret)
- return 1;
- setenv("GLOBUS_VERSION", "22", 0);
- if (VOMS_INSTALL_PATH != NULL && *VOMS_INSTALL_PATH != '\0') {
- path = getenv("PATH");
- asprintf(&new_path, "%s:%s/bin", path, VOMS_INSTALL_PATH);
- setenv("PATH", new_path, 1);
- }
- }
-
+ 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(&pid);
if (ret)
return 1;
return 1;
edg_wlpr_Log(LOG_DEBUG, "Listening at %s", sockname);
-#if 0
- /* XXX ??? */
- install_handlers();
-#endif
-
-
-#if 0
- /* XXX this overrides setings done by install_handlers()? */
- signal(SIGTERM, cleanup);
- signal(SIGINT, cleanup);
- signal(SIGKILL, cleanup);
- signal(SIGPIPE, SIG_IGN);
-
- atexit(cleanup);
-#endif
-
ret = doit(sock);
close(sock);
X509_NAME *subject = NULL;
int ret;
- ret = load_proxy(file, &cert, &key, &chain);
+ ret = load_proxy(file, &cert, &key, &chain, NULL);
if (ret)
return ret;
#include <myproxy.h>
#include <myproxy_delegation.h>
-#include <globus_gsi_cert_utils.h>
+#include <globus_gsi_credential.h>
+#include <globus_gsi_proxy.h>
+#include <globus_gsi_cert_utils_constants.h>
#include "renewal.h"
time_t next_renewal;
} proxy_record;
-typedef struct vomses_record {
- char *nick;
- char *hostname;
- int port;
-} vomses_record;
-
-typedef struct vomses_records {
- unsigned int len;
- struct vomses_record **val;
-} vomses_records;
-
/* commands */
void
register_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response);
int
load_proxy(const char *filename, X509 **cert, EVP_PKEY **privkey,
- STACK_OF(X509) **chain);
+ STACK_OF(X509) **chain, globus_gsi_cred_handle_t *proxy);
int
get_proxy_base_name(char *file, char **subject);
+int
+renew_voms_creds(const char *cur_file, const char *renewed_file, const char *new_file);
+
#endif /* RENEWALD_LOCL_H */
--- /dev/null
+#include "renewal_locl.h"
+#include "renewd_locl.h"
+
+#include <string.h>
+#include <openssl/x509.h>
+
+#include "glite/security/voms/voms_apic.h"
+
+#include "newformat.h"
+
+char * Decode(const char *, int, int *);
+char **listadd(char **, char *, int);
+
+extern char *vomsconf;
+
+static int
+generate_proxy(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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) {
+ edg_wlpr_Log(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(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) {
+ edg_wlpr_Log(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(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) {
+ edg_wlpr_Log(LOG_ERR, "VOMS_Ordering() failed\n");
+ return 1;
+ }
+ }
+#endif
+
+ if (voms_cert == NULL || *voms_cert == NULL || (*voms_cert)->std == NULL) {
+ edg_wlpr_Log(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(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, vomsconf, NULL, &voms_error);
+
+ if (voms_contacts == NULL) {
+ edg_wlpr_Log(LOG_ERR, "VOMS_FindByVO() failed\n");
+ return 1;
+ }
+
+ ret = create_voms_command(vd, voms_cert, &command);
+
+ /* 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) {
+ edg_wlpr_Log(LOG_ERR, "VOMS_Contact() failed\n");
+ return 1;
+ }
+
+ VOMS_DeleteContacts(voms_contacts);
+
+ if (command)
+ free(command);
+
+ return 0;
+}
+
+static int
+renew_voms_certs(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 = load_proxy(cur_file, &cert, NULL, &chain, &cur_proxy);
+ if (ret)
+ goto end;
+
+ vd = VOMS_Init(NULL, NULL);
+ if (vd == NULL) {
+ edg_wlpr_Log(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 */
+ edg_wlpr_Log(LOG_ERR, "No VOMS attributes found in proxy %s\n", cur_file);
+ ret = 0;
+ goto end;
+ } else {
+ edg_wlpr_Log(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(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(buf, buf_len, &extension);
+ if (ret)
+ goto end;
+
+ ret = load_proxy(renewed_file, NULL, NULL, NULL, &new_proxy);
+ if (ret)
+ goto end;
+
+ ret = generate_proxy(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
+renew_voms_creds(const char *cur_file, const char *renewed_file, const char *new_file)
+{
+ return renew_voms_certs(cur_file, renewed_file, new_file);
+}
+
+#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) {
+ edg_wlpr_Log(LOG_ERR, "[%d]: Unable to initialize Globus modules\n", getpid());
+ return 1;
+ }
+
+ ret = renew_voms_certs(current_proxy, renewed_proxy);
+
+ return 0;
+}
+#endif
Revision history:
$Log$
+ Revision 1.1.1.1 2004/07/21 18:16:57 eronchie
+ Moved out exception from org.glite.wms.common/src/utilitiesY
+
-->
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
+ <property file="${module.build.file}" />
<!-- ==============================================
Local private targets
#
# Revision history:
# $Log$
+# Revision 1.10 2004/12/10 07:31:35 eronchie
+# Increased version
+#
# Revision 1.9 2004/11/16 15:31:13 eronchie
# Increased version
#
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
-AC_INIT([GLite WMS Utils Exception], [1.0.0])
+AC_INIT([GLite WMS Utils Exception], [1.0.1])
AC_CONFIG_AUX_DIR([./project])
AM_INIT_AUTOMAKE([1.6.3 subdir-objects])
AC_CONFIG_SRCDIR([src/Exception.cpp])
* @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)
- * @param line_number the number of the line in the file that raised the exception(if the source has been given as a file) */
+ * @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);
/**
*/
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
--- /dev/null
+#Sun Apr 03 03:07:40 CEST 2005
+module.build=214
-#Fri Dec 10 12:18:50 CET 2004
-module.version=1.0.0
-module.build=105
-module.age=1
+
+module.version = 1.0.1
+module.age = 1
+
\ No newline at end of file
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="" ;
+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;
// stack= "";
line = 0;
};
+
int Exception::getCode(){
- if (error_code != 0)
- return error_code ;
+ 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() ;
- if ( error_message != "")
- return error_message.c_str() ;
- else return "" ;
+const char* Exception::what() const throw(){
+ if (!ancestor.empty()) return ancestor.c_str();
+
+ return error_message.c_str();
};
+
string Exception::getExceptionName(){
- if (exception_name!= "")
- return exception_name;
- else
- return "" ;
+ return exception_name;
};
+
void Exception::log(const std::string& logfile)
{
- if ( logfile == "")
- syslog ( LOG_PERROR, (char *) (dbgMessage()).c_str() );
+ if (logfile == "")
+ syslog (LOG_PERROR, (char *)(dbgMessage()).c_str());
else{
pthread_mutex_lock( &METHOD_MUTEX); // LOCK
//TBD : test if file exist-->>Create HEADER ??
pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK
}
};
+
string Exception::printStackTrace(){
string stack = "" ;
for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){
}
return stack +dbgMessage();
};
+
vector<string> Exception::getStackTrace(){
// make a copy of the stack
vector<string> stack = stack_strings ;
- stack.push_back(dbgMessage() ) ;
+ stack.push_back(dbgMessage()) ;
return stack;
};
string Exception::dbgMessage(){
string result ;
//Adding exception Name
- if ( exception_name!="")
- result = exception_name ;
+ result = exception_name;
+
//Adding error msg
- if (error_message!="")
- result +=": " + string(what());
- if (result != "")
- result+="\n";
+ 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] ;
Revision history:
$Log$
+ Revision 1.4 2004/07/21 17:53:36 eronchie
+ Moved out org.glite.wms.jobid from org.glite.wms and put in org.glite.wms-utils
+
-->
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
+ <property file="${module.build.file}" />
<!-- ==============================================
Local private targets
--- /dev/null
+#Sun Apr 03 03:12:33 CEST 2005
+module.build=213
-#Fri Dec 10 12:23:10 CET 2004
-module.version=1.0.0
-module.build=104
-module.age=1
+
+module.version = 1.0.0
+module.age = 1
+
\ No newline at end of file
+* Fri Jun 10 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Tidy up gsexec vs GridSiteDiskPerms
+* Fri Jun 10 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.10 ====
+* Wed Jun 8 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- 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 <Andrew.McNab@man.ac.uk>
+- 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 <Andrew.McNab@man.ac.uk>
+- 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 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.9 ====
+* Mon Apr 25 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Avoid build problems when using pre-0.9.7 OpenSSL
+ (ie with Globus compatibility.)
+* Mon Apr 25 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.8 ====
+* Mon Feb 28 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Fix to GRSTgaclUndenyPerm in gridsite.h (bug #7135)
+ from Marco Sottilaro <marco.sottilaro@datamat.it>
+* Mon Feb 28 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.7 ====
+* Thu Feb 24 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Add more sanity checking (signatures, dates, issuer,)
+ holder) to VOMS attribute parser.
+* Mon Feb 21 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Add bugfix for Bug #6357 from Fabrizio Pacini
+ <fabrizio.pacini@cern.ch> to fix delegation proxy
+ cache names in OpenSSL 0.9.7.
+* Sun Feb 20 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Add basic VOMS support (signature checking not yet
+ in) for X.509 Attribute Certificates.
+* Tue Feb 8 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.6 ====
+* Tue Feb 8 2005 Andrew McNab <Andrew.McNab@man.ac.uk>
+- 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 <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.5 ====
+* Tue Dec 14 2004 Andrew McNab <Andrew.McNab@man.ac.uk>
+- Patch from Daniel Kouril <kouril@ics.muni.cz> to allow
+ switching Globus vs system OpenSSL libraries/headers.
+* Tue Dec 14 2004 Andrew McNab <Andrew.McNab@man.ac.uk>
+- ==== GridSite version 1.1.4 ====
* Mon Nov 15 2004 Andrew McNab <Andrew.McNab@man.ac.uk>
- Back out of (most of) redone VOMS support for committing
to JRA1 CVS.
MAJOR_VERSION=1
MINOR_VERSION=1.1
-PATCH_VERSION=1.1.3
+PATCH_VERSION=1.1.10
VERSION=$(PATCH_VERSION)
Revision history:
$Log$
+ Revision 1.11 2005/02/16 14:14:39 dimeglio
+ Added patch to use globus compilation flags also in the RPMS
+
+ Revision 1.10 2004/12/17 09:11:43 dimeglio
+ Added local tag targets (because of special naming rules here)
+
+ Revision 1.9 2004/12/17 09:02:49 dimeglio
+ Removed redefinition of global.prefix
+
+ Revision 1.8 2004/12/17 00:32:50 dimeglio
+ Fixed global.prefix
+
+ Revision 1.7 2004/12/03 14:49:59 dimeglio
+ Added OPENSSL_FLAGS and _LIBS options
+
Revision 1.6 2004/11/13 10:55:44 glbuild
Added artifacts RPMS directory
Load version file
========================================= -->
<property file="${module.version.file}"/>
+ <property file="${module.build.file}"/>
<!-- ===============================================
Public common targets
=============================================== -->
- <var name="global.prefix" unset="true"/>
- <property name="global.prefix" value="gridsite"/>
-
<target name="localinit" depends="envcheck">
<mkdir dir="${stage.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<target name="dist" depends="stage">
- <make target="rpm" dir="${module.src.dir}" failonerror="${failonerror}"/>
+ <make target="rpm" dir="${module.src.dir}" failonerror="${failonerror}" args="${build.make.arguments}"/>
<exec dir="${module.dir}/RPMTMP/BUILDROOT/usr" executable="tar">
<arg line="-czf ${module.dir}/gridsite-${module.version}_bin.tar.gz ." />
</exec>
Private targets
=============================================== -->
- <!-- ===============================================
+ <!-- ========================================================
+ tag: Tag module
+ ======================================================== -->
+ <target name="tag" description="Apply tag.">
+
+ <property name="tag.type" value="B"/>
+ <!-- Set module CVS Label -->
+ <exec executable="tr" inputstring="${module.version}" outputproperty="cvs.module.version">
+ <arg line=". _"/>
+ </exec>
+ <property name="cvs.label" value="gridsite-core_${tag.type}_${cvs.module.version}_${module.build}" />
+ <echo>New tag is ${cvs.label}</echo>
+
+ <!-- Apply tag -->
+ <property name="failonerror" value="true"/>
+ <property name="tag.switch" value="-FR"/>
+ <exec dir="${workspace.abs.dir}" executable="cvs" failonerror="${failonerror}">
+ <arg line="tag ${tag.switch} ${cvs.label} ${module.name}" />
+ </exec>
+
+ </target>
+
+ <target name="component_release_tag">
+
+ <!-- Set module CVS Label -->
+ <exec executable="tr" inputstring="${module.version}" outputproperty="cvs.module.version">
+ <arg line=". _"/>
+ </exec>
+ <property name="cvs.label" value="gridsite-core_R_${cvs.module.version}" />
+ <echo>New tag is ${cvs.label}</echo>
+
+ <!-- Apply tag -->
+ <exec dir="${workspace.abs.dir}" executable="cvs" failonerror="true">
+ <arg line="tag -R ${cvs.label} ${module.name}" />
+ </exec>
+
+ </target>
+
+ <!-- ===============================================
Modules proxy targets
=============================================== -->
The easiest way to get started is to examine the example httpd.conf files we
provide.
+<p>
+<b>Please note: this version of GridSite is <b>not</b> compatible with the
+SHM SSL session cache - use the DBM or per-process caches instead.
+
<!--
virtual servers
directory sections
--- /dev/null
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "GSEXEC" 8 "2005-05-27" "GridSite Apache Extensions" "gsexec"
+
+.SH NAME
+gsexec \- Switch user before executing external programs
+
+.SH "SYNOPSIS"
+
+.PP
+\fBgsexec\fR -\fBV\fR
+
+
+.SH "SUMMARY"
+
+.PP
+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\&.
+
+.PP
+gsexec is based on Apache's suexec.
+For further information about the concepts and the security model of
+the original suexec
+please refer to the suexec documentation:
+
+(http://httpd\&.apache\&.org/docs-2\&.0/suexec\&.html)\&.
+
+
+.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\&.
+
# Secured and possibly authenticated HTTPS on port 443
######################################################################
Listen 443
+SSLSessionCacheTimeout 300
+SSLSessionCache dbm:/var/cache/mod_ssl/scache
+# This version of GridSite is NOT compatible with the SHM SSL cache!!!
<VirtualHost *:443>
SSLEngine on
SSLCertificateKeyFile /etc/grid-security/hostkey.pem
SSLCACertificatePath /etc/grid-security/certificates
#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE
-SSLSessionCache dbm:/var/cache/mod_ssl/scache
-SSLSessionCacheTimeout 300
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +ExportCertData +StdEnvVars
# Secured and possibly authenticated HTTPS on port 443
######################################################################
Listen 443
+SSLSessionCacheTimeout 300
+SSLSessionCache dbm:/var/cache/mod_ssl/scache
+# This version of GridSite is NOT compatible with the SHM SSL cache!!!
<VirtualHost *:443>
SSLEngine on
SSLCertificateKeyFile /etc/grid-security/hostkey.pem
SSLCACertificatePath /etc/grid-security/certificates
#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE
-SSLSessionCache dbm:/var/cache/mod_ssl/scache
-SSLSessionCacheTimeout 300
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +ExportCertData +StdEnvVars
/// No such file or directory
#define GRST_RET_NO_SUCH_FILE 1003
-#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.1"
-#define GRST_VOMS_DIR "/etc/grid-security/vomsdir"
-
-
-
typedef struct { char *name;
char *value;
void *next; } GRSTgaclNamevalue;
#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; } ;
+
int GRSTgaclInit(void);
/* #define GACLnewCred(x) GRSTgaclCredNew((x)) */
int GRSTgaclEntryDenyPerm(GRSTgaclEntry *, GRSTgaclPerm);
/* #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) */
-int GRSTgaclUndenyPerm(GRSTgaclEntry *, GRSTgaclPerm);
+int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *, GRSTgaclPerm);
/* #define GACLpermToChar(x) GRSTgaclPermToChar((x)) */
char *GRSTgaclPermToChar(GRSTgaclPerm);
/* #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) */
GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *, GRSTgaclUser *);
-
char *GRSThttpUrlDecode(char *);
/* #define GACLurlEncode(x) GRSThttpUrlEncode((x)) */
int GRSTx509KnownCriticalExts(X509 *);
-time_t GRSTasn1TimeToTimeT(char *);
int GRSTx509IsCA(X509 *);
int GRSTx509CheckChain(int *, X509_STORE_CTX *);
int GRSTx509VerifyCallback(int, X509_STORE_CTX *);
int GRSTx509MakeProxyCert(char **, FILE *, char *, char *, char *, int);
char *GRSTx509CachedProxyKeyFind(char *, char *, char *);
int GRSTx509MakeProxyRequest(char **, char *, char *, char *);
+int GRSTx509StringToChain(STACK_OF(X509) **, char *);
+char *GRSTx509MakeProxyFileName(char *, STACK_OF(X509) *);
int GRSTx509CacheProxy(char *, char *, char *, char *);
#define GRST_HEADFILE "gridsitehead.txt"
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);
--- /dev/null
+#Wed Feb 23 03:19:54 CET 2005
+module.build=141
<project name="configure options">
<property name="build.make.arguments"
- value="prefix=${stage.abs.dir} GSOAPDIR=${with.gsoap.prefix} OPENSSL_FLAGS=-I${with.globus.prefix}/include/gcc32/openssl OPENSSL_LIBS=-L${with.globus.prefix}/lib/"/>
+ value="prefix=${stage.abs.dir} GSOAPDIR=${ext.gsoap.subdir} OPENSSL_GLOBUS_FLAGS=-I${with.globus.prefix}/include/gcc32 OPENSSL_GLOBUS_LIBS=-L${with.globus.prefix}/lib/ FLAVOR_GLOBUS_EXT=_gcc32" />
</project>
-#Fri Dec 10 12:31:28 CET 2004
-module.version=1.1.3
-module.build=71
-module.age=2
+module.version=1.1.10
+module.age=1
#
# Andrew McNab and Shiv Kaushal, University of Manchester.
-# Copyright (c) 2002-4. All rights reserved.
+# 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
export MYCFLAGS=-I. -I../interface -I/usr/include/httpd -I/usr/include/apr-0 -I/opt/glite/include
endif
-ifndef OPENSSL_FLAGS
-export OPENSSL_FLAGS=-I/usr/include/openssl
-endif
-
ifndef MYLDFLAGS
export MYLDFLAGS=-L.
-# export MYLDFLAGS=-L. -L/opt/glite/lib -lvomsc
-endif
-
-ifndef OPENSSL_LIBS
-export OPENSSL_LIBS=-L/usr/lib/openssl
endif
#
#
build: libgridsite.so.$(VERSION) libgridsite.a htcp mod_gridsite.so \
- urlencode findproxyfile real-gridsite-admin.cgi \
- # gridsite-delegation.cgi # htproxyput
+ urlencode findproxyfile real-gridsite-admin.cgi gsexec \
+ # gridsite-delegation.cgi # htproxyput
-libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_http.o
+build: libgridsite_globus.so.$(VERSION) libgridsite_globus.a
+
+# First, normal versions using system OpenSSL rather than Globus OpenSSL
+
+libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o
gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \
- -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_http.o
+ -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o
-libgridsite.a: grst_x509.o grst_gacl.o grst_http.o
- ar src libgridsite.a grst_x509.o grst_gacl.o grst_http.o
+libgridsite.a: grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o
+ ar src libgridsite.a grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o
grst_x509.o: grst_x509.c ../interface/gridsite.h
- gcc $(MYCFLAGS) $(OPENSSL_FLAGS) \
+ gcc $(MYCFLAGS) \
-I/usr/kerberos/include -c grst_x509.c
grst_gacl.o: grst_gacl.c ../interface/gridsite.h
- gcc $(MYCFLAGS) $(OPENSSL_FLAGS) \
+ gcc $(MYCFLAGS) \
-I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c
+grst_xacml.o: grst_xacml.c ../interface/gridsite.h
+ gcc $(MYCFLAGS) \
+ -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c
+
grst_http.o: grst_http.c ../interface/gridsite.h
- gcc $(MYCFLAGS) $(OPENSSL_FLAGS) \
+ gcc $(MYCFLAGS) \
-I/usr/kerberos/include -c grst_http.c
+grst_asn1.o: grst_asn1.c ../interface/gridsite.h
+ gcc $(MYCFLAGS) \
+ -I/usr/kerberos/include -c grst_asn1.c
+
+# Then build versions using Globus OpenSSL if configured
+
+ifdef OPENSSL_GLOBUS_LIBS
+
+libgridsite_globus.so.$(VERSION): \
+ grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o \
+ grst_asn1_globus.o grst_xacml_globus.o
+ gcc -shared -Wl,-soname,libgridsite_globus.so.$(MINOR_VERSION) \
+ -o libgridsite_globus.so.$(PATCH_VERSION) \
+ grst_x509_globus.o grst_gacl_globus.o grst_xacml_globus.o grst_http_globus.o grst_asn1_globus.o
+
+libgridsite_globus.a: grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o
+ ar src libgridsite_globus.a \
+ grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o
+
+grst_x509_globus.o: grst_x509.c ../interface/gridsite.h
+ gcc $(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 $(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 $(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 $(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 $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \
+ -I/usr/kerberos/include -c grst_asn1.c \
+ -o grst_asn1_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 -DVERSION=\"$(PATCH_VERSION)\" -I/usr/include/httpd \
+ -I/usr/include/apr-0 \
+ -o gsexec gsexec.c
+
urlencode: urlencode.c libgridsite.a
gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \
-o urlencode urlencode.c -L. \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include -lgridsite
+ -I/usr/kerberos/include -lgridsite
htcp: htcp.c
gcc -DVERSION=\"$(PATCH_VERSION)\" -I. -o htcp htcp.c \
mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a
gcc $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include \
+ -I/usr/kerberos/include \
-I/usr/include/libxml2 \
-DVERSION=\"$(VERSION)\" -o mod_gridsite.so \
mod_gridsite.c $(MYLDFLAGS) -lxml2 -lm -lz -lgridsite
grst_admin_main.c \
grst_admin_gacl.c \
grst_admin_file.c \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include \
- -DVERSION=\"$(VERSION)\" $(OPENSSL_LIBS) -lgridsite -lssl -lcrypto -lxml2 -lz -lm
+ -I/usr/kerberos/include \
+ -DVERSION=\"$(VERSION)\" -lgridsite -lssl -lcrypto -lxml2 -lz -lm
findproxyfile: findproxyfile.c libgridsite.a
gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \
-o findproxyfile findproxyfile.c -L. \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include -lgridsite \
- $(OPENSSL_LIBS) -lssl -lcrypto -lxml2 -lz -lm
+ -I/usr/kerberos/include -lgridsite \
+ -lssl -lcrypto -lxml2 -lz -lm
+showx509exts: showx509exts.c libgridsite.a
+ gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \
+ -o showx509exts showx509exts.c -L. \
+ -I/usr/kerberos/include \
+ -lgridsite \
+ -lssl -lcrypto
+
apidoc:
doxygen Doxyfile
gaclexample: gaclexample.c libgridsite.a
gcc -o gaclexample gaclexample.c -I. -L. \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include -lgridsite \
- -lssl -lcrypto -lxml2 -lz -lm
+ -I/usr/kerberos/include -lgridsite \
+ -lssl -lcrypto -lxml2 -lz -lm
+
+xacmlexample: xacmlexample.c libgridsite.a
+ gcc -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
soapC.c soapServer.c
gcc $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \
grst-delegation.c \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include -I$(GSOAPDIR)/include \
+ -I/usr/kerberos/include -I$(GSOAPDIR)/include \
-DVERSION=\"$(VERSION)\" -L$(GSOAPDIR)/lib \
soapC.c soapServer.c -lgsoap \
-lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm
soapC.c soapServer.c
gcc $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \
htproxyput.c \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include \
+ -I/usr/kerberos/include \
-g -DVERSION=\"$(VERSION)\" \
-I$(GSOAPDIR)/include -DWITH_OPENSSL -L$(GSOAPDIR)/lib \
soapC.c soapClient.c -lgsoap \
-lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm
proxyput-example: proxyput-example.c delegation.h delegation.wsdl \
- soapC.c soapServer.c libstdsoap2.a
+ soapC.c soapServer.c
gcc $(MYCFLAGS) $(MYLDFLAGS) -o proxyput-example \
proxyput-example.c \
- $(OPENSSL_FLAGS) -I/usr/kerberos/include \
+ -I/usr/kerberos/include \
-g -DVERSION=\"$(VERSION)\" \
-I$(GSOAPDIR) -DWITH_OPENSSL \
soapC.c soapClient.c libstdsoap2.a \
$(prefix)/bin \
$(prefix)/sbin \
$(prefix)/share/man/man1 \
+ $(prefix)/share/man/man8 \
$(prefix)/lib/httpd/modules \
$(prefix)/share/doc/gridsite-$(PATCH_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 libgridsite.a $(prefix)/lib
cp -f real-gridsite-admin.cgi $(prefix)/sbin
+ cp -f libgridsite.a $(prefix)/lib
cp -f libgridsite.so.$(PATCH_VERSION) $(prefix)/lib
ln -sf libgridsite.so.$(PATCH_VERSION) \
$(prefix)/lib/libgridsite.so
$(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)
cp -f doxygen/index.html \
$(prefix)/share/doc/gridsite-$(PATCH_VERSION)/doxygen-index.html
cp -f doxygen/* $(prefix)/share/doc/gridsite-$(PATCH_VERSION)
cp -f ../CHANGES ../README ../INSTALL ../LICENSE ../VERSION \
$(prefix)/share/doc/gridsite-$(PATCH_VERSION)
- cp -f ../doc/*.html ../doc/*.conf ../doc/*.1 ../doc/*.sh \
+ cp -f ../doc/*.html ../doc/*.conf ../doc/*.1 ../doc/*.8 ../doc/*.sh \
$(prefix)/share/doc/gridsite-$(VERSION)
cp -f ../doc/*.1 $(prefix)/share/man/man1
+ cp -f ../doc/*.8 $(prefix)/share/man/man8
gzip -f $(prefix)/share/man/man1/*.1
- cd ../doc ; for i in *.1 ; do ../src/roffit < $$i \
+ gzip -f $(prefix)/share/man/man8/*.8
+ cd ../doc ; for i in *.1 *.8 ; do ../src/roffit < $$i \
> $(prefix)/share/doc/gridsite-$(VERSION)/$$i.html ; 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
+ cp -f gsexec $(prefix)/sbin
cp -f mod_gridsite.so $(prefix)/lib/httpd/modules
#
cp -f Makefile grst*.c htproxyput.c proxyput-example.c htcp.c \
urlencode.c findproxyfile.c gaclexample.c mod_gridsite.c \
delegation.h grst_admin.h mod_ssl-private.h \
+ gsexec.c gsexec.h \
roffit gridsite.spec \
Doxyfile doxygen.css doxyheader.html \
../gridsite-$(PATCH_VERSION)/src
- cp -f ../doc/*.html ../doc/*.1 ../doc/*.conf ../doc/*.sh \
+ cp -f ../doc/*.html ../doc/*.1 ../doc/*.8 ../doc/*.conf ../doc/*.sh \
../gridsite-$(PATCH_VERSION)/doc
cp -f ../interface/*.h \
../gridsite-$(PATCH_VERSION)/interface
printenv
ls -l
ls -lR /usr/local/
-
+ ls -lR $(GSOAPDIR)
Name: gridsite
Version: %(echo ${MYVERSION:-1.1.x})
-Release: 2
+Release: 1
Summary: GridSite
Copyright: Modified BSD
Group: System Environment/Daemons
Vendor: GridPP
#Requires: libxml2,curl-ssl,mod_ssl
#Buildrequires: libxml2-devel,curl-ssl-devel,httpd-devel
-Packager: Andrew McNab <Andrew.McNab@man.ac.uk>
+Packager: Andrew McNab <Andrew.McNab@manchester.ac.uk>
%description
GridSite adds GSI, VOMS and GACL support to Apache 2.0 (mod_gridsite),
onto remote servers using HTTPS. htcp is similar to scp(1), but uses
HTTP/HTTPS rather than ssh as its transfer protocol.
+%package gsexec
+Group: Applications/Internet
+Summary: gsexec binary for the Apache HTTP server
+#Requires: curl-ssl
+
+%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.
+
%prep
%setup
%build
cd src
-make prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr})
+make prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr}) \
+GSOAPDIR=$GSOAPDIR OPENSSL_FLAGS=$OPENSSL_FLAGS \
+OPENSSL_LIBS=$OPENSSL_LIBS FLAVOR_EXT=$FLAVOR_EXT
%install
cd src
-make install prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr})
+make install prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr}) \
+GSOAPDIR=$GSOAPDIR OPENSSL_FLAGS=$OPENSSL_FLAGS \
+OPENSSL_LIBS=$OPENSSL_LIBS FLAVOR_EXT=$FLAVOR_EXT
%post
/sbin/ldconfig
%files
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so.%{version}
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so
+%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.so.%{version}
+%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.so
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/urlencode
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/findproxyfile
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version}
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/include/gridsite.h
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/include/gridsite-gacl.h
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.a
+%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.a
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/httpd/modules/mod_gridsite.so
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/sbin/real-gridsite-admin.cgi
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htls.1.gz
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htll.1.gz
%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htmkdir.1.gz
+
+%files gsexec
+%attr(4510, root, apache) %(echo ${MYPREFIX:-/usr})/sbin/gsexec
+%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man8/gsexec.8.gz
char *docroot, *method, *request, *p, *client_dn, *user_dn,
*delegation_id, *reqtxt, *proxydir;
struct soap soap;
+
+chdir("/var/tmp");
method = getenv("REQUEST_METHOD");
if (strcmp(method, "POST") == 0)
{
GRSThttpPrintf(&bp, "<td><a href=\"");
if (strcmp (file, GRST_ACL_FILE)==0)
- GRSThttpPrintf(&bp, "%s%s?cmd=acl_history&dir_uri=%s&file=%s\">View</a></td></tr>\n",
+ GRSThttpPrintf(&bp, "%s%s?cmd=acl_history&dir_uri=%s&file=%s\">View</a></td></tr>\n",
dir_uri, admin_file, dir_uri, namelist[i]->d_name);
else GRSThttpPrintf(&bp, "%s%s\">View</a></td></tr>\n",
dir_uri, namelist[i]->d_name);
statbuf.st_size, modified);
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=history&file=%s\">"
+ "<td><a href=\"%s%s?cmd=history&file=%s\">"
"History</a></td>",
dir_uri, admin_file, GRST_ACL_FILE);
}
if (GRSTgaclPermHasAdmin(perm))
GRSThttpPrintf(&bp,
"<td><a href=\"%s%s?cmd=admin_acl\">Edit</a></td>"
- "<td><a href=\"%s%s?cmd=delete&file=%s\">Delete</a></td>",
+ "<td><a href=\"%s%s?cmd=delete&file=%s\">Delete</a></td>",
dir_uri, admin_file,
dir_uri, admin_file, GRST_ACL_FILE);
else if (GRSTgaclPermHasRead(perm))
if (numfiles == 0)
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=delete&file=%s\">"
+ "<td><a href=\"%s%s?cmd=delete&file=%s\">"
"Delete</a></td>\n",
dir_uri, admin_file, namelist[n]->d_name);
else GRSThttpPrintf(&bp, "<td> </td>\n");
statbuf.st_size, modified);
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=history&file=%s\">"
+ "<td><a href=\"%s%s?cmd=history&file=%s\">"
"History</a></td>",
dir_uri, admin_file, d_name);
(strcasecmp(&p[1], "zip") == 0) &&
GRSTgaclPermHasRead(perm))
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=ziplist&file=%s\">"
+ "<td><a href=\"%s%s?cmd=ziplist&file=%s\">"
"List</a></td>\n",
dir_uri, admin_file, d_name);
else if ((p != NULL) &&
(strstr(editable, &p[1]) != NULL) &&
GRSTgaclPermHasWrite(perm))
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=edit&file=%s\">"
+ "<td><a href=\"%s%s?cmd=edit&file=%s\">"
"Edit</a></td>\n",
dir_uri, admin_file, d_name);
else GRSThttpPrintf(&bp, "<td> </td>");
if (GRSTgaclPermHasWrite(perm))
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=delete&file=%s\">"
+ "<td><a href=\"%s%s?cmd=delete&file=%s\">"
"Delete</a></td>\n", dir_uri, admin_file, d_name);
else
GRSThttpPrintf(&bp, "<td> </td>\n");
if (GRSTgaclPermHasWrite(perm))
GRSThttpPrintf(&bp,
- "<td><a href=\"%s%s?cmd=rename&file=%s\">"
+ "<td><a href=\"%s%s?cmd=rename&file=%s\">"
"Rename</a></td></tr>\n", dir_uri, admin_file, d_name);
else
GRSThttpPrintf(&bp, "<td> </td></tr>");
/*
- Copyright (c) 2003, Shiv Kaushal, University of Manchester
+ Copyright (c) 2003-5, Shiv Kaushal, University of Manchester
All rights reserved.
Redistribution and use in source and binary forms, with or
strcat(dir_path_vfile, "/");
strcat(dir_path_vfile, vfile);
- GRSTgaclAclSave(acl, dir_path_vfile); // save the new ACL to the temporary file
+
+ // 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");
/*
Andrew McNab and Shiv Kaushal, University of Manchester.
- Copyright (c) 2002-3. All rights reserved.
+ 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
--- /dev/null
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/x509_vfy.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+
+#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; i<bs->length; 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; i<bs->length; 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)
+ {
+ sprintf(coordstmp, coords, i, 1);
+ iobj = GRSTasn1SearchTaglist(taglist, lasttag, coordstmp);
+ if (iobj < 0) break;
+
+ sprintf(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 GRST_RET_OK;
+}
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 *
* */
newentry->allowed = 0;
newentry->denied = 0;
newentry->next = NULL;
-
+
return newentry;
}
{
GRSTgaclCred *cred;
GRSTgaclPerm i;
-
+
fputs("<entry>\n", fp);
for (cred = entry->firstcred; cred != NULL; cred = cred->next)
if (xmlStrcmp(cur->name, (const xmlChar *) "entry") != 0) return NULL;
cur = cur->xmlChildrenNode;
-
+
entry = GRSTgaclEntryNew();
while (cur != NULL)
xmlDocPtr doc;
xmlNodePtr cur;
GRSTgaclAcl *acl;
- GRSTgaclEntry *entry;
-
+
doc = xmlParseFile(filename);
if (doc == NULL) return NULL;
-
+
cur = xmlDocGetRootElement(doc);
-
- if (xmlStrcmp(cur->name, (const xmlChar *) "gacl"))
+ 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 */
{
free(doc);
free(cur);
return NULL;
}
+
+ xmlFreeDoc(doc);
+ return acl;
+}
+
+GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl)
+{
+ GRSTgaclEntry *entry;
+
cur = cur->xmlChildrenNode;
acl = GRSTgaclAclNew();
-
+
while (cur != NULL)
{
entry = GRSTgaclEntryParse(cur);
}
GRSTgaclAclAddEntry(acl, entry);
-
+
cur=cur->next;
}
- xmlFreeDoc(doc);
return acl;
}
-
int GRSTgaclFileIsAcl(char *pathandfile)
-/* Return 1 if filename in *pathandfile starts GRST_ACL_FILE
+/* 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);
}
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) &&
+ if ((stat(path, &statbuf) == 0) &&
S_ISDIR(statbuf.st_mode) &&
(path[len-1] != '/'))
{
{
GRSTgaclCred *crediter;
GRSTgaclNamevalue *usernamevalue, *crednamevalue;
+ int i;
+ char buf[12];
if (cred == NULL) return 0;
return GRSTgaclDNlistHasUser((cred->firstname)->value, user);
}
-
+ /* Check for voms attributes*/
+
+ if (strcmp(cred->type, "voms")==0)
+ {
+ if ( (user->firstcred==NULL) ||
+ ((user->firstcred)->firstname == NULL) ||
+ (cred->firstname == NULL) ||
+ (strcmp((cred->firstname)->name, "fqan") != 0) ||
+ ((cred->firstname)->next != NULL)) return 0;
+
+ /*assuimng only one name/value pair per cred*/
+ for(i=1; ; i++)
+ {
+ sprintf (buf, "GRST_CRED_%d", i);
+ if (getenv(buf)==NULL) break;
+
+ if (strcmp (
+ index(getenv(buf),'/'),
+ (cred->firstname)->value
+ )
+ == 0) return 1;
+ }
+ /* no match found */
+ return 0;
+ }
+
if (strcmp(cred->type, "dns") == 0)
{
if ((user->firstcred == NULL) ||
return (fnmatch((cred->firstname)->value,
(crediter->firstname)->value, FNM_CASEFOLD) == 0);
}
-
+
+
return 0;
}
usernamevalue = (GRSTgaclNamevalue *) usernamevalue->next;
}
}
-
+
return 0;
}
/*
- Copyright (c) 2002-4, Andrew McNab, University of Manchester
+ Copyright (c) 2002-5, Andrew McNab, University of Manchester
All rights reserved.
Redistribution and use in source and binary forms, with or
#include <openssl/des.h>
#include <openssl/rand.h>
-#ifdef GRST_VOMS_SUPPORT
-#include <glite/security/voms/voms_apic.h>
-#endif
-
#include "gridsite.h"
#define GRST_KEYSIZE 512
#endif
}
-/// 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)
-{
- char zone;
- struct tm time_tm;
-
- if ((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 */
-
- /* time format fixups */
-
- if (time_tm.tm_year < 90) time_tm.tm_year += 100;
- --(time_tm.tm_mon);
-
- return timegm(&time_tm);
-}
-
/// 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.
/* we check times and reject immediately if invalid */
if (now <
- GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert))))
+ 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))))
+ 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
// else return GRST_RET_FAILED;
}
-/// Get the VOMS attributes in the extensions to the given cert
+/// Check the signature of the VOMS attributes
/*
- * Puts any VOMS credentials found into the Compact Creds string array
- * starting at *creds. Always returns GRST_RET_OK.
+ * Returns GRST_RET_OK if signature is ok, other values if not.
*/
-int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen,
- char *creds, X509 *cert, STACK_OF(X509) *certstack,
- char *vomsdir)
-{
-#ifndef GRST_VOMS_SUPPORT
- return GRST_RET_OK;
-}
-#else
+static int GRSTx509VerifyVomsSig(time_t *time1_time, time_t *time2_time,
+ unsigned char *asn1string,
+ struct GRSTasn1TagList taglist[],
+ int lasttag,
+ char *vomsdir)
+{
+#define GRST_ASN1_COORDS_VOMS_DN "-1-1-1-1-3-1-1-1-%d-1-%d"
+#define GRST_ASN1_COORDS_VOMS_INFO "-1-1-1-1"
+#define GRST_ASN1_COORDS_VOMS_SIG "-1-1-1-3"
+ int ret, isig, iinfo;
+ char *certpath, acvomsdn[200];
+ unsigned char *q;
+ DIR *vomsDIR;
+ struct dirent *vomsdirent;
+ X509 *cert;
+ EVP_PKEY *prvkey;
+ FILE *fp;
+ EVP_MD_CTX ctx;
+ time_t voms_service_time1, voms_service_time2;
+
+ if ((vomsdir == NULL) || (vomsdir[0] == '\0')) return GRST_RET_FAILED;
+
+ if (GRSTasn1GetX509Name(acvomsdn, sizeof(acvomsdn),
+ GRST_ASN1_COORDS_VOMS_DN,
+ asn1string, taglist, lasttag) != GRST_RET_OK) return GRST_RET_FAILED;
+
+ iinfo = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_VOMS_INFO);
+ isig = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_VOMS_SIG);
-/*
- int j;
- unsigned int siglen=-1, datalength=-1, dataoffset = -1;
- char s[80];
- unsigned char *charstr, *p, *time1 = NULL, *time2 = NULL, *vo = NULL,
- *uri = NULL, *user = NULL, *group = "NULL", *role = "NULL",
- *cap = "NULL", *server = NULL, *ucuser, *signature = NULL,
- *data = NULL, *datalen = NULL;
- X509_EXTENSION *ex;
- ASN1_STRING *asn1str;
- time_t now, time1_time = 0, time2_time = 0,
- uctime1_time, uctime2_time;
-*/
+ if ((iinfo < 0) || (isig < 0)) return GRST_RET_FAILED;
+ vomsDIR = opendir(vomsdir);
+ if (vomsDIR == NULL) return GRST_RET_FAILED;
+
+ while ((vomsdirent = readdir(vomsDIR)) != NULL)
+ {
+ asprintf(&certpath, "%s/%s", vomsdir, vomsdirent->d_name);
+ fp = fopen(certpath, "r");
+ free(certpath);
+ if (fp == NULL) continue;
+
+ cert = PEM_read_X509(fp, NULL, NULL, NULL);
+ fclose(fp);
+ if (cert == NULL) continue;
+
+ if (GRSTx509NameCmp(acvomsdn,
+ X509_NAME_oneline(X509_get_subject_name(cert),NULL,0)) != 0)
+ {
+ X509_free(cert);
+ continue;
+ }
+
+ prvkey = X509_extract_key(cert);
+ if (prvkey == NULL)
+ {
+ X509_free(cert);
+ continue;
+ }
+
+ OpenSSL_add_all_digests();
+#if OPENSSL_VERSION_NUMBER >= 0x0090701fL
+ EVP_MD_CTX_init(&ctx);
+ EVP_VerifyInit_ex(&ctx, EVP_md5(), NULL);
+#endif
+
+ EVP_VerifyUpdate(&ctx,
+ &asn1string[taglist[iinfo].start+
+ 0*taglist[iinfo].headerlength],
+ taglist[iinfo].length+taglist[iinfo].headerlength);
+
+ ret = EVP_VerifyFinal(&ctx,
+ &asn1string[taglist[isig].start+
+ taglist[isig].headerlength]+1,
+ taglist[isig].length - 1,
+ prvkey);
+
+#if OPENSSL_VERSION_NUMBER >= 0x0090701fL
+ EVP_MD_CTX_cleanup(&ctx);
+#endif
+ EVP_PKEY_free(prvkey);
+
+ if (ret != 1) /* signature doesnt match, look for more */
+ {
+ continue;
+ X509_free(cert);
+ }
+
+ 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;
+
+ X509_free(cert);
+ closedir(vomsDIR);
+ return GRST_RET_OK ; /* verified */
+ }
- struct vomsdata *vd;
- int i, j, vomserror;
+ closedir(vomsDIR);
+ return GRST_RET_FAILED;
+}
- vd = VOMS_Init(NULL, NULL);
+/// 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.
+ */
- if (VOMS_Retrieve(cert, certstack, RECURSE_CHAIN, vd, &vomserror) &&
- (vd->data != NULL))
- {
- for (i = 0; vd->data[i] != NULL; ++i)
- {
- if (vd->data[i]->fqan != NULL)
- for (j = 0; vd->data[i]->fqan[j] != NULL; ++j)
- {
- if (*lastcred >= maxcreds - 1)
- {
- VOMS_Destroy(vd);
- return GRST_RET_OK;
- }
+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-1-1-7-1-2-1-2-%d"
+#define GRST_ASN1_COORDS_USER_DN "-1-1-1-1-2-1-1-1-1-%d-1-%d"
+#define GRST_ASN1_COORDS_TIME1 "-1-1-1-1-6-1"
+#define GRST_ASN1_COORDS_TIME2 "-1-1-1-1-6-2"
+ ASN1_OCTET_STRING *asn1data;
+ char *asn1string, s[81], acuserdn[200], acvomsdn[200];
+ long asn1length;
+ int lasttag=-1, itag, i;
+ 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);
+
+ GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), GRST_ASN1_COORDS_USER_DN,
+ asn1string, taglist, lasttag);
+ if (GRSTx509NameCmp(ucuserdn, acuserdn) != 0) return GRST_RET_FAILED;
+
+ if (GRSTx509VerifyVomsSig(&time1_time, &time2_time,
+ asn1string, taglist, lasttag, vomsdir)
+ != GRST_RET_OK) return GRST_RET_FAILED;
+
+ itag = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_TIME1);
+ actime1 = GRSTasn1TimeToTimeT(&asn1string[taglist[itag].start+
+ taglist[itag].headerlength],
+ taglist[itag].length);
+ if (actime1 > time1_time) time1_time = actime1;
+
+ itag = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_TIME2);
+ 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) || (time2_time < time_now))
+ return GRST_RET_OK; /* expiration isnt invalidity ...? */
+
+ for (i=1; ; ++i)
+ {
+ sprintf(s, GRST_ASN1_COORDS_FQAN, i);
+ itag = GRSTasn1SearchTaglist(taglist, lasttag, s);
- ++(*lastcred);
-
- snprintf(&creds[*lastcred * (credlen + 1)],
- credlen+1,
- "VOMS %010lu %010lu 0 %s",
- GRSTasn1TimeToTimeT(vd->data[i]->date1),
- GRSTasn1TimeToTimeT(vd->data[i]->date2),
- vd->data[i]->fqan[j]);
- }
+ 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
- {
- FILE *fp = fopen("/tmp/getvoms.log", "w");
- fprintf(fp, "%d\n", vomserror);
- fclose(fp);
- }
-
- VOMS_Destroy(vd);
+ else break;
+ }
+
return GRST_RET_OK;
}
-#if 0
+/// 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.
+ */
- time(&now);
+int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen,
+ char *creds, X509 *usercert, STACK_OF(X509) *certstack,
+ char *vomsdir)
+{
+ int i, j, vomsfound=0;
+ 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)));
+ GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(usercert)),0);
uctime2_time =
- GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)));
+ GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)),0);
ucuser =
X509_NAME_oneline(X509_get_subject_name(usercert), NULL, 0);
- 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 */
- {
- asn1str = X509_EXTENSION_get_data(ex);
- charstr = (char *) malloc(ASN1_STRING_length(asn1str) + 1);
- memcpy(charstr, ASN1_STRING_data(asn1str),
- ASN1_STRING_length(asn1str));
- charstr[ASN1_STRING_length(asn1str)] = '\0';
-
- siglen = -1;
-
- if ((sscanf(charstr, "SIGLEN:%u", &siglen) != 1) ||
- (siglen == -1) ||
- ((p = index(charstr, '\n')) == NULL))
- {
- free(charstr);
- continue;
- }
-
- ++p;
-
- if (strncmp(p, "SIGNATURE:", sizeof("SIGNATURE:") - 1) != 0)
- {
- free(charstr);
- continue;
- }
+ for (j=sk_X509_num(certstack)-1; j >= 0; --j)
+ {
+ cert = sk_X509_value(certstack, j);
- signature = &p[sizeof("SIGNATURE:") - 1];
-
- p = &p[siglen + sizeof("SIGNATURE:") - 1];
- data = p;
+ time1_time =
+ GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0);
+ uctime1_time = (time1_time > uctime1_time) ? time1_time:uctime1_time;
- /* nasty pointer arithmetic! */
- dataoffset = (unsigned int) ((long) data - (long) charstr);
- datalength = (unsigned int)
- (ASN1_STRING_length(asn1str) - dataoffset);
+ time2_time =
+ GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0);
+ uctime2_time = (time2_time < uctime2_time) ? time2_time:uctime2_time;
- if (datalength <= 0)
- {
- free(charstr);
- continue;
- }
+ 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);
- while (1)
- {
- if (strncmp(p, "USER:", sizeof("USER:") - 1) == 0)
- {
- p = &p[sizeof("USER:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- user = p;
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- else if (strncmp(p, "TIME1:", sizeof("TIME1:") - 1) == 0)
- {
- p = &p[sizeof("TIME1:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- time1 = p;
- p = index(p, '\n');
- if (p != NULL) *p = '\0';
-
- time1_time = GRSTasn1TimeToTimeT(time1);
- if (time1_time < uctime1_time) time1_time = uctime1_time;
- if (p == NULL) break;
- ++p;
- }
- else if (strncmp(p, "TIME2:", sizeof("TIME2:") - 1) == 0)
- {
- p = &p[sizeof("TIME2:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- time2 = p;
- p = index(p, '\n');
- if (p != NULL) *p = '\0';
-
- time2_time = GRSTasn1TimeToTimeT(time2);
- if (time2_time > uctime2_time) time2_time = uctime2_time;
- if (p == NULL) break;
- ++p;
- }
- else if (strncmp(p, "VO:", sizeof("VO:") - 1) == 0)
- {
- p = &p[sizeof("VO:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- vo = p;
-
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- else if (strncmp(p, "SERVER:", sizeof("SERVER:") - 1) == 0)
- {
- p = &p[sizeof("SERVER:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- server = p;
-
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- else if (strncmp(p, "DATALEN:", sizeof("DATALEN:") - 1) == 0)
- {
- p = &p[sizeof("DATALEN:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- datalen = p;
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- break;
- }
- else /* not something we use */
- {
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- }
-/*
- if ((now >= time1_time) &&
- (now <= time2_time) &&
- (signature != NULL) &&
- (data != NULL) &&
- (siglen > 0) &&
- (user != NULL) &&
- (ucuser != NULL) &&
- (strcmp(user, ucuser) == 0) &&
- (GRSTx509CheckVomsSig(signature, siglen,
- &((ASN1_STRING_data(asn1str))[dataoffset]),
- datalength, vomsdir, vo,
- server) == GRST_RET_OK))
- while (1)
-*/
+ if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */
{
- if (strncmp(p, "GROUP:", sizeof("GROUP:") - 1) == 0)
- {
- p = &p[sizeof("GROUP:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- group = p;
- role = "NULL";
- cap = "NULL";
-
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- else if (strncmp(p, "ROLE:", sizeof("ROLE:") - 1) == 0)
- {
- p = &p[sizeof("ROLE:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- role = p;
-
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
- else if (strncmp(p, "CAP:", sizeof("CAP:") - 1) == 0)
- {
- p = &p[sizeof("CAP:") - 1];
- while ((*p != '\n') && (*p != '\0') && (*p <= ' ')) ++p;
- cap = p;
-
- p = index(p, '\n');
- if (p != NULL) *p = '\0';
-
- if (*lastcred < maxcreds - 1)
- {
- ++(*lastcred);
-
- if ((strcmp(role, "NULL") == 0) &&
- (strcmp(cap , "NULL") == 0))
- snprintf(&creds[*lastcred * (credlen + 1)], credlen+1,
- "VOMS %010lu %010lu 0 /%s%s",
- time1_time, time2_time, vo, group);
- else if ((strcmp(role, "NULL") != 0) &&
- (strcmp(cap , "NULL") == 0))
- snprintf(&creds[*lastcred * (credlen + 1)], credlen+1,
- "VOMS %010lu %010lu 0 /%s%s/Role=%s",
- time1_time, time2_time, vo, group, role);
- else if ((strcmp(role, "NULL") == 0) &&
- (strcmp(cap , "NULL") != 0))
- snprintf(&creds[*lastcred * (credlen + 1)], credlen+1,
- "VOMS %010lu %010lu 0 /%s%s/Capability=%s",
- time1_time, time2_time, vo, group, cap);
- else
- snprintf(&creds[*lastcred * (credlen + 1)], credlen+1,
- "VOMS %010lu %010lu 0 /%s%s/Role=%s/Capability=%s",
- time1_time, time2_time, vo, group, role, cap);
- }
-
- if (p == NULL) break;
- ++p;
- }
- else /* not something we use */
- {
- p = index(p, '\n');
- if (p == NULL) break;
- *p = '\0';
- ++p;
- }
+ vomsfound=1;
+ GRSTx509ParseVomsExt(lastcred, maxcreds, credlen, creds,
+ uctime1_time, uctime2_time,
+ ex, ucuser, vomsdir);
}
-
- free(charstr);
- }
- }
+ }
+
+ if (vomsfound) return GRST_RET_OK;
+ }
return GRST_RET_OK;
}
-#endif
-
-#endif
/// Turn a Compact Cred line into a GRSTgaclCred object
/**
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))),
- GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert))),
+ 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)
||
if ((gsiproxycert != NULL)
&&
(snprintf(credtemp, credlen+1, "GSIPROXY %010lu %010lu %d %s",
- GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(gsiproxycert))),
- GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(gsiproxycert))),
+ 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);
strcpy(&creds[*lastcred * (credlen + 1)], credtemp);
-
+
GRSTx509GetVomsCreds(lastcred, maxcreds, credlen, creds,
- gsiproxycert, certstack, vomsdir);
+ usercert, certstack, vomsdir);
+
}
return GRST_RET_OK;
{
char *ptr, *certchain;
int i, subjAltName_pos, ncerts;
- long serial = 1, ptrlen;
+ long serial = 2796, ptrlen;
EVP_PKEY *pkey, *CApkey;
const EVP_MD *digest;
X509 *certs[GRST_MAX_CHAIN_LEN];
const EVP_MD *digest;
struct stat statbuf;
- if ((keypair = RSA_generate_key(GRST_KEYSIZE, 3, NULL, NULL)) == NULL)
+ if ((keypair = RSA_generate_key(GRST_KEYSIZE, 65537, NULL, NULL)) == NULL)
return 1;
asprintf(&prvkeyfile, "%s/.XXXXXX", proxydir);
return 0;
}
+/// 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;
+}
+
+/// 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);
+}
+
/// 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
int GRSTx509CacheProxy(char *proxydir, char *delegation_id,
char *user_dn, char *proxychain)
{
- int fd, c, len = 0, i;
- char *cert, *upcertfile, *prvkeyfile, *p;
+ int c, len = 0, i;
+ char *upcertfile, *upcertpath, *prvkeyfile, *p, *ptr;
FILE *ifp, *ofp;
+ STACK_OF(X509) *certstack;
+ BIO *certmem;
+ X509 *cert;
+ long ptrlen;
prvkeyfile = GRSTx509CachedProxyKeyFind(proxydir, delegation_id, user_dn);
if (prvkeyfile == NULL)
{
- free(proxydir);
return GRST_RET_FAILED;
}
if ((ifp = fopen(prvkeyfile, "r")) == NULL)
{
free(prvkeyfile);
- free(proxydir);
return GRST_RET_FAILED;
}
- if (asprintf(&upcertfile, "%s/XXXXXX", proxydir) == -1)
+// fprintf(stderr, "\n\n\n\n PROXYCHAIN = \n %s", proxychain);
+ if (GRSTx509StringToChain(&certstack, proxychain) != GRST_RET_OK)
return GRST_RET_FAILED;
- if ((fd = mkstemp(upcertfile)) == -1)
+ upcertfile = GRSTx509MakeProxyFileName(delegation_id, certstack);
+
+ if (upcertfile == NULL)
{
- fclose(ifp);
free(prvkeyfile);
- free(upcertfile);
+ sk_X509_free(certstack);
return GRST_RET_FAILED;
}
- if ((ofp = fdopen(fd, "w")) == NULL)
+ asprintf(&upcertpath, "%s/%s", proxydir, upcertfile);
+ ofp = fopen(upcertpath, "w");
+ chmod(upcertpath, S_IRUSR | S_IWUSR);
+ free(upcertpath);
+
+ if (ofp == NULL)
{
- close(fd);
fclose(ifp);
free(prvkeyfile);
free(upcertfile);
fprintf(ofp, "%s\n%s\n", delegation_id, user_dn);
- fputs(proxychain, ofp); /* write out certificates */
+ /* 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);
+ }
- while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); /* append proxy private key */
-
- if (fclose(ifp) != 0) return GRST_RET_FAILED;
- if (fclose(ofp) != 0) return GRST_RET_FAILED;
+ /* insert proxy private key */
+ 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);
+ }
+ }
+
+ fputs(proxychain, ofp); /* write out certificates */
+
+
+ sk_X509_free(certstack);
free(upcertfile);
+ if (fclose(ifp) != 0) return GRST_RET_FAILED;
+ if (fclose(ofp) != 0) return GRST_RET_FAILED;
+
/* should also check validity of proxy cert to avoid suprises? */
return GRST_RET_OK;
--- /dev/null
+/*
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <ctype.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <fnmatch.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#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 <Subject> or <AnySubjects/>, 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
+ <Rule> tag refers to the same <Target> by checking the <RuleId> 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 <Rule> tag found
+ // if (xmlStrcmp(cur->name, (const xmlChar *) "Rule") != 0) return NULL;
+ // cur and rule_root point to the <Rule> tag
+
+ cur = cur->xmlChildrenNode->xmlChildrenNode;
+ // cur should now be pointing at <Subjects> 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 <Subjects> tag make cur2 point to <Subject> 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-><Action>
+ 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-><Action>
+ 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 <Subjects> 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 */
+ {
+ free(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 <Target> tag and set cur to first <Rule> 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);
+ xmlFreeDoc(doc);
+ 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<Subject>\n", fp);
+ fputs("\t\t\t\t\t<SubjectMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
+ fputs("\t\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", 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("</AttributeValue>\n", fp);
+
+ fputs("\t\t\t\t\t\t<SubjectAttributeDesignator\n", fp);
+ fputs("\t\t\t\t\t\t\tAttributeId=", fp);
+ fprintf(fp, "\"%s\"\n", cred->type);
+ fputs("\t\t\t\t\t\t\tDataType=", fp);
+ fprintf(fp, "\"%s\"/>\n", p->name);
+ fputs("\t\t\t\t\t</SubjectMatch>\n", fp);
+ fputs("\t\t\t\t</Subject>\n", fp);
+ p = (GRSTgaclNamevalue *) p->next;
+ } while (p != NULL);
+
+ }
+ else fputs("\t\t\t\t<AnySubject/>\n", fp);
+
+ return 1;
+}
+
+
+int GRSTxacmlEntryPrint(GRSTgaclEntry *entry, FILE *fp, int rule_number)
+{
+ GRSTgaclCred *cred;
+ GRSTgaclPerm i;
+
+ if (entry->allowed){
+
+ fprintf(fp, "\t<Rule RuleId=\"Entry%dA\" Effect=\"Permit\">\n", rule_number);
+ fputs("\t\t<Target>\n", fp);
+ fputs("\t\t\t<Subjects>\n", fp);
+
+ for (cred = entry->firstcred; cred != NULL; cred = cred->next)
+ GRSTxacmlCredPrint(cred, fp);
+
+ fputs("\t\t\t</Subjects>\n", fp);
+ fputs("\t\t\t<Actions>\n", fp);
+
+ for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
+ if ((entry->allowed) & i) GRSTxacmlPermPrint(i, fp);
+
+ fputs("\t\t\t</Actions>\n", fp);
+ fputs("\t\t</Target>\n", fp);
+ fputs("\t</Rule>\n", fp);
+ }
+
+ if (entry->denied){
+
+ fprintf(fp, "\t<Rule RuleId=\"Entry%dD\" Effect=\"Deny\">\n", rule_number);
+ fputs("\t\t<Target>\n", fp);
+ fputs("\t\t\t<Subjects>\n", fp);
+
+ for (cred = entry->firstcred; cred != NULL; cred = cred->next)
+ GRSTxacmlCredPrint(cred, fp);
+
+ fputs("\t\t\t</Subjects>\n", fp);
+ fputs("\t\t\t<Actions>\n", fp);
+
+ for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
+ if (entry->denied & i) GRSTxacmlPermPrint(i, fp);
+
+ fputs("\t\t\t</Actions>\n", fp);
+ fputs("\t\t</Target>\n", fp);
+ fputs("\t</Rule>\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<Action>\n", fp);
+ fputs("\t\t\t\t\t<ActionMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
+ fputs("\t\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", fp);
+ fprintf(fp, "%s", grst_perm_syms[i]);
+ fputs("</AttributeValue>\n", fp);
+ fputs("\t\t\t\t\t\t<ActionAttributeDesignator\n", fp);
+ fputs("\t\t\t\t\t\t\tAttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\"\n", fp);
+ fputs("\t\t\t\t\t\t\tDataType=\"http://www.w3.org/2001/XMLSchema#string\"/>\n", fp);
+ fputs("\t\t\t\t\t</ActionMatch>\n", fp);
+ fputs("\t\t\t\t</Action>\n",fp);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int GRSTxacmlAclPrint(GRSTgaclAcl *acl, FILE *fp, char* dir_uri)
+{
+ GRSTgaclEntry *entry;
+ int rule_number=1;
+
+ fputs("<Policy", fp);
+ fputs("\txmlns=\"urn:oasis:names:tc:xacml:1.0:policy\"\n", fp);
+ fputs("\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n", fp);
+ fputs("\txsi:schemaLocation=\"urn:oasis:names:tc:xacml:1.0:policy cs-xacml-schema-policy-01.xsd\"\n", fp);
+ fputs("\tPolicyId=\"GridSitePolicy\"\n", fp);
+ fputs("\tRuleCombiningAlgId=\"urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides\">\n\n", fp);
+
+ fputs("\t<Target>\n\t\t<Resources>\n\t\t\t<Resource>\n", fp);
+ fputs("\t\t\t\t<ResourceMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
+ fputs("\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", fp);
+ fprintf(fp, "%s", dir_uri);
+ fputs("</AttributeValue>\n", fp);
+ fputs("\t\t\t\t\t<ResourceAttributeDesignator\n", fp);
+ fputs("\t\t\t\t\t\tAttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"\n", fp);
+ fputs("\t\t\t\t\t\tDataType=\"http://www.w3.org/2001/XMLSchema#string\"/>\n", fp);
+
+ fputs("\t\t\t\t</ResourceMatch>\n\t\t\t</Resource>\n\t\t</Resources>\n\t\t<Subjects>\n\t\t\t<AnySubject/>\n\t\t</Subjects>", fp);
+ fputs("\n\t\t<Actions>\n\t\t\t<AnyAction/>\n\t\t</Actions>\n\t</Target>\n\n", fp);
+
+ for (entry = acl->firstentry; entry != NULL; entry = entry->next){
+
+ GRSTxacmlEntryPrint(entry, fp, rule_number);
+ rule_number++;
+ }
+
+ fputs("</Policy>\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,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+
+ ret = GRSTxacmlAclPrint(acl, fp, dir_uri);
+
+ fclose(fp);
+
+ return ret;
+}
+
+
+
+
--- /dev/null
+/* 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 <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <time.h>
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#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 <utime.h>
+#include <errno.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+/******************************************************************************
+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 */
+}
+
+/******************************************************************************
+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;
+
+ if (key[0] != '/') return 1; /* must be a proper X.509 DN or path */
+
+ encodedkey = mapdir_urlencode(key);
+log_err("encodedkey=%s\n", encodedkey);
+ *target_uname = mapdir_otherlink(mapdir, encodedkey);
+log_err("*target_uname=%s\n", *target_uname);
+
+ 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);
+
+// nasty hack for now
+*target_gname = strdup(*target_uname);
+
+ 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"
+ "<html><head><title>500 Internal Server Error</title></head>\n"
+ "<body><h1>Internal Server Error</h1></body></html>");
+}
+
+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"
+ "<html><head><title>403 Forbidden</title></head>\n"
+ "<body><h1>Forbidden</h1></body></html>");
+}
+
+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 *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");
+// log_err("mapping_type from GRST_EXEC_METHOD=%s\n",mapping_type);
+ 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)
+ {
+// log_err("X509DN mapping type\n");
+ if ((map_x509dn = getenv("GRST_CRED_0")) == NULL)
+ map_x509dn = getenv("SSL_CLIENT_S_DN");
+
+ 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);
+}
--- /dev/null
+/* 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 */
/*
- Copyright (c) 2003-4, Andrew McNab, University of Manchester
+ Copyright (c) 2003-5, Andrew McNab and Shiv Kaushal, University of Manchester
All rights reserved.
Redistribution and use in source and binary forms, with or
#include <http_log.h>
#include <http_protocol.h>
#include <http_request.h>
+#include <unixd.h>
#include <stdio.h>
#include <sys/types.h>
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 downgrade;
- char *authcookiesdir;
- int soap2cgi;
+ 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 downgrade;
+ char *authcookiesdir;
+ int soap2cgi;
+ char *aclformat;
+ char *execmethod;
+ ap_unix_identity_t execugid;
+ apr_fileperms_t diskmode;
} mod_gridsite_cfg; /* per-directory config choices */
p[1] = '\0';
/* dir_uri always gets both a leading and a trailing slash */
- out = apr_pstrdup(r->pool, "<p><small>\n");
+ out = apr_pstrdup(r->pool, "<p>\n");
if (!isdirectory)
{
localtime_r(&mtime_time, &mtime_tm);
strftime(modified, sizeof(modified),
"%a %e %B %Y", &mtime_tm);
- temp = apr_psprintf(r->pool,"<hr>Last modified %s\n", modified);
+ temp = apr_psprintf(r->pool,"<hr><small>Last modified %s\n", modified);
out = apr_pstrcat(r->pool, out, temp, NULL);
if ((conf->adminuri != NULL) &&
(strncmp(file, GRST_HIST_PREFIX, sizeof(GRST_HIST_PREFIX)-1) != 0))
{
temp = apr_psprintf(r->pool,
- ". <a href=\"%s?cmd=history&file=%s\">"
+ ". <a href=\"%s?cmd=history&file=%s\">"
"View page history</a>\n",
conf->adminfile, file);
out = apr_pstrcat(r->pool, out, temp, NULL);
}
+
+ out = apr_pstrcat(r->pool, out, "</small>", NULL);
}
- out = apr_pstrcat(r->pool, out, "<hr>", NULL);
+ out = apr_pstrcat(r->pool, out, "<hr><small>", NULL);
if (r->connection->notes != NULL)
grst_cred_0 = (char *)
sizeof(GRST_HIST_PREFIX) - 1) != 0))
{
temp = apr_psprintf(r->pool,
- "<a href=\"%s?cmd=edit&file=%s\">"
+ "<a href=\"%s?cmd=edit&file=%s\">"
"Edit page</a> .\n", conf->adminfile, file);
out = apr_pstrcat(r->pool, out, temp, NULL);
}
(conf->adminfile != NULL) &&
(conf->adminfile[0] != '\0'))
{
- temp = apr_psprintf(r->pool, ". <a href=\"%s?cmd=print&file=%s\">"
+ temp = apr_psprintf(r->pool, ". <a href=\"%s?cmd=print&file=%s\">"
"Print View</a>\n", conf->adminfile, file);
out = apr_pstrcat(r->pool, out, temp, NULL);
}
(r->unparsed_uri[0] != '\0') &&
(r->unparsed_uri[strlen(r->unparsed_uri) - 1] == '/'))
{
- if (apr_dir_make(r->filename, APR_UREAD | APR_UWRITE | APR_UEXECUTE,
- r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR;
+ 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 *** */
if (apr_file_open(&fp, r->filename, APR_WRITE | APR_CREATE | APR_BUFFERED,
- APR_UREAD | APR_UWRITE, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR;
+ conf->diskmode, 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);
+
// TODO: need to add Range: support at some point too
retcode = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
mod_gridsite_cfg *conf = apr_palloc(p, sizeof(*conf));
if (path == NULL) /* set up server defaults */
- {
+ {
conf->auth = 0; /* GridSiteAuth on/off */
conf->envs = 1; /* GridSiteEnvs on/off */
conf->format = 0; /* GridSiteHtmlFormat on/off */
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);
+ conf->footfile = apr_pstrdup(p, GRST_FOOTFILE);
/* GridSiteHeadFile and GridSiteFootFile file name */
conf->downgrade = 0; /* GridSiteDowngrade on/off */
conf->authcookiesdir = apr_pstrdup(p, "gridauthcookies");
/* GridSiteAuthCookiesDir dir-path */
conf->soap2cgi = 0; /* GridSiteSoap2cgi on/off */
+ conf->aclformat = apr_pstrdup(p, "GACL");
+ /* GridSiteACLFormat gacl/xacml */
+ 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->downgrade = UNSET; /* GridSiteDowngrade on/off */
conf->authcookiesdir= NULL; /* GridSiteAuthCookiesDir dir-path */
conf->soap2cgi = UNSET; /* GridSiteSoap2cgi on/off */
+ conf->aclformat = NULL; /* GridSiteACLFormat gacl/xacml */
+ 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,
+static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver,
void *vdirect)
/* merge directory with server-wide directory configs */
{
mod_gridsite_cfg *conf, *server, *direct;
-
+
server = (mod_gridsite_cfg *) vserver;
direct = (mod_gridsite_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->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)
+
+ 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->downgrade != UNSET) conf->downgrade = direct->downgrade;
else conf->downgrade = server->downgrade;
if (direct->soap2cgi != UNSET) conf->soap2cgi = direct->soap2cgi;
else conf->soap2cgi = server->soap2cgi;
+
+ if (direct->aclformat != NULL) conf->aclformat = direct->aclformat;
+ else conf->aclformat = server->aclformat;
+
+ 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;
}
((mod_gridsite_cfg *) cfg)->authcookiesdir =
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_cfg *) cfg)->aclformat = apr_pstrdup(a->pool, parm);
+ }
+ else if (strcasecmp(a->cmd->name, "GridSiteExecMethod") == 0)
+ {
+ if (strcasecmp(parm, "nosetuid") == 0)
+ {
+ ((mod_gridsite_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_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)
+{
+ 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_cfg *) cfg)->execugid.uid = ap_uname2id(parm1);
+ ((mod_gridsite_cfg *) cfg)->execugid.gid = ap_gname2id(parm2);
+ ((mod_gridsite_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_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));
+ }
+
return NULL;
}
AP_INIT_TAKE1("GridSiteIndexHeader", mod_gridsite_take1_cmds,
NULL, OR_FILEINFO, "filename of directory header"),
- AP_INIT_FLAG("GridSiteDowngrade", mod_gridsite_flag_cmds,
+ AP_INIT_FLAG("GridSiteDowngrade", mod_gridsite_flag_cmds,
NULL, OR_FILEINFO, "on or off"),
AP_INIT_TAKE1("GridSiteAuthCookiesDir", mod_gridsite_take1_cmds,
NULL, OR_FILEINFO, "directory with Grid Auth Cookies"),
-
+
AP_INIT_FLAG("GridSiteSoap2cgi", mod_gridsite_flag_cmds,
NULL, OR_FILEINFO, "on or off"),
+
+ AP_INIT_TAKE1("GridSiteACLFormat", mod_gridsite_take1_cmds,
+ NULL, OR_FILEINFO, "format to save access control lists in"),
+
+ 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}
};
apr_table_setn(env, "GRST_ADMIN_LIST",
((mod_gridsite_cfg *) cfg)->adminlist);
- apr_table_setn(env, "GRST_GSIPROXY_LIMIT",
- apr_psprintf(r->pool, "%d",
+ apr_table_setn(env, "GRST_GSIPROXY_LIMIT",
+ apr_psprintf(r->pool, "%d",
((mod_gridsite_cfg *)cfg)->gsiproxylimit));
if (((mod_gridsite_cfg *) cfg)->unzip != NULL)
if (!(((mod_gridsite_cfg *) cfg)->gridsitelink))
apr_table_setn(env, "GRST_NO_LINK", "1");
+
+ if (((mod_gridsite_cfg *) cfg)->aclformat != NULL)
+ apr_table_setn(env, "GRST_ACL_FORMAT",
+ ((mod_gridsite_cfg *) cfg)->aclformat);
+
+ if (((mod_gridsite_cfg *) cfg)->execmethod != NULL)
+ {
+ apr_table_setn(env, "GRST_EXEC_METHOD",
+ ((mod_gridsite_cfg *) cfg)->execmethod);
+
+ if ((strcasecmp(((mod_gridsite_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_cfg *)cfg)->diskmode));
}
-
+
if (((mod_gridsite_cfg *) cfg)->auth)
{
/* *** Check HTTP method to decide which perm bits to check *** */
-
+
if (r->filename != NULL)
{
file = rindex(r->filename, '/');
else file = NULL;
content_type = r->content_type;
- if ((content_type != NULL) &&
+ if ((content_type != NULL) &&
(strcmp(content_type, DIR_MAGIC_TYPE) == 0) &&
(((mod_gridsite_cfg *) cfg)->dnlistsuri != NULL) &&
(strncmp(r->uri,
strlen(((mod_gridsite_cfg *) cfg)->dnlistsuri)) == 0) &&
(strlen(r->uri) > strlen(((mod_gridsite_cfg *) cfg)->dnlistsuri)))
content_type = "text/html";
-
+
if ( GRSTgaclPermHasNone(perm) ||
/* first two M_GET conditions make the subtle distinction
Read perm) or to dir list (governed by List perm);
third M_GET condition deals with typeless CGI requests */
- ((r->method_number == M_GET) &&
+ ((r->method_number == M_GET) &&
!GRSTgaclPermHasRead(perm) &&
(content_type != NULL) &&
(strcmp(content_type, DIR_MAGIC_TYPE) != 0)) ||
- ((r->method_number == M_GET) &&
+ ((r->method_number == M_GET) &&
!GRSTgaclPermHasList(perm) &&
(content_type != NULL) &&
(strcmp(content_type, DIR_MAGIC_TYPE) == 0)) ||
- ((r->method_number == M_GET) &&
+ ((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)) &&
(((r->method_number == M_PUT) || (r->method_number == M_DELETE)) &&
!GRSTgaclPermHasAdmin(perm) &&
- (file != NULL) &&
+ (file != NULL) &&
(strcmp(file, GRST_ACL_FILE) == 0) ) ) retcode = HTTP_FORBIDDEN;
}
return mod_gridsite_nondir_handler(r, conf);
}
+static ap_unix_identity_t *mod_gridsite_get_suexec_id_doer(const request_rec *r)
+{
+ mod_gridsite_cfg *conf;
+
+ conf = (mod_gridsite_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)
{
/* set up the Soap2cgi input and output filters */
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 =
--- /dev/null
+
+#include <stdio.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+
+#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;
+
+ 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);
+
+/*
+ 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]);
+*/
+ }
+}
--- /dev/null
+/*
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <gridsite.h>
+
+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;
+}
+